All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 6.12 000/877] 6.12.112-rc1 review
@ 2026-09-30 15:15 Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 001/877] Revert "hwmon: (emc1403) Drop hysteresis for low limit temperature" Greg Kroah-Hartman
                   ` (884 more replies)
  0 siblings, 885 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, linux-kernel, torvalds, akpm, linux,
	shuah, patches, lkft-triage, pavel, jonathanh, f.fainelli,
	sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr

This is the start of the stable review cycle for the 6.12.112 release.
There are 877 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 Fri, 02 Oct 2026 15:23:04 +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.12.112-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.12.y
and the diffstat can be found below.

thanks,

greg k-h

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

Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Linux 6.12.112-rc1

Longlong Xia <xialonglong@kylinos.cn>
    mm/hugetlb: keep max_huge_pages when dissolving surplus folios

Jiayuan Chen <jiayuan.chen@linux.dev>
    bpf: Reject key-less BTF for hash maps

Pei Xiao <xiaopei01@kylinos.cn>
    usb: dwc3: gadget: Fix use-after-free in dwc3_gadget_free_endpoints due to race condition

Mario Limonciello <mario.limonciello@amd.com>
    platform/x86/amd/pmc: Fix LPS0 and debugfs leaks when STB init fails

Miquel Raynal (DAVE) <miquel.raynal@bootlin.com>
    mtd: rawnand: pl353: Fix debug prints

Steven Rostedt <rostedt@goodmis.org>
    tracing: Move d_max_latency out of CONFIG_FSNOTIFY protection

Ben Hutchings <benh@debian.org>
    bootconfig: Fix negative seeks on 32-bit with LFS enabled

Christoph Hellwig <hch@lst.de>
    nvme: revert the cross-controller atomic write size validation

Lin.Cao <lincao12@amd.com>
    drm/amdgpu: fix ring timeout issue in gfx10 sr-iov environment

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: don't free fd-owned sockets when reaping in the heartbeat

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: clear neighbour pointer in rose_kill_by_device()

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: cancel neighbour timers in rose_neigh_put() before freeing

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: drop CALL_REQUEST in loopback timer when device is not running

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: release netdev ref and destroy orphaned incoming sockets

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: fix netdev double-hold in rose_make_new()

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: disconnect orphaned STATE_2 sockets when device is gone

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: set SOCK_DESTROY in rose_kill_by_device() for prompt cleanup

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: fix notifier unregistered too early in rose_exit()

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: fix netdev double-hold in rose_rx_call_request()

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: guard rose_neigh_put() against NULL in timer expiry

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: clear neighbour pointer after rose_neigh_put() in state machines

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: fix race between loopback timer and module removal

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: hold loopback neighbour reference across timer callback

Bernard Pidoux <bernard.f6bvp@gmail.com>
    rose: fix dev_put() leak in rose_loopback_timer()

Xie Bo <xb@ultrarisc.com>
    RISC-V: KVM: Serialize IMSIC attributes with vCPU migration

Jiakai Xu <jiakaipeanut@gmail.com>
    RISC-V: KVM: Fix null pointer dereference in kvm_riscv_aia_imsic_rw_attr()

Dapeng Mi <dapeng1.mi@linux.intel.com>
    perf/x86/intel: Fix GRT PEBS load/store direction for latency events, to fix sample classification

Dapeng Mi <dapeng1.mi@linux.intel.com>
    perf/x86/intel: Update event constraints and cache_extra_regsfor ADL

Dapeng Mi <dapeng1.mi@linux.intel.com>
    perf/x86/intel: Remove incorrect LionCove PEBS data-source constraints

Dapeng Mi <dapeng1.mi@linux.intel.com>
    perf/x86/intel: Update event constraints and cache_extra_regsfor LNL

Sean Christopherson <seanjc@google.com>
    KVM: SEV: Do cache maintenance on the source VM during intra-host migration

Zheyun Shen <szy0127@sjtu.edu.cn>
    KVM: SVM: Flush cache only on CPUs running SEV guest

Guangshuo Li <lgs201920130244@gmail.com>
    net: ena: fix MMIO read buffer leak on probe failure

Dr. David Alan Gilbert <linux@treblig.org>
    net: ena: Remove autopolling mode

Yuqi Xu <xuyuqiabc@gmail.com>
    net: ipconfig: bound DHCP option construction

Thorsten Blum <thorsten.blum@linux.dev>
    net: ipconfig: Remove outdated comment and indent code block

Ilya Maximets <i.maximets@ovn.org>
    net/sched: act_ct: avoid modifying shared unconfirmed ct entry

Ilya Maximets <i.maximets@ovn.org>
    net/sched: act_ct: fix helper UAF due to extensions realloc

Chen Changcheng <chenchangcheng@kylinos.cn>
    HID: alps: unregister DualPoint Stick input device on remove

Bastien Nocera <hadess@hadess.net>
    HID: hid-alps: Use pm_ptr instead of #ifdef CONFIG_PM

Willem de Bruijn <willemb@google.com>
    packet: use ubuf_info completion for TX_RING packets

Liz Fong-Jones <lizf@honeycomb.io>
    PCI: Fix BAR resize for devices on a root bus

Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
    PCI: Fix Resizable BAR restore order

Christian Brauner <brauner@kernel.org>
    super: make iterate_supers_type() deletion-safe

Longlong Xia <xialonglong@kylinos.cn>
    mm/hugetlb: do not dissolve gigantic pages without runtime support

Usama Arif <usamaarif642@gmail.com>
    mm/hugetlb: create hstate_is_gigantic_no_runtime helper

Jinjiang Tu <tujinjiang@huawei.com>
    mm/hugetlb: fix surplus pages in dissolve_free_huge_page()

SJ Park <sj@kernel.org>
    mm/damon/vaddr: avoid hw-driven pte updates during damon_hugetlb_mkold()

Matthew Auld <matthew.auld@intel.com>
    drm/xe/vm: nuke PTs only after unlinking contested VMAs

Jinjiang Tu <tujinjiang@huawei.com>
    mm/rmap: fix missing barrier between anon_vma init and vma->anon_vma publish

Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
    mm/rmap: allocate anon_vma_chain objects unlocked when possible

Imre Deak <imre.deak@intel.com>
    drm/i915/dp_mst: Fix configuring FEC for a disconnected stream

Jani Nikula <jani.nikula@intel.com>
    drm/i915/mst: add mst sub-struct to struct intel_dp

shechenglong <shechenglong@xfusion.com>
    drm/client: fix restore of partially initialized client

Thomas Zimmermann <tzimmermann@suse.de>
    drm/client: Pass force parameter to client restore

Wentao Liang <vulab@iscas.ac.cn>
    drm/amdgpu: Fix acpi device leak in amdgpu_acpi_enumerate_xcc()

Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
    i2c: qcom-geni: Fix hardcoded clock index in SE_GENI_CLK_SEL

Myeonghun Pak <mhun512@gmail.com>
    bna: prevent IOC timer rearm during teardown

Fan Wu <wufan@kernel.org>
    ipe: fix use-after-free when auditing a newly loaded policy

Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
    gpio: cdev: fix kernel stack leak to user-space in error path

Xiang Mei <xmei5@asu.edu>
    vlan: require the MAC header to be present in __vlan_insert_inner_tag()

Fuad Tabba <fuad.tabba@linux.dev>
    arm64/boot: Disable trapping of PMZR_EL0 writes to EL2

April Cardenas <april.cardenas@canonical.com>
    smb/client: send lease break ACKs thru correct session for multiuser mounts

Frank Sorenson <sorenson@redhat.com>
    smb: client: fix reparse buffer bounds in cifs_query_reparse_point()

Mike Lothian <mike@fireburn.co.uk>
    drm/amdgpu: hold a runtime PM reference for P2P dma-buf attachments

Yunxiang Li <Yunxiang.Li@amd.com>
    drm: add drm_memory_stats_is_zero

Frank Sorenson <sorenson@redhat.com>
    smb: client: fix OOB struct field reads in move_smb2_ea_to_cifs()

Chengjun Yao <Chengjun.Yao@amd.com>
    drm/amdgpu: fix rmmio iounmap skipped on device removal

Christian König <christian.koenig@amd.com>
    drm/amdgpu: use GFP_NOWAIT for memory allocations

Saleemkhan Jamadar <saleemkhan.jamadar@amd.com>
    drm/amdgpu/umsch: remove vpe test from umsch

Christian König <christian.koenig@amd.com>
    drm/amdgpu: set the VM pointer to NULL in amdgpu_job_prepare

Andrew Martin <Andrew.Martin@amd.com>
    drm/amdgpu: Failed to check various return code

Joseph Qi <joseph.qi@linux.alibaba.com>
    smb: client: fix use-after-free of iface in cifs_try_adding_channels()

Bharath SM <bharathsm@microsoft.com>
    smb: mark the new channel addition log as informational log with cifs_info

Devin Wittmayer <lucid_duck@justthetip.ca>
    wifi: mac80211: refuse to make a monitor active when it has no queue

Benjamin Berg <benjamin.berg@intel.com>
    wifi: mac80211: track MU-MIMO configuration on disabled interfaces

Daehyeon Ko <4ncienth@gmail.com>
    wifi: libipw: reject TKIP frames without a full MIC

Saim Shujah <saimzst@gmail.com>
    drm/msm/dpu: clear pending peripheral flush state

Yibo Tan <lhfff@tju.edu.cn>
    hwmon: (pwm-fan) Stop RPM timer before freeing tach data

Fan Wu <fanwu01@zju.edu.cn>
    wifi: wcn36xx: Fix potential use-after-free in TX ack timer teardown

Runyu Xiao <runyu.xiao@seu.edu.cn>
    Input: hp_sdc - shut down kicker timer on module exit

Arun Easi <aeasi@cisco.com>
    scsi: fnic: Fix missed link-up when critical IRQ targets offline CPU

Liu Zhenlong <dragonliu2018@gmail.com>
    i2c: qcom-cci: fix device_node refcount leak in cci_probe()/cci_remove()

Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
    i2c: qcom-cci: Remove the unused variable cci_clk_rate

Bryan O'Donoghue <bryan.odonoghue@linaro.org>
    i2c: qcom-cci: Stop complaining about DT set clock rate

Mark Rutland <mark.rutland@arm.com>
    arm64: percpu: Fix LSE operations on {8,16}-bit types

Catalin Marinas <catalin.marinas@arm.com>
    arm64: Use load LSE atomics for the non-return per-CPU atomic operations

Hongling Zeng <zenghongling@kylinos.cn>
    btrfs: take commit root semaphore when iterating in mark_block_group_to_copy()

Ahmed Naseef <naseefkm@gmail.com>
    net: phy: mediatek: do not report link and per-speed LED rules together

Donggeun Yoo <donggeunyoo.kernel@gmail.com>
    swiotlb: use the adjusted address for the highmem page lookup

Xiang Mei <xmei5@asu.edu>
    ALSA: usb-audio: Clamp implicit feedback packet count to URB capacity

Takashi Iwai <tiwai@suse.de>
    ALSA: usb-audio: Optimize the copy of packet sizes for implicit fb handling

Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
    phy: renesas: rcar-gen3-usb2: Avoid long delay in atomic context

David Howells <dhowells@redhat.com>
    9p: Fix v9fs_issue_write() to update i_size and remote_i_size

David Howells <dhowells@redhat.com>
    cifs: Fix specification of function pointers

Darrick J. Wong <djwong@kernel.org>
    xfs: fix backwards mergeability logic in refcount scrubber

Darrick J. Wong <djwong@kernel.org>
    xfs: fix under-reservation of blocks when repairing sf directories

Christoph Hellwig <hch@lst.de>
    xfs: remove the i_ino field in struct xfs_inode

Darrick J. Wong <djwong@kernel.org>
    xfs: strengthen the "is cow staging" helpers in scrub

Darrick J. Wong <djwong@kernel.org>
    xfs: fix short ifork reaping computation in xreap_bmapi_binval

Darrick J. Wong <djwong@kernel.org>
    xfs: report healthy filesystem events in scrub stats

Bjoern Doebel <doebel@amazon.de>
    smb: client: fail DACL rewrite when the new DACL exceeds 64K

Ralph Boehme <slow@samba.org>
    smb/client: fix security flag calculation when setting security descriptors

Ralph Boehme <slow@samba.org>
    smb: client: refactor ACL setting control flow in id_mode_to_cifs_acl()

Paolo Abeni <pabeni@redhat.com>
    mptcp: prevent race between disconnect() and rtx

Paolo Abeni <pabeni@redhat.com>
    mptcp: do not reschedule the RTX timer for fallback sockets

Eric Dumazet <edumazet@google.com>
    tcp: introduce icsk->icsk_keepalive_timer

Kalpan Jani <kalpan.jani@mpiricsoftware.com>
    mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0

Matthieu Baerts (NGI0) <matttbe@kernel.org>
    mptcp: pm: rename add_entry structure to add_addr

Matthieu Baerts (NGI0) <matttbe@kernel.org>
    mptcp: pm: use for_each_subflow helper

Matthieu Baerts (NGI0) <matttbe@kernel.org>
    mptcp: pm: reset retrans_time when ADD_ADDR entry is reused

Joe Damato <joe@dama.to>
    bnxt_en: Don't free the live ring's TPA state on queue restart failure

Will Chen <will.chen.tty@gmail.com>
    bnxt: fix memory leak in bnxt_queue_mem_alloc error cases

Pavel Begunkov <asml.silence@gmail.com>
    eth: bnxt: store rx buffer size per queue

Michael Chan <michael.chan@broadcom.com>
    bnxt_en: Do not set EOP on RX AGG BDs on 5760X chips

Qing Luo <luoqing@kylinos.cn>
    mptcp: pm: userspace: fix address ID overflow

Geliang Tang <geliang@kernel.org>
    mptcp: use sock_kmemdup for address entry

Geliang Tang <geliang@kernel.org>
    sock: add sock_kmemdup helper

Geliang Tang <geliang@kernel.org>
    mptcp: pm: drop match in userspace_pm_append_new_local_addr

Joe Damato <joe@dama.to>
    bnxt_en: Propagate TPA buffer allocation failures in bnxt_queue_mem_alloc()

Mina Almasry <almasrymina@google.com>
    page_pool: disable sync for cpu for dmabuf memory provider

Mina Almasry <almasrymina@google.com>
    net: page_pool: rename page_pool_alloc_netmem to *_netmems

Alexander Lobakin <aleksander.lobakin@intel.com>
    netmem: add a couple of page helper wrappers

Norbert Szetei <norbert@doyensec.com>
    landlock: Fix use-after-free of the source's parent directory

Günther Noack <gnoack3000@gmail.com>
    landlock: Clarify documentation for the IOCTL access right

Zhiling Zou <zhilinz@nebusec.ai>
    ipv6: flowlabel: cap duplicate leases per socket

Kuniyuki Iwashima <kuniyu@google.com>
    ipv6: Move ipv6_fl_list from ipv6_pinfo to inet_sock.

Eric Dumazet <edumazet@google.com>
    ipv6: reorganise struct ipv6_pinfo

Eric Dumazet <edumazet@google.com>
    ipv6: make ipv6_pinfo.saddr_cache a boolean

Eric Dumazet <edumazet@google.com>
    ipv4: remove fib_info_devhash[]

Eric Dumazet <edumazet@google.com>
    ipv4: use rcu in ip_fib_check_default()

Eric Dumazet <edumazet@google.com>
    ipv4: remove fib_devindex_hashfn()

Myeonghun Pak <mhun512@gmail.com>
    idpf: disable DIM work before freeing q_vectors

Pavan Kumar Linga <pavan.kumar.linga@intel.com>
    idpf: introduce idpf_q_vec_rsrc struct and move vector resources to it

Andy Shevchenko <andriy.shevchenko@linux.intel.com>
    idpf: Fix kernel-doc descriptions to avoid warnings

Jingbo Xu <jefflexu@linux.alibaba.com>
    erofs: add sysfs feature entry for xattr prefixes

Runyu Xiao <runyu.xiao@seu.edu.cn>
    net: macb: initialize PTP state before registering clock

Théo Lebrun <theo.lebrun@bootlin.com>
    net: macb: unify device pointer naming convention

Kevin Hao <haokexin@gmail.com>
    net: macb: Use netif_napi_add_tx() instead of netif_napi_add() for TX NAPI

Kevin Hao <haokexin@gmail.com>
    net: macb: Replace open-coded implementation with napi_schedule()

Chengfeng Ye <nicoyip.dev@gmail.com>
    netfilter: cttimeout: prevent UAF during module unload

Pablo Neira Ayuso <pablo@netfilter.org>
    netfilter: cttimeout: detach dataplane timeout policy and repurpose refcount

Thomas Hellström <thomas.hellstrom@linux.intel.com>
    drm/xe: Flush LSC untyped L1 dataport cache after rcs/ccs batches

Zhiling Zou <zhilinz@nebusec.ai>
    net: bridge: use option bits for CFM/MRP frame handlers

Masami Hiramatsu (Google) <mhiramat@kernel.org>
    bootconfig: Fix integer overflow in initrd size check

Gabriel Krisman Bertazi <krisman@suse.de>
    io_uring/net: don't overconsume buffers when using MSG_TRUNC

Jens Axboe <axboe@kernel.dk>
    io_uring/rw: end write accounting from ->ki_complete

Leonardo Costa <leonardo.costa@toradex.com>
    drm/bridge: tc358768: Enforce input bus flags via atomic_check

XingWang Xiang <v3rdant.xiang@gmail.com>
    genetlink: pin family module during policy dump

Dinh Nguyen <dinguyen@kernel.org>
    EDAC/altera: Use parent device for devres in altr_portb_setup()

Rounak Das <rounakdas2025@gmail.com>
    EDAC/altera: Use ECC manager compatible to select A10/S10 IRQ layout

Donggeun Yoo <donggeunyoo.kernel@gmail.com>
    tracing: Undo the registration when enabling the histogram trigger fails

Donggeun Yoo <donggeunyoo.kernel@gmail.com>
    tracing: Take the reference before publishing the named histogram trigger

Steven Rostedt <rostedt@goodmis.org>
    tracing: Take trace_array reference when opening a tracer options file

Masami Hiramatsu (Google) <mhiramat@kernel.org>
    tools/bootconfig: Fix integer overflow and truncation in size checks

Masami Hiramatsu (Google) <mhiramat@kernel.org>
    tools/bootconfig: Cleanup bootconfig footer size calculations

Xiong Weimin <xiongweimin@kylinos.cn>
    virtio_mmio: disable IRQ wake before free_irq

Viresh Kumar <viresh.kumar@linaro.org>
    virtio-mmio: Remove virtqueue list from mmio device

Donggeun Yoo <donggeunyoo.kernel@gmail.com>
    tracing: Set the trace clock before registering the histogram trigger

Steven Rostedt <rostedt@goodmis.org>
    tracing: Merge struct event_trigger_ops into struct event_command

Steven Rostedt <rostedt@goodmis.org>
    tracing: Remove get_trigger_ops() and add count_func() from trigger ops

Christophe JAILLET <christophe.jaillet@wanadoo.fr>
    tracing: Constify struct event_trigger_ops

Vasileios Almpanis <vasilisalmpanis@gmail.com>
    configfs: unhash the dentry before dropping the item in rmdir

Cen Zhang (Microsoft) <blbllhy@gmail.com>
    reboot: fix cad_pid use-after-free race

Oleg Nesterov <oleg@redhat.com>
    sysctl: move the "cad_pid" entry from pid_table[] to kern_reboot_table[]

Zihan Xi <zihanx@nebusec.ai>
    ipmr: account multicast table and route memory

Donggeun Yoo <donggeunyoo.kernel@gmail.com>
    tracing: Fix memory corruption from a "STACKTRACE" histogram key

Vasileios Almpanis <vasilisalmpanis@gmail.com>
    configfs: pin the symlink target's dirent instead of chasing ->ci_dentry

Al Viro <viro@zeniv.linux.org.uk>
    configfs:get_target() - release path as soon as we grab configfs_item reference

Shixiong Ou <oushixiong@kylinos.cn>
    drm/sysfb: ofdrm: Fix is_avivo() constant comparison bug

Shixiong Ou <oushixiong@kylinos.cn>
    drm/sysfb: ofdrm: Fix integer overflow in fb_size calculation

Thomas Zimmermann <tzimmermann@suse.de>
    drm/sysfb: simpledrm: Improve framebuffer-size validation

Thomas Zimmermann <tzimmermann@suse.de>
    firmware: sysfb: Move bpp-depth calculation into screen_info helper

Thomas Zimmermann <tzimmermann@suse.de>
    drm/sysfb: simpledrm: Improve stride validation

Thomas Zimmermann <tzimmermann@suse.de>
    drm/sysfb: simpledrm: Improve panel-size validation

Roman Li <Roman.Li@amd.com>
    drm/amd/display: Set gpuvm min page size to 4K on dcn35/36

Lyude Paul <lyude@redhat.com>
    drm/nouveau/disp/r535: Add scanline position support + head state support

Bob Zhou <bobzhou2@amd.com>
    drm/amdgpu: avoid force-completing uninitialized UVD rings

Alex Deucher <alexander.deucher@amd.com>
    drm/amdgpu: plumb timedout fence through to force completion

Alex Deucher <alexander.deucher@amd.com>
    drm/amdgpu: add a helper to calculate ring distance

Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
    drm/amdgpu: Fix missing unwind in amdgpu_ib_schedule() error path

Daeho Jeong <daehojeong@google.com>
    f2fs: accurately adjust free_sections during free_segment_range

Chao Yu <chao@kernel.org>
    f2fs: fix to clear dirty flag on folio in error path

Matthew Wilcox (Oracle) <willy@infradead.org>
    f2fs: Convert clear_node_page_dirty() to clear_node_folio_dirty()

Chao Yu <chao@kernel.org>
    f2fs: embed f2fs_gc_kthread in f2fs_sb_info

Guanghui Yang <3497809730@qq.com>
    f2fs: fix dentry folio leak in find_in_level

Wenjie Qi <qwjhust@gmail.com>
    f2fs: limit recovery filename logging to stored length

Joanne Chang <joannechien@google.com>
    f2fs: dirty directory inodes on mtime/ctime update

Chao Yu <chao@kernel.org>
    f2fs: fix to avoid potential section-unaligned pinfile

wangzijie <wangzijie1@honor.com>
    f2fs: don't allow unaligned truncation to smaller/equal size on pinned file

wangzijie <wangzijie1@honor.com>
    f2fs: convert F2FS_I_SB to sbi in f2fs_setattr()

Wenjie Qi <qwjhust@gmail.com>
    f2fs: validate MOVE_RANGE destination size

Nilesh Javali <njavali@marvell.com>
    scsi: qla2xxx: Validate BSG request_len before reading vendor_cmd[]

Nilesh Javali <njavali@marvell.com>
    scsi: qla2xxx: Serialize NVMe unsol ctx list with a per-fcport lock

Nilesh Javali <njavali@marvell.com>
    scsi: qla2xxx: Unlink NVMe unsol ctx before freeing on LS reject error

Nilesh Javali <njavali@marvell.com>
    scsi: qla2xxx: Clamp max_npiv_vports to VP_CTRL bitmap capacity

Nilesh Javali <njavali@marvell.com>
    scsi: qla2xxx: Fix soft lockup polling continuation IOCB signature

Nilesh Javali <njavali@marvell.com>
    scsi: qla2xxx: Skip vport under deletion in report ID acquisition

Nilesh Javali <njavali@marvell.com>
    scsi: qla2xxx: Fix 64G link speed reporting in get_data_rate

Nilesh Javali <njavali@marvell.com>
    scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot

Nilesh Javali <njavali@marvell.com>
    scsi: qla2xxx: Use ring-slot helpers in __qla2x00_alloc_iocbs

Jackson Lee <jackson.lee@chipsnmedia.com>
    media: chips-media: wave5: Add timeout while stop_streaming

Nilesh Javali <njavali@marvell.com>
    scsi: qla2xxx: Bound VP index against VP_CTRL IOCB bitmap size

Nilesh Javali <njavali@marvell.com>
    scsi: qla2xxx: Null out freed pointers in qla2x00_mem_alloc() error path

Nilesh Javali <njavali@marvell.com>
    scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown

Nilesh Javali <njavali@marvell.com>
    scsi: qla2xxx: Fix queue teardown NULL dma_free and bitmap locking

Nilesh Javali <njavali@marvell.com>
    scsi: qla2xxx: Zero dport diagnostics buffer to avoid info leak

Yosry Ahmed <yosry@kernel.org>
    KVM: x86: Disallow EFER.LME and EFER.LMA if long mode is not supported

Christian Borntraeger <borntraeger@linux.ibm.com>
    KVM: s390: Zero initialize data structures for inject_pfault_token

Narasimharao Vadlamudi <ahmisaranrao@gmail.com>
    media: rkvdec: Propagate platform_get_irq() errors

Dave Stevenson <dave.stevenson@raspberrypi.com>
    media: imx355: Avoid calling imx355_power_off twice in error path

Laurent Pinchart <laurent.pinchart@ideasonboard.com>
    media: i2c: imx355: Replace client->dev usage

Yosry Ahmed <yosry@kernel.org>
    KVM: x86: Check EFER validity on KVM_SET_SREGS*

Sean Christopherson <seanjc@google.com>
    KVM: x86: Move the bulk of register specific code from x86.c to regs.c

Sean Christopherson <seanjc@google.com>
    KVM: x86: Rename __{g,s}et_sregs2() => kvm_vcpu_ioctl_x86_{g,s}et_sregs2()

Sean Christopherson <seanjc@google.com>
    KVM: x86: Extract REGS and SREGS runtime sync code to helpers

Sean Christopherson <seanjc@google.com>
    KVM: x86/mmu: Split kvm_mmu_zap_all_fast() into "front" and "back" halves

Sean Christopherson <seanjc@google.com>
    KVM: x86/mmu: Dynamically allocate shadow MMU's hashed page list

Lorenzo Stoakes (ARM) <ljs@kernel.org>
    mm/mremap: reset unfaulted VMA page offset for MREMAP_DONTUNMAP

Jon Hunter <jonathanh@nvidia.com>
    ASoC: tegra: Fix the MIXER enable default value

Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
    ASoC: tegra210_mixer: sort the register default table

Imran Shaik <imran.shaik@oss.qualcomm.com>
    clk: qcom: Fix test_ctl_hi field for DEFAULT_EVO PLLs

Miquel Raynal (DAVE) <miquel.raynal@bootlin.com>
    mtd: rawnand: pl353: Make sure we use the monolithic helpers for raw accesses

Andrea Scian <andrea.scian@dave.eu>
    mtd: rawnand: pl353: Add message about ECC mode

Li Chen <me@linux.beauty>
    nvdimm: virtio_pmem: refcount requests for token lifetime

Li Chen <me@linux.beauty>
    nvdimm: virtio_pmem: use READ_ONCE()/WRITE_ONCE() for wait flags

Li Chen <me@linux.beauty>
    nvdimm: virtio_pmem: always wake -ENOSPC waiters

Li Chen <me@linux.beauty>
    nvdimm: virtio_pmem: stop allocating child flush bio

Li Chen <me@linux.beauty>
    nvdimm: pmem: keep PREFLUSH before data writes

Li Chen <me@linux.beauty>
    nvdimm: preserve flush callback -ENOMEM

Baolin Wang <baolin.wang@linux.alibaba.com>
    mm: fix incorrect vm_flags usage when checking allowable orders for tmpfs

Anthony Krowiak <akrowiak@linux.ibm.com>
    s390/vfio-ap: Fix missing lock required to access list of ap_matrix_mdev objects

Chao Shi <coshi036@gmail.com>
    nvme: skip the zoned limits update if the zone info query failed

Christoph Hellwig <hch@lst.de>
    nvme: fix atomic write size validation

Christoph Hellwig <hch@lst.de>
    nvme: refactor the atomic write unit detection

Alan Adamson <alan.adamson@oracle.com>
    nvme: all namespaces in a subsystem must adhere to a common atomic write size

Tristan Madani <tristan@talencesecurity.com>
    nvme: add missing SRCU grace period in error path

Vincent Donnefort <vdonnefort@google.com>
    ring-buffer: Allow splice reads on static buffers

Steven Rostedt <rostedt@goodmis.org>
    ring-buffer: Show persistent buffer dropped events in trace_pipe file

Dapeng Mi <dapeng1.mi@linux.intel.com>
    perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities

Yabin Cui <yabinc@google.com>
    perf/aux: Allocate non-contiguous AUX pages by default

Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
    rtc: rzn1: Handle unset alarm weekday in rzn1_rtc_read_alarm

Sebastian Andrzej Siewior <bigeasy@linutronix.de>
    futex: Provide rt_mutex_.*_schedule() equivalents for futex scheduling

Marco Elver <elver@google.com>
    compiler_types: Move lock checking attributes to compiler-context-analysis.h

Baineng Shou <shoubaineng@gmail.com>
    dma-buf: dma-heap: don't publish fd before copy_to_user() succeeds

Steven Rostedt <rostedt@goodmis.org>
    ftrace: Take trace_array reference before accessing its ftrace_ops

Steven Rostedt <rostedt@goodmis.org>
    tracing: Take trace_array reference when opening options file

Steven Rostedt <rostedt@goodmis.org>
    tracing: Clean up use of trace_create_maxlat_file()

Lorenzo Stoakes (ARM) <ljs@kernel.org>
    mm/secretmem: properly account locked pages

Masami Hiramatsu (Google) <mhiramat@kernel.org>
    tracing/probes: Fix BTF kflag check for anonymous struct member access

Steven Rostedt <rostedt@goodmis.org>
    Documentation: tracing: Add documentation about eprobes

Masami Hiramatsu (Google) <mhiramat@kernel.org>
    tracing/probes: Fix anon_stack check for unnamed bitfields in btf_find_struct_member

Muhammad Bilal <meatuni001@gmail.com>
    staging: sm750fb: fix mono image source stride mismatch in lynxfb_ops_imageblit()

Muhammad Bilal <meatuni001@gmail.com>
    staging: rtl8723bs: fix OOB read in rtw_restruct_wmm_ie()

Vivek BalachandharTN <vivek.balachandhar@gmail.com>
    staging: rtl8723bs: fix spacing around operators

Jeffin Philip <jeffinphilip14@gmail.com>
    usb: gadget: f_mass_storage: fix null pointer dereference in fsg_common_set_num_buffers()

Myeonghun Pak <mhun512@gmail.com>
    usb: storage: realtek_cr: fix use-after-free on disconnect

Pawel Laszczak <pawell@cadence.com>
    usb: cdnsp: fix wakeup from S3 after controller context loss

Théo Lebrun <theo.lebrun@bootlin.com>
    usb: cdns3: rename hibernated argument of role->resume() to lost_power

Mathias Nyman <mathias.nyman@linux.intel.com>
    xhci: Cleanup Candence controller PCI device and vendor ID usage

Bryam Vargas <hexlabsecurity@proton.me>
    wifi: mt76: mt7996: bound the device EEPROM address before the EFUSE copy

Amit Sunil Dhamne <amitsd@google.com>
    usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling

Xu Yang <xu.yang_2@nxp.com>
    usb: typec: tcpm: fix debug accessory mode detection for sink ports

Yuhang.chen <yhchen312@gmail.com>
    wifi: rtw89: pci: add .shutdown callback to stop rfkill polling on reboot

Bitterblue Smith <rtl8821cerfe2@gmail.com>
    wifi: rtw89: Hide some errors when the device is unplugged

Zong-Zhe Yang <kevin_yang@realtek.com>
    wifi: rtw89: cleanup unused rtwdev::roc_work

Elson Serrao <elson.serrao@oss.qualcomm.com>
    usb: dwc3: clear forceRM when issuing EndTransfer

Thinh Nguyen <Thinh.Nguyen@synopsys.com>
    usb: dwc3: gadget: Reinitiate stream for all host NoStream behavior

Jan Kara <jack@suse.cz>
    udf: Fix data loss when converting inline inodes to out of line

Jan Kara <jack@suse.cz>
    udf: Move udf_map_block() up

Adrian Hunter <adrian.hunter@intel.com>
    i3c: master: Fix use-after-free of master->this

Bryam Vargas <hexlabsecurity@proton.me>
    wifi: mt76: mt7915: bound the device EEPROM address before the EFUSE copy

StanleyYP Wang <StanleyYP.Wang@mediatek.com>
    wifi: mt76: mt7915: set correct background radar capability

Adrian Hunter <adrian.hunter@intel.com>
    i3c: master: Do not treat master device as a duplicate target

Can Peng <pengcan@kylinos.cn>
    hwrng: stm32 - Fix runtime PM cleanup on registration failure

Uwe Kleine-König <u.kleine-koenig@baylibre.com>
    hwrng: drivers - Switch back to struct platform_driver::remove()

Xu Rao <raoxu@uniontech.com>
    ALSA: hda/ext: preserve PPLCCTL bits when clearing reset

Glenn Judd <gmj@meta.com>
    net/mlx5e: do not HW-GRO coalesce small frames

Dragos Tatulea <dtatulea@nvidia.com>
    net/mlx5e: SHAMPO, Always calculate page size

Hidayath Khan <hidayath@linux.ibm.com>
    net/smc: stop killed, freed and out_of_sync sharing a byte

Simon Horman <horms@kernel.org>
    net/smc: Address spelling errors

Fan Wu <fanwu01@zju.edu.cn>
    power: supply: qcom_battmgr: fix use-after-free

Hui Su <sh_def@163.com>
    io_uring/waitid: avoid siginfo copy during ring teardown

Jens Axboe <axboe@kernel.dk>
    io_uring/waitid: have io_waitid_complete() remove wait queue entry

Mario Limonciello <mario.limonciello@amd.com>
    platform/x86/amd/pmc: Propagate SMU errors and validate S2D address

Mario Limonciello <mario.limonciello@amd.com>
    platform/x86/amd/pmc: Restore msg_port on amd_stb_s2d_init() error paths

Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
    platform/x86/amd/pmc: Define enum for S2D/PMC msg_port and add helper function

Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
    platform/x86/amd/pmc: Move STB functionality to a new file for better code organization

Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
    platform/x86/amd/pmc: Move STB block into amd_pmc_s2d_init()

Abdun Nihaal <nihaal@cse.iitm.ac.in>
    platform/x86: int1092: Fix potential memory leak in sar_probe()

Rafael J. Wysocki <rafael.j.wysocki@intel.com>
    platform/x86: intel_sar: Check ACPI_HANDLE() against NULL

Thorsten Blum <thorsten.blum@linux.dev>
    platform/x86: think-lmi: Fix certificate thumbprint sysfs output

Mark Pearson <mpearson-lenovo@squebb.ca>
    platform/x86: think-lmi: improve check if BIOS account security enabled

Thorsten Blum <thorsten.blum@linux.dev>
    platform/x86: think-lmi: Fix current password length check

Farhan Ali <alifm@linux.ibm.com>
    PCI: Allow per function PCI slots to fix slot reset on s390

Farhan Ali <alifm@linux.ibm.com>
    PCI: Introduce PCI_SLOT_PLACEHOLDER constant for slot_nr placeholder value

Fan Wu <fanwu01@zju.edu.cn>
    mmc: via-sdmmc: cancel card-detect work on remove

Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
    platform/x86: ISST: Validate max level for set feature

Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
    platform/x86: ISST: Check for admin capability for write commands

Peiyang He <peiyang_he@smail.nju.edu.cn>
    iommufd: Fix UAF in selftest IOPF reporting

Yi Liu <yi.l.liu@intel.com>
    iommufd: Pass @pasid through the device attach/replace path

Weimin Xiong <xiongwm2026@163.com>
    iommu/msm: Unwind probe state on registration failure

Zhang Heng <zhangheng@kylinos.cn>
    iommu/msm: Use helper function devm_clk_get_prepared()

Ali Tariq <alitariq45892@gmail.com>
    PCI: starfive: Fix resource leaks on error paths in host_init()

Hal Feng <hal.feng@starfivetech.com>
    PCI: starfive: Use regulator APIs to control the 3v3 power supply of PCIe slots

Fan Wu <fanwu01@zju.edu.cn>
    power: supply: ab8500_fg: fix use-after-free on remove

Pan Chuang <panchuang@vivo.com>
    power: supply: ab8500_fg: Remove redundant dev_err()/dev_err_probe()

Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
    remoteproc: qcom: pas: Guard dtb metadata release with dtb_pas_id check

Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
    remoteproc: pas: Replace metadata context with PAS context structure

Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
    firmware: qcom_scm: Rename peripheral as pas_id

Oscar Ou <oscarou@synology.com>
    lockd: fix swapped arguments in nlmsvc_match_ip()

Ruoyu Wang <ruoyuw560@gmail.com>
    i2c: mxs: fix DMA channel leak on probe error

Bence Csókás <csokas.bence@prolan.hu>
    dmaengine: Add devm_dma_request_chan()

Vincent Donnefort <vdonnefort@google.com>
    ring-buffer: Make cpu_buffer::free_page a buffer_data_read_page

Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
    ASoC: codecs: aw88261: only check PLL and clock state at power-up

Val Packett <val@packett.cool>
    ASoC: codecs: aw88261: reduce log spam

Tejun Heo <tj@kernel.org>
    sched/core: Make core-sched flips wait for in-flight selections

John Stultz <jstultz@google.com>
    sched: Rework prev_balance() to avoid stale prev references

Vincent Donnefort <vdonnefort@google.com>
    ring-buffer: Fix subbuf resize race with ring_buffer_alloc_read_page()

Steven Rostedt <rostedt@goodmis.org>
    ring-buffer: Add helper functions for allocations

James Clark <james.clark@linaro.org>
    perf test: Change all remaining #!/bin/sh to #!/bin/bash

Jakub Kicinski <kuba@kernel.org>
    net: tls: fix silent data drop under pipe back-pressure

Darrick J. Wong <djwong@kernel.org>
    xfs: fix blockgc group quota scanning when usrquota isn't enforced

Darrick J. Wong <djwong@kernel.org>
    xfs: drop dquot flush lock when we can't find a buffer to flush

Darrick J. Wong <djwong@kernel.org>
    xfs: check di_forkoff correctly in scrub

Darrick J. Wong <djwong@kernel.org>
    xfs: don't call xfs_exchange_range_finish for a dry run

Darrick J. Wong <djwong@kernel.org>
    xfs: check padding field in xfs_ioc_commit_range

Darrick J. Wong <djwong@kernel.org>
    xfs: use correct jiffies comparison function in xchk_maybe_relax

Darrick J. Wong <djwong@kernel.org>
    xfs: release orphanage dir inode if chown fails

Darrick J. Wong <djwong@kernel.org>
    xfs: fix attr fork block count checks in xrep_inode_blockcounts

Darrick J. Wong <djwong@kernel.org>
    xfs: don't assert when XFS_SCRUB_TYPE_HEALTHY scans return corruption

Zihan Xi <zihanx@nebusec.ai>
    smb: client: validate POSIX create context length

Zihan Xi <zihanx@nebusec.ai>
    smb: client: clean up failed cached directory opens

Zihan Xi <zihanx@nebusec.ai>
    smb: client: fix create context out-of-bounds reads

Hui Peng <benquike@gmail.com>
    Bluetooth: RFCOMM: fix NULL dereference of dlc->session in RFCOMM_CONNINFO

Aldo Ariel Panzardo <qwe.aldo@gmail.com>
    Bluetooth: mgmt: fix race in read_unconf_index_list()

Aldo Ariel Panzardo <qwe.aldo@gmail.com>
    Bluetooth: L2CAP: validate frame length before control and FCS access

Aldo Ariel Panzardo <qwe.aldo@gmail.com>
    Bluetooth: ISO: balance the parent hold in hci_bind_bis()

Aldo Ariel Panzardo <qwe.aldo@gmail.com>
    Bluetooth: hci_sock: reject out-of-range OCF values

Aldo Ariel Panzardo <qwe.aldo@gmail.com>
    Bluetooth: hci_sock: validate event length before filtering

Aldo Ariel Panzardo <qwe.aldo@gmail.com>
    Bluetooth: hci_conn: fix CIS hold ownership on reuse

Tan Chi <tanchi25@mails.ucas.ac.cn>
    RISC-V: KVM: Fix HSM hart status error propagation

Myeonghun Pak <mhun512@gmail.com>
    RISC-V: KVM: Synchronize hrtimer callback during teardown

Lorenzo Stoakes (ARM) <ljs@kernel.org>
    KVM: arm64: Fix spurious warning for benign stage 2 teardown race

Zeng Chi <zengchi@kylinos.cn>
    KVM: Don't treat reserved xarray entries as having memory attributes

David Ballesteros <davimaba.v@proton.me>
    KVM: Ensure memory attributes xarray nodes are accounted to the caller's memcg

Anthony Krowiak <akrowiak@linux.ibm.com>
    s390/vfio-ap: fix KVM GISC and page leak when queue removed from host config

Peter Oberparleiter <oberpar@linux.ibm.com>
    s390/cmf: Fix virtual vs physical address confusion

Vineeth Vijayan <vneethv@linux.ibm.com>
    s390/cio: Fix NULL pointer dereference in ccw_device_get_util_str()

Ilya Titov <ilya.titov@wirenboard.com>
    pinctrl: sunxi: keep a shadow copy of the data register output latches

Myeonghun Pak <mhun512@gmail.com>
    pinctrl: single: free the IRQ on domain creation failure

Puranjay Mohan <puranjay@kernel.org>
    perf/core: Run sched_task() for PMUs with only CPU-wide events

Puranjay Mohan <puranjay@kernel.org>
    perf/core: Fix NULL pmu_ctx passed to pmu->sched_task()

Yehyeong Lee <yhlee@isslab.korea.ac.kr>
    scsi: libiscsi_tcp: Check the data direction of a Data-In PDU

Doruk Tan Ozturk <doruk@0sec.ai>
    nfc: port100: reject frames whose declared length exceeds the received data

Aamir Ahmed <elb12345@hotmail.co.uk>
    nfc: llcp: drop truncated I/RR/RNR PDUs in nfc_llcp_recv_hdlc()

Luxiao Xu <rakukuip@gmail.com>
    nfc: fix use-after-free in nfc_get_local_general_bytes

Aohan Mei <henrymei@tencent.com>
    netfilter: nf_tables: skip expired catchall elements on insert and delete

Luxiao Xu <rakukuip@gmail.com>
    netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read

Weiming Shi <bestswngs@gmail.com>
    netfilter: ip6t_rpfilter: reject routes without inet6_dev

Wentao Liang <vulab@iscas.ac.cn>
    net: usb: lan78xx: Fix URB reference leak in lan78xx_submit_deferred_urbs()

Ming Wang <wangming01@loongson.cn>
    net: usb: cdc_mbim: add MeiG Smart SRM821 to ZLP whitelist

Fourie Zhang <littleddfu@gmail.com>
    net: bridge: mdb: restart port group walk after deletion

Gajdos Tamás <tamas@rimpianto.com>
    net: atl1e: fix soft lockup on out-of-range hw_next_to_clean read

Gajdos Tamás <tamas@rimpianto.com>
    net: atl1c: fix soft lockup on out-of-range tpd_cons read

Ilya Maximets <i.maximets@ovn.org>
    net: openvswitch: conntrack: fix helper UAF due to extensions realloc

Ilya Maximets <i.maximets@ovn.org>
    net: openvswitch: conntrack: remove 'add_helper' dead code

Ilya Maximets <i.maximets@ovn.org>
    net: openvswitch: conntrack: avoid modifying shared unconfirmed ct entry

Wentao Liang <vulab@iscas.ac.cn>
    net: hisilicon: hns_dsaf_mac: fix mdio device leak in hns_mac_register_phy()

Gajdos Tamás <tamas@rimpianto.com>
    net: atl1: fix soft lockup on out-of-range cmb_tpd_next_to_clean read

Zijie Huang <milkory@outlook.com>
    net: arp: terminate device name before lookup

Weiming Shi <bestswngs@gmail.com>
    net/sched: reject IDR error pointers when deleting actions

Ralf Lici <ralf@mandelbit.com>
    net/mlx5e: advertise MACsec offload only when supported

Wentao Liang <vulab@iscas.ac.cn>
    net/mlx5: Fix rev_entry reference leak in mlx5_tc_ct_shared_counter_get()

Wei Jie LAW <98lawweijie@gmail.com>
    HID: wacom: fix OOB read in wacom_wac_pen_serial_enforce()

Junjie Cao <junjie.cao@intel.com>
    HID: quirks: add ALWAYS_POLL quirk for SDINNOVATION gaming keyboard

Chen Changcheng <chenchangcheng@kylinos.cn>
    HID: alps: fix use-after-free on input2 registration failure

Angel J <iamanaws@httpd.dev>
    PCI: of_property: Omit bus properties without a subordinate bus

Jaewook You <jaewook376@gmail.com>
    mm/hugetlb: preserve mremap address delta when skipping page tables

Karl Mehltretter <kmehltretter@gmail.com>
    gpio: tps65219: Fix GPIO input value reads

Peiyang He <peiyang_he@smail.nju.edu.cn>
    drm/virtio: fix NULL pointer dereference on fence allocation failure

Peiyang He <peiyang_he@smail.nju.edu.cn>
    drm/virtio: fix memory leak of fence event on execbuffer failure

Szymon Acedański <accek@invisiblethingslab.com>
    drm/xe: Limit sg segment size to PAGE_SIZE on Xen PV

Peiyang He <peiyang_he@smail.nju.edu.cn>
    drm/nouveau: don't bump pin count on failed re-pin in nouveau_bo_pin_locked()

Jonghyuk Kim(MalHyuk) <malhyuk97@gmail.com>
    drm/nouveau: RCU-free the scheduler-containing nouveau_sched

Wentao Liang <vulab@iscas.ac.cn>
    drm/nouveau: Fix runtime PM leak in nouveau_connector_detect()

Wentao Liang <vulab@iscas.ac.cn>
    drm/nouveau: Fix gem reference leak in validate_init()

Peiyang He <peiyang_he@smail.nju.edu.cn>
    drm/nouveau: fix double-free in nvif_vmm_dtor

Wentao Liang <vulab@iscas.ac.cn>
    drm/nouveau: Fix bridge reference leak in nv1a_ram_new()

Guangshuo Li <lgs201920130244@gmail.com>
    drm/nouveau: fix autosuspend cleanup during teardown

Peiyang He <peiyang_he@smail.nju.edu.cn>
    drm/nouveau/uvmm: fix UAF in nouveau_uvmm_sm when BO is in TTM_PL_SYSTEM

Wentao Liang <vulab@iscas.ac.cn>
    drm/amdgpu: Fix vmid_wait fence leak in amdgpu_ring_init()

Wentao Liang <vulab@iscas.ac.cn>
    drm/amdgpu: Fix runtime PM leak in amdgpu_debugfs_test_ib_show()

Wentao Liang <vulab@iscas.ac.cn>
    drm/amdgpu: Fix last_update fence leak in amdgpu_vm_init()

Ivan Lipski <ivan.lipski@amd.com>
    drm/amd/display: Bump frame warning limit for clang builds of dml

Wentao Liang <vulab@iscas.ac.cn>
    drm/amd/display: Fix dc stream excess put in dm_update_crtc_state()

Christian König <ckoenig.leichtzumerken@gmail.com>
    drm/i915: fix incorrect RCU teardown order

Brajesh Gupta <brajesh.gupta@imgtec.com>
    drm/imagination: Fix page count for page table for map() interface

Brajesh Gupta <brajesh.gupta@imgtec.com>
    drm/imagination: Propagate map failures correctly from pvr_mmu_map_sgl()

Dongliang Qin <cccccccccccc777777@gmail.com>
    rds: ib: Clear the sg list when mapping an MR fails

Hui Peng <benquike@gmail.com>
    mctp: route: iterate socket tag list in mctp_lookup_prealloc_tag()

Zixuan Chai <petalzu987@gmail.com>
    llc: reserve device headroom for allocated frames

Ridham Khurana <khurana.ridham222@gmail.com>
    gpio: zynq: fix runtime PM leak on request error path

Wentao Liang <vulab@iscas.ac.cn>
    gpio: arizona: Fix runtime PM leak in arizona_gpio_direction_out()

Hui Peng <benquike@gmail.com>
    ipv6: sr: enforce exact attribute length for SEG6_ATTR_DST

Norbert Szetei <norbert@doyensec.com>
    ipv6: do not let ipv6_find_hdr() return an offset past the packet end

Fan Wu <wufan@kernel.org>
    ipe: protect the dm-verity root hash with RCU

Wentao Liang <vulab@iscas.ac.cn>
    fsl/fman: Fix clk reference leak in read_dts_node()

Josef Bacik <josef@toxicpanda.com>
    writeback: report a Tasks-RCU quiescent state per cgwb drain pass

Pavankumar Kondeti <pavan.kondeti@oss.qualcomm.com>
    workqueue: Fix NULL current_pwq deref in flush dependency check

Patrick Lu (Anthropic) <perf.patrick.lu@gmail.com>
    writeback: bound cleanup_offline_cgwb() rescans by rotating scanned inodes

Christian Brauner <brauner@kernel.org>
    fs/ntfs3: use d_instantiate_new() in ntfs_create_inode() and murder syzbot's "WARNING in do_new_mount" saga

Hui Peng <benquike@gmail.com>
    fou: reject omitted FOU_ATTR_IPPROTO on FOU_ENCAP_DIRECT

Guopeng Zhang <zhangguopeng@kylinos.cn>
    cgroup/pids: Restore pids.events notifications in local mode

Matthias Goergens <matthias.goergens@gmail.com>
    ata: libata-scsi: bound the ATA passthru sense descriptor writes

Dairui Zhang <zhangdairui@gmail.com>
    af_packet: fix integer overflow in prb_calc_retire_blk_tmo()

Aohan Mei <henrymei@tencent.com>
    sctp: discard the rest of the packet on a stale-cookie error

Willem de Bruijn <willemb@google.com>
    tcp: prevent collapsing skbs across boundary in rtx queue

Eric Dumazet <edumazet@google.com>
    tipc: reject invalid and unexpected GRP_ACK_MSG to prevent bc_ackers underflow

Willem de Bruijn <willemb@google.com>
    virtio_net: copy zerocopy frags in start_xmit without NAPI

Mario Limonciello <mario.limonciello@amd.com>
    x86/PCI: Disable enhanced atomics on AMD NBIO 7.7 and 7.11

Masami Hiramatsu (Google) <mhiramat@kernel.org>
    x86/mce: Fix hardware debug register corruption on task migration

Pablo Neira Ayuso <pablo@netfilter.org>
    netfilter: nf_tables: join hook list via splice_list_rcu() in commit phase

Pablo Neira Ayuso <pablo@netfilter.org>
    rculist: add list_splice_rcu() for private lists

Mark Amirkan <markdamirkan@gmail.com>
    mptcp: return sk_wait_data() errors from recvmsg()

Sean Christopherson <seanjc@google.com>
    perf/x86/intel: Make @data a mandatory param for intel_guest_get_msrs()

Sean Christopherson <seanjc@google.com>
    perf/x86/intel: Don't pointlessly context switch DS_AREA (and PEBS config) if PEBS is unused

Sean Christopherson <seanjc@google.com>
    perf/x86/intel: Don't write PEBS_ENABLED on host<=>guest xfers if CPU has PEBS isolation, to fix stuck PEBS_ENABLED

Sean Christopherson <seanjc@google.com>
    perf/x86/intel: Ensure KVM guest PEBS path doesn't set unwanted PERF_GLOBAL_CTRL bits

Hui Peng <benquike@gmail.com>
    autofs: fix sbi->pipe file reference leak in autofs_kill_sb()

Eric Dumazet <edumazet@google.com>
    vlan: ensure sufficient headroom in vlan_dev_hard_header()

Eric Dumazet <edumazet@google.com>
    net/sched: sch_teql: fix shadowed err in __teql_resolve()

Eric Dumazet <edumazet@google.com>
    bridge: check llc_mac_hdr_init() return value in br_send_bpdu()

Eric Dumazet <edumazet@google.com>
    llc: fix skb UAF and leaks on llc_mac_hdr_init() failure

Coia Prant <coiaprant@gmail.com>
    net: ethernet: stmmac: dwmac-rk: fix bulk clock leak when the PHY clock fails

Ginger Li <ginger.jzllee@gmail.com>
    tipc: Fix a data race on mon->peer_cnt in mon_timeout()

Sidraya Jayagond <sidraya@linux.ibm.com>
    net/smc: fix UAF on lgr list traversal in smcr_port_err()

Sang-Hoon Choi <csh0052@gmail.com>
    nfp: hold IPsec RX state under the XArray lock

Yilin Zhang <yilinzhang@moonshot.ai>
    tcp: fix use-after-free of retransmit_skb_hint in tcp_send_synack()

Aleksei Sviridkin <f@lex.la>
    net: dsa: mt7530: fix NULL dereference on unbind of MT7531 and MT7621

Haseeb Malik <haseebulhaq55@gmail.com>
    macsec: initialize SecY before registering the netdevice

Sabrina Dubroca <sd@queasysnail.net>
    macsec: inherit lower device's TSO limits when offloading

Sabrina Dubroca <sd@queasysnail.net>
    macsec: add some of the lower device's features when offloading

David Dai <zdai@linux.ibm.com>
    bonding: crypto offload enabled, non-offload slave failover, rekey failed

Pengpeng Hou <hppiscas@163.com>
    drm/imagination: clamp freelist reconstruction requests

Norbert Szetei <norbert@doyensec.com>
    net: xps: reject an out of range traffic class

Sanghyun Park <sanghyun.park.cnu@gmail.com>
    vxlan: use one headroom snapshot for neighbour replies

Xuanqiang Luo <luoxuanqiang@kylinos.cn>
    ip_gre: Reject enabling collect metadata through changelink

Florian Fainelli <florian.fainelli@broadcom.com>
    net: bcmgenet: mask DMA_TIMEOUT_MASK when reading DMA_RING0_TIMEOUT

Florian Fainelli <florian.fainelli@broadcom.com>
    net: bcmgenet: validate Ethernet address in bcmgenet_set_mac_addr

Florian Fainelli <florian.fainelli@broadcom.com>
    net: bcmgenet: do not skip WoL power up on GENET V1

Doug Berger <opendmb@gmail.com>
    net: bcmgenet: allow return of power up status

Doug Berger <opendmb@gmail.com>
    net: bcmgenet: move bcmgenet_power_up into resume_noirq

Florian Fainelli <florian.fainelli@broadcom.com>
    net: bcmgenet: initialize u64 stats seq counter for all queues

Florian Fainelli <florian.fainelli@broadcom.com>
    net: bcmgenet: fix 64-bit RTNL stats reading in ethtool on 32-bit systems

Ivan Delalande <colona@arista.com>
    tg3: use random MAC address when tg3_get_device_address fails

Dragan Simic <dsimic@manjaro.org>
    driver core: Add device probe log helper dev_warn_probe()

Johan Almbladh <johan.almbladh@anyfinetworks.com>
    bpf: Fix BSWAP 32 and 16 on MIPS64

Johan Almbladh <johan.almbladh@anyfinetworks.com>
    bpf: Fix immediate JMP JEQ/JNE on MIPS32

Ido Schimmel <idosch@nvidia.com>
    vrf: Stop corrupting skb->csum when capturing CHECKSUM_COMPLETE packets

Shihuang Liu <shlomojune6@gmail.com>
    net: skbuff: fix pull-bound underflow in skb_checksum_setup_ipv6()

Jakub Kicinski <kuba@kernel.org>
    veth: manage XDP program pointers during channel resize

Victor Nogueira <victor@mojatatu.com>
    net/sched: act_gate: budget the per-entry list in get_fill_size

Deepanshu Kartikey <kartikey406@gmail.com>
    nfc: pn533: fix OOB read in pn533_acr122_is_rx_frame_valid()

Ömer Mete Kaya <omermetekaya0@gmail.com>
    nfc: llcp: fix slab-out-of-bounds reads when logging service names

Ömer Mete Kaya <omermetekaya0@gmail.com>
    nfc: llcp: fix WKS SAP hijacking via prefix match in nfc_llcp_wks_sap()

Ömer Mete Kaya <omermetekaya0@gmail.com>
    nfc: llcp: fix -ENOMEM on connect with zero-length service name

Pengpeng Hou <pengpeng@iscas.ac.cn>
    nfc: st21nfca: validate ISO15693 inventory length

Cong Nguyen <congnt264@gmail.com>
    nfc: llcp: fix sdreq TLV list leak on parse/alloc/send failure

Chris Gellermann <christian.gellermann@codasip.com>
    nfc: virtual_ncidev: Add missing ioctl compat handler

Chris Gellermann <christian.gellermann@codasip.com>
    selftests/nci: Fix out-of-bounds store on thread join

Chaithanya Lagisetty <nagachaithanya9911@gmail.com>
    selftests: nci: Fix uninitialized family ID on missing attribute

Lee Jones <lee@kernel.org>
    nfc: llcp: Fix race condition in accept_queue lifecycle

Lei Zhu <zhulei@kylinos.cn>
    selftests: nci: Correct pthread_create return value check

Aldo Ariel Panzardo <qwe.aldo@gmail.com>
    nfc: llcp: Fix list corruption / refcount desync in nfc_llcp_recv_dm()

Pengpeng Hou <pengpeng@iscas.ac.cn>
    nfc: st21nfca: validate received frame size

Pengpeng Hou <pengpeng@iscas.ac.cn>
    nfc: nfcmrvl: validate helper command length before pull

Weiming Shi <bestswngs@gmail.com>
    bpf: Reject dev-bound-only programs on other devices

Maxime Chevallier <maxime.chevallier@bootlin.com>
    net: stmmac: dwmac4: Use the correct bufzise when the len is exactly 8K

Maxime Chevallier <maxime.chevallier@bootlin.com>
    net: stmmac: selftests: Capture all packets for vlan checks

Maxime Chevallier <maxime.chevallier@bootlin.com>
    net: stmmac: selftests: Check the dev->features for S-TAG offload testing

Maxime Chevallier <maxime.chevallier@bootlin.com>
    net: stmmac: selftests: Support running selftests on DSA conduits

Xin Long <lucien.xin@gmail.com>
    sctp: hold asoc or transport before mod_timer() in timer handlers

Bernardo Soares <bsoares.it@gmail.com>
    net/mlx5: Bridge, don't fail unlink of untracked/unsupported peer ports

Bernardo Soares <bsoares.it@gmail.com>
    net/mlx5: Bridge, don't fail switchdev events of sibling eswitch ports

Zhao Gongyi <zhaogongyi@BYTEDANCE.COM>
    bpf, sockmap: Reject max_entries > INT_MAX in sock_map_alloc

Emil Tsalapatis <emil@etsalapatis.com>
    bpf: Fix bpf_sock context code generation

Emil Tsalapatis <emil@etsalapatis.com>
    bpf: Fix bounds check for skb-backed dynptrs

Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
    thermal: gov_step_wise: Fix stale mitigation vote with non-zero lower bounds

Coia Prant <coiaprant@gmail.com>
    net: pcs: xpcs: fix clock reference leak on xpcs_init_clks failure

Jakub Kicinski <kuba@kernel.org>
    genetlink: report the real command id for dump-only ops in policy dumps

bui duc phuc <phucduc.bui@gmail.com>
    net: ethernet: ti: netcp: fix pm_runtime usage counter leak on error

Mikhail Zaslonko <zaslonko@linux.ibm.com>
    s390/debug: Fix NULL pointer dereference in debug_info_copy()

Mikhail Zaslonko <zaslonko@linux.ibm.com>
    s390/debug: Do not register views for failed static debug areas

Nemesa Garg <nemesa.garg@intel.com>
    drm/i915/psr: Clear stale sel fetch enable bits on sel fetch disable

Jouni Högander <jouni.hogander@intel.com>
    drm/i915/psr: Add new SU area calculation helper to apply workarounds

Myeonghun Pak <mhun512@gmail.com>
    tg3: clean up PHYLIB resources on probe failure

Kuniyuki Iwashima <kuniyu@google.com>
    ipv6: Fix dst leak for uncached routes.

Pengpeng Hou <hppiscas@163.com>
    net: usb: sr9700: include receive overhead in the length check

Ivan Vecera <ivecera@redhat.com>
    dpll: use exact lookup for reference sync pin id

Ratheesh Kannoth <rkannoth@marvell.com>
    octeontx2-af: Fix memory scaling limitation in SR-IOV mode

Hui Peng <benquike@gmail.com>
    Bluetooth: RFCOMM: Reject short EA=0 frames in rfcomm_recv_frame()

Ravindra <ravindra@intel.com>
    Bluetooth: btintel_pcie: validate device-supplied DMA indices

Hui Peng <benquike@gmail.com>
    Bluetooth: bnep: fix out-of-bounds reads on short RX/TX frames and control fallthrough

Li Youhong <liyouhong@kylinos.cn>
    drm/bridge: samsung-dsim: fix TE GPIO lifetime for host attach

Junrui Luo <moonafterrain@outlook.com>
    drm/virtio: release the GEM object on virtio_gpu_vram_create() errors

Junrui Luo <moonafterrain@outlook.com>
    drm/virtio: fix object leaks in virtio_gpu_resource_create_blob_ioctl()

Junrui Luo <moonafterrain@outlook.com>
    drm/virtio: fix object leak in virtio_gpu_resource_create_ioctl()

Junrui Luo <moonafterrain@outlook.com>
    drm/virtio: fix object leak when drm_gem_handle_create() fails

Jamal Hadi Salim <jhs@mojatatu.com>
    net/sched: sch_hfsc: bound the classify inner-filter walk with a drift budget

Yuqi Xu <xuyuqiabc@gmail.com>
    bpf: Check params size before reading reserved fields

Aamir Ahmed <elb12345@hotmail.co.uk>
    net: usb: catc: bound the RX packet length in catc_rx_done()

Kumar Kartikeya Dwivedi <memxor@gmail.com>
    bpf: Bound ownership depth through local kptrs and graph roots

Yiqi Sun <sunyiqixm@gmail.com>
    sctp: avoid livelock while updating retransmit path

Alexander Duyck <alexanderduyck@fb.com>
    eth: fbnic: Set AW_FLUSH_MODE alongside AW_FLUSH when flushing the mailbox

Björn Töpel <bjorn@kernel.org>
    eth: fbnic: Handle maximum standalone channels

Kuniyuki Iwashima <kuniyu@google.com>
    ip6_gre: Call ip6erspan_tunnel_unlink_md() in ip6erspan_changelink().

Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
    net: ethernet: mtk_eth_soc: unregister net_devices in case of probe failure

Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
    net: gue: reject invalid REMCSUM offsets

Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
    net/sched: act_ct: don't WARN on benign flow_offload_alloc() failure

Giuseppe Ranieri <giuseppe@ranieri.dev>
    drm/nouveau/disp: don't reject HDMI config on cards without SCDC

Francesco Magazzu <postadelmaga@gmail.com>
    drm/nouveau/clk: don't clobber reclock status when restoring volt/fan

Dan Carpenter <error27@gmail.com>
    drm/nouveau/clk: fix list cursor use after loop in nvkm_clk_ustate_update

Joseph Qi <joseph.qi@linux.alibaba.com>
    ocfs2: make ocfs2_calc_xattr_init() return void

Zeng Heng <zengheng4@huawei.com>
    arm64: io: Reject non-user protection in ioremap_prot()

Naman Gulati <namangulati@google.com>
    netfilter: ctnetlink: fix suspicious RCU usage in expect_iter_name

Julian Anastasov <ja@ssi.bg>
    ipvs: revalidate ihl before icmp_send

Karl Mehltretter <kmehltretter@gmail.com>
    netfilter: nft_synproxy: use the family-aware checksum helper

Florian Westphal <fw@strlen.de>
    netfilter: nfnetlink_queue: hold nfnl mutex in event notifier

Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
    netfilter: flowtable: publish HW_DEAD after worker is done

Kumar Kartikeya Dwivedi <memxor@gmail.com>
    libbpf: Reject truncated ldimm64 CO-RE relocations

Kumar Kartikeya Dwivedi <memxor@gmail.com>
    bpf: Restrict CO-RE poisoning to relocatable instructions

Shay Drory <shayd@nvidia.com>
    net/mlx5: devcom, Base component size on linked devices

Jamal Hadi Salim <jhs@mojatatu.com>
    net/sched: cls_u32: fix manual hash table handle IDR aliasing

Weiming Shi <bestswngs@gmail.com>
    bpf: Skip unsettled links in link iterator

Zhiling Zou <zhilinz@nebusec.ai>
    xsk: Use a 32-bit compare in xsk_map_gen_lookup

Julian Sun <sunjunchao@bytedance.com>
    fs: avoid repeated scans in evict_inodes()

Vineeth Vijayan <vneethv@linux.ibm.com>
    s390/cio: Guard PMCW field accesses with dnv check

Vineeth Vijayan <vneethv@linux.ibm.com>
    s390/cio: Check pmcw.dnv before pmcw.ena in I/O entry points

Vineeth Vijayan <vneethv@linux.ibm.com>
    s390/cio: Fix cio_update_schib() to not cache invalid schib

Karl Mehltretter <kmehltretter@gmail.com>
    s390/pci/docs: Fix sriov_numvfs attribute name

Niklas Schnelle <schnelle@linux.ibm.com>
    docs: s390/pci: Improve and update PCI documentation

Bart Van Assche <bvanassche@acm.org>
    scsi: megaraid_sas: Protect megasas_get_ctrl_info() in megasas_resume()

Eva Kurchatova <eva.kurchatova@virtuozzo.com>
    selftests: cgroup: give the O_TMPFILE open in get_temp_fd() a mode

Sean Christopherson <seanjc@google.com>
    cgroup: selftests: Move memcontrol specific helpers out of common cgroup_util.c

Lee Jones <lee@kernel.org>
    Bluetooth: mgmt: Dequeue pending mesh_send_sync entries on cancel

Christiano Amora <christiano.amora@gmail.com>
    Bluetooth: SMP: reject Security Request over BR/EDR

ZHOU Jiaxiang <me@fxti.xyz>
    scsi: sd_zbc: Reject disks with too many zones

Ran Hongyun <ranhongyun1@huawei.com>
    squashfs: Add dictionary size range check to prevent shift-out-of-bounds

Mark Brown <broonie@kernel.org>
    KVM: arm64: Fix FGT mapping for HFGITR_EL2.nGCSEPP

Karl Mehltretter <kmehltretter@gmail.com>
    KVM: arm64: Return -EINVAL for an empty SMCCC filter range at base 0

Fuad Tabba <fuad.tabba@linux.dev>
    KVM: arm64: vgic-its: Skip unreachable devices instead of failing the save

Marc Zyngier <maz@kernel.org>
    KVM: arm64: vgic-its: Add stronger type-checking to the ITS entry sizes

Fuad Tabba <fuad.tabba@linux.dev>
    KVM: arm64: vgic-its: Free the caches when GITS_BASER changes

SeungJu Cheon <suunj1331@gmail.com>
    RISC-V: KVM: Fix perf-backed counter accounting across stop and read

SeungJu Cheon <suunj1331@gmail.com>
    RISC-V: KVM: Report snapshot write failure to the guest

SeungJu Cheon <suunj1331@gmail.com>
    RISC-V: KVM: Preserve firmware counter value across stop/start

Benjamin Tissoires <bentiss@kernel.org>
    HID: bpf: fix __hid_bpf_hw_check_params report length

Slawomir Stepien <sst@poczta.fm>
    HID: amd_sfh: Validate PCI BAR size before mapping

Sean Anderson <sanderson@brivo.com>
    pinctrl: meson: Fix typo in s4 group name

Donggeun Yoo <donggeunyoo.kernel@gmail.com>
    bpf, arm64: set up the frame pointer for the exception callback

Geliang Tang <geliang@kernel.org>
    bpf, sockmap: Fix self-redirect copied_seq double-counting

Pu Lehui <pulehui@huawei.com>
    bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk

Kumar Kartikeya Dwivedi <memxor@gmail.com>
    bpf: Register dtor for freeing special fields

Hou Tao <houtao1@huawei.com>
    bpf: Factor out htab_elem_value helper()

Hou Tao <houtao1@huawei.com>
    bpf: Bail out early in __htab_map_lookup_and_delete_elem()

Hou Tao <houtao1@huawei.com>
    bpf: Remove migrate_{disable|enable} in ->map_for_each_callback

Jiayuan Chen <jiayuan.chen@linux.dev>
    bpf: Fix out-of-bounds read of rtt_min in sock_ops

Jose Fernandez (Anthropic) <jose.fernandez@linux.dev>
    bpf: Avoid soft lockup in __htab_map_lookup_and_delete_batch()

Jim Mattson <jmattson@google.com>
    KVM: x86/pmu: Move Intel PMU global MSRs to intel_is_valid_msr()

Oscar Priego Verdugo <oscar.priegov@gmail.com>
    HID: elecom: fix bus type for M-XGL20DLBK

Jiayuan Chen <jiayuan.chen@linux.dev>
    tcp: Skip cond_resched() in inet_csk_listen_stop() under BPF context

Jiayuan Chen <jiayuan.chen@linux.dev>
    bpf: Fix out-of-bounds read of sk_protocol in bpf_sock_destroy()

Jiayuan Chen <jiayuan.chen@linux.dev>
    bpf: Fix divide-by-zero in btf_struct_walk()

Sven Schnelle <svens@linux.ibm.com>
    selftests/ftrace: Fix unique symbol check in kprobe_non_uniq_symbol.tc

Weiming Shi <bestswngs@gmail.com>
    bpf: Disallow bpf_skb_pull_data() for LWT_SEG6LOCAL

Daniel Borkmann <daniel@iogearbox.net>
    bpf: Fix bpf_skb_change_tail wrt csum partial skbs

Claudio Imbrenda <imbrenda@linux.ibm.com>
    KVM: s390: Fix IRQ injection with SIGP Stop and Store Status

Mostafa Saleh <smostafa@google.com>
    remoteproc: qcom_q6v5_adsp: Fix iommu_unmap() usage

Zhiling Zou <zhilinz@nebusec.ai>
    xfrm: save input state data before secpath resets

Dong Chenchen <dongchenchen2@huawei.com>
    xfrm: Fix dev use-after-free in xfrm async resumption

Jianbo Liu <jianbol@nvidia.com>
    xfrm: Refactor xfrm_input lock to reduce contention with RSS

Phil Sutter <phil@nwl.cc>
    netfilter: nf_tables: Simplify chain netdev notifier

Phil Sutter <phil@nwl.cc>
    netfilter: nf_tables: Tolerate chains with no remaining hooks

Sean Rhodes <sean@starlabs.systems>
    ALSA: hda/realtek: Add StarFighter HDA SSID

Sean Rhodes <sean@starlabs.systems>
    ALSA: hda/realtek: Limit Star Labs internal mic boost

Wenwu Hou <hwenwur@gmail.com>
    erofs: fix large folio race in erofs_fscache_req_complete

Darrick J. Wong <djwong@kernel.org>
    xfs: don't stash removename operations with unknown ftype

Zizhi Wo <wozizhi@huawei.com>
    smb: client: fix busy dentry warning on unmount after DIO

Itai Handler <itai.handler@gmail.com>
    spi: spi-zynqmp-gqspi: stop the controller on shutdown

Namjae Jeon <linkinjeon@kernel.org>
    ksmbd: fix partial normalized name responses

Antheas Kapenekakis <lkml@antheas.dev>
    HID: asus: fortify keyboard handshake

Frank Sorenson <sorenson@redhat.com>
    smb: client: fix missing iov bounds check in parse_posix_sids()

Frank Sorenson <sorenson@redhat.com>
    smb: client: fix missing lower-bound check on DFS referral string offsets

Frank Sorenson <sorenson@redhat.com>
    smb: client: fix server->total_read for compound encrypted PDUs

Frank Sorenson <sorenson@redhat.com>
    smb: client: fix potential OOB read in smb3_enum_snapshots()

Frank Sorenson <sorenson@redhat.com>
    smb: client: fix next_buffer UAF and NextCommand bounds in compound PDUs

Paulo Alcantara <pc@manguebit.org>
    smb: client: fix unaligned access in WSL reparse point parser

Paulo Alcantara <pc@manguebit.org>
    smb: client: fix smbd_connection leak on cifs_get_tcp_session() error

Frank Sorenson <sorenson@redhat.com>
    smb: client: reject short Next offsets in parse_server_interfaces()

Paulo Alcantara <pc@manguebit.org>
    smb: client: fix rlist race and missing initialization

Paulo Alcantara <pc@manguebit.org>
    smb: client: cancel reconnect work in clean_demultiplex_info()

Guangshuo Li <lgs201920130244@gmail.com>
    drm/msm/hdmi_phy: fix runtime PM cleanup on probe failure

Guangshuo Li <lgs201920130244@gmail.com>
    drm/msm/adreno: fix autosuspend cleanup during teardown

Sajal Gupta <sajal2005gupta@gmail.com>
    drm/gud: fix out-of-bounds write in gud_plane_atomic_check()

Rik van Riel <riel@surriel.com>
    wifi: mac80211: avoid WARN in set_bitrate_mask when sdata not in driver

Zhao Li <enderaoelyther@gmail.com>
    wifi: mwifiex: validate action frame fixed fields

Linmao Li <lilinmao@kylinos.cn>
    wifi: mwifiex: prevent authentication frame length truncation

Pengpeng Hou <pengpeng@iscas.ac.cn>
    wifi: mwifiex: validate scan response extents

Doruk Tan Ozturk <doruk@0sec.ai>
    wifi: mwifiex: bound the pairwise-cipher OUI walk to the IE length

Shengzhuo Wei <me@cherr.cc>
    wifi: p54: require a full exp_if record in PDR_INTERFACE_LIST

Shengzhuo Wei <me@cherr.cc>
    wifi: p54: validate curve data length in the calibration curve converters

Tianchu Chen <flynnnchen@tencent.com>
    wifi: wilc1000: fix RX buffer OOB-write in wilc_wlan_handle_isr_ext()

Ali Ahmet Memis <ali@iusegentoo.com>
    wifi: wilc1000: fix out-of-bounds read in P2P public action frames

Runyu Xiao <runyu.xiao@seu.edu.cn>
    wifi: wlcore: release runtime PM ref on regdomain config failure

Tianchu Chen <flynnnchen@tencent.com>
    wifi: rsi: fix heap OOB write on key removal

Jiangshan Yi <yijiangshan@kylinos.cn>
    wifi: libertas_tf: fix UAF in lbtf_free_adapter()

Stanislaw Gruszka <stf_xl@wp.pl>
    wifi: iwlegacy: fix broadcast stations deallocation

Jiangshan Yi <yijiangshan@kylinos.cn>
    wifi: brcmsmac: fix UAF in brcms_free_timer()

Wentao Liang <vulab@iscas.ac.cn>
    watchdog: starfive-wdt: Fix runtime PM leak in starfive_wdt_pm_start()

Wentao Liang <vulab@iscas.ac.cn>
    watchdog: sp5100_tco: Fix pci_dev reference leak in sp5100_tco_init()

Tzung-Bi Shih <tzungbi@kernel.org>
    watchdog: rtd119x: Avoid division by zero

Tzung-Bi Shih <tzungbi@kernel.org>
    watchdog: msc313e: Propagate error code in resume()

Tzung-Bi Shih <tzungbi@kernel.org>
    watchdog: msc313e: Fix premature reset during timeout update

Tzung-Bi Shih <tzungbi@kernel.org>
    watchdog: digicolor: Avoid division by zero

Li Jun <lijun01@kylinos.cn>
    watchdog: da9063: fix suspend/resume handling of HW_RUNNING watchdog

Guangshuo Li <lgs201920130244@gmail.com>
    hwmon: (w83793) release probe data through kref

Guangshuo Li <lgs201920130244@gmail.com>
    hwmon: (w83791d) remove fan/pwm 4-5 sysfs group on remove

Sanman Pradhan <psanman@juniper.net>
    hwmon: (pmbus/tps53679) Select page 0 for single-page TPS53676

Sanman Pradhan <psanman@juniper.net>
    hwmon: (pmbus/tps53679) Fix TPS53676 phase page decoding

Nuno Sá <nuno.sa@analog.com>
    hwmon: (pmbus/core) increase number of phases and add new mask

Muhammad Bilal <meatuni001@gmail.com>
    hwmon: (hp-wmi-sensors) Fix use-after-free in fungible_show()

Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>
    Input: zero ff_effect before compat copy in input_ff_effect_from_user

Dmitry Torokhov <dmitry.torokhov@gmail.com>
    Input: synaptics-rmi4 - fix GPF in suspend and resume when unbound

Raphaël Larocque <rlarocque@disroot.org>
    Input: synaptics - disable InterTouch on ThinkPad T440p (board id 2722)

Hans de Goede <johannes.goede@oss.qualcomm.com>
    Input: soc_button_array - check btns_desc->package.count

Hans de Goede <johannes.goede@oss.qualcomm.com>
    Input: soc_button_array - fix MS Surface Pro 11 probe failure

Dmitry Torokhov <dmitry.torokhov@gmail.com>
    Input: rmi_smbus - fix out-of-bounds read in rmi_smb_write_block()

Chris Sommers <chris.sommers@icloud.com>
    Input: i8042 - add quirk for Acer Aspire Go 15 AG15-42P

Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>
    Input: evdev - zero absinfo before partial copy in EVIOCSABS

Linkai Gong <gonglinkai@kylinos.cn>
    Input: cyttsp5 - clamp the HID report size before memcpy

Alexei Turtanov <9alexei9@gmail.com>
    Input: atkbd - skip deactivate for Xiaomi Redmi Book Pro 16 2026

Alvin Šipraga <alvin.sipraga@analog.com>
    Input: adp5588-keys - cache GPIO state before registering the gpiochip

Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
    mmc: sdhci_am654: Fallback to DT-provided itap delay on DDR50 tuning failure

Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
    mmc: sdhci_am654: Clear ITAPDLY on tuning failure

Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
    mmc: sdhci_am654: Reset command and data lines on failed tuning

Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
    mmc: sdhci_am654: Move tuning_loop to local variable

Xu Rao <raoxu@uniontech.com>
    mmc: spi: reset bytes_xfered before retrying CRC failures

Runyu Xiao <runyu.xiao@seu.edu.cn>
    mmc: sh_mmcif: initialize IRQ-thread mutex before requesting interrupt

Felix Gu <ustc.gu@gmail.com>
    mmc: sdio_uart: fix xmit_fifo leak when the port table is full

Myeonghun Pak <mhun512@gmail.com>
    mmc: sdhci-of-aspeed: Remove children before releasing SDC resources

Florian Maillard <florian.maillard@mailoo.org>
    mmc: rtsx_pci_sdmmc: ignore broken write-protect on ThinkPad X260

Fan Wu <fanwu01@zju.edu.cn>
    mmc: mxcmmc: cancel data work and watchdog on remove

Fan Wu <fanwu01@zju.edu.cn>
    mmc: mmci: Fix use-after-free in busy-timeout work

Fan Wu <fanwu01@zju.edu.cn>
    mmc: hsq: Fix use-after-free in retry work

Zhu Ling <zhuling0805@qq.com>
    mmc: core: Fix OF node reference leak on card add failure

Fan Wu <fanwu01@zju.edu.cn>
    mmc: core: Cancel SDIO IRQ work before freeing host

Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
    power: sequencing: fix NULL-pointer dereference in pwrseq_device_register()

Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
    power: sequencing: fix NULL-pointer dereference in pwrseq_unit_new()

Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
    power: sequencing: don't call .post_enable() if pwrseq_unit_enable() failed

Christian Göttsche <cgzones@googlemail.com>
    selinux: always fill AVC decision in avc_has_perm_noaudit()

Karl Mehltretter <kmehltretter@gmail.com>
    selinux: recheck intermediate backing files on mprotect()

Karl Mehltretter <kmehltretter@gmail.com>
    selinux: preserve user SID across nested backing files

Shuhei Takeshita <jyohuku.alterego@gmail.com>
    IB/hfi1: Fix the PIO_CRED credit-return mmap

Shuhei Takeshita <jyohuku.alterego@gmail.com>
    IB/hfi1: Resolve the credit-return buffer through the send context's node

Shuangpeng Bai <shuangpeng.kernel@gmail.com>
    IB/mlx4: Fix use-after-free on pkey sysfs registration failure

Guangshuo Li <lgs201920130244@gmail.com>
    i2c: imx: disable autosuspend on remove

Shengzhuo Wei <me@cherr.cc>
    i2c: imx: release DMA channels on probe error

Linkai Gong <gonglinkai@kylinos.cn>
    i2c: atr: fix dangling adapter pointer on add failure

Shengzhuo Wei <me@cherr.cc>
    i2c: at91: release DMA channels on remove and probe error

Jarkko Sakkinen <jarkko@kernel.org>
    KEYS: trusted: Fix tpm2_load_cmd() boundary check

Maoyi Xie <maoyixie.tju@gmail.com>
    keys: translate request_key_auth pid for the reading procfs instance

Cen Zhang <cenzhang@linux.microsoft.com>
    KEYS: encrypted: fix integer overflow of datablob_len

Shakeel Butt <shakeel.butt@linux.dev>
    mm/mlock: use the IRQ-safe accessor for NR_MLOCK in __munlock_folio()

Yifei Gao <gyf161023@gmail.com>
    memstick: ms_block: destroy io_queue workqueue on removal

Siwei Zhang <fourdizhang@tencent.com>
    xfrm: use hlist_del_init_rcu for state_cache and state_cache_input

Chengfeng Ye <nicoyip.dev@gmail.com>
    xfrm: serialize state GC with device state flush

Alberto Carboneri <acarboneri@drivesec.com>
    scsi: core: Validate MODE SENSE lengths in scsi_cdl_enable()

Mark Amirkan <markdamirkan@gmail.com>
    net/packet: avoid truncating TPACKET_V3 private size

Mark Amirkan <markdamirkan@gmail.com>
    net/packet: clear RX owner on VNET header error

Jamal Hadi Salim <jhs@mojatatu.com>
    net/sched: hhf: cap hh_flows_limit at change time

Xuanqiang Luo <luoxuanqiang@kylinos.cn>
    net/sched: act_api: release tail references on DELACTION failure

Guanglei Zhu <zhugl3@xiaopeng.com>
    net: wwan: mhi_wwan_mbim: check skb_copy_bits() return value

Guanglei Zhu <zhugl3@xiaopeng.com>
    net: wwan: mhi_wwan_mbim: guard against a cyclic NDP chain

Guanglei Zhu <zhugl3@xiaopeng.com>
    net: wwan: t7xx: validate the netif index in t7xx_ccmni_recv_skb()

Mark Amirkan <markdamirkan@gmail.com>
    net: lan743x: fix RX checksum use-after-free

Zhiling Zou <zhilinz@nebusec.ai>
    ipv6: xfrm: use full sockets in local error paths

Alexander Chesnokov <Alexander.Chesnokov@kaspersky.com>
    dmaengine: ti: k3-udma-glue: fix NULL dereference in k3_udma_glue_release_rx_chn()

Christian Lugnberg <christian.lugnberg@soundtrack.io>
    dmaengine: sun6i: fix undefined behaviour in sun6i_dma_tx_status

Christian Lugnberg <christian.lugnberg@soundtrack.io>
    dmaengine: sun6i: fix non-atomic read of DMA position registers

Chengfeng Ye <nicoyip.dev@gmail.com>
    Bluetooth: hci_sync: Serialize local codec list cleanup

Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
    Bluetooth: hci_codec: validate vendor codec count length

Aamir Ahmed <elb12345@hotmail.co.uk>
    Bluetooth: eir: validate service data length before reading UUID

Nicolas Thibert <nithibert@gmail.com>
    Bluetooth: btusb: fix NXP IW610 composite device handling

Mark Rutland <mark.rutland@arm.com>
    arm64: percpu: Fix this_cpu_and() mask generation

Mark Rutland <mark.rutland@arm.com>
    arm64: percpu: Fix this_cpu_write() casting

Koichiro Den <den@valinux.co.jp>
    arm64: dts: renesas: r8a779f0: Set UFS lane count

Bradley Morgan <include@grrlz.net>
    arm64: hibernate: pass HVC_SET_VECTORS args to the resume hvc

Thomas Huth <thuth@redhat.com>
    kselftest/arm64: Fix size of thread_data values for pthread_join()

Benoît Sevens <bsevens@google.com>
    HID: logitech-hidpp: fix race condition when accessing stale stack pointer

Wyatt Feng <wf.kernel.dev@gmail.com>
    net: xfrm: reject unrepresentable espintcp transport headers

Zhiling Zou <zhilinz@nebusec.ai>
    openvswitch: avoid reallocating confirmed conntrack labels

Jeffin Philip <jeffinphilip14@gmail.com>
    RDMA/core: fix refcount bug in iwpm_get_nlmsg_request()

Quanye Yang <quanyeyang@proton.me>
    RDMA/ucma: Serialize join and leave on copy_to_user failure

Inbal Schussheim <inbal.lipshtat@mail.huji.ac.il>
    tcp: exclude old ACKs from tcp fast path

Chang S. Bae <chang.seok.bae@intel.com>
    x86/microcode/intel: Reject problematic loading on Granite Rapids systems

Aohan Mei <henrymei@tencent.com>
    rds: ib: use rds_conn_drop() on protocol version mismatch

Hyunwoo Kim <imv4bel@gmail.com>
    exec: Cleanup POSIX timers right after de_thread()

Wentao Liang <vulab@iscas.ac.cn>
    cifs: Fix server use-after-free in cifs_chan_skip_or_disable()

Wentao Liang <vulab@iscas.ac.cn>
    ata: libahci_platform: Fix device reference leak in ahci_platform_get_resources()

Niklas Cassel <cassel@kernel.org>
    ata: libahci: clear PxCLBU and PxFBU for AHCI_HFLAG_32BIT_ONLY

Jiangshan Yi <yijiangshan@kylinos.cn>
    ASoC: codecs: rt712-sdca-dmic: fix uninitialized stream_config->type

Yuho Choi <oss.patchbox@gmail.com>
    ALSA: virtio: reset device before deleting virtqueues

Takashi Iwai <tiwai@suse.de>
    ALSA: core: Fix potential UAF after asynchronous card release

Jeremy Nyberg <slickstretch3.0@gmail.com>
    Input: xpad - fix PDP Marvel Xbox 360 controller

Roberts Kursitis <roberts.kursitis@azeron.eu>
    Input: xpad - add support for Azeron devices

Erich Sartison <byt.es@mailbox.org>
    Input: xpad - add support for Victrix Pro BFG Controller

Bitterblue Smith <rtl8821cerfe2@gmail.com>
    wifi: rtw88: Fix the random "error beacon valid" messages for USB

Bitterblue Smith <rtl8821cerfe2@gmail.com>
    wifi: rtw88: TX QOS Null data the same way as Null data

Zi Yan <ziy@nvidia.com>
    mm/huge_memory: use folio's memcg inside __folio_split()

Matthew Schwartz <matthew.schwartz@linux.dev>
    x86/fred: Reconstruct the #GP context for rejected INT instructions

Filipe Manana <fdmanana@suse.com>
    btrfs: abort transaction on failure to update inode for hole punching and reflinking

Dmitriy Chumachenko <Dmitry.Chumachenko@cyberprotect.ru>
    drm/amdgpu: check ras and obj before dereference

Eric Dumazet <edumazet@google.com>
    net: skbuff: do not leave stale header offsets after pskb_carve()

Dmitriy Okunev <dokunevdmitriy@gmail.com>
    net: mvpp2: prevent buffer overflow in page_pool allocation

James Clark <jjc@jclark.com>
    net: macb: fix ordering around PTP timestamp read

Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
    net: stmmac: propagate FPE preemption-class mapping errors

Linus Walleij <linusw@kernel.org>
    net: ethernet: cortina: Ack RX overrun interrupt correctly

Eric Dumazet <edumazet@google.com>
    net: lock the socket in sock_gettstamp()

Yige Jiang <yigejiang86@gmail.com>
    net: netsec: fix device_node reference leak on phy_np

HyeongJun An <sammiee5311@gmail.com>
    ASoC: hdmi-codec: Report a change when the channel status moves

Sasha Levin <sashal@kernel.org>
    ASoC: ux500: Parenthesize MSP_{RX,TX}_CLKPOL_BIT() arguments

Shivaprasad G Bhat <sbhat@linux.ibm.com>
    powerpc/iommu: Fix the overflow validation in iommu_tce_check_ioba

Amit Machhiwal <amachhiw@linux.ibm.com>
    KVM: PPC: Book3S HV: fix secure device page leak on uv_page_in() failure

Amit Machhiwal <amachhiw@linux.ibm.com>
    KVM: PPC: Book3S HV: fix use-after-free in kvmhv_emulate_tlbie_all_lpid()

Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
    net: stmmac: do not overwrite phc_index when no PTP clock is registered

Eric Dumazet <edumazet@google.com>
    drop_monitor: fix out-of-bounds write in reset_per_cpu_data()

Eric Dumazet <edumazet@google.com>
    drop_monitor: synchronize tracepoint unregistration on error path

Eric Dumazet <edumazet@google.com>
    pppoatm: ensure a writable skb header and linear data

Juan Perdomo <jcperdomo100@gmail.com>
    Bluetooth: RFCOMM: avoid socket lock inversion in listener cleanup

Sai Teja Aluvala <aluvala.sai.teja@intel.com>
    Bluetooth: btintel_pcie: fix off-by-one bounds check in RX submit

Tzung-Bi Shih <tzungbi@kernel.org>
    Bluetooth: btmtksdio: Fix PM runtime reference leak in shutdown

Chris Lu <chris.lu@mediatek.com>
    Bluetooth: btmtk: fix wrong status for short WMT FUNC_CTRL events

Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
    Bluetooth: ISO: set BT_LISTEN before requesting a BIG sync

Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
    Bluetooth: ISO: Fix parent socket leak in iso_conn_ready()

Weiming Shi <bestswngs@gmail.com>
    Bluetooth: coredump: Quiesce dump work on unregister

ThangNN99 <ngocthang2710.1999@gmail.com>
    Bluetooth: hci_core: Fix queuing tx_work after workqueue is drained

Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
    Bluetooth: hci_core: Print number of packets in conn->data_q

Baineng Shou <shoubaineng@gmail.com>
    dmaengine: mmp_pdma: fix wrong sg length in mmp_pdma_prep_slave_sg()

Namjae Jeon <linkinjeon@kernel.org>
    ksmbd: keep compound responses on query info errors

Namjae Jeon <linkinjeon@kernel.org>
    ksmbd: fix partial file information responses

Namjae Jeon <linkinjeon@kernel.org>
    ksmbd: return buffer overflow for partial filesystem info

Eric Dumazet <edumazet@google.com>
    tcp: do not let tcp_rmem be set below 4096

Kuniyuki Iwashima <kuniyu@google.com>
    tcp: Don't call skb_clone_and_charge_r() for close()d listener in tcp_v6_do_rcv().

Nikolay Aleksandrov <razor@blackwall.org>
    net: bridge: mst: move switchdev call outside rcu

Karl Mehltretter <kmehltretter@gmail.com>
    wifi: brcmfmac: fix lost 802.1x TX completion wakeup

Hohyun Sim <tlaghgus0425@korea.ac.kr>
    net: fddi: skfp: fix NULL deref when setting the MAC address while down

Dong Chenchen <dongchenchen2@huawei.com>
    ipv4: icmp: reject RTN_UNREACHABLE input routes in icmp_route_lookup

Andrea Mayer <andrea.mayer@uniroma2.it>
    seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation

Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
    drm/msm/dsi: round the byte clock rate after reparenting to the PHY PLL

Filipe Manana <fdmanana@suse.com>
    btrfs: tree-checker: print dev extent offset in error message

Nicolas Escande <nico.escande@gmail.com>
    wifi: ath11k: cleanup arsta in ath11k_mac_peer_cleanup_all()

Slavin Liu <bolin.liu@seu.edu.cn>
    ALSA: hda: trace PCM open only after assigning a stream

Karl Mehltretter <kmehltretter@gmail.com>
    drm/vc4: Use managed KMS polling to fix UAF on unbind

Zihan Xi <zihanx@nebusec.ai>
    wifi: virt_wifi: don't transfer operstate before register

Xiang Mei <xmei5@asu.edu>
    ALSA: 6fire: fix OOB write from device-reported iso length

Takashi Iwai <tiwai@suse.de>
    ALSA: usb: 6fire: Avoid embedded URBs

Takashi Iwai <tiwai@suse.de>
    ALSA: 6fire: Clean ups with guard()

Runyu Xiao <runyu.xiao@seu.edu.cn>
    gpio: virtuser: skip free_irq when no IRQ is installed

Karl Mehltretter <kmehltretter@gmail.com>
    Input: trackpoint - fix the inertia attribute name in the ABI document

Richard Fitzgerald <rf@opensource.cirrus.com>
    ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params

Richard Fitzgerald <rf@opensource.cirrus.com>
    ASoC: Add codec_ch_mask to snd_soc_dai_link_ch_map

Richard Fitzgerald <rf@opensource.cirrus.com>
    ASoC: Rename snd_soc_dai_link_ch_map.ch_mask to cpu_ch_mask

Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
    ALSA: pcm: set timer->private_data before registering the PCM timer

AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
    phy: mediatek: phy-mtk-hdmi-mt8195: Fix TMDS clk bit ratio setting

AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
    phy: mediatek: phy-mtk-hdmi-mt8195: Fix PLL calc divisor overflow

Takashi Iwai <tiwai@suse.de>
    ALSA: bcd2000: Fix race between rawmidi and disconnect

Kuniyuki Iwashima <kuniyu@google.com>
    neighbour: Skip default parms when resumed in neightbl_dump_info().

Kuniyuki Iwashima <kuniyu@google.com>
    neighbour: Add missing RCU annotation for neightbl_dump_info().

Kuniyuki Iwashima <kuniyu@google.com>
    neighbour: Convert RTM_GETNEIGHTBL to RCU.

Kuniyuki Iwashima <kuniyu@google.com>
    neighbour: Convert RTM_GETNEIGH to RCU.

Kuniyuki Iwashima <kuniyu@google.com>
    neighbour: Move neigh_find_table() to neigh_get().

Kuniyuki Iwashima <kuniyu@google.com>
    neighbour: Allocate skb in neigh_get().

Kuniyuki Iwashima <kuniyu@google.com>
    neighbour: Move two validations from neigh_get() to neigh_valid_get_req().

Kuniyuki Iwashima <kuniyu@google.com>
    neighbour: Make neigh_valid_get_req() return ndmsg.

Kuniyuki Iwashima <kuniyu@amazon.com>
    neighbour: Use rtnl_register_many().

Karl Mehltretter <kmehltretter@gmail.com>
    keys: fix lost wakeup when reaping a dead key type

Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
    drm: Fix drm_pending_vblank_event leak in error path for out_fence_ptr

Breno Leitao <leitao@debian.org>
    arm64: hibernate: clone only the linear map that exists at runtime

Shouping Wang <allen.wang@hj-micro.com>
    perf/arm-cmn: Fix wp_dev_sel2 setting for multi-DTM configurations

Pablo Neira Ayuso <pablo@netfilter.org>
    netfilter: flowtable: hold reference on ct until flow is released

Theodor Arsenij Larionov Trichkine <theodorlarionov@gmail.com>
    netfilter: nft_nat: fully initialise new_addr in netmap setup

Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
    RDMA/siw: Bound fragmented header copies by the remaining length

Leon Romanovsky <leon@kernel.org>
    RDMA/efa: Keep EQ resources alive while IRQ is registered

Leon Romanovsky <leon@kernel.org>
    RDMA/efa: Keep admin queues alive while IRQ is registered

Alex Bereza <alex@bereza.email>
    dmaengine: xilinx_dma: Fix hardware buffer descriptor chain after cyclic DMA

Alex Bereza <alex@bereza.email>
    dmaengine: xilinx_dma: Fix hardware buffer descriptor reuse order

Karl Mehltretter <kmehltretter@gmail.com>
    scsi: qla2xxx: Fix the ql2xfc2target parameter description

Meijing Zhao <zhaomeijing@lixiang.com>
    mm: memblock: show all region flags in debugfs

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: set up the TX info early to fix failure paths

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: mesh: release the channel if start fails

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: mesh: reset the CSA state when leaving

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: add HE 6 GHz capability in the scan elems len

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: don't access the TSF of a down interface

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: don't RCU-dereference the mesh CSA settings we just set

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: don't allow link changes when iface is down

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: require a peer station for TDLS setup confirm

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: reset the AP_VLAN tailroom counter on ifdown

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: don't allow injecting frames wider than the chanctx

Johannes Berg <johannes.berg@intel.com>
    wifi: cfg80211: expose cfg80211_chandef_get_width()

Kavita Kavita <quic_kkavita@quicinc.com>
    wifi: cfg80211: skip regulatory for punctured subchannels

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211_hwsim: don't hand frames to mac80211 while stopping

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: unlist vifs when their netdev is unregistered

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: reset state when starting AP fails

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: abort chanswitch when leaving a mesh

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: suppress chanctx warning for debugfs reset

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: don't offload TC setup on AP_VLAN interfaces

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: don't warn when an IBSS has no channel to scan

Felix Fietkau <nbd@nbd.name>
    wifi: mac80211: use vif radio mask to limit ibss scan frequencies

Felix Fietkau <nbd@nbd.name>
    wifi: cfg80211: add option for vif allowed radios

Johannes Berg <johannes.berg@intel.com>
    wifi: mac80211: don't start a ROC while scanning

Johannes Berg <johannes.berg@intel.com>
    wifi: cfg80211: don't filter by BSS type when removing stale entries

Johannes Berg <johannes.berg@intel.com>
    wifi: cfg80211: only group hidden BSSes with beacon entries

Shivank Garg <shivankg@amd.com>
    dmaengine: wait for RCU readers before releasing dma_device

Shivank Garg <shivankg@amd.com>
    dmaengine: fix use-after-free in dma_chan_put() and dma_release_channel()

Shivank Garg <shivankg@amd.com>
    dmaengine: Fix device kref underflow in dma_chan_put()

Donggeun Yoo <donggeunyoo.kernel@gmail.com>
    dma-coherent: report a failed reserved memory assignment

Chen-Yu Tsai <wenst@chromium.org>
    dma-coherent: Warn if OF reserved memory is beyond current coherent DMA mask

Orgad Shaneh <orgads@gmail.com>
    MIPS: Octeon: apply USB FDT fixups also when USB is modular

Bard Liao <yung-chuan.liao@linux.intel.com>
    soundwire: cadence_master: wait and cancel cdns->work before clock stop

Johannes Berg <johannes.berg@intel.com>
    wifi: cfg80211: check IP header size in cfg80211_classify8021d()

Johannes Berg <johannes.berg@intel.com>
    wifi: cfg80211: don't get the radio mask for netdev-less wdevs

Carolina Jubran <cjubran@nvidia.com>
    IB/IPoIB: Avoid restoring OPER_UP after multicast flush

Shmulik Cohen <anuk909@gmail.com>
    wifi: libipw: reject too-short association responses

Shmulik Cohen <anuk909@gmail.com>
    wifi: libipw: reject too-short beacon and probe responses

Peng Hao <flyingpenghao@gmail.com>
    wifi: mwifiex: fix IRQ leak using wrong index in MSI-X error path

Mariano Baragiola <mbaragiola@linux.com>
    wifi: virt_wifi: free skb when disconnected

Ruoyu Wang <ruoyuw560@gmail.com>
    dmaengine: sprd: Fix runtime PM reference leak in probe

Quanye Yang <quanyeyang@proton.me>
    RDMA/rtrs-clt: Fix CQ pool leak when connect is interrupted

Jacob Moroni <jmoroni@google.com>
    RDMA/irdma: Enforce local fence for IB_WR_REG_MR

Li RongQing <lirongqing@baidu.com>
    RDMA/mad: Fix receive buffer leak when PKey enforcement fails

Yehyeong Lee <yhlee@isslab.korea.ac.kr>
    IB/isert: wait for deferred control PDU completions before releasing the connection

Yehyeong Lee <yhlee@isslab.korea.ac.kr>
    IB/iser: reject a remote invalidation of an unregistered direction

Krystian Kaniewski <krystianmkaniewski@gmail.com>
    RDMA/core: Reject unregistering netdevs in ib_get_eth_speed

Michael Bommarito <michael.bommarito@gmail.com>
    RDMA/rxe: insert mcg into mcg_tree only after rxe_mcast_add() succeeds

Xixin Liu <liuxixin@kylinos.cn>
    clk: scpi: bound-check DVFS index in scpi_dvfs_recalc_rate

Xixin Liu <liuxixin@kylinos.cn>
    firmware: arm_scpi: reject DVFS OPP count above MAX_DVFS_OPPS

Gang Yan <yangang@kylinos.cn>
    RDMA/rxe: Fix integer overflow in mr_check_range() leading to OOB access

Norbert Szetei <norbert@doyensec.com>
    RDMA/rxe: validate access flags before swapping the MR's PD

Guoqing Jiang <guoqing.jiang@linux.dev>
    RDMA/siw: Clear association under lock if siw_qp_modify fails in siw_accept

Pengpeng Hou <pengpeng@iscas.ac.cn>
    ARM: socfpga: select the PL310 erratum 753970 workaround

Maher Azzouzi <maherazz04@gmail.com>
    esp: downgrade zerocopy managed frags before mutating skb frags

Eric Dumazet <edumazet@google.com>
    xfrm: add missing rcu_read_lock(), skb_dst_force() and dev_hold() for xfrm_trans_reinject()

Kyle Zeng <kylebot@openai.com>
    xfrm: fix compat ALLOCSPI request use-after-free

Sabrina Dubroca <sd@queasysnail.net>
    xfrm: avoid RCU warnings around the per-netns netlink socket

Chen Linxuan <me@black-desk.cn>
    pidfd: hold exec_update_lock around namespace ioctl

Ido Schimmel <idosch@nvidia.com>
    ipv6: Honor oif when choosing nexthop for locally generated traffic

Ido Schimmel <idosch@nvidia.com>
    ipv6: Select best matching nexthop object in fib6_table_lookup()

Arash Golgol <arash.golgol@gmail.com>
    media: video-i2c: fix buffer queue ordering

Eric Dumazet <edumazet@google.com>
    ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source()

Kuniyuki Iwashima <kuniyu@google.com>
    ipv6: mcast: Don't hold RTNL for MCAST_ socket options.

Kuniyuki Iwashima <kuniyu@google.com>
    ipv6: mcast: Don't hold RTNL for IPV6_DROP_MEMBERSHIP and MCAST_LEAVE_GROUP.

Kuniyuki Iwashima <kuniyu@google.com>
    ipv6: mcast: Don't hold RTNL for IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP.

Kuniyuki Iwashima <kuniyu@google.com>
    ipv6: mcast: Use in6_dev_get() in ipv6_dev_mc_dec().

Kevin Hao <haokexin@gmail.com>
    net: cpsw: Execute ndo_set_rx_mode callback in a work queue

Kevin Hao <haokexin@gmail.com>
    net: cpsw_new: Execute ndo_set_rx_mode callback in a work queue

Jens Axboe <axboe@kernel.dk>
    sunvdc: fix -EIO issue due to lack of retries

Günther Noack <gnoack@google.com>
    selftests/landlock: Add tests for whiteout object creation

Vasily Gorbik <gor@linux.ibm.com>
    s390/boot: Avoid IPL parameter append past command line

Vasily Gorbik <gor@linux.ibm.com>
    s390/boot: Add sized_strscpy() to enable strscpy() usage

Mickaël Salaün <mic@digikod.net>
    selftests/landlock: Add disconnected leafs and branch test suites

Tingmao Wang <m@maowtm.org>
    selftests/landlock: Add tests for access through disconnected paths

Matthieu Buffet <matthieu@buffet.re>
    selftests/landlock: Add missing connect(minimal AF_UNSPEC) test

Matthieu Buffet <matthieu@buffet.re>
    selftests/landlock: Add test for TCP fast open

Matthieu Buffet <matthieu@buffet.re>
    landlock: Fix TCP Fast Open connection bypass

Sasha Levin <sashal@kernel.org>
    Revert "hwmon: (emc1403) Rely on subsystem locking"

Sasha Levin <sashal@kernel.org>
    Revert "hwmon: (emc1403) Drop hysteresis for low limit temperature"


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

Diffstat:

 .../ABI/testing/sysfs-devices-platform-trackpoint  |    2 +-
 Documentation/ABI/testing/sysfs-fs-erofs           |    2 +-
 Documentation/arch/arm64/booting.rst               |    1 +
 Documentation/arch/s390/pci.rst                    |  144 +-
 Documentation/hwmon/emc1403.rst                    |    8 +-
 Documentation/networking/ip-sysctl.rst             |    2 +
 .../net_cachelines/inet_connection_sock.rst        |    1 +
 .../networking/net_cachelines/inet_sock.rst        |    1 +
 .../networking/net_cachelines/net_device.rst       |    1 +
 Documentation/trace/eprobetrace.rst                |  269 ++++
 Documentation/trace/index.rst                      |    1 +
 Makefile                                           |    4 +-
 arch/arm/mach-socfpga/Kconfig                      |    2 +-
 arch/arm64/boot/dts/renesas/r8a779f0.dtsi          |    1 +
 arch/arm64/include/asm/el2_setup.h                 |    8 +-
 arch/arm64/include/asm/io.h                        |    3 +-
 arch/arm64/include/asm/percpu.h                    |   33 +-
 arch/arm64/kernel/hibernate-asm.S                  |    2 +
 arch/arm64/kernel/hibernate.c                      |    4 +-
 arch/arm64/kvm/emulate-nested.c                    |    2 +-
 arch/arm64/kvm/hypercalls.c                        |    3 +-
 arch/arm64/kvm/mmu.c                               |   15 +-
 arch/arm64/kvm/vgic/vgic-its.c                     |  108 +-
 arch/arm64/kvm/vgic/vgic.h                         |   23 -
 arch/arm64/net/bpf_jit_comp.c                      |    2 +
 arch/mips/cavium-octeon/octeon-platform.c          |    4 +-
 arch/mips/net/bpf_jit_comp32.c                     |    2 +-
 arch/mips/net/bpf_jit_comp64.c                     |    3 +-
 arch/powerpc/kernel/iommu.c                        |    2 +-
 arch/powerpc/kvm/book3s_hv_nested.c                |    2 +
 arch/powerpc/kvm/book3s_hv_uvmem.c                 |    5 +-
 arch/riscv/kvm/aia_imsic.c                         |   11 +-
 arch/riscv/kvm/vcpu_pmu.c                          |   33 +-
 arch/riscv/kvm/vcpu_sbi_hsm.c                      |    4 +-
 arch/riscv/kvm/vcpu_timer.c                        |    5 +-
 arch/s390/boot/ipl_parm.c                          |   26 +-
 arch/s390/boot/string.c                            |   12 +
 arch/s390/include/asm/debug.h                      |    8 +-
 arch/s390/kernel/debug.c                           |   15 +-
 arch/s390/kvm/interrupt.c                          |   72 +-
 arch/s390/kvm/kvm-s390.c                           |    4 +-
 arch/x86/entry/entry_fred.c                        |   11 +-
 arch/x86/events/intel/core.c                       |   89 +-
 arch/x86/events/intel/ds.c                         |   36 +-
 arch/x86/events/intel/pt.c                         |    2 +
 arch/x86/events/perf_event.h                       |    2 +-
 arch/x86/include/asm/kvm_host.h                    |    4 +-
 arch/x86/kernel/cpu/mce/core.c                     |   27 +-
 arch/x86/kernel/cpu/microcode/intel.c              |   26 +
 arch/x86/kvm/Makefile                              |    2 +-
 arch/x86/kvm/mmu/mmu.c                             |   60 +-
 arch/x86/kvm/pmu.c                                 |    8 -
 arch/x86/kvm/regs.c                                |  872 ++++++++++
 arch/x86/kvm/svm/sev.c                             |   77 +-
 arch/x86/kvm/svm/svm.h                             |    1 +
 arch/x86/kvm/vmx/pmu_intel.c                       |    3 +
 arch/x86/kvm/x86.c                                 |  900 +----------
 arch/x86/kvm/x86.h                                 |   28 +
 arch/x86/pci/fixup.c                               |   99 ++
 drivers/ata/libahci.c                              |   15 +-
 drivers/ata/libahci_platform.c                     |    2 +-
 drivers/ata/libata-scsi.c                          |   10 +-
 drivers/base/core.c                                |  131 +-
 drivers/block/sunvdc.c                             |    9 +-
 drivers/bluetooth/btintel_pcie.c                   |   18 +-
 drivers/bluetooth/btmtk.c                          |    7 +-
 drivers/bluetooth/btmtksdio.c                      |    4 +-
 drivers/bluetooth/btusb.c                          |   17 +
 drivers/char/hw_random/atmel-rng.c                 |    2 +-
 drivers/char/hw_random/cctrng.c                    |    2 +-
 drivers/char/hw_random/exynos-trng.c               |    2 +-
 drivers/char/hw_random/ingenic-rng.c               |    2 +-
 drivers/char/hw_random/ks-sa-rng.c                 |    2 +-
 drivers/char/hw_random/mxc-rnga.c                  |    2 +-
 drivers/char/hw_random/n2-drv.c                    |    2 +-
 drivers/char/hw_random/npcm-rng.c                  |    2 +-
 drivers/char/hw_random/omap-rng.c                  |    2 +-
 drivers/char/hw_random/stm32-rng.c                 |   11 +-
 drivers/char/hw_random/timeriomem-rng.c            |    2 +-
 drivers/char/hw_random/xgene-rng.c                 |    2 +-
 drivers/clk/clk-scpi.c                             |    2 +-
 drivers/clk/qcom/gcc-qcm2290.c                     |    6 +-
 drivers/clk/qcom/gcc-sm6115.c                      |    6 +-
 drivers/dma-buf/dma-heap.c                         |   80 +-
 drivers/dma/dmaengine.c                            |   40 +-
 drivers/dma/mmp_pdma.c                             |    2 +-
 drivers/dma/sprd-dma.c                             |    3 +-
 drivers/dma/sun6i-dma.c                            |    9 +-
 drivers/dma/ti/k3-udma-glue.c                      |    5 +-
 drivers/dma/xilinx/xilinx_dma.c                    |   26 +-
 drivers/dpll/dpll_netlink.c                        |    3 +-
 drivers/edac/altera_edac.c                         |  115 +-
 drivers/edac/altera_edac.h                         |    1 +
 drivers/firmware/arm_scpi.c                        |    4 +-
 drivers/firmware/qcom/qcom_scm.c                   |   44 +-
 drivers/firmware/sysfb_simplefb.c                  |   31 +-
 drivers/gpio/gpio-arizona.c                        |    8 +-
 drivers/gpio/gpio-tps65219.c                       |    2 +-
 drivers/gpio/gpio-virtuser.c                       |    3 +-
 drivers/gpio/gpio-zynq.c                           |   10 +-
 drivers/gpio/gpiolib-cdev.c                        |   30 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c           |    1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c         |    2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c   |   20 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c             |   18 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c        |    6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c         |   11 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c        |   36 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c          |   25 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c             |    2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c            |   11 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c            |    9 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c            |    4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c           |    2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h           |   21 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c           |   11 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h           |    3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c       |  459 +-----
 drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c            |    3 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c             |    1 +
 drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c             |    2 +-
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |    4 +-
 drivers/gpu/drm/amd/display/dc/dml/Makefile        |    6 +-
 .../amd/display/dc/dml2/dml2_translation_helper.c  |    1 +
 drivers/gpu/drm/armada/armada_fbdev.c              |    4 +-
 drivers/gpu/drm/bridge/samsung-dsim.c              |    2 +-
 drivers/gpu/drm/bridge/tc358768.c                  |   15 +-
 drivers/gpu/drm/drm_atomic_uapi.c                  |   13 +-
 drivers/gpu/drm/drm_client.c                       |    4 +-
 drivers/gpu/drm/drm_fb_helper.c                    |   24 +-
 drivers/gpu/drm/drm_fbdev_client.c                 |   14 +-
 drivers/gpu/drm/drm_fbdev_dma.c                    |    4 +-
 drivers/gpu/drm/drm_fbdev_shmem.c                  |    4 +-
 drivers/gpu/drm/drm_fbdev_ttm.c                    |    4 +-
 drivers/gpu/drm/drm_file.c                         |   12 +-
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c          |    4 +-
 drivers/gpu/drm/gma500/fbdev.c                     |    4 +-
 drivers/gpu/drm/gud/gud_pipe.c                     |    4 +-
 drivers/gpu/drm/i915/display/intel_connector.c     |    4 +-
 drivers/gpu/drm/i915/display/intel_cursor.c        |    7 +-
 drivers/gpu/drm/i915/display/intel_ddi.c           |    4 +-
 .../gpu/drm/i915/display/intel_display_debugfs.c   |    8 +-
 drivers/gpu/drm/i915/display/intel_display_types.h |   20 +-
 drivers/gpu/drm/i915/display/intel_dp.c            |   36 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c       |    6 +-
 .../gpu/drm/i915/display/intel_dp_link_training.c  |    4 +-
 drivers/gpu/drm/i915/display/intel_dp_mst.c        |  155 +-
 drivers/gpu/drm/i915/display/intel_fbdev.c         |    8 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c          |    8 +-
 drivers/gpu/drm/i915/display/intel_psr.c           |   39 +-
 drivers/gpu/drm/i915/display/skl_universal_plane.c |    9 +-
 drivers/gpu/drm/i915/gem/i915_gem_object.c         |    2 +-
 drivers/gpu/drm/imagination/pvr_free_list.c        |   15 +-
 drivers/gpu/drm/imagination/pvr_mmu.c              |   19 +-
 drivers/gpu/drm/imagination/pvr_mmu.h              |    2 +-
 drivers/gpu/drm/imagination/pvr_vm.c               |    4 +-
 drivers/gpu/drm/msm/adreno/adreno_gpu.c            |    2 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c         |    1 +
 drivers/gpu/drm/msm/dsi/dsi_host.c                 |   36 +-
 drivers/gpu/drm/msm/hdmi/hdmi_phy.c                |    8 +-
 drivers/gpu/drm/msm/msm_fbdev.c                    |    4 +-
 drivers/gpu/drm/nouveau/nouveau_bo.c               |    3 +-
 drivers/gpu/drm/nouveau/nouveau_connector.c        |    5 +-
 drivers/gpu/drm/nouveau/nouveau_drm.c              |    5 +-
 drivers/gpu/drm/nouveau/nouveau_gem.c              |    2 +
 drivers/gpu/drm/nouveau/nouveau_sched.c            |    2 +-
 drivers/gpu/drm/nouveau/nouveau_sched.h            |    1 +
 drivers/gpu/drm/nouveau/nouveau_uvmm.c             |   13 +-
 drivers/gpu/drm/nouveau/nvif/vmm.c                 |    1 +
 drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c   |    4 +-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h    |    2 +
 drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c    |    8 +-
 drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c   |    3 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c     |   23 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c   |    2 +
 drivers/gpu/drm/omapdrm/omap_fbdev.c               |    4 +-
 drivers/gpu/drm/radeon/radeon_fbdev.c              |    4 +-
 drivers/gpu/drm/tegra/fbdev.c                      |    4 +-
 drivers/gpu/drm/tiny/ofdrm.c                       |    8 +-
 drivers/gpu/drm/tiny/simpledrm.c                   |   61 +-
 drivers/gpu/drm/vc4/vc4_kms.c                      |    2 +-
 drivers/gpu/drm/virtio/virtgpu_gem.c               |    2 +-
 drivers/gpu/drm/virtio/virtgpu_ioctl.c             |    6 +-
 drivers/gpu/drm/virtio/virtgpu_submit.c            |   11 +-
 drivers/gpu/drm/virtio/virtgpu_vram.c              |   17 +-
 drivers/gpu/drm/xe/instructions/xe_gpu_commands.h  |    1 +
 drivers/gpu/drm/xe/xe_bo.h                         |   19 +
 drivers/gpu/drm/xe/xe_ring_ops.c                   |   16 +-
 drivers/gpu/drm/xe/xe_vm.c                         |   29 +-
 drivers/hid/amd-sfh-hid/amd_sfh_common.h           |    4 +
 drivers/hid/amd-sfh-hid/amd_sfh_pcie.c             |   10 +
 drivers/hid/bpf/hid_bpf_dispatch.c                 |   12 +-
 drivers/hid/hid-alps.c                             |   31 +-
 drivers/hid/hid-asus.c                             |   34 +-
 drivers/hid/hid-ids.h                              |    3 +
 drivers/hid/hid-logitech-hidpp.c                   |   24 +-
 drivers/hid/hid-quirks.c                           |    3 +-
 drivers/hid/wacom_sys.c                            |    5 +-
 drivers/hwmon/emc1403.c                            |   73 +-
 drivers/hwmon/hp-wmi-sensors.c                     |    2 +
 drivers/hwmon/pmbus/pmbus.h                        |    3 +-
 drivers/hwmon/pmbus/tps53679.c                     |   11 +-
 drivers/hwmon/pwm-fan.c                            |   13 +-
 drivers/hwmon/w83791d.c                            |    1 +
 drivers/hwmon/w83793.c                             |    4 +-
 drivers/i2c/busses/i2c-at91-core.c                 |    3 +
 drivers/i2c/busses/i2c-at91-master.c               |   12 +-
 drivers/i2c/busses/i2c-at91.h                      |    1 +
 drivers/i2c/busses/i2c-imx.c                       |    3 +
 drivers/i2c/busses/i2c-mxs.c                       |    5 +-
 drivers/i2c/busses/i2c-qcom-cci.c                  |   37 +-
 drivers/i2c/busses/i2c-qcom-geni.c                 |   33 +-
 drivers/i2c/i2c-atr.c                              |    1 +
 drivers/i3c/master.c                               |   20 +-
 drivers/infiniband/core/iwpm_util.c                |    9 +-
 drivers/infiniband/core/mad.c                      |    3 +-
 drivers/infiniband/core/ucma.c                     |    7 +-
 drivers/infiniband/core/verbs.c                    |   12 +-
 drivers/infiniband/hw/efa/efa_com.c                |    7 +-
 drivers/infiniband/hw/efa/efa_com.h                |    1 +
 drivers/infiniband/hw/efa/efa_main.c               |   35 +-
 drivers/infiniband/hw/hfi1/file_ops.c              |   23 +-
 drivers/infiniband/hw/irdma/verbs.c                |    2 +-
 drivers/infiniband/hw/mlx4/sysfs.c                 |    4 +
 drivers/infiniband/sw/rxe/rxe_mcast.c              |   50 +-
 drivers/infiniband/sw/rxe/rxe_mr.c                 |    3 +-
 drivers/infiniband/sw/rxe/rxe_verbs.c              |   13 +-
 drivers/infiniband/sw/siw/siw_cm.c                 |    7 +-
 drivers/infiniband/sw/siw/siw_qp_rx.c              |    2 +-
 drivers/infiniband/ulp/ipoib/ipoib.h               |    7 +
 drivers/infiniband/ulp/ipoib/ipoib_ib.c            |   12 +-
 drivers/infiniband/ulp/ipoib/ipoib_multicast.c     |   16 +-
 drivers/infiniband/ulp/iser/iser_initiator.c       |   16 +-
 drivers/infiniband/ulp/isert/ib_isert.c            |   22 +
 drivers/infiniband/ulp/isert/ib_isert.h            |    2 +
 drivers/infiniband/ulp/rtrs/rtrs-clt.c             |    8 +
 drivers/infiniband/ulp/rtrs/rtrs-clt.h             |    2 +
 drivers/input/evdev.c                              |    2 +
 drivers/input/input-compat.c                       |    2 +
 drivers/input/joystick/xpad.c                      |   10 +-
 drivers/input/keyboard/adp5588-keys.c              |   12 +-
 drivers/input/keyboard/atkbd.c                     |    8 +
 drivers/input/misc/soc_button_array.c              |   16 +-
 drivers/input/mouse/synaptics.c                    |    8 +
 drivers/input/rmi4/rmi_driver.c                    |   13 +
 drivers/input/rmi4/rmi_smbus.c                     |   10 +-
 drivers/input/serio/hp_sdc.c                       |    2 +-
 drivers/input/serio/i8042-acpipnpio.h              |    7 +
 drivers/input/touchscreen/cyttsp5.c                |    1 +
 drivers/iommu/iommufd/device.c                     |   70 +-
 drivers/iommu/iommufd/hw_pagetable.c               |   13 +-
 drivers/iommu/iommufd/iommufd_private.h            |    8 +-
 drivers/iommu/iommufd/selftest.c                   |   20 +
 drivers/iommu/msm_iommu.c                          |   55 +-
 drivers/media/i2c/imx355.c                         |   62 +-
 drivers/media/i2c/video-i2c.c                      |    5 +-
 .../platform/chips-media/wave5/wave5-vpu-dec.c     |   12 +-
 .../platform/chips-media/wave5/wave5-vpuconfig.h   |    1 +
 drivers/memstick/core/ms_block.c                   |    2 +
 drivers/mmc/core/bus.c                             |    2 +-
 drivers/mmc/core/host.c                            |    1 +
 drivers/mmc/core/sdio_uart.c                       |    3 +
 drivers/mmc/host/mmc_hsq.c                         |    8 +-
 drivers/mmc/host/mmc_spi.c                         |    1 +
 drivers/mmc/host/mmci.c                            |    3 +
 drivers/mmc/host/mxcmmc.c                          |    4 +
 drivers/mmc/host/rtsx_pci_sdmmc.c                  |    5 +
 drivers/mmc/host/sdhci-of-aspeed.c                 |    5 +-
 drivers/mmc/host/sdhci_am654.c                     |   43 +-
 drivers/mmc/host/sh_mmcif.c                        |    3 +-
 drivers/mmc/host/via-sdmmc.c                       |    4 +
 drivers/mtd/nand/raw/pl35x-nand-controller.c       |   10 +-
 drivers/net/bonding/bond_main.c                    |    2 +-
 drivers/net/dsa/mt7530-mdio.c                      |   18 +-
 drivers/net/ethernet/amazon/ena/ena_com.c          |   25 +-
 drivers/net/ethernet/amazon/ena/ena_com.h          |   14 -
 drivers/net/ethernet/amazon/ena/ena_netdev.c       |    1 +
 drivers/net/ethernet/atheros/atl1c/atl1c_main.c    |    3 +
 drivers/net/ethernet/atheros/atl1e/atl1e_main.c    |    3 +
 drivers/net/ethernet/atheros/atlx/atl1.c           |    3 +
 drivers/net/ethernet/broadcom/bnxt/bnxt.c          |   82 +-
 drivers/net/ethernet/broadcom/bnxt/bnxt.h          |    2 +
 drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c      |    6 +-
 drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h      |    2 +-
 drivers/net/ethernet/broadcom/genet/bcmgenet.c     |   63 +-
 drivers/net/ethernet/broadcom/genet/bcmgenet.h     |    5 +-
 drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c |   20 +-
 drivers/net/ethernet/broadcom/tg3.c                |   15 +-
 drivers/net/ethernet/brocade/bna/bnad.c            |   16 +-
 drivers/net/ethernet/cadence/macb_main.c           |   13 +-
 drivers/net/ethernet/cadence/macb_ptp.c            |   20 +-
 .../chelsio/inline_crypto/chtls/chtls_cm.c         |    4 +-
 drivers/net/ethernet/cortina/gemini.c              |    2 +-
 drivers/net/ethernet/freescale/fman/fman.c         |    1 +
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c  |    3 +
 drivers/net/ethernet/intel/idpf/idpf.h             |   24 +-
 drivers/net/ethernet/intel/idpf/idpf_dev.c         |   10 +-
 drivers/net/ethernet/intel/idpf/idpf_lib.c         |   35 +-
 drivers/net/ethernet/intel/idpf/idpf_txrx.c        |  301 ++--
 drivers/net/ethernet/intel/idpf/idpf_txrx.h        |   14 +-
 drivers/net/ethernet/intel/idpf/idpf_vf_dev.c      |   10 +-
 drivers/net/ethernet/intel/idpf/idpf_virtchnl.c    |   20 +-
 drivers/net/ethernet/intel/idpf/idpf_virtchnl.h    |    3 +-
 drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c    |    3 +-
 drivers/net/ethernet/marvell/octeontx2/af/common.h |   45 +-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c        |    6 +-
 .../ethernet/mellanox/mlx5/core/en/rep/bridge.c    |   45 +-
 drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c |    3 +
 .../ethernet/mellanox/mlx5/core/en_accel/macsec.c  |    2 +
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c  |    1 -
 drivers/net/ethernet/mellanox/mlx5/core/en_rx.c    |   39 +-
 .../net/ethernet/mellanox/mlx5/core/esw/bridge.c   |   15 +-
 .../net/ethernet/mellanox/mlx5/core/esw/bridge.h   |    2 +
 .../net/ethernet/mellanox/mlx5/core/lib/devcom.c   |    5 +-
 drivers/net/ethernet/meta/fbnic/fbnic_csr.h        |    1 +
 drivers/net/ethernet/meta/fbnic/fbnic_fw.c         |    9 +-
 drivers/net/ethernet/meta/fbnic/fbnic_txrx.c       |    2 +-
 drivers/net/ethernet/microchip/lan743x_main.c      |    2 +-
 drivers/net/ethernet/netronome/nfp/crypto/ipsec.c  |    3 +-
 drivers/net/ethernet/socionext/netsec.c            |    2 +
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c     |    5 +-
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c |    4 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h         |    4 +-
 drivers/net/ethernet/stmicro/stmmac/ring_mode.c    |    4 +-
 .../net/ethernet/stmicro/stmmac/stmmac_ethtool.c   |    2 -
 .../net/ethernet/stmicro/stmmac/stmmac_selftests.c |  106 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c    |   19 +-
 drivers/net/ethernet/ti/cpsw.c                     |   41 +-
 drivers/net/ethernet/ti/cpsw_new.c                 |   35 +-
 drivers/net/ethernet/ti/cpsw_priv.h                |    1 +
 drivers/net/ethernet/ti/netcp_core.c               |    2 +-
 drivers/net/fddi/skfp/skfddi.c                     |    3 +-
 drivers/net/macsec.c                               |  123 +-
 drivers/net/pcs/pcs-xpcs.c                         |    4 +-
 drivers/net/phy/mediatek/mtk-ge-soc.c              |   23 +-
 drivers/net/usb/catc.c                             |   15 +-
 drivers/net/usb/cdc_mbim.c                         |    5 +
 drivers/net/usb/lan78xx.c                          |    2 +
 drivers/net/usb/sr9700.c                           |    3 +-
 drivers/net/veth.c                                 |    2 +
 drivers/net/virtio_net.c                           |    9 +
 drivers/net/vrf.c                                  |    2 -
 drivers/net/vxlan/vxlan_core.c                     |    6 +-
 drivers/net/wireless/ath/ath11k/mac.c              |   25 +-
 drivers/net/wireless/ath/wcn36xx/dxe.c             |    2 +-
 .../wireless/broadcom/brcm80211/brcmfmac/core.c    |    2 +
 .../broadcom/brcm80211/brcmsmac/mac80211_if.c      |    4 +
 drivers/net/wireless/intel/ipw2x00/libipw_rx.c     |    6 +
 drivers/net/wireless/intel/iwlegacy/common.c       |    2 +-
 drivers/net/wireless/intersil/p54/eeprom.c         |   22 +-
 drivers/net/wireless/marvell/libertas_tf/main.c    |    2 +-
 drivers/net/wireless/marvell/mwifiex/cfg80211.c    |   12 +-
 drivers/net/wireless/marvell/mwifiex/pcie.c        |    2 +-
 drivers/net/wireless/marvell/mwifiex/scan.c        |   54 +-
 drivers/net/wireless/marvell/mwifiex/util.c        |   10 +-
 .../net/wireless/mediatek/mt76/mt7915/debugfs.c    |    5 +
 drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c |   33 +-
 drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h |    1 +
 drivers/net/wireless/mediatek/mt76/mt7915/init.c   |    7 +-
 drivers/net/wireless/mediatek/mt76/mt7915/mcu.c    |   15 +-
 drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h |    3 +-
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c    |    8 +-
 drivers/net/wireless/microchip/wilc1000/cfg80211.c |   14 +
 drivers/net/wireless/microchip/wilc1000/wlan.c     |    9 +
 drivers/net/wireless/realtek/rtw88/fw.c            |    8 +-
 drivers/net/wireless/realtek/rtw88/tx.c            |    2 +-
 drivers/net/wireless/realtek/rtw89/core.h          |    3 +-
 drivers/net/wireless/realtek/rtw89/mac.c           |   13 +-
 drivers/net/wireless/realtek/rtw89/mac80211.c      |    3 +-
 drivers/net/wireless/realtek/rtw89/pci.c           |   13 +
 drivers/net/wireless/realtek/rtw89/pci.h           |    1 +
 drivers/net/wireless/realtek/rtw89/phy.c           |    3 +-
 drivers/net/wireless/realtek/rtw89/rtw8851be.c     |    1 +
 drivers/net/wireless/realtek/rtw89/rtw8852ae.c     |    1 +
 drivers/net/wireless/realtek/rtw89/rtw8852be.c     |    1 +
 drivers/net/wireless/realtek/rtw89/rtw8852bte.c    |    1 +
 drivers/net/wireless/realtek/rtw89/rtw8852ce.c     |    1 +
 drivers/net/wireless/realtek/rtw89/rtw8922ae.c     |    1 +
 drivers/net/wireless/rsi/rsi_91x_mgmt.c            |    2 -
 drivers/net/wireless/ti/wlcore/main.c              |    4 +-
 drivers/net/wireless/virtual/mac80211_hwsim.c      |   39 +-
 drivers/net/wireless/virtual/virt_wifi.c           |    4 +-
 drivers/net/wwan/mhi_wwan_mbim.c                   |   28 +-
 drivers/net/wwan/t7xx/t7xx_netdev.c                |    4 +
 drivers/nfc/microread/microread.c                  |    6 +-
 drivers/nfc/nfcmrvl/fw_dnld.c                      |   11 +-
 drivers/nfc/pn533/pn533.c                          |   14 +-
 drivers/nfc/pn533/pn533.h                          |    4 +-
 drivers/nfc/pn533/usb.c                            |    4 +-
 drivers/nfc/pn544/pn544.c                          |    7 +-
 drivers/nfc/port100.c                              |    7 +
 drivers/nfc/st21nfca/core.c                        |   12 +-
 drivers/nfc/st21nfca/i2c.c                         |   29 +-
 drivers/nfc/virtual_ncidev.c                       |    3 +-
 drivers/nvdimm/nd_virtio.c                         |  125 +-
 drivers/nvdimm/pmem.c                              |   15 +-
 drivers/nvdimm/region_devs.c                       |    5 +-
 drivers/nvdimm/virtio_pmem.c                       |   14 +-
 drivers/nvdimm/virtio_pmem.h                       |    6 +
 drivers/nvme/host/core.c                           |   83 +-
 drivers/nvme/host/nvme.h                           |    2 +-
 drivers/pci/controller/plda/pcie-starfive.c        |   36 +-
 drivers/pci/hotplug/pnv_php.c                      |    2 +-
 drivers/pci/hotplug/rpaphp_slot.c                  |    2 +-
 drivers/pci/of_property.c                          |   11 +-
 drivers/pci/pci.c                                  |    5 +-
 drivers/pci/rebar.c                                |   19 +-
 drivers/pci/setup-bus.c                            |   56 +-
 drivers/pci/slot.c                                 |   67 +-
 drivers/perf/arm-cmn.c                             |   10 +-
 drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c         |    4 +-
 drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h         |    3 +
 drivers/phy/renesas/phy-rcar-gen3-usb2.c           |  302 +++-
 drivers/pinctrl/meson/pinctrl-meson-s4.c           |    2 +-
 drivers/pinctrl/pinctrl-single.c                   |    3 +-
 drivers/pinctrl/sunxi/pinctrl-sunxi.c              |   76 +-
 drivers/pinctrl/sunxi/pinctrl-sunxi.h              |    7 +
 drivers/platform/x86/amd/pmc/Makefile              |    2 +-
 drivers/platform/x86/amd/pmc/mp1_stb.c             |  316 ++++
 drivers/platform/x86/amd/pmc/pmc.c                 |  314 +---
 drivers/platform/x86/amd/pmc/pmc.h                 |   18 +-
 drivers/platform/x86/intel/int1092/intel_sar.c     |   39 +-
 .../x86/intel/speed_select_if/isst_tpmi_core.c     |   14 +-
 drivers/platform/x86/think-lmi.c                   |   45 +-
 drivers/platform/x86/think-lmi.h                   |    2 +-
 drivers/power/sequencing/core.c                    |   11 +-
 drivers/power/supply/ab8500_fg.c                   |   32 +-
 drivers/power/supply/qcom_battmgr.c                |    8 +-
 drivers/remoteproc/qcom_q6v5_adsp.c                |    8 +-
 drivers/remoteproc/qcom_q6v5_pas.c                 |   93 +-
 drivers/rtc/rtc-rzn1.c                             |   16 +-
 drivers/s390/cio/chp.c                             |    3 +
 drivers/s390/cio/cio.c                             |   11 +-
 drivers/s390/cio/cio.h                             |    5 +-
 drivers/s390/cio/cmf.c                             |    2 +-
 drivers/s390/cio/device.c                          |    9 +-
 drivers/s390/cio/device_fsm.c                      |    3 +
 drivers/s390/cio/device_ops.c                      |   23 +
 drivers/s390/cio/vfio_ccw_fsm.c                    |    2 +-
 drivers/s390/crypto/vfio_ap_ops.c                  |   44 +-
 drivers/scsi/fnic/fnic.h                           |    2 +-
 drivers/scsi/fnic/fnic_isr.c                       |   13 +-
 drivers/scsi/fnic/fnic_main.c                      |   33 +-
 drivers/scsi/libiscsi_tcp.c                        |    3 +
 drivers/scsi/megaraid/megaraid_sas_base.c          |    4 +-
 drivers/scsi/qla2xxx/qla_bsg.c                     |   47 +-
 drivers/scsi/qla2xxx/qla_def.h                     |    2 +
 drivers/scsi/qla2xxx/qla_fw.h                      |    4 +
 drivers/scsi/qla2xxx/qla_init.c                    |   14 +
 drivers/scsi/qla2xxx/qla_iocb.c                    |   23 +-
 drivers/scsi/qla2xxx/qla_isr.c                     |   33 +-
 drivers/scsi/qla2xxx/qla_mbx.c                     |    6 +-
 drivers/scsi/qla2xxx/qla_mid.c                     |   49 +-
 drivers/scsi/qla2xxx/qla_nvme.c                    |   10 +
 drivers/scsi/qla2xxx/qla_os.c                      |   17 +-
 drivers/scsi/scsi.c                                |   24 +-
 drivers/scsi/sd_zbc.c                              |    8 +-
 drivers/soc/qcom/mdt_loader.c                      |    4 +-
 drivers/soundwire/cadence_master.c                 |    7 +
 drivers/spi/spi-zynqmp-gqspi.c                     |   34 +
 drivers/staging/media/rkvdec/rkvdec.c              |    4 +-
 drivers/staging/rtl8723bs/core/rtw_mlme.c          |    5 +-
 drivers/staging/sm750fb/sm750.c                    |    2 +-
 drivers/staging/sm750fb/sm750.h                    |    2 +-
 drivers/staging/sm750fb/sm750_accel.c              |    6 +-
 drivers/staging/sm750fb/sm750_accel.h              |    4 +-
 drivers/thermal/gov_step_wise.c                    |   10 +-
 drivers/usb/cdns3/cdns3-gadget.c                   |    4 +-
 drivers/usb/cdns3/cdnsp-gadget.c                   |  112 +-
 drivers/usb/cdns3/cdnsp-gadget.h                   |    1 +
 drivers/usb/cdns3/cdnsp-mem.c                      |   98 +-
 drivers/usb/cdns3/core.h                           |    2 +-
 drivers/usb/dwc3/core.h                            |    3 +-
 drivers/usb/dwc3/ep0.c                             |    2 +-
 drivers/usb/dwc3/gadget.c                          |  129 +-
 drivers/usb/gadget/function/f_mass_storage.c       |    3 +
 drivers/usb/host/xhci-pci.c                        |    8 +-
 drivers/usb/storage/realtek_cr.c                   |    9 +-
 drivers/usb/typec/tcpm/tcpm.c                      |   39 +-
 drivers/video/screen_info_generic.c                |   36 +
 drivers/virtio/virtio_mmio.c                       |   66 +-
 drivers/watchdog/da9063_wdt.c                      |    4 +-
 drivers/watchdog/digicolor_wdt.c                   |   13 +-
 drivers/watchdog/msc313e_wdt.c                     |   16 +-
 drivers/watchdog/rtd119x_wdt.c                     |    7 +-
 drivers/watchdog/sp5100_tco.c                      |    6 +-
 drivers/watchdog/starfive-wdt.c                    |    2 +-
 fs/9p/vfs_addr.c                                   |   12 +
 fs/autofs/inode.c                                  |    4 +
 fs/btrfs/dev-replace.c                             |    1 +
 fs/btrfs/file.c                                    |    4 +-
 fs/btrfs/tree-checker.c                            |    2 +-
 fs/configfs/dir.c                                  |   13 +-
 fs/configfs/symlink.c                              |   51 +-
 fs/erofs/fscache.c                                 |    2 +
 fs/erofs/sysfs.c                                   |    2 +
 fs/exec.c                                          |   29 +-
 fs/f2fs/debug.c                                    |    4 -
 fs/f2fs/dir.c                                      |    7 +-
 fs/f2fs/f2fs.h                                     |   29 +-
 fs/f2fs/file.c                                     |   47 +-
 fs/f2fs/gc.c                                       |   51 +-
 fs/f2fs/gc.h                                       |   25 -
 fs/f2fs/inline.c                                   |    2 +-
 fs/f2fs/namei.c                                    |    6 +-
 fs/f2fs/node.c                                     |   22 +-
 fs/f2fs/recovery.c                                 |   41 +-
 fs/f2fs/segment.c                                  |    9 +-
 fs/f2fs/super.c                                    |    4 +-
 fs/f2fs/sysfs.c                                    |   18 +-
 fs/fs-writeback.c                                  |   25 +-
 fs/inode.c                                         |   11 +-
 fs/kernfs/mount.c                                  |    4 +-
 fs/lockd/svcsubs.c                                 |    2 +-
 fs/ntfs3/inode.c                                   |    7 +-
 fs/ocfs2/namei.c                                   |    9 +-
 fs/ocfs2/xattr.c                                   |   13 +-
 fs/ocfs2/xattr.h                                   |    8 +-
 fs/pidfs.c                                         |   43 +-
 fs/smb/client/cached_dir.c                         |   32 +-
 fs/smb/client/cifs_fs_sb.h                         |    1 +
 fs/smb/client/cifsacl.c                            |   69 +-
 fs/smb/client/cifsfs.c                             |   12 +
 fs/smb/client/cifsglob.h                           |   12 +-
 fs/smb/client/cifsproto.h                          |    8 +-
 fs/smb/client/cifssmb.c                            |    2 +-
 fs/smb/client/connect.c                            |   10 +
 fs/smb/client/file.c                               |   11 +-
 fs/smb/client/misc.c                               |   12 +-
 fs/smb/client/reparse.c                            |    4 +-
 fs/smb/client/reparse.h                            |    7 +-
 fs/smb/client/sess.c                               |  106 +-
 fs/smb/client/smb2inode.c                          |   11 +
 fs/smb/client/smb2ops.c                            |   78 +-
 fs/smb/client/smb2pdu.c                            |   64 +-
 fs/smb/client/transport.c                          |    4 +-
 fs/smb/server/smb2pdu.c                            |   89 +-
 fs/smb/server/smb2pdu.h                            |    1 +
 fs/squashfs/xz_wrapper.c                           |    6 +-
 fs/super.c                                         |   43 +-
 fs/udf/inode.c                                     |  129 +-
 fs/xfs/libxfs/xfs_da_btree.c                       |    2 +-
 fs/xfs/libxfs/xfs_da_btree.h                       |    2 +
 fs/xfs/scrub/attr_repair.c                         |    4 +-
 fs/xfs/scrub/dir_repair.c                          |   23 +-
 fs/xfs/scrub/health.c                              |    6 +-
 fs/xfs/scrub/inode.c                               |    2 +-
 fs/xfs/scrub/inode_repair.c                        |    2 +-
 fs/xfs/scrub/orphanage.c                           |    6 +-
 fs/xfs/scrub/reap.c                                |    2 +-
 fs/xfs/scrub/refcount.c                            |    8 +-
 fs/xfs/scrub/scrub.h                               |    2 +-
 fs/xfs/scrub/stats.c                               |    1 +
 fs/xfs/scrub/tempfile.c                            |   29 +-
 fs/xfs/xfs_exchrange.c                             |   13 +-
 fs/xfs/xfs_icache.c                                |    2 +-
 fs/xfs/xfs_inode.h                                 |    3 +
 fs/xfs/xfs_qm.c                                    |   10 +-
 include/drm/drm_client.h                           |   10 +-
 include/drm/drm_fb_helper.h                        |   11 +-
 include/drm/drm_file.h                             |    1 +
 include/keys/request_key_auth-type.h               |    2 +-
 include/linux/bpf_mem_alloc.h                      |    6 +
 include/linux/compiler-context-analysis.h          |   32 +
 include/linux/compiler_types.h                     |   18 +-
 include/linux/dev_printk.h                         |    1 +
 include/linux/dmaengine.h                          |    7 +
 include/linux/firmware/qcom/qcom_scm.h             |   20 +-
 include/linux/ftrace.h                             |    5 +-
 include/linux/if_vlan.h                            |    3 +
 include/linux/ipv6.h                               |   40 +-
 include/linux/libnvdimm.h                          |    9 +
 include/linux/lockd/lockd.h                        |    2 +-
 include/linux/netdevice.h                          |    3 +
 include/linux/pci.h                                |   14 +-
 include/linux/perf_event.h                         |    1 +
 include/linux/rculist.h                            |   29 +
 include/linux/sched.h                              |   16 +-
 include/linux/sched/rt.h                           |    2 +
 include/linux/sched/signal.h                       |    5 +-
 include/linux/sched/user.h                         |    3 +-
 include/linux/screen_info.h                        |    2 +
 include/linux/skbuff.h                             |   24 +-
 include/linux/soc/qcom/mdt_loader.h                |    6 +-
 include/linux/virtio.h                             |    2 +-
 include/net/bluetooth/coredump.h                   |    2 +
 include/net/cfg80211.h                             |   25 +
 include/net/gue.h                                  |   19 +-
 include/net/if_inet6.h                             |    2 -
 include/net/inet_connection_sock.h                 |   11 +-
 include/net/inet_sock.h                            |    1 +
 include/net/ip6_route.h                            |    8 +-
 include/net/mac80211.h                             |    5 +-
 include/net/netfilter/nf_conntrack.h               |    5 +
 include/net/netfilter/nf_conntrack_timeout.h       |   27 +-
 include/net/netfilter/nf_tables.h                  |    2 -
 include/net/netmem.h                               |   78 +-
 include/net/netns/xfrm.h                           |    2 +-
 include/net/nfc/hci.h                              |    2 +-
 include/net/nfc/nfc.h                              |    3 +-
 include/net/page_pool/helpers.h                    |   35 +-
 include/net/page_pool/types.h                      |    5 +-
 include/net/rose.h                                 |   12 +
 include/net/sock.h                                 |    8 +-
 include/net/tcp.h                                  |    4 +-
 include/sound/soc.h                                |    3 +-
 include/uapi/linux/landlock.h                      |   37 +-
 include/uapi/linux/nl80211.h                       |    5 +
 init/main.c                                        |   27 +-
 io_uring/net.c                                     |   41 +-
 io_uring/rw.c                                      |   32 +-
 io_uring/waitid.c                                  |   44 +-
 kernel/bpf/arraymap.c                              |    6 +-
 kernel/bpf/btf.c                                   |  140 +-
 kernel/bpf/crypto.c                                |    5 +-
 kernel/bpf/hashtab.c                               |  236 ++-
 kernel/bpf/memalloc.c                              |  106 +-
 kernel/bpf/offload.c                               |    2 +
 kernel/bpf/syscall.c                               |    5 +-
 kernel/cgroup/pids.c                               |    5 +
 kernel/dma/coherent.c                              |   13 +-
 kernel/dma/swiotlb.c                               |    4 +-
 kernel/events/core.c                               |   15 +-
 kernel/events/ring_buffer.c                        |   29 +-
 kernel/futex/pi.c                                  |   10 -
 kernel/locking/rtmutex_api.c                       |    2 +
 kernel/reboot.c                                    |   55 +-
 kernel/sched/core.c                                |   77 +-
 kernel/sched/sched.h                               |    9 +-
 kernel/signal.c                                    |   24 +-
 kernel/sysctl.c                                    |   31 -
 kernel/trace/ftrace.c                              |   57 +-
 kernel/trace/ring_buffer.c                         |  135 +-
 kernel/trace/trace.c                               |  155 +-
 kernel/trace/trace.h                               |  131 +-
 kernel/trace/trace_btf.c                           |   31 +-
 kernel/trace/trace_btf.h                           |    3 +-
 kernel/trace/trace_eprobe.c                        |   19 +-
 kernel/trace/trace_events_hist.c                   |  167 +-
 kernel/trace/trace_events_trigger.c                |  344 ++--
 kernel/trace/trace_functions.c                     |    2 +-
 kernel/trace/trace_probe.c                         |    5 +-
 kernel/trace/trace_stack.c                         |    2 +-
 kernel/workqueue.c                                 |    2 +-
 mm/backing-dev.c                                   |    5 +-
 mm/damon/vaddr.c                                   |    1 +
 mm/huge_memory.c                                   |   10 +
 mm/hugetlb.c                                       |   55 +-
 mm/khugepaged.c                                    |    6 -
 mm/madvise.c                                       |    8 +
 mm/memblock.c                                      |   18 +-
 mm/mlock.c                                         |    2 +-
 mm/mremap.c                                        |   12 +-
 mm/rmap.c                                          |   23 +-
 mm/secretmem.c                                     |  117 +-
 mm/vma.c                                           |    8 +
 net/8021q/vlan_dev.c                               |    5 +
 net/atm/pppoatm.c                                  |   42 +-
 net/bluetooth/bnep/core.c                          |   17 +-
 net/bluetooth/bnep/netdev.c                        |    8 +-
 net/bluetooth/coredump.c                           |   65 +-
 net/bluetooth/eir.c                                |   10 +-
 net/bluetooth/hci_codec.c                          |   36 +-
 net/bluetooth/hci_conn.c                           |   14 +-
 net/bluetooth/hci_core.c                           |   26 +-
 net/bluetooth/hci_sock.c                           |   20 +-
 net/bluetooth/hci_sync.c                           |    2 +
 net/bluetooth/iso.c                                |   53 +-
 net/bluetooth/l2cap_core.c                         |   10 +-
 net/bluetooth/mgmt.c                               |   27 +-
 net/bluetooth/rfcomm/core.c                        |    3 +-
 net/bluetooth/rfcomm/sock.c                        |   19 +-
 net/bluetooth/smp.c                                |   17 +
 net/bridge/br_cfm.c                                |   11 +-
 net/bridge/br_device.c                             |    1 -
 net/bridge/br_input.c                              |   35 +-
 net/bridge/br_mdb.c                                |    2 +
 net/bridge/br_mrp.c                                |   13 +-
 net/bridge/br_mst.c                                |   20 +-
 net/bridge/br_private.h                            |   26 +-
 net/bridge/br_stp_bpdu.c                           |    5 +-
 net/core/dev.c                                     |    2 +-
 net/core/devmem.c                                  |    1 +
 net/core/drop_monitor.c                            |    4 +-
 net/core/filter.c                                  |   46 +-
 net/core/neighbour.c                               |  241 ++-
 net/core/page_pool.c                               |    9 +-
 net/core/skbuff.c                                  |   41 +-
 net/core/skmsg.c                                   |    4 +
 net/core/sock.c                                    |   25 +-
 net/core/sock_map.c                                |    1 +
 net/dccp/ipv6.c                                    |    4 +-
 net/dccp/timer.c                                   |    4 +-
 net/ipv4/arp.c                                     |    1 +
 net/ipv4/esp4.c                                    |    6 +
 net/ipv4/fib_semantics.c                           |   59 +-
 net/ipv4/fou_core.c                                |    4 +
 net/ipv4/icmp.c                                    |   17 +-
 net/ipv4/inet_connection_sock.c                    |   13 +-
 net/ipv4/inet_diag.c                               |    4 +-
 net/ipv4/ip_gre.c                                  |   12 +
 net/ipv4/ipconfig.c                                |   90 +-
 net/ipv4/ipmr.c                                    |    3 +-
 net/ipv4/ipmr_base.c                               |    2 +-
 net/ipv4/sysctl_net_ipv4.c                         |    4 +-
 net/ipv4/tcp_input.c                               |    3 +-
 net/ipv4/tcp_ipv4.c                                |    4 +-
 net/ipv4/tcp_output.c                              |    3 +
 net/ipv4/tcp_timer.c                               |    5 +-
 net/ipv4/xfrm4_input.c                             |    2 -
 net/ipv6/addrconf.c                                |    3 +-
 net/ipv6/af_inet6.c                                |    2 +-
 net/ipv6/esp6.c                                    |    6 +
 net/ipv6/exthdrs_core.c                            |    3 +
 net/ipv6/inet6_connection_sock.c                   |    2 +-
 net/ipv6/ip6_flowlabel.c                           |   67 +-
 net/ipv6/ip6_gre.c                                 |    2 +-
 net/ipv6/ip6_output.c                              |    3 +-
 net/ipv6/ip6mr.c                                   |    2 +-
 net/ipv6/ipv6_sockglue.c                           |    9 -
 net/ipv6/mcast.c                                   |  253 +--
 net/ipv6/netfilter/ip6t_rpfilter.c                 |    2 +-
 net/ipv6/netfilter/ip6t_rt.c                       |   11 +-
 net/ipv6/route.c                                   |   33 +-
 net/ipv6/seg6.c                                    |    4 +-
 net/ipv6/seg6_local.c                              |    3 +
 net/ipv6/tcp_ipv6.c                                |   21 +-
 net/ipv6/xfrm6_input.c                             |    2 -
 net/ipv6/xfrm6_output.c                            |   10 +-
 net/llc/llc_c_ac.c                                 |    2 +-
 net/llc/llc_s_ac.c                                 |    4 +
 net/llc/llc_sap.c                                  |    8 +-
 net/mac80211/cfg.c                                 |   55 +-
 net/mac80211/debugfs.c                             |    2 +-
 net/mac80211/debugfs_netdev.c                      |    9 +
 net/mac80211/ieee80211_i.h                         |    5 +-
 net/mac80211/iface.c                               |   76 +-
 net/mac80211/main.c                                |    4 +
 net/mac80211/mesh.c                                |   34 +-
 net/mac80211/offchannel.c                          |    7 +
 net/mac80211/pm.c                                  |    8 +-
 net/mac80211/scan.c                                |   24 +-
 net/mac80211/tdls.c                                |   19 +-
 net/mac80211/tx.c                                  |   66 +-
 net/mac80211/util.c                                |    3 +-
 net/mctp/route.c                                   |    2 +-
 net/mptcp/Makefile                                 |    2 +-
 net/mptcp/ctrl.c                                   |    4 +-
 net/mptcp/mib.c                                    |    5 +
 net/mptcp/mib.h                                    |    5 +
 net/mptcp/options.c                                |    6 +-
 net/mptcp/{pm_netlink.c => pm_kernel.c}            |   71 +-
 net/mptcp/pm_userspace.c                           |   32 +-
 net/mptcp/protocol.c                               |   95 +-
 net/mptcp/protocol.h                               |   36 +-
 net/mptcp/subflow.c                                |   10 +-
 net/netfilter/ipvs/ip_vs_core.c                    |    6 +
 net/netfilter/nf_conntrack_core.c                  |    6 +-
 net/netfilter/nf_conntrack_netlink.c               |    3 +-
 net/netfilter/nf_conntrack_timeout.c               |   27 +-
 net/netfilter/nf_flow_table_core.c                 |   12 +-
 net/netfilter/nf_flow_table_offload.c              |    7 +-
 net/netfilter/nf_tables_api.c                      |   59 +-
 net/netfilter/nfnetlink_cttimeout.c                |  114 +-
 net/netfilter/nfnetlink_queue.c                    |    8 +-
 net/netfilter/nft_chain_filter.c                   |   50 +-
 net/netfilter/nft_ct.c                             |    7 +-
 net/netfilter/nft_nat.c                            |    2 +-
 net/netfilter/nft_synproxy.c                       |    3 +-
 net/netfilter/xt_CT.c                              |    2 +-
 net/netlink/genetlink.c                            |   29 +-
 net/nfc/core.c                                     |   15 +-
 net/nfc/digital_dep.c                              |    8 +-
 net/nfc/llcp.h                                     |    1 +
 net/nfc/llcp_commands.c                            |    2 +-
 net/nfc/llcp_core.c                                |  173 +-
 net/nfc/llcp_sock.c                                |   67 +-
 net/nfc/nci/core.c                                 |   10 +-
 net/nfc/netlink.c                                  |    7 +-
 net/nfc/nfc.h                                      |    3 +-
 net/openvswitch/conntrack.c                        |   39 +-
 net/packet/af_packet.c                             |  108 +-
 net/packet/internal.h                              |    2 +-
 net/rds/ib_cm.c                                    |    2 +-
 net/rds/ib_frmr.c                                  |   11 +-
 net/rose/af_rose.c                                 |   49 +-
 net/rose/rose_in.c                                 |    6 +
 net/rose/rose_loopback.c                           |   61 +-
 net/rose/rose_timer.c                              |   87 +-
 net/sched/act_api.c                                |   13 +-
 net/sched/act_ct.c                                 |   41 +-
 net/sched/act_gate.c                               |   30 +-
 net/sched/cls_u32.c                                |   12 +-
 net/sched/sch_hfsc.c                               |   22 +
 net/sched/sch_hhf.c                                |    9 +-
 net/sched/sch_teql.c                               |    7 +-
 net/sctp/associola.c                               |   15 +-
 net/sctp/input.c                                   |    7 +-
 net/sctp/ipv6.c                                    |    8 +-
 net/sctp/sm_sideeffect.c                           |   37 +-
 net/sctp/sm_statefuns.c                            |    2 +
 net/smc/smc.h                                      |    6 +-
 net/smc/smc_clc.h                                  |    2 +-
 net/smc/smc_core.c                                 |    4 +-
 net/smc/smc_core.h                                 |    4 +-
 net/smc/smc_ib.c                                   |   10 +-
 net/tipc/group.c                                   |    4 +-
 net/tipc/monitor.c                                 |    3 +-
 net/tls/tls_sw.c                                   |    6 +-
 net/wireless/chan.c                                |  389 ++---
 net/wireless/core.c                                |    2 +
 net/wireless/lib80211_crypt_tkip.c                 |   13 +-
 net/wireless/nl80211.c                             |   60 +-
 net/wireless/scan.c                                |   22 +-
 net/wireless/util.c                                |   68 +-
 net/xdp/xskmap.c                                   |    2 +-
 net/xfrm/espintcp.c                                |    6 +-
 net/xfrm/xfrm_input.c                              |   63 +-
 net/xfrm/xfrm_state.c                              |    9 +-
 net/xfrm/xfrm_user.c                               |   37 +-
 security/ipe/eval.c                                |   12 +-
 security/ipe/eval.h                                |    2 +-
 security/ipe/fs.c                                  |    4 -
 security/ipe/hooks.c                               |   22 +-
 security/ipe/policy_fs.c                           |    4 +
 security/keys/encrypted-keys/encrypted.c           |   20 +-
 security/keys/gc.c                                 |    4 +-
 security/keys/request_key_auth.c                   |   12 +-
 security/keys/trusted-keys/trusted_tpm2.c          |   12 +-
 security/landlock/fs.c                             |   18 +-
 security/landlock/net.c                            |   14 +
 security/selinux/avc.c                             |    5 +-
 security/selinux/hooks.c                           |  158 +-
 security/selinux/include/objsec.h                  |   10 +-
 sound/core/init.c                                  |    3 +-
 sound/core/pcm_timer.c                             |    7 +-
 sound/hda/ext/hdac_ext_stream.c                    |    4 +-
 sound/pci/hda/hda_controller.c                     |    2 +-
 sound/pci/hda/patch_realtek.c                      |    9 +
 sound/soc/codecs/aw88261.c                         |   30 +-
 sound/soc/codecs/aw88261.h                         |    6 -
 sound/soc/codecs/hdmi-codec.c                      |    6 +-
 sound/soc/codecs/rt712-sdca-dmic.c                 |   14 +-
 sound/soc/sdw_utils/soc_sdw_utils.c                |    2 +-
 sound/soc/soc-pcm.c                                |   18 +-
 sound/soc/tegra/tegra210_mixer.c                   |   10 +-
 sound/soc/ux500/ux500_msp_i2s.h                    |    4 +-
 sound/usb/6fire/chip.c                             |   40 +-
 sound/usb/6fire/comm.c                             |   42 +-
 sound/usb/6fire/comm.h                             |    2 +-
 sound/usb/6fire/midi.c                             |   64 +-
 sound/usb/6fire/midi.h                             |    2 +-
 sound/usb/6fire/pcm.c                              |  221 +--
 sound/usb/6fire/pcm.h                              |    5 +-
 sound/usb/bcd2000/bcd2000.c                        |   33 +-
 sound/usb/card.h                                   |    3 +-
 sound/usb/endpoint.c                               |   16 +-
 sound/virtio/virtio_card.c                         |    4 +-
 tools/bootconfig/main.c                            |   32 +-
 tools/lib/bpf/libbpf.c                             |    7 +
 tools/lib/bpf/relo_core.c                          |   58 +-
 tools/perf/tests/shell/stat_bpf_counters.sh        |    2 +-
 .../selftests/arm64/mte/check_gcr_el1_cswitch.c    |    2 +-
 .../testing/selftests/bpf/prog_tests/linked_list.c |    4 +-
 tools/testing/selftests/bpf/progs/bpf_iter_tcp4.c  |    4 +-
 tools/testing/selftests/bpf/progs/bpf_iter_tcp6.c  |    4 +-
 tools/testing/selftests/cgroup/cgroup_util.c       |   82 +-
 tools/testing/selftests/cgroup/cgroup_util.h       |    8 +-
 tools/testing/selftests/cgroup/test_memcontrol.c   |   78 +
 .../ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc |    2 +-
 tools/testing/selftests/landlock/fs_test.c         | 1679 +++++++++++++++++++-
 tools/testing/selftests/landlock/net_test.c        |  169 +-
 tools/testing/selftests/mm/memfd_secret.c          |   30 +-
 tools/testing/selftests/nci/nci_dev.c              |   45 +-
 virt/kvm/kvm_main.c                                |   30 +-
 875 files changed, 14469 insertions(+), 7651 deletions(-)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 001/877] Revert "hwmon: (emc1403) Drop hysteresis for low limit temperature"
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 002/877] Revert "hwmon: (emc1403) Rely on subsystem locking" Greg Kroah-Hartman
                   ` (883 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Sasha Levin

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

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

This reverts commit 5cc075ffa1c986474c1f56ba6f869dcc41a363d4.

Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 Documentation/hwmon/emc1403.rst |  8 ++++----
 drivers/hwmon/emc1403.c         | 27 ++++++++++++++++-----------
 2 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/Documentation/hwmon/emc1403.rst b/Documentation/hwmon/emc1403.rst
index ebf2435a76a62..57f833b1a800e 100644
--- a/Documentation/hwmon/emc1403.rst
+++ b/Documentation/hwmon/emc1403.rst
@@ -71,10 +71,10 @@ and EMC14x8 support eight sensors (one internal, seven external).
 
 The chips implement three limits for each sensor: low (tempX_min), high
 (tempX_max) and critical (tempX_crit.) The chips also implement an
-hysteresis mechanism which applies to high and critical limits. The relative
-difference is stored in a single register on the chip, which means that the
-relative difference between the limit and its hysteresis is always the same
-for high and critical limits.
+hysteresis mechanism which applies to all limits. The relative difference
+is stored in a single register on the chip, which means that the relative
+difference between the limit and its hysteresis is always the same for
+all three limits.
 
 This implementation detail implies the following:
 
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index 39f69adb88c25..ccce948a4306e 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -305,9 +305,10 @@ static int emc1403_get_hyst(struct thermal_data *data, int channel,
 	ret = regmap_read(data->regmap, 0x21, &hyst);
 	if (ret < 0)
 		return ret;
-
-	*val = limit - hyst * 1000;
-
+	if (map == temp_min)
+		*val = limit + hyst * 1000;
+	else
+		*val = limit - hyst * 1000;
 	return 0;
 }
 
@@ -323,6 +324,9 @@ static int emc1403_temp_read(struct thermal_data *data, u32 attr, int channel, l
 	case hwmon_temp_input:
 		ret = emc1403_get_temp(data, channel, ema1403_temp_map[attr], val);
 		break;
+	case hwmon_temp_min_hyst:
+		ret = emc1403_get_hyst(data, channel, temp_min, val);
+		break;
 	case hwmon_temp_max_hyst:
 		ret = emc1403_get_hyst(data, channel, temp_max, val);
 		break;
@@ -544,6 +548,7 @@ static umode_t emc1403_temp_is_visible(const void *_data, u32 attr, int channel)
 	case hwmon_temp_max_alarm:
 	case hwmon_temp_crit_alarm:
 	case hwmon_temp_fault:
+	case hwmon_temp_min_hyst:
 	case hwmon_temp_max_hyst:
 		return 0444;
 	case hwmon_temp_min:
@@ -586,35 +591,35 @@ static const struct hwmon_channel_info * const emc1403_info[] = {
 	HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL),
 	HWMON_CHANNEL_INFO(temp,
 			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
-			   HWMON_T_CRIT | HWMON_T_MAX_HYST |
+			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
 			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
 			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM,
 			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
-			   HWMON_T_CRIT | HWMON_T_MAX_HYST |
+			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
 			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
 			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,
 			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
-			   HWMON_T_CRIT | HWMON_T_MAX_HYST |
+			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
 			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
 			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,
 			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
-			   HWMON_T_CRIT | HWMON_T_MAX_HYST |
+			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
 			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
 			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,
 			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
-			   HWMON_T_CRIT | HWMON_T_MAX_HYST |
+			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
 			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
 			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,
 			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
-			   HWMON_T_CRIT | HWMON_T_MAX_HYST |
+			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
 			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
 			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,
 			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
-			   HWMON_T_CRIT | HWMON_T_MAX_HYST |
+			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
 			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
 			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT,
 			   HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
-			   HWMON_T_CRIT | HWMON_T_MAX_HYST |
+			   HWMON_T_CRIT | HWMON_T_MIN_HYST | HWMON_T_MAX_HYST |
 			   HWMON_T_CRIT_HYST | HWMON_T_MIN_ALARM |
 			   HWMON_T_MAX_ALARM | HWMON_T_CRIT_ALARM | HWMON_T_FAULT
 			   ),
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 002/877] Revert "hwmon: (emc1403) Rely on subsystem locking"
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 001/877] Revert "hwmon: (emc1403) Drop hysteresis for low limit temperature" Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 003/877] landlock: Fix TCP Fast Open connection bypass Greg Kroah-Hartman
                   ` (882 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Sasha Levin

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

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

This reverts commit 52dfb8be29d9918c40b512f3d65529f88304afe4.

Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/hwmon/emc1403.c | 46 ++++++++++++++++++++++++++++++++---------
 1 file changed, 36 insertions(+), 10 deletions(-)

diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index ccce948a4306e..eca33220d34a0 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -17,6 +17,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/sysfs.h>
+#include <linux/mutex.h>
 #include <linux/regmap.h>
 #include <linux/util_macros.h>
 
@@ -29,6 +30,7 @@ enum emc1403_chip { emc1402, emc1403, emc1404, emc1428 };
 struct thermal_data {
 	enum emc1403_chip chip;
 	struct regmap *regmap;
+	struct mutex mutex;
 };
 
 static ssize_t power_state_show(struct device *dev, struct device_attribute *attr, char *buf)
@@ -266,8 +268,8 @@ static s8 emc1403_temp_regs_low[][4] = {
 	},
 };
 
-static int emc1403_get_temp(struct thermal_data *data, int channel,
-			    enum emc1403_reg_map map, long *val)
+static int __emc1403_get_temp(struct thermal_data *data, int channel,
+			      enum emc1403_reg_map map, long *val)
 {
 	unsigned int regvalh;
 	unsigned int regvall = 0;
@@ -293,23 +295,38 @@ static int emc1403_get_temp(struct thermal_data *data, int channel,
 	return 0;
 }
 
+static int emc1403_get_temp(struct thermal_data *data, int channel,
+			    enum emc1403_reg_map map, long *val)
+{
+	int ret;
+
+	mutex_lock(&data->mutex);
+	ret = __emc1403_get_temp(data, channel, map, val);
+	mutex_unlock(&data->mutex);
+
+	return ret;
+}
+
 static int emc1403_get_hyst(struct thermal_data *data, int channel,
 			    enum emc1403_reg_map map, long *val)
 {
 	int hyst, ret;
 	long limit;
 
-	ret = emc1403_get_temp(data, channel, map, &limit);
+	mutex_lock(&data->mutex);
+	ret = __emc1403_get_temp(data, channel, map, &limit);
 	if (ret < 0)
-		return ret;
+		goto unlock;
 	ret = regmap_read(data->regmap, 0x21, &hyst);
 	if (ret < 0)
-		return ret;
+		goto unlock;
 	if (map == temp_min)
 		*val = limit + hyst * 1000;
 	else
 		*val = limit - hyst * 1000;
-	return 0;
+unlock:
+	mutex_unlock(&data->mutex);
+	return ret;
 }
 
 static int emc1403_temp_read(struct thermal_data *data, u32 attr, int channel, long *val)
@@ -434,16 +451,20 @@ static int emc1403_set_hyst(struct thermal_data *data, long val)
 	else
 		val = clamp_val(val, 0, 255000);
 
-	ret = emc1403_get_temp(data, 0, temp_crit, &limit);
+	mutex_lock(&data->mutex);
+	ret = __emc1403_get_temp(data, 0, temp_crit, &limit);
 	if (ret < 0)
-		return ret;
+		goto unlock;
 
 	hyst = limit - val;
 	if (data->chip == emc1428)
 		hyst = clamp_val(DIV_ROUND_CLOSEST(hyst, 1000), 0, 127);
 	else
 		hyst = clamp_val(DIV_ROUND_CLOSEST(hyst, 1000), 0, 255);
-	return regmap_write(data->regmap, 0x21, hyst);
+	ret = regmap_write(data->regmap, 0x21, hyst);
+unlock:
+	mutex_unlock(&data->mutex);
+	return ret;
 }
 
 static int emc1403_set_temp(struct thermal_data *data, int channel,
@@ -457,6 +478,7 @@ static int emc1403_set_temp(struct thermal_data *data, int channel,
 	regh = emc1403_temp_regs[channel][map];
 	regl = emc1403_temp_regs_low[channel][map];
 
+	mutex_lock(&data->mutex);
 	if (regl >= 0) {
 		if (data->chip == emc1428)
 			val = clamp_val(val, -128000, 127875);
@@ -465,7 +487,7 @@ static int emc1403_set_temp(struct thermal_data *data, int channel,
 		regval = DIV_ROUND_CLOSEST(val, 125);
 		ret = regmap_write(data->regmap, regh, (regval >> 3) & 0xff);
 		if (ret < 0)
-			return ret;
+			goto unlock;
 		ret = regmap_write(data->regmap, regl, (regval & 0x07) << 5);
 	} else {
 		if (data->chip == emc1428)
@@ -475,6 +497,8 @@ static int emc1403_set_temp(struct thermal_data *data, int channel,
 		regval = DIV_ROUND_CLOSEST(val, 1000);
 		ret = regmap_write(data->regmap, regh, regval);
 	}
+unlock:
+	mutex_unlock(&data->mutex);
 	return ret;
 }
 
@@ -671,6 +695,8 @@ static int emc1403_probe(struct i2c_client *client)
 	if (IS_ERR(data->regmap))
 		return PTR_ERR(data->regmap);
 
+	mutex_init(&data->mutex);
+
 	hwmon_dev = devm_hwmon_device_register_with_info(&client->dev,
 							 client->name, data,
 							 &emc1403_chip_info,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 003/877] landlock: Fix TCP Fast Open connection bypass
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 001/877] Revert "hwmon: (emc1403) Drop hysteresis for low limit temperature" Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 002/877] Revert "hwmon: (emc1403) Rely on subsystem locking" Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 004/877] selftests/landlock: Add test for TCP fast open Greg Kroah-Hartman
                   ` (881 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Matthieu Buffet,
	Mickaël Salaün, Sasha Levin

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

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

From: Matthieu Buffet <matthieu@buffet.re>

[ Upstream commit 33cb713db0161b54f04fe830e062c9e102c29a04 ]

The documentation of the socket_connect() LSM hook states that it
controls connecting a socket to a remote address. It has not been the
case since the addition of TCP Fast Open (RFC 7413) support, which
allows opening a TCP connection (thus, setting a socket's destination
address) via the MSG_FASTOPEN flag passed to
sendto()/sendmsg()/sendmmsg(). The problem then got duplicated into
MPTCP.

Landlock did not take it into account when its TCP support was added,
leaving a bypass of TCP connect policy.

Ideally a call to the LSM hook would be added in the fastopen code path,
in order to fix this generically. But connect() hooks are designed to
run with the socket locked, unlike sendmsg() hooks.

Closes: https://github.com/landlock-lsm/linux/issues/41
Fixes: fff69fb03dde ("landlock: Support network rules with TCP bind and connect")
Signed-off-by: Matthieu Buffet <matthieu@buffet.re>
Link: https://patch.msgid.link/20260701214628.33319-1-matthieu@buffet.re
Cc: stable@vger.kernel.org
[mic: Wrap commit message]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
[mic: Backport: adapt the TCP Fast Open check to the TCP-only network
hooks]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 security/landlock/net.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/security/landlock/net.c b/security/landlock/net.c
index 9c9608924fbdb..c5c26e9029924 100644
--- a/security/landlock/net.c
+++ b/security/landlock/net.c
@@ -193,9 +193,23 @@ static int hook_socket_connect(struct socket *const sock,
 					   LANDLOCK_ACCESS_NET_CONNECT_TCP);
 }
 
+static int hook_socket_sendmsg(struct socket *const sock,
+			       struct msghdr *const msg, const int size)
+{
+	struct sockaddr *const address = msg->msg_name;
+
+	if ((msg->msg_flags & MSG_FASTOPEN) && address)
+		return current_check_access_socket(
+			sock, address, msg->msg_namelen,
+			LANDLOCK_ACCESS_NET_CONNECT_TCP);
+
+	return 0;
+}
+
 static struct security_hook_list landlock_hooks[] __ro_after_init = {
 	LSM_HOOK_INIT(socket_bind, hook_socket_bind),
 	LSM_HOOK_INIT(socket_connect, hook_socket_connect),
+	LSM_HOOK_INIT(socket_sendmsg, hook_socket_sendmsg),
 };
 
 __init void landlock_add_net_hooks(void)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 004/877] selftests/landlock: Add test for TCP fast open
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (2 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 003/877] landlock: Fix TCP Fast Open connection bypass Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 005/877] selftests/landlock: Add missing connect(minimal AF_UNSPEC) test Greg Kroah-Hartman
                   ` (880 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Matthieu Buffet,
	Mickaël Salaün, Sasha Levin

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

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

From: Matthieu Buffet <matthieu@buffet.re>

[ Upstream commit f4b30e0b1d488e7ffd8ea28d1365b9ba8e551edb ]

Enforce that TCP Fast Open is controlled by
LANDLOCK_ACCESS_NET_CONNECT_TCP. Semantics of connect() and
sendmsg(MSG_FASTOPEN) should be identical from Landlock's perspective.
Also enforce error code consistency, since UDP sockets ignore the
MSG_FASTOPEN flag while Unix sockets reject it.

Signed-off-by: Matthieu Buffet <matthieu@buffet.re>
Link: https://patch.msgid.link/20260701214628.33319-2-matthieu@buffet.re
Cc: stable@vger.kernel.org
[mic: Fix formatting]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
[mic: Backport: adapt the test to the older network fixture and add the
required send helper]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 tools/testing/selftests/landlock/net_test.c | 155 ++++++++++++++++++++
 1 file changed, 155 insertions(+)

diff --git a/tools/testing/selftests/landlock/net_test.c b/tools/testing/selftests/landlock/net_test.c
index 897131bc8a13b..63b1e655afb25 100644
--- a/tools/testing/selftests/landlock/net_test.c
+++ b/tools/testing/selftests/landlock/net_test.c
@@ -257,6 +257,64 @@ static int connect_variant(const int sock_fd,
 	return connect_variant_addrlen(sock_fd, srv, get_addrlen(srv, false));
 }
 
+static int sendto_variant_addrlen(const int sock_fd,
+				  const struct service_fixture *const srv,
+				  const socklen_t addrlen, void *buf,
+				  size_t len, size_t flags)
+{
+	const struct sockaddr *dst = NULL;
+	ssize_t ret;
+
+	/*
+	 * We never want our processes to be killed by SIGPIPE: we check return
+	 * codes and errno, so that we have actual error messages.
+	 */
+	flags |= MSG_NOSIGNAL;
+
+	if (srv != NULL) {
+		switch (srv->protocol.domain) {
+		case AF_UNSPEC:
+		case AF_INET:
+			dst = (const struct sockaddr *)&srv->ipv4_addr;
+			break;
+
+		case AF_INET6:
+			dst = (const struct sockaddr *)&srv->ipv6_addr;
+			break;
+
+		case AF_UNIX:
+			dst = (const struct sockaddr *)&srv->unix_addr;
+			break;
+
+		default:
+			errno = EAFNOSUPPORT;
+			return -errno;
+		}
+	}
+
+	ret = sendto(sock_fd, buf, len, flags, dst, addrlen);
+	if (ret < 0)
+		return -errno;
+
+	/* errno is not set in cases of partial writes. */
+	if (ret != len)
+		return -EINTR;
+
+	return 0;
+}
+
+static int sendto_variant(const int sock_fd,
+			  const struct service_fixture *const srv, void *buf,
+			  size_t len, size_t flags)
+{
+	socklen_t addrlen = 0;
+
+	if (srv != NULL)
+		addrlen = get_addrlen(srv, false);
+
+	return sendto_variant_addrlen(sock_fd, srv, addrlen, buf, len, flags);
+}
+
 FIXTURE(protocol)
 {
 	struct service_fixture srv0, srv1, srv2, unspec_any0, unspec_srv0;
@@ -937,6 +995,103 @@ TEST_F(protocol, connect_unspec)
 	EXPECT_EQ(0, close(bind_fd));
 }
 
+TEST_F(protocol, tcp_fastopen)
+{
+	const bool restricted = variant->sandbox == TCP_SANDBOX &&
+				variant->prot.type == SOCK_STREAM &&
+				(variant->prot.protocol == IPPROTO_TCP ||
+				 variant->prot.protocol == IPPROTO_IP) &&
+				(variant->prot.domain == AF_INET ||
+				 variant->prot.domain == AF_INET6);
+	const struct landlock_ruleset_attr ruleset_attr = {
+		.handled_access_net = LANDLOCK_ACCESS_NET_CONNECT_TCP,
+	};
+	int bind_fd, client_fd, status;
+	char buf;
+	pid_t child;
+
+	bind_fd = socket_variant(&self->srv0);
+	ASSERT_LE(0, bind_fd);
+	EXPECT_EQ(0, bind_variant(bind_fd, &self->srv0));
+	if (self->srv0.protocol.type == SOCK_STREAM)
+		EXPECT_EQ(0, listen(bind_fd, backlog));
+
+	child = fork();
+	ASSERT_LE(0, child);
+	if (child == 0) {
+		int connect_fd, ret;
+
+		/* Closes listening socket for the child. */
+		EXPECT_EQ(0, close(bind_fd));
+
+		connect_fd = socket_variant(&self->srv0);
+		ASSERT_LE(0, connect_fd);
+
+		if (variant->sandbox == TCP_SANDBOX) {
+			const int ruleset_fd = landlock_create_ruleset(
+				&ruleset_attr, sizeof(ruleset_attr), 0);
+			ASSERT_LE(0, ruleset_fd);
+
+			enforce_ruleset(_metadata, ruleset_fd);
+			EXPECT_EQ(0, close(ruleset_fd));
+		}
+
+		/* Fast Open with no address. */
+		ret = sendto_variant(connect_fd, NULL, NULL, 0, MSG_FASTOPEN);
+		if (self->srv0.protocol.domain == AF_UNIX) {
+			EXPECT_EQ(-ENOTCONN, ret);
+		} else if (self->srv0.protocol.type == SOCK_DGRAM) {
+			EXPECT_EQ(-EDESTADDRREQ, ret);
+		} else {
+			EXPECT_EQ(-EINVAL, ret);
+		}
+
+		/* Fast Open to a denied address. */
+		ret = sendto_variant(connect_fd, &self->srv0, "A", 1,
+				     MSG_FASTOPEN);
+		if (restricted) {
+			EXPECT_EQ(-EACCES, ret);
+		} else if (self->srv0.protocol.domain == AF_UNIX &&
+			   self->srv0.protocol.type == SOCK_STREAM) {
+			EXPECT_EQ(-EOPNOTSUPP, ret);
+		} else {
+			EXPECT_EQ(0, ret);
+		}
+
+		EXPECT_EQ(0, close(connect_fd));
+		_exit(_metadata->exit_code);
+		return;
+	}
+
+	client_fd = bind_fd;
+	if (!restricted && self->srv0.protocol.type == SOCK_STREAM &&
+	    self->srv0.protocol.domain != AF_UNIX) {
+		client_fd = accept(bind_fd, NULL, 0);
+		ASSERT_LE(0, client_fd);
+	}
+
+	if (restricted) {
+		EXPECT_EQ(-1, read(client_fd, &buf, 1));
+		EXPECT_EQ(ENOTCONN, errno);
+	} else if (self->srv0.protocol.domain == AF_UNIX &&
+		   self->srv0.protocol.type == SOCK_STREAM) {
+		EXPECT_EQ(-1, read(client_fd, &buf, 1));
+		EXPECT_EQ(EINVAL, errno);
+	} else {
+		EXPECT_EQ(1, read(client_fd, &buf, 1));
+		EXPECT_EQ('A', buf);
+	}
+
+	EXPECT_EQ(child, waitpid(child, &status, 0));
+	EXPECT_EQ(1, WIFEXITED(status));
+	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+	if (client_fd != bind_fd)
+		EXPECT_LE(0, close(client_fd));
+
+	EXPECT_EQ(0, close(bind_fd));
+}
+
 FIXTURE(ipv4)
 {
 	struct service_fixture srv0, srv1;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 005/877] selftests/landlock: Add missing connect(minimal AF_UNSPEC) test
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (3 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 004/877] selftests/landlock: Add test for TCP fast open Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 006/877] selftests/landlock: Add tests for access through disconnected paths Greg Kroah-Hartman
                   ` (879 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Matthieu Buffet,
	Mickaël Salaün, Sasha Levin

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

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

From: Matthieu Buffet <matthieu@buffet.re>

[ Upstream commit 6685201ebfacff0c889bcd569181fa6e8af5575e ]

connect_variant(unspec_any0) is called twice. Both calls end
up in connect_variant_addrlen() with an address length of
get_addrlen(minimal=false).
However, the connect() syscall and its variants (e.g.
iouring/compat) accept much shorter addresses of 4 bytes
and that behaviour was not tested.

Replace one of these calls with one using a minimal address
length (just a bare sa_family=AF_UNSPEC field with no actual
address). Also add a call using a truncated address for good
measure.

Signed-off-by: Matthieu Buffet <matthieu@buffet.re>
Link: https://lore.kernel.org/r/20251027190726.626244-3-matthieu@buffet.re
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 tools/testing/selftests/landlock/net_test.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/landlock/net_test.c b/tools/testing/selftests/landlock/net_test.c
index 63b1e655afb25..0be69fcc4efbe 100644
--- a/tools/testing/selftests/landlock/net_test.c
+++ b/tools/testing/selftests/landlock/net_test.c
@@ -963,7 +963,19 @@ TEST_F(protocol, connect_unspec)
 			EXPECT_EQ(0, close(ruleset_fd));
 		}
 
-		ret = connect_variant(connect_fd, &self->unspec_any0);
+		/* Try to re-disconnect with a truncated address struct. */
+		EXPECT_EQ(-EINVAL,
+			  connect_variant_addrlen(
+				  connect_fd, &self->unspec_any0,
+				  get_addrlen(&self->unspec_any0, true) - 1));
+
+		/*
+		 * Re-disconnect, with a minimal sockaddr struct (just a
+		 * bare af_family=AF_UNSPEC field).
+		 */
+		ret = connect_variant_addrlen(connect_fd, &self->unspec_any0,
+					      get_addrlen(&self->unspec_any0,
+							  true));
 		if (self->srv0.protocol.domain == AF_UNIX &&
 		    self->srv0.protocol.type == SOCK_STREAM) {
 			EXPECT_EQ(-EINVAL, ret);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 006/877] selftests/landlock: Add tests for access through disconnected paths
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (4 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 005/877] selftests/landlock: Add missing connect(minimal AF_UNSPEC) test Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 007/877] selftests/landlock: Add disconnected leafs and branch test suites Greg Kroah-Hartman
                   ` (878 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Günther Noack, Song Liu,
	Tingmao Wang, Mickaël Salaün, Sasha Levin

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

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

From: Tingmao Wang <m@maowtm.org>

[ Upstream commit a18ee3f31fd714173a62515d049d77e76ab55649 ]

This adds tests for the edge case discussed in [1], with specific ones
for rename and link operations when the operands are through
disconnected paths, as that go through a separate code path in Landlock.

This has resulted in a warning, due to collect_domain_accesses() not
expecting to reach a different root from path->mnt:

  #  RUN           layout1_bind.path_disconnected ...
  #            OK  layout1_bind.path_disconnected
  ok 96 layout1_bind.path_disconnected
  #  RUN           layout1_bind.path_disconnected_rename ...
  [..] ------------[ cut here ]------------
  [..] WARNING: CPU: 3 PID: 385 at security/landlock/fs.c:1065 collect_domain_accesses
  [..] ...
  [..] RIP: 0010:collect_domain_accesses (security/landlock/fs.c:1065 (discriminator 2) security/landlock/fs.c:1031 (discriminator 2))
  [..] current_check_refer_path (security/landlock/fs.c:1205)
  [..] ...
  [..] hook_path_rename (security/landlock/fs.c:1526)
  [..] security_path_rename (security/security.c:2026 (discriminator 1))
  [..] do_renameat2 (fs/namei.c:5264)
  #            OK  layout1_bind.path_disconnected_rename
  ok 97 layout1_bind.path_disconnected_rename

Move the const char definitions a bit above so that we can use the path
for s4d1 in cleanup code.

Cc: Günther Noack <gnoack@google.com>
Cc: Song Liu <song@kernel.org>
Link: https://lore.kernel.org/r/027d5190-b37a-40a8-84e9-4ccbc352bcdf@maowtm.org [1]
Signed-off-by: Tingmao Wang <m@maowtm.org>
Link: https://lore.kernel.org/r/20251128172200.760753-4-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 tools/testing/selftests/landlock/fs_test.c | 423 ++++++++++++++++++++-
 1 file changed, 415 insertions(+), 8 deletions(-)

diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index c781014e6a5c6..1109d0e932336 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -4363,6 +4363,18 @@ TEST_F_FORK(ioctl, handle_file_access_file)
 FIXTURE(layout1_bind) {};
 /* clang-format on */
 
+static const char bind_dir_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3";
+static const char bind_file1_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3/f1";
+
+/* Move targets for disconnected path tests. */
+static const char dir_s4d1[] = TMP_DIR "/s4d1";
+static const char file1_s4d1[] = TMP_DIR "/s4d1/f1";
+static const char file2_s4d1[] = TMP_DIR "/s4d1/f2";
+static const char dir_s4d2[] = TMP_DIR "/s4d1/s4d2";
+static const char file1_s4d2[] = TMP_DIR "/s4d1/s4d2/f1";
+static const char file1_name[] = "f1";
+static const char file2_name[] = "f2";
+
 FIXTURE_SETUP(layout1_bind)
 {
 	prepare_layout(_metadata);
@@ -4378,14 +4390,14 @@ FIXTURE_TEARDOWN_PARENT(layout1_bind)
 {
 	/* umount(dir_s2d2)) is handled by namespace lifetime. */
 
+	remove_path(file1_s4d1);
+	remove_path(file2_s4d1);
+
 	remove_layout1(_metadata);
 
 	cleanup_layout(_metadata);
 }
 
-static const char bind_dir_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3";
-static const char bind_file1_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3/f1";
-
 /*
  * layout1_bind hierarchy:
  *
@@ -4396,20 +4408,25 @@ static const char bind_file1_s1d3[] = TMP_DIR "/s2d1/s2d2/s1d3/f1";
  * │   └── s1d2
  * │       ├── f1
  * │       ├── f2
- * │       └── s1d3
+ * │       └── s1d3 [disconnected by path_disconnected]
  * │           ├── f1
  * │           └── f2
  * ├── s2d1
  * │   ├── f1
- * │   └── s2d2
+ * │   └── s2d2 [bind mount from s1d2]
  * │       ├── f1
  * │       ├── f2
  * │       └── s1d3
  * │           ├── f1
  * │           └── f2
- * └── s3d1
- *     └── s3d2
- *         └── s3d3
+ * ├── s3d1
+ * │   └── s3d2
+ * │       └── s3d3
+ * └── s4d1 [renamed from s1d3 by path_disconnected]
+ *     ├── f1
+ *     ├── f2
+ *     └── s4d2
+ *         └── f1
  */
 
 TEST_F_FORK(layout1_bind, no_restriction)
@@ -4608,6 +4625,396 @@ TEST_F_FORK(layout1_bind, reparent_cross_mount)
 	ASSERT_EQ(0, rename(bind_file1_s1d3, file1_s2d2));
 }
 
+/*
+ * Make sure access to file through a disconnected path works as expected.
+ * This test moves s1d3 to s4d1.
+ */
+TEST_F_FORK(layout1_bind, path_disconnected)
+{
+	const struct rule layer1_allow_all[] = {
+		{
+			.path = TMP_DIR,
+			.access = ACCESS_ALL,
+		},
+		{},
+	};
+	const struct rule layer2_allow_just_f1[] = {
+		{
+			.path = file1_s1d3,
+			.access = LANDLOCK_ACCESS_FS_READ_FILE,
+		},
+		{},
+	};
+	const struct rule layer3_only_s1d2[] = {
+		{
+			.path = dir_s1d2,
+			.access = LANDLOCK_ACCESS_FS_READ_FILE,
+		},
+		{},
+	};
+
+	/* Landlock should not deny access just because it is disconnected. */
+	int ruleset_fd_l1 =
+		create_ruleset(_metadata, ACCESS_ALL, layer1_allow_all);
+
+	/* Creates the new ruleset now before we move the dir containing the file. */
+	int ruleset_fd_l2 =
+		create_ruleset(_metadata, ACCESS_RW, layer2_allow_just_f1);
+	int ruleset_fd_l3 =
+		create_ruleset(_metadata, ACCESS_RW, layer3_only_s1d2);
+	int bind_s1d3_fd;
+
+	ASSERT_LE(0, ruleset_fd_l1);
+	ASSERT_LE(0, ruleset_fd_l2);
+	ASSERT_LE(0, ruleset_fd_l3);
+
+	enforce_ruleset(_metadata, ruleset_fd_l1);
+	EXPECT_EQ(0, close(ruleset_fd_l1));
+
+	bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_CLOEXEC);
+	ASSERT_LE(0, bind_s1d3_fd);
+
+	/* Tests access is possible before we move. */
+	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
+	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, "..", O_RDONLY | O_DIRECTORY));
+
+	/* Makes it disconnected. */
+	ASSERT_EQ(0, rename(dir_s1d3, dir_s4d1))
+	{
+		TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d1,
+		       strerror(errno));
+	}
+
+	/* Tests that access is still possible. */
+	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
+
+	/*
+	 * Tests that ".." is not possible (not because of Landlock, but just
+	 * because it's disconnected).
+	 */
+	EXPECT_EQ(ENOENT,
+		  test_open_rel(bind_s1d3_fd, "..", O_RDONLY | O_DIRECTORY));
+
+	/* This should still work with a narrower rule. */
+	enforce_ruleset(_metadata, ruleset_fd_l2);
+	EXPECT_EQ(0, close(ruleset_fd_l2));
+
+	EXPECT_EQ(0, test_open(file1_s4d1, O_RDONLY));
+	/*
+	 * Accessing a file through a disconnected file descriptor can still be
+	 * allowed by a rule tied to this file, even if it is no longer visible in
+	 * its mount point.
+	 */
+	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+	EXPECT_EQ(EACCES, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
+
+	enforce_ruleset(_metadata, ruleset_fd_l3);
+	EXPECT_EQ(0, close(ruleset_fd_l3));
+
+	EXPECT_EQ(EACCES, test_open(file1_s4d1, O_RDONLY));
+	/*
+	 * Accessing a file through a disconnected file descriptor can still be
+	 * allowed by a rule tied to the original mount point, even if it is no
+	 * longer visible in its mount point.
+	 */
+	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+	EXPECT_EQ(EACCES, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
+}
+
+/*
+ * Test that renameat with disconnected paths works under Landlock.  This test
+ * moves s1d3 to s4d2, so that we can have a rule allowing refers on the move
+ * target's immediate parent.
+ */
+TEST_F_FORK(layout1_bind, path_disconnected_rename)
+{
+	const struct rule layer1[] = {
+		{
+			.path = dir_s1d2,
+			.access = LANDLOCK_ACCESS_FS_REFER |
+				  LANDLOCK_ACCESS_FS_MAKE_DIR |
+				  LANDLOCK_ACCESS_FS_REMOVE_DIR |
+				  LANDLOCK_ACCESS_FS_MAKE_REG |
+				  LANDLOCK_ACCESS_FS_REMOVE_FILE |
+				  LANDLOCK_ACCESS_FS_READ_FILE,
+		},
+		{
+			.path = dir_s4d1,
+			.access = LANDLOCK_ACCESS_FS_REFER |
+				  LANDLOCK_ACCESS_FS_MAKE_DIR |
+				  LANDLOCK_ACCESS_FS_REMOVE_DIR |
+				  LANDLOCK_ACCESS_FS_MAKE_REG |
+				  LANDLOCK_ACCESS_FS_REMOVE_FILE |
+				  LANDLOCK_ACCESS_FS_READ_FILE,
+		},
+		{}
+	};
+
+	/* This layer only handles LANDLOCK_ACCESS_FS_READ_FILE. */
+	const struct rule layer2_only_s1d2[] = {
+		{
+			.path = dir_s1d2,
+			.access = LANDLOCK_ACCESS_FS_READ_FILE,
+		},
+		{},
+	};
+	int ruleset_fd_l1, ruleset_fd_l2;
+	pid_t child_pid;
+	int bind_s1d3_fd, status;
+
+	ASSERT_EQ(0, mkdir(dir_s4d1, 0755))
+	{
+		TH_LOG("Failed to create %s: %s", dir_s4d1, strerror(errno));
+	}
+	ruleset_fd_l1 = create_ruleset(_metadata, ACCESS_ALL, layer1);
+	ruleset_fd_l2 = create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_FILE,
+				       layer2_only_s1d2);
+	ASSERT_LE(0, ruleset_fd_l1);
+	ASSERT_LE(0, ruleset_fd_l2);
+
+	enforce_ruleset(_metadata, ruleset_fd_l1);
+	EXPECT_EQ(0, close(ruleset_fd_l1));
+
+	bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_CLOEXEC);
+	ASSERT_LE(0, bind_s1d3_fd);
+	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+
+	/* Tests ENOENT priority over EACCES for disconnected directory. */
+	EXPECT_EQ(EACCES, test_open_rel(bind_s1d3_fd, "..", O_DIRECTORY));
+	ASSERT_EQ(0, rename(dir_s1d3, dir_s4d2))
+	{
+		TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d2,
+		       strerror(errno));
+	}
+	EXPECT_EQ(ENOENT, test_open_rel(bind_s1d3_fd, "..", O_DIRECTORY));
+
+	/*
+	 * The file is no longer under s1d2 but we should still be able to access it
+	 * with layer 2 because its mount point is evaluated as the first valid
+	 * directory because it was initially a parent.  Do a fork to test this so
+	 * we don't prevent ourselves from renaming it back later.
+	 */
+	child_pid = fork();
+	ASSERT_LE(0, child_pid);
+	if (child_pid == 0) {
+		enforce_ruleset(_metadata, ruleset_fd_l2);
+		EXPECT_EQ(0, close(ruleset_fd_l2));
+		EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+		EXPECT_EQ(EACCES, test_open(file1_s4d2, O_RDONLY));
+
+		/*
+		 * Tests that access widening checks indeed prevents us from renaming it
+		 * back.
+		 */
+		EXPECT_EQ(-1, rename(dir_s4d2, dir_s1d3));
+		EXPECT_EQ(EXDEV, errno);
+
+		/*
+		 * Including through the now disconnected fd (but it should return
+		 * EXDEV).
+		 */
+		EXPECT_EQ(-1, renameat(bind_s1d3_fd, file1_name, AT_FDCWD,
+				       file1_s2d2));
+		EXPECT_EQ(EXDEV, errno);
+		_exit(_metadata->exit_code);
+		return;
+	}
+
+	EXPECT_EQ(child_pid, waitpid(child_pid, &status, 0));
+	EXPECT_EQ(1, WIFEXITED(status));
+	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+	ASSERT_EQ(0, rename(dir_s4d2, dir_s1d3))
+	{
+		TH_LOG("Failed to rename %s back to %s: %s", dir_s4d1, dir_s1d3,
+		       strerror(errno));
+	}
+
+	/* Now checks that we can access it under l2. */
+	child_pid = fork();
+	ASSERT_LE(0, child_pid);
+	if (child_pid == 0) {
+		enforce_ruleset(_metadata, ruleset_fd_l2);
+		EXPECT_EQ(0, close(ruleset_fd_l2));
+		EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+		EXPECT_EQ(0, test_open(file1_s1d3, O_RDONLY));
+		_exit(_metadata->exit_code);
+		return;
+	}
+
+	EXPECT_EQ(child_pid, waitpid(child_pid, &status, 0));
+	EXPECT_EQ(1, WIFEXITED(status));
+	EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
+
+	/*
+	 * Also test that we can rename via a disconnected path.  We move the
+	 * dir back to the disconnected place first, then we rename file1 to
+	 * file2 through our dir fd.
+	 */
+	ASSERT_EQ(0, rename(dir_s1d3, dir_s4d2))
+	{
+		TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d2,
+		       strerror(errno));
+	}
+	ASSERT_EQ(0,
+		  renameat(bind_s1d3_fd, file1_name, bind_s1d3_fd, file2_name))
+	{
+		TH_LOG("Failed to rename %s to %s within disconnected %s: %s",
+		       file1_name, file2_name, bind_dir_s1d3, strerror(errno));
+	}
+	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file2_name, O_RDONLY));
+	ASSERT_EQ(0, renameat(bind_s1d3_fd, file2_name, AT_FDCWD, file1_s2d2))
+	{
+		TH_LOG("Failed to rename %s to %s through disconnected %s: %s",
+		       file2_name, file1_s2d2, bind_dir_s1d3, strerror(errno));
+	}
+	EXPECT_EQ(0, test_open(file1_s2d2, O_RDONLY));
+	EXPECT_EQ(0, test_open(file1_s1d2, O_RDONLY));
+
+	/* Move it back using the disconnected path as the target. */
+	ASSERT_EQ(0, renameat(AT_FDCWD, file1_s2d2, bind_s1d3_fd, file1_name))
+	{
+		TH_LOG("Failed to rename %s to %s through disconnected %s: %s",
+		       file1_s1d2, file1_name, bind_dir_s1d3, strerror(errno));
+	}
+
+	/* Now make it connected again. */
+	ASSERT_EQ(0, rename(dir_s4d2, dir_s1d3))
+	{
+		TH_LOG("Failed to rename %s back to %s: %s", dir_s4d2, dir_s1d3,
+		       strerror(errno));
+	}
+
+	/* Checks again that we can access it under l2. */
+	enforce_ruleset(_metadata, ruleset_fd_l2);
+	EXPECT_EQ(0, close(ruleset_fd_l2));
+	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+	EXPECT_EQ(0, test_open(file1_s1d3, O_RDONLY));
+}
+
+/*
+ * Test that linkat(2) with disconnected paths works under Landlock. This
+ * test moves s1d3 to s4d1.
+ */
+TEST_F_FORK(layout1_bind, path_disconnected_link)
+{
+	/* Ruleset to be applied after renaming s1d3 to s4d1. */
+	const struct rule layer1[] = {
+		{
+			.path = dir_s4d1,
+			.access = LANDLOCK_ACCESS_FS_REFER |
+				  LANDLOCK_ACCESS_FS_READ_FILE |
+				  LANDLOCK_ACCESS_FS_MAKE_REG |
+				  LANDLOCK_ACCESS_FS_REMOVE_FILE,
+		},
+		{
+			.path = dir_s2d2,
+			.access = LANDLOCK_ACCESS_FS_REFER |
+				  LANDLOCK_ACCESS_FS_READ_FILE |
+				  LANDLOCK_ACCESS_FS_MAKE_REG |
+				  LANDLOCK_ACCESS_FS_REMOVE_FILE,
+		},
+		{}
+	};
+	int ruleset_fd, bind_s1d3_fd;
+
+	/* Removes unneeded files created by layout1, otherwise it will EEXIST. */
+	ASSERT_EQ(0, unlink(file1_s1d2));
+	ASSERT_EQ(0, unlink(file2_s1d3));
+
+	bind_s1d3_fd = open(bind_dir_s1d3, O_PATH | O_CLOEXEC);
+	ASSERT_LE(0, bind_s1d3_fd);
+	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY));
+
+	/* Disconnects bind_s1d3_fd. */
+	ASSERT_EQ(0, rename(dir_s1d3, dir_s4d1))
+	{
+		TH_LOG("Failed to rename %s to %s: %s", dir_s1d3, dir_s4d1,
+		       strerror(errno));
+	}
+
+	/* Need this later to test different parent link. */
+	ASSERT_EQ(0, mkdir(dir_s4d2, 0755))
+	{
+		TH_LOG("Failed to create %s: %s", dir_s4d2, strerror(errno));
+	}
+
+	ruleset_fd = create_ruleset(_metadata, ACCESS_ALL, layer1);
+	ASSERT_LE(0, ruleset_fd);
+	enforce_ruleset(_metadata, ruleset_fd);
+	EXPECT_EQ(0, close(ruleset_fd));
+
+	/* From disconnected to connected. */
+	ASSERT_EQ(0, linkat(bind_s1d3_fd, file1_name, AT_FDCWD, file1_s2d2, 0))
+	{
+		TH_LOG("Failed to link %s to %s via disconnected %s: %s",
+		       file1_name, file1_s2d2, bind_dir_s1d3, strerror(errno));
+	}
+
+	/* Tests that we can access via the new link... */
+	EXPECT_EQ(0, test_open(file1_s2d2, O_RDONLY))
+	{
+		TH_LOG("Failed to open newly linked %s: %s", file1_s2d2,
+		       strerror(errno));
+	}
+
+	/* ...as well as the old one. */
+	EXPECT_EQ(0, test_open(file1_s4d1, O_RDONLY))
+	{
+		TH_LOG("Failed to open original %s: %s", file1_s4d1,
+		       strerror(errno));
+	}
+
+	/* From connected to disconnected. */
+	ASSERT_EQ(0, unlink(file1_s4d1));
+	ASSERT_EQ(0, linkat(AT_FDCWD, file1_s2d2, bind_s1d3_fd, file2_name, 0))
+	{
+		TH_LOG("Failed to link %s to %s via disconnected %s: %s",
+		       file1_s2d2, file2_name, bind_dir_s1d3, strerror(errno));
+	}
+	EXPECT_EQ(0, test_open(file2_s4d1, O_RDONLY));
+	ASSERT_EQ(0, unlink(file1_s2d2));
+
+	/* From disconnected to disconnected (same parent). */
+	ASSERT_EQ(0,
+		  linkat(bind_s1d3_fd, file2_name, bind_s1d3_fd, file1_name, 0))
+	{
+		TH_LOG("Failed to link %s to %s within disconnected %s: %s",
+		       file2_name, file1_name, bind_dir_s1d3, strerror(errno));
+	}
+	EXPECT_EQ(0, test_open(file1_s4d1, O_RDONLY))
+	{
+		TH_LOG("Failed to open newly linked %s: %s", file1_s4d1,
+		       strerror(errno));
+	}
+	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, file1_name, O_RDONLY))
+	{
+		TH_LOG("Failed to open %s through newly created link under disconnected path: %s",
+		       file1_name, strerror(errno));
+	}
+	ASSERT_EQ(0, unlink(file2_s4d1));
+
+	/* From disconnected to disconnected (different parent). */
+	ASSERT_EQ(0,
+		  linkat(bind_s1d3_fd, file1_name, bind_s1d3_fd, "s4d2/f1", 0))
+	{
+		TH_LOG("Failed to link %s to %s within disconnected %s: %s",
+		       file1_name, "s4d2/f1", bind_dir_s1d3, strerror(errno));
+	}
+	EXPECT_EQ(0, test_open(file1_s4d2, O_RDONLY))
+	{
+		TH_LOG("Failed to open %s after link: %s", file1_s4d2,
+		       strerror(errno));
+	}
+	EXPECT_EQ(0, test_open_rel(bind_s1d3_fd, "s4d2/f1", O_RDONLY))
+	{
+		TH_LOG("Failed to open %s through disconnected path after link: %s",
+		       "s4d2/f1", strerror(errno));
+	}
+}
+
 #define LOWER_BASE TMP_DIR "/lower"
 #define LOWER_DATA LOWER_BASE "/data"
 static const char lower_fl1[] = LOWER_DATA "/fl1";
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 007/877] selftests/landlock: Add disconnected leafs and branch test suites
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (5 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 006/877] selftests/landlock: Add tests for access through disconnected paths Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 008/877] s390/boot: Add sized_strscpy() to enable strscpy() usage Greg Kroah-Hartman
                   ` (877 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Günther Noack, Song Liu,
	Tingmao Wang, Mickaël Salaün, Sasha Levin

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

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

From: Mickaël Salaün <mic@digikod.net>

[ Upstream commit 54f9baf537b0a091adad860ec92e3e18e0a0754c ]

Test disconnected directories with two test suites
(layout4_disconnected_leafs and layout5_disconnected_branch) and 43
variants to cover the main corner cases.

These tests are complementary to the previous commit.

Add test_renameat() and test_exchangeat() helpers.

Test coverage for security/landlock is 92.1% of 1927 lines according to
LLVM 20.

Cc: Günther Noack <gnoack@google.com>
Cc: Song Liu <song@kernel.org>
Cc: Tingmao Wang <m@maowtm.org>
Link: https://lore.kernel.org/r/20251128172200.760753-5-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 tools/testing/selftests/landlock/fs_test.c | 1051 ++++++++++++++++++++
 1 file changed, 1051 insertions(+)

diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index 1109d0e932336..732ba5a92df56 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -2109,6 +2109,22 @@ static int test_exchange(const char *const oldpath, const char *const newpath)
 	return 0;
 }
 
+static int test_renameat(int olddirfd, const char *oldpath, int newdirfd,
+			 const char *newpath)
+{
+	if (renameat2(olddirfd, oldpath, newdirfd, newpath, 0))
+		return errno;
+	return 0;
+}
+
+static int test_exchangeat(int olddirfd, const char *oldpath, int newdirfd,
+			   const char *newpath)
+{
+	if (renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_EXCHANGE))
+		return errno;
+	return 0;
+}
+
 TEST_F_FORK(layout1, rename_file)
 {
 	const struct rule rules[] = {
@@ -5015,6 +5031,1041 @@ TEST_F_FORK(layout1_bind, path_disconnected_link)
 	}
 }
 
+/*
+ * layout4_disconnected_leafs with bind mount and renames:
+ *
+ * tmp
+ * ├── s1d1
+ * │   └── s1d2 [source of the bind mount]
+ * │       ├── s1d31
+ * │       │   └── s1d41 [now renamed beneath s3d1]
+ * │       │       ├── f1
+ * │       │       └── f2
+ * │       └── s1d32
+ * │           └── s1d42 [now renamed beneath s4d1]
+ * │               ├── f3
+ * │               └── f4
+ * ├── s2d1
+ * │   └── s2d2 [bind mount of s1d2]
+ * │       ├── s1d31
+ * │       │   └── s1d41 [opened FD, now renamed beneath s3d1]
+ * │       │       ├── f1
+ * │       │       └── f2
+ * │       └── s1d32
+ * │           └── s1d42 [opened FD, now renamed beneath s4d1]
+ * │               ├── f3
+ * │               └── f4
+ * ├── s3d1
+ * │   └── s1d41 [renamed here]
+ * │       ├── f1
+ * │       └── f2
+ * └── s4d1
+ *     └── s1d42 [renamed here]
+ *         ├── f3
+ *         └── f4
+ */
+/* clang-format off */
+FIXTURE(layout4_disconnected_leafs) {
+	int s2d2_fd;
+};
+/* clang-format on */
+
+FIXTURE_SETUP(layout4_disconnected_leafs)
+{
+	prepare_layout(_metadata);
+
+	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f1");
+	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f2");
+	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d32/s1d42/f3");
+	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d32/s1d42/f4");
+	create_directory(_metadata, TMP_DIR "/s2d1/s2d2");
+	create_directory(_metadata, TMP_DIR "/s3d1");
+	create_directory(_metadata, TMP_DIR "/s4d1");
+
+	self->s2d2_fd =
+		open(TMP_DIR "/s2d1/s2d2", O_DIRECTORY | O_PATH | O_CLOEXEC);
+	ASSERT_LE(0, self->s2d2_fd);
+
+	set_cap(_metadata, CAP_SYS_ADMIN);
+	ASSERT_EQ(0, mount(TMP_DIR "/s1d1/s1d2", TMP_DIR "/s2d1/s2d2", NULL,
+			   MS_BIND, NULL));
+	clear_cap(_metadata, CAP_SYS_ADMIN);
+}
+
+FIXTURE_TEARDOWN_PARENT(layout4_disconnected_leafs)
+{
+	/* umount(TMP_DIR "/s2d1") is handled by namespace lifetime. */
+
+	/* Removes files after renames. */
+	remove_path(TMP_DIR "/s3d1/s1d41/f1");
+	remove_path(TMP_DIR "/s3d1/s1d41/f2");
+	remove_path(TMP_DIR "/s4d1/s1d42/f1");
+	remove_path(TMP_DIR "/s4d1/s1d42/f3");
+	remove_path(TMP_DIR "/s4d1/s1d42/f4");
+	remove_path(TMP_DIR "/s4d1/s1d42/f5");
+
+	cleanup_layout(_metadata);
+}
+
+FIXTURE_VARIANT(layout4_disconnected_leafs)
+{
+	/*
+	 * Parent of the bind mount source.  It should always be ignored when
+	 * testing against files under the s1d41 or s1d42 disconnected directories.
+	 */
+	const __u64 allowed_s1d1;
+	/*
+	 * Source of bind mount (to s2d2).  It should always be enforced when
+	 * testing against files under the s1d41 or s1d42 disconnected directories.
+	 */
+	const __u64 allowed_s1d2;
+	/*
+	 * Original parent of s1d41.  It should always be ignored when testing
+	 * against files under the s1d41 disconnected directory.
+	 */
+	const __u64 allowed_s1d31;
+	/*
+	 * Original parent of s1d42.  It should always be ignored when testing
+	 * against files under the s1d42 disconnected directory.
+	 */
+	const __u64 allowed_s1d32;
+	/*
+	 * Opened and disconnected source directory.  It should always be enforced
+	 * when testing against files under the s1d41 disconnected directory.
+	 */
+	const __u64 allowed_s1d41;
+	/*
+	 * Opened and disconnected source directory.  It should always be enforced
+	 * when testing against files under the s1d42 disconnected directory.
+	 */
+	const __u64 allowed_s1d42;
+	/*
+	 * File in the s1d41 disconnected directory.  It should always be enforced
+	 * when testing against itself under the s1d41 disconnected directory.
+	 */
+	const __u64 allowed_f1;
+	/*
+	 * File in the s1d41 disconnected directory.  It should always be enforced
+	 * when testing against itself under the s1d41 disconnected directory.
+	 */
+	const __u64 allowed_f2;
+	/*
+	 * File in the s1d42 disconnected directory.  It should always be enforced
+	 * when testing against itself under the s1d42 disconnected directory.
+	 */
+	const __u64 allowed_f3;
+	/*
+	 * Parent of the bind mount destination.  It should always be enforced when
+	 * testing against files under the s1d41 or s1d42 disconnected directories.
+	 */
+	const __u64 allowed_s2d1;
+	/*
+	 * Directory covered by the bind mount.  It should always be ignored when
+	 * testing against files under the s1d41 or s1d42 disconnected directories.
+	 */
+	const __u64 allowed_s2d2;
+	/*
+	 * New parent of the renamed s1d41.  It should always be ignored when
+	 * testing against files under the s1d41 disconnected directory.
+	 */
+	const __u64 allowed_s3d1;
+	/*
+	 * New parent of the renamed s1d42.  It should always be ignored when
+	 * testing against files under the s1d42 disconnected directory.
+	 */
+	const __u64 allowed_s4d1;
+
+	/* Expected result of the call to open([fd:s1d41]/f1, O_RDONLY). */
+	const int expected_read_result;
+	/* Expected result of the call to renameat([fd:s1d41]/f1, [fd:s1d42]/f1). */
+	const int expected_rename_result;
+	/*
+	 * Expected result of the call to renameat([fd:s1d41]/f2, [fd:s1d42]/f3,
+	 * RENAME_EXCHANGE).
+	 */
+	const int expected_exchange_result;
+	/* Expected result of the call to renameat([fd:s1d42]/f4, [fd:s1d42]/f5). */
+	const int expected_same_dir_rename_result;
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d1_mount_src_parent) {
+	/* clang-format on */
+	.allowed_s1d1 = LANDLOCK_ACCESS_FS_REFER |
+			LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_EXECUTE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d2_mount_src_refer) {
+	/* clang-format on */
+	.allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d2_mount_src_create) {
+	/* clang-format on */
+	.allowed_s1d2 = LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = EXDEV,
+	.expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d2_mount_src_rename) {
+	/* clang-format on */
+	.allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = 0,
+	.expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d31_s1d32_old_parent) {
+	/* clang-format on */
+	.allowed_s1d31 = LANDLOCK_ACCESS_FS_REFER |
+			 LANDLOCK_ACCESS_FS_READ_FILE |
+			 LANDLOCK_ACCESS_FS_EXECUTE |
+			 LANDLOCK_ACCESS_FS_MAKE_REG,
+	.allowed_s1d32 = LANDLOCK_ACCESS_FS_REFER |
+			 LANDLOCK_ACCESS_FS_READ_FILE |
+			 LANDLOCK_ACCESS_FS_EXECUTE |
+			 LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_refer) {
+	/* clang-format on */
+	.allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER |
+			 LANDLOCK_ACCESS_FS_READ_FILE,
+	.allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER |
+			 LANDLOCK_ACCESS_FS_READ_FILE,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_create) {
+	/* clang-format on */
+	.allowed_s1d41 = LANDLOCK_ACCESS_FS_READ_FILE |
+			 LANDLOCK_ACCESS_FS_MAKE_REG,
+	.allowed_s1d42 = LANDLOCK_ACCESS_FS_READ_FILE |
+			 LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = EXDEV,
+	.expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_rename_even) {
+	/* clang-format on */
+	.allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = 0,
+	.expected_exchange_result = 0,
+};
+
+/* The destination directory has more access right. */
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_rename_more) {
+	/* clang-format on */
+	.allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER |
+			 LANDLOCK_ACCESS_FS_MAKE_REG |
+			 LANDLOCK_ACCESS_FS_EXECUTE,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = 0,
+	/* Access denied. */
+	.expected_rename_result = EXDEV,
+	.expected_exchange_result = EXDEV,
+};
+
+/* The destination directory has less access right. */
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s1d41_s1d42_disconnected_rename_less) {
+	/* clang-format on */
+	.allowed_s1d41 = LANDLOCK_ACCESS_FS_REFER |
+			 LANDLOCK_ACCESS_FS_MAKE_REG |
+			 LANDLOCK_ACCESS_FS_EXECUTE,
+	.allowed_s1d42 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = 0,
+	/* Access allowed. */
+	.expected_rename_result = 0,
+	.expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d1_mount_dst_parent_create) {
+	/* clang-format on */
+	.allowed_s2d1 = LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = EXDEV,
+	.expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d1_mount_dst_parent_refer) {
+	/* clang-format on */
+	.allowed_s2d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d1_mount_dst_parent_mini) {
+	/* clang-format on */
+	.allowed_s2d1 = LANDLOCK_ACCESS_FS_REFER |
+			LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = 0,
+	.expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s2d2_covered_by_mount) {
+	/* clang-format on */
+	.allowed_s2d2 = LANDLOCK_ACCESS_FS_REFER |
+			LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_EXECUTE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* Tests collect_domain_accesses(). */
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_new_parent_refer) {
+	/* clang-format on */
+	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_new_parent_create) {
+	/* clang-format on */
+	.allowed_s3d1 = LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.allowed_s4d1 = LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = EXDEV,
+	.expected_exchange_result = EXDEV,
+};
+
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs,
+		    s3d1_s4d1_disconnected_rename_even){
+	/* clang-format on */
+	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = 0,
+	.expected_exchange_result = 0,
+};
+
+/* The destination directory has more access right. */
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_disconnected_rename_more) {
+	/* clang-format on */
+	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG |
+			LANDLOCK_ACCESS_FS_EXECUTE,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = 0,
+	/* Access denied. */
+	.expected_rename_result = EXDEV,
+	.expected_exchange_result = EXDEV,
+};
+
+/* The destination directory has less access right. */
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, s3d1_s4d1_disconnected_rename_less) {
+	/* clang-format on */
+	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG |
+			LANDLOCK_ACCESS_FS_EXECUTE,
+	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = 0,
+	/* Access allowed. */
+	.expected_rename_result = 0,
+	.expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout4_disconnected_leafs, f1_f2_f3) {
+	/* clang-format on */
+	.allowed_f1 = LANDLOCK_ACCESS_FS_READ_FILE,
+	.allowed_f2 = LANDLOCK_ACCESS_FS_READ_FILE,
+	.allowed_f3 = LANDLOCK_ACCESS_FS_READ_FILE,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+TEST_F_FORK(layout4_disconnected_leafs, read_rename_exchange)
+{
+	const __u64 handled_access =
+		LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE |
+		LANDLOCK_ACCESS_FS_EXECUTE | LANDLOCK_ACCESS_FS_MAKE_REG;
+	const struct rule rules[] = {
+		{
+			.path = TMP_DIR "/s1d1",
+			.access = variant->allowed_s1d1,
+		},
+		{
+			.path = TMP_DIR "/s1d1/s1d2",
+			.access = variant->allowed_s1d2,
+		},
+		{
+			.path = TMP_DIR "/s1d1/s1d2/s1d31",
+			.access = variant->allowed_s1d31,
+		},
+		{
+			.path = TMP_DIR "/s1d1/s1d2/s1d32",
+			.access = variant->allowed_s1d32,
+		},
+		{
+			.path = TMP_DIR "/s1d1/s1d2/s1d31/s1d41",
+			.access = variant->allowed_s1d41,
+		},
+		{
+			.path = TMP_DIR "/s1d1/s1d2/s1d32/s1d42",
+			.access = variant->allowed_s1d42,
+		},
+		{
+			.path = TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f1",
+			.access = variant->allowed_f1,
+		},
+		{
+			.path = TMP_DIR "/s1d1/s1d2/s1d31/s1d41/f2",
+			.access = variant->allowed_f2,
+		},
+		{
+			.path = TMP_DIR "/s1d1/s1d2/s1d32/s1d42/f3",
+			.access = variant->allowed_f3,
+		},
+		{
+			.path = TMP_DIR "/s2d1",
+			.access = variant->allowed_s2d1,
+		},
+		/* s2d2_fd */
+		{
+			.path = TMP_DIR "/s3d1",
+			.access = variant->allowed_s3d1,
+		},
+		{
+			.path = TMP_DIR "/s4d1",
+			.access = variant->allowed_s4d1,
+		},
+		{},
+	};
+	int ruleset_fd, s1d41_bind_fd, s1d42_bind_fd;
+
+	ruleset_fd = create_ruleset(_metadata, handled_access, rules);
+	ASSERT_LE(0, ruleset_fd);
+
+	/* Adds rule for the covered directory. */
+	if (variant->allowed_s2d2) {
+		ASSERT_EQ(0, landlock_add_rule(
+				     ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
+				     &(struct landlock_path_beneath_attr){
+					     .parent_fd = self->s2d2_fd,
+					     .allowed_access =
+						     variant->allowed_s2d2,
+				     },
+				     0));
+	}
+	EXPECT_EQ(0, close(self->s2d2_fd));
+
+	s1d41_bind_fd = open(TMP_DIR "/s2d1/s2d2/s1d31/s1d41",
+			     O_DIRECTORY | O_PATH | O_CLOEXEC);
+	ASSERT_LE(0, s1d41_bind_fd);
+	s1d42_bind_fd = open(TMP_DIR "/s2d1/s2d2/s1d32/s1d42",
+			     O_DIRECTORY | O_PATH | O_CLOEXEC);
+	ASSERT_LE(0, s1d42_bind_fd);
+
+	/* Disconnects and checks source and destination directories. */
+	EXPECT_EQ(0, test_open_rel(s1d41_bind_fd, "..", O_DIRECTORY));
+	EXPECT_EQ(0, test_open_rel(s1d42_bind_fd, "..", O_DIRECTORY));
+	/* Renames to make it accessible through s3d1/s1d41 */
+	ASSERT_EQ(0, test_renameat(AT_FDCWD, TMP_DIR "/s1d1/s1d2/s1d31/s1d41",
+				   AT_FDCWD, TMP_DIR "/s3d1/s1d41"));
+	/* Renames to make it accessible through s4d1/s1d42 */
+	ASSERT_EQ(0, test_renameat(AT_FDCWD, TMP_DIR "/s1d1/s1d2/s1d32/s1d42",
+				   AT_FDCWD, TMP_DIR "/s4d1/s1d42"));
+	EXPECT_EQ(ENOENT, test_open_rel(s1d41_bind_fd, "..", O_DIRECTORY));
+	EXPECT_EQ(ENOENT, test_open_rel(s1d42_bind_fd, "..", O_DIRECTORY));
+
+	enforce_ruleset(_metadata, ruleset_fd);
+	EXPECT_EQ(0, close(ruleset_fd));
+
+	EXPECT_EQ(variant->expected_read_result,
+		  test_open_rel(s1d41_bind_fd, "f1", O_RDONLY));
+
+	EXPECT_EQ(variant->expected_rename_result,
+		  test_renameat(s1d41_bind_fd, "f1", s1d42_bind_fd, "f1"));
+	EXPECT_EQ(variant->expected_exchange_result,
+		  test_exchangeat(s1d41_bind_fd, "f2", s1d42_bind_fd, "f3"));
+
+	EXPECT_EQ(variant->expected_same_dir_rename_result,
+		  test_renameat(s1d42_bind_fd, "f4", s1d42_bind_fd, "f5"));
+}
+
+/*
+ * layout5_disconnected_branch before rename:
+ *
+ * tmp
+ * ├── s1d1
+ * │   └── s1d2 [source of the first bind mount]
+ * │       └── s1d3
+ * │           ├── s1d41
+ * │           │   ├── f1
+ * │           │   └── f2
+ * │           └── s1d42
+ * │               ├── f3
+ * │               └── f4
+ * ├── s2d1
+ * │   └── s2d2 [source of the second bind mount]
+ * │       └── s2d3
+ * │           └── s2d4 [first s1d2 bind mount]
+ * │               └── s1d3
+ * │                   ├── s1d41
+ * │                   │   ├── f1
+ * │                   │   └── f2
+ * │                   └── s1d42
+ * │                       ├── f3
+ * │                       └── f4
+ * ├── s3d1
+ * │   └── s3d2 [second s2d2 bind mount]
+ * │       └── s2d3
+ * │           └── s2d4 [first s1d2 bind mount]
+ * │               └── s1d3
+ * │                   ├── s1d41
+ * │                   │   ├── f1
+ * │                   │   └── f2
+ * │                   └── s1d42
+ * │                       ├── f3
+ * │                       └── f4
+ * └── s4d1
+ *
+ * After rename:
+ *
+ * tmp
+ * ├── s1d1
+ * │   └── s1d2 [source of the first bind mount]
+ * │       └── s1d3
+ * │           ├── s1d41
+ * │           │   ├── f1
+ * │           │   └── f2
+ * │           └── s1d42
+ * │               ├── f3
+ * │               └── f4
+ * ├── s2d1
+ * │   └── s2d2 [source of the second bind mount]
+ * ├── s3d1
+ * │   └── s3d2 [second s2d2 bind mount]
+ * └── s4d1
+ *     └── s2d3 [renamed here]
+ *         └── s2d4 [first s1d2 bind mount]
+ *             └── s1d3
+ *                 ├── s1d41
+ *                 │   ├── f1
+ *                 │   └── f2
+ *                 └── s1d42
+ *                     ├── f3
+ *                     └── f4
+ *
+ * Decision path for access from the s3d1/s3d2/s2d3/s2d4/s1d3 file descriptor:
+ *   1. first bind mount:   s1d3 -> s1d2
+ *   2. second bind mount:    s2d3
+ *   3. tmp mount:              s4d1 -> tmp [disconnected branch]
+ *   4. second bind mount:        s2d2
+ *   5. tmp mount:                  s3d1 -> tmp
+ *   6. parent mounts:                [...] -> /
+ *
+ * The s4d1 directory is evaluated even if it is not in the s2d2 mount.
+ */
+
+/* clang-format off */
+FIXTURE(layout5_disconnected_branch) {
+	int s2d4_fd, s3d2_fd;
+};
+/* clang-format on */
+
+FIXTURE_SETUP(layout5_disconnected_branch)
+{
+	prepare_layout(_metadata);
+
+	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f1");
+	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f2");
+	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f3");
+	create_file(_metadata, TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f4");
+	create_directory(_metadata, TMP_DIR "/s2d1/s2d2/s2d3/s2d4");
+	create_directory(_metadata, TMP_DIR "/s3d1/s3d2");
+	create_directory(_metadata, TMP_DIR "/s4d1");
+
+	self->s2d4_fd = open(TMP_DIR "/s2d1/s2d2/s2d3/s2d4",
+			     O_DIRECTORY | O_PATH | O_CLOEXEC);
+	ASSERT_LE(0, self->s2d4_fd);
+
+	self->s3d2_fd =
+		open(TMP_DIR "/s3d1/s3d2", O_DIRECTORY | O_PATH | O_CLOEXEC);
+	ASSERT_LE(0, self->s3d2_fd);
+
+	set_cap(_metadata, CAP_SYS_ADMIN);
+	ASSERT_EQ(0, mount(TMP_DIR "/s1d1/s1d2", TMP_DIR "/s2d1/s2d2/s2d3/s2d4",
+			   NULL, MS_BIND, NULL));
+	ASSERT_EQ(0, mount(TMP_DIR "/s2d1/s2d2", TMP_DIR "/s3d1/s3d2", NULL,
+			   MS_BIND | MS_REC, NULL));
+	clear_cap(_metadata, CAP_SYS_ADMIN);
+}
+
+FIXTURE_TEARDOWN_PARENT(layout5_disconnected_branch)
+{
+	/* Bind mounts are handled by namespace lifetime. */
+
+	/* Removes files after renames. */
+	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f1");
+	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d41/f2");
+	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f1");
+	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f3");
+	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f4");
+	remove_path(TMP_DIR "/s1d1/s1d2/s1d3/s1d42/f5");
+
+	cleanup_layout(_metadata);
+}
+
+FIXTURE_VARIANT(layout5_disconnected_branch)
+{
+	/*
+	 * Parent of all files.  It should always be enforced when testing against
+	 * files under the s1d41 or s1d42 disconnected directories.
+	 */
+	const __u64 allowed_base;
+	/*
+	 * Parent of the first bind mount source.  It should always be ignored when
+	 * testing against files under the s1d41 or s1d42 disconnected directories.
+	 */
+	const __u64 allowed_s1d1;
+	const __u64 allowed_s1d2;
+	const __u64 allowed_s1d3;
+	const __u64 allowed_s2d1;
+	const __u64 allowed_s2d2;
+	const __u64 allowed_s2d3;
+	const __u64 allowed_s2d4;
+	const __u64 allowed_s3d1;
+	const __u64 allowed_s3d2;
+	const __u64 allowed_s4d1;
+
+	/* Expected result of the call to open([fd:s1d3]/s1d41/f1, O_RDONLY). */
+	const int expected_read_result;
+	/*
+	 * Expected result of the call to renameat([fd:s1d3]/s1d41/f1,
+	 * [fd:s1d3]/s1d42/f1).
+	 */
+	const int expected_rename_result;
+	/*
+	 * Expected result of the call to renameat([fd:s1d3]/s1d41/f2,
+	 * [fd:s1d3]/s1d42/f3,  RENAME_EXCHANGE).
+	 */
+	const int expected_exchange_result;
+	/*
+	 * Expected result of the call to renameat([fd:s1d3]/s1d42/f4,
+	 * [fd:s1d3]/s1d42/f5).
+	 */
+	const int expected_same_dir_rename_result;
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d1_mount1_src_parent) {
+	/* clang-format on */
+	.allowed_s1d1 = LANDLOCK_ACCESS_FS_REFER |
+			LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_EXECUTE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d2_mount1_src_refer) {
+	/* clang-format on */
+	.allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d2_mount1_src_create) {
+	/* clang-format on */
+	.allowed_s1d2 = LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = EXDEV,
+	.expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d2_mount1_src_rename) {
+	/* clang-format on */
+	.allowed_s1d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = 0,
+	.expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_refer) {
+	/* clang-format on */
+	.allowed_s1d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_create) {
+	/* clang-format on */
+	.allowed_s1d3 = LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = EXDEV,
+	.expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_rename) {
+	/* clang-format on */
+	.allowed_s1d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = 0,
+	.expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s1d3_fd_full) {
+	/* clang-format on */
+	.allowed_s1d3 = LANDLOCK_ACCESS_FS_REFER |
+			LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_EXECUTE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = 0,
+	.expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d1_mount2_src_parent) {
+	/* clang-format on */
+	.allowed_s2d1 = LANDLOCK_ACCESS_FS_REFER |
+			LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_EXECUTE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d2_mount2_src_refer) {
+	/* clang-format on */
+	.allowed_s2d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d2_mount2_src_create) {
+	/* clang-format on */
+	.allowed_s2d2 = LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = EXDEV,
+	.expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d2_mount2_src_rename) {
+	/* clang-format on */
+	.allowed_s2d2 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = 0,
+	.expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d3_mount1_dst_parent_refer) {
+	/* clang-format on */
+	.allowed_s2d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d3_mount1_dst_parent_create) {
+	/* clang-format on */
+	.allowed_s2d3 = LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = EXDEV,
+	.expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d3_mount1_dst_parent_rename) {
+	/* clang-format on */
+	.allowed_s2d3 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = 0,
+	.expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s2d4_mount1_dst) {
+	/* clang-format on */
+	.allowed_s2d4 = LANDLOCK_ACCESS_FS_REFER |
+			LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_EXECUTE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d1_mount2_dst_parent_refer) {
+	/* clang-format on */
+	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d1_mount2_dst_parent_create) {
+	/* clang-format on */
+	.allowed_s3d1 = LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = EXDEV,
+	.expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d1_mount2_dst_parent_rename) {
+	/* clang-format on */
+	.allowed_s3d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = 0,
+	.expected_exchange_result = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s3d2_mount1_dst) {
+	/* clang-format on */
+	.allowed_s3d2 = LANDLOCK_ACCESS_FS_REFER |
+			LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_EXECUTE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s4d1_rename_parent_refer) {
+	/* clang-format on */
+	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = EACCES,
+	.expected_rename_result = EACCES,
+	.expected_exchange_result = EACCES,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s4d1_rename_parent_create) {
+	/* clang-format on */
+	.allowed_s4d1 = LANDLOCK_ACCESS_FS_READ_FILE |
+			LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = 0,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = EXDEV,
+	.expected_exchange_result = EXDEV,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(layout5_disconnected_branch, s4d1_rename_parent_rename) {
+	/* clang-format on */
+	.allowed_s4d1 = LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_MAKE_REG,
+	.expected_read_result = EACCES,
+	.expected_same_dir_rename_result = 0,
+	.expected_rename_result = 0,
+	.expected_exchange_result = 0,
+};
+
+TEST_F_FORK(layout5_disconnected_branch, read_rename_exchange)
+{
+	const __u64 handled_access =
+		LANDLOCK_ACCESS_FS_REFER | LANDLOCK_ACCESS_FS_READ_FILE |
+		LANDLOCK_ACCESS_FS_EXECUTE | LANDLOCK_ACCESS_FS_MAKE_REG;
+	const struct rule rules[] = {
+		{
+			.path = TMP_DIR "/s1d1",
+			.access = variant->allowed_s1d1,
+		},
+		{
+			.path = TMP_DIR "/s1d1/s1d2",
+			.access = variant->allowed_s1d2,
+		},
+		{
+			.path = TMP_DIR "/s1d1/s1d2/s1d3",
+			.access = variant->allowed_s1d3,
+		},
+		{
+			.path = TMP_DIR "/s2d1",
+			.access = variant->allowed_s2d1,
+		},
+		{
+			.path = TMP_DIR "/s2d1/s2d2",
+			.access = variant->allowed_s2d2,
+		},
+		{
+			.path = TMP_DIR "/s2d1/s2d2/s2d3",
+			.access = variant->allowed_s2d3,
+		},
+		/* s2d4_fd */
+		{
+			.path = TMP_DIR "/s3d1",
+			.access = variant->allowed_s3d1,
+		},
+		/* s3d2_fd */
+		{
+			.path = TMP_DIR "/s4d1",
+			.access = variant->allowed_s4d1,
+		},
+		{},
+	};
+	int ruleset_fd, s1d3_bind_fd;
+
+	ruleset_fd = create_ruleset(_metadata, handled_access, rules);
+	ASSERT_LE(0, ruleset_fd);
+
+	/* Adds rules for the covered directories. */
+	if (variant->allowed_s2d4) {
+		ASSERT_EQ(0, landlock_add_rule(
+				     ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
+				     &(struct landlock_path_beneath_attr){
+					     .parent_fd = self->s2d4_fd,
+					     .allowed_access =
+						     variant->allowed_s2d4,
+				     },
+				     0));
+	}
+	EXPECT_EQ(0, close(self->s2d4_fd));
+
+	if (variant->allowed_s3d2) {
+		ASSERT_EQ(0, landlock_add_rule(
+				     ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
+				     &(struct landlock_path_beneath_attr){
+					     .parent_fd = self->s3d2_fd,
+					     .allowed_access =
+						     variant->allowed_s3d2,
+				     },
+				     0));
+	}
+	EXPECT_EQ(0, close(self->s3d2_fd));
+
+	s1d3_bind_fd = open(TMP_DIR "/s3d1/s3d2/s2d3/s2d4/s1d3",
+			    O_DIRECTORY | O_PATH | O_CLOEXEC);
+	ASSERT_LE(0, s1d3_bind_fd);
+
+	/* Disconnects and checks source and destination directories. */
+	EXPECT_EQ(0, test_open_rel(s1d3_bind_fd, "..", O_DIRECTORY));
+	EXPECT_EQ(0, test_open_rel(s1d3_bind_fd, "../..", O_DIRECTORY));
+	/* Renames to make it accessible through s3d1/s1d41 */
+	ASSERT_EQ(0, test_renameat(AT_FDCWD, TMP_DIR "/s2d1/s2d2/s2d3",
+				   AT_FDCWD, TMP_DIR "/s4d1/s2d3"));
+	EXPECT_EQ(0, test_open_rel(s1d3_bind_fd, "..", O_DIRECTORY));
+	EXPECT_EQ(ENOENT, test_open_rel(s1d3_bind_fd, "../..", O_DIRECTORY));
+
+	enforce_ruleset(_metadata, ruleset_fd);
+	EXPECT_EQ(0, close(ruleset_fd));
+
+	EXPECT_EQ(variant->expected_read_result,
+		  test_open_rel(s1d3_bind_fd, "s1d41/f1", O_RDONLY));
+
+	EXPECT_EQ(variant->expected_rename_result,
+		  test_renameat(s1d3_bind_fd, "s1d41/f1", s1d3_bind_fd,
+				"s1d42/f1"));
+	EXPECT_EQ(variant->expected_exchange_result,
+		  test_exchangeat(s1d3_bind_fd, "s1d41/f2", s1d3_bind_fd,
+				  "s1d42/f3"));
+
+	EXPECT_EQ(variant->expected_same_dir_rename_result,
+		  test_renameat(s1d3_bind_fd, "s1d42/f4", s1d3_bind_fd,
+				"s1d42/f5"));
+}
+
 #define LOWER_BASE TMP_DIR "/lower"
 #define LOWER_DATA LOWER_BASE "/data"
 static const char lower_fl1[] = LOWER_DATA "/fl1";
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 008/877] s390/boot: Add sized_strscpy() to enable strscpy() usage
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (6 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 007/877] selftests/landlock: Add disconnected leafs and branch test suites Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 009/877] s390/boot: Avoid IPL parameter append past command line Greg Kroah-Hartman
                   ` (876 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vasily Gorbik, Heiko Carstens,
	Sasha Levin

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

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

From: Vasily Gorbik <gor@linux.ibm.com>

[ Upstream commit f271df9d41c216f6189c40fa1cb83839a6117c3e ]

Add a simple sized_strscpy() implementation to allow the use of strscpy()
in the decompressor.

Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/s390/boot/string.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/s390/boot/string.c b/arch/s390/boot/string.c
index f6b9b1df48a82..bd68161434a60 100644
--- a/arch/s390/boot/string.c
+++ b/arch/s390/boot/string.c
@@ -29,6 +29,18 @@ int strncmp(const char *cs, const char *ct, size_t count)
 	return 0;
 }
 
+ssize_t sized_strscpy(char *dst, const char *src, size_t count)
+{
+	size_t len;
+
+	if (count == 0)
+		return -E2BIG;
+	len = strnlen(src, count - 1);
+	memcpy(dst, src, len);
+	dst[len] = '\0';
+	return src[len] ? -E2BIG : len;
+}
+
 void *memset64(uint64_t *s, uint64_t v, size_t count)
 {
 	uint64_t *xs = s;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 009/877] s390/boot: Avoid IPL parameter append past command line
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (7 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 008/877] s390/boot: Add sized_strscpy() to enable strscpy() usage Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 010/877] selftests/landlock: Add tests for whiteout object creation Greg Kroah-Hartman
                   ` (875 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Heiko Carstens, Vasily Gorbik,
	Sasha Levin

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

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

From: Vasily Gorbik <gor@linux.ibm.com>

[ Upstream commit d76181dfabdaa720703167393704efacba343442 ]

A command line may occupy all but the terminating byte of
COMMAND_LINE_SIZE. In that case append_ipl_block_parm() passes a zero size
to the IPL parameter conversion helpers and points the destination one
byte past early_command_line. The helpers subtract one from the unsigned
size and write the converted parameter outside the command line buffer.

Convert the IPL parameter in the command line parsing buffer first. A
parameter beginning with '=' can then replace the existing command line
regardless of its length, while other parameters are appended only when
space remains.

Fixes: 5ecb2da660ab ("s390: support command lines longer than 896 bytes")
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/s390/boot/ipl_parm.c | 26 ++++++++++++--------------
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c
index 557462e62cd73..6c77afb3b8a11 100644
--- a/arch/s390/boot/ipl_parm.c
+++ b/arch/s390/boot/ipl_parm.c
@@ -21,6 +21,7 @@ struct parmarea parmarea __section(".parmarea") = {
 };
 
 char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
+static char command_line_buf[COMMAND_LINE_SIZE];
 
 unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL;
 struct ipl_parameter_block __bootdata_preserved(ipl_block);
@@ -148,31 +149,29 @@ static size_t ipl_block_get_ascii_scpdata(char *dest, size_t size,
 
 static void append_ipl_block_parm(void)
 {
-	char *parm, *delim;
-	size_t len, rc = 0;
+	size_t len, extra = 0;
+	char *delim;
 
 	len = strlen(early_command_line);
-
-	delim = early_command_line + len;    /* '\0' character position */
-	parm = early_command_line + len + 1; /* append right after '\0' */
+	delim = early_command_line + len; /* '\0' character position */
 
 	switch (ipl_block.pb0_hdr.pbt) {
 	case IPL_PBT_CCW:
-		rc = ipl_block_get_ascii_vmparm(
-			parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
+		extra = ipl_block_get_ascii_vmparm(command_line_buf, sizeof(command_line_buf), &ipl_block);
 		break;
 	case IPL_PBT_FCP:
 	case IPL_PBT_NVME:
 	case IPL_PBT_ECKD:
-		rc = ipl_block_get_ascii_scpdata(
-			parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
+		extra = ipl_block_get_ascii_scpdata(command_line_buf, sizeof(command_line_buf), &ipl_block);
 		break;
 	}
-	if (rc) {
-		if (*parm == '=')
-			memmove(early_command_line, parm + 1, rc);
-		else
+	if (extra) {
+		if (command_line_buf[0] == '=') {
+			memmove(early_command_line, command_line_buf + 1, extra);
+		} else if (len < COMMAND_LINE_SIZE - 2) {
 			*delim = ' '; /* replace '\0' with space */
+			sized_strscpy(delim + 1, command_line_buf, COMMAND_LINE_SIZE - len - 1);
+		}
 	}
 }
 
@@ -258,7 +257,6 @@ static void modify_fac_list(char *str)
 	check_cleared_facilities();
 }
 
-static char command_line_buf[COMMAND_LINE_SIZE];
 void parse_boot_command_line(void)
 {
 	char *param, *val;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 010/877] selftests/landlock: Add tests for whiteout object creation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (8 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 009/877] s390/boot: Avoid IPL parameter append past command line Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 011/877] sunvdc: fix -EIO issue due to lack of retries Greg Kroah-Hartman
                   ` (874 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Günther Noack,
	Mickaël Salaün, Sasha Levin

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

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

From: Günther Noack <gnoack@google.com>

[ Upstream commit ee890889b30b22f9a21636061def7a04e4f89380 ]

Add tests to check that whiteout object creation is guarded by
LANDLOCK_ACCESS_FS_MAKE_REG, in the cases where these are created from
userspace:

* Conventional creation with mknod()
* Linking or renaming an existing whiteout object
* renameat2() with RENAME_WHITEOUT,
  which creates a new whiteout object in the source location
* renameat2() with RENAME_EXCHANGE,
  with one of the renamed objects being a whiteout object

Signed-off-by: Günther Noack <gnoack@google.com>
Link: https://patch.msgid.link/20260813093157.1436894-4-gnoack@google.com
[mic: Update commit message as requested]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
[mic: Backport: adapt the tests to the older filesystem fixture and
ruleset helper]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 tools/testing/selftests/landlock/fs_test.c | 205 ++++++++++++++++++++-
 1 file changed, 203 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index 732ba5a92df56..ae96637ad40e9 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -85,6 +85,8 @@ static const char file1_s3d1[] = TMP_DIR "/s3d1/f1";
 /* dir_s3d2 is a mount point. */
 static const char dir_s3d2[] = TMP_DIR "/s3d1/s3d2";
 static const char dir_s3d3[] = TMP_DIR "/s3d1/s3d2/s3d3";
+static const char file1_s3d3[] = TMP_DIR "/s3d1/s3d2/s3d3/f1";
+static const char file1_s3d4[] = TMP_DIR "/s3d1/s3d2/s3d4/f1";
 
 /*
  * layout1 hierarchy:
@@ -358,7 +360,8 @@ static void create_layout1(struct __test_metadata *const _metadata)
 	ASSERT_EQ(0, mount_opt(&mnt_tmp, dir_s3d2));
 	clear_cap(_metadata, CAP_SYS_ADMIN);
 
-	ASSERT_EQ(0, mkdir(dir_s3d3, 0700));
+	create_file(_metadata, file1_s3d3);
+	create_file(_metadata, file1_s3d4);
 }
 
 static void remove_layout1(struct __test_metadata *const _metadata)
@@ -378,7 +381,8 @@ static void remove_layout1(struct __test_metadata *const _metadata)
 	EXPECT_EQ(0, remove_path(dir_s2d2));
 
 	EXPECT_EQ(0, remove_path(file1_s3d1));
-	EXPECT_EQ(0, remove_path(dir_s3d3));
+	EXPECT_EQ(0, remove_path(file1_s3d3));
+	EXPECT_EQ(0, remove_path(file1_s3d4));
 	set_cap(_metadata, CAP_SYS_ADMIN);
 	umount(dir_s3d2);
 	clear_cap(_metadata, CAP_SYS_ADMIN);
@@ -772,6 +776,27 @@ static int create_ruleset(struct __test_metadata *const _metadata,
 	return ruleset_fd;
 }
 
+static void enforce_fs(struct __test_metadata *const _metadata,
+		       const __u64 access_fs, const struct rule rules[])
+{
+	int ruleset_fd;
+
+	if (rules) {
+		ruleset_fd = create_ruleset(_metadata, access_fs, rules);
+	} else {
+		const struct landlock_ruleset_attr ruleset_attr = {
+			.handled_access_fs = access_fs,
+		};
+
+		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
+						     sizeof(ruleset_attr), 0);
+		ASSERT_LE(0, ruleset_fd);
+	}
+
+	enforce_ruleset(_metadata, ruleset_fd);
+	EXPECT_EQ(0, close(ruleset_fd));
+}
+
 TEST_F_FORK(layout0, proc_nsfs)
 {
 	const struct rule rules[] = {
@@ -2207,6 +2232,170 @@ TEST_F_FORK(layout1, rename_file)
 			       RENAME_EXCHANGE));
 }
 
+TEST_F_FORK(layout1, rename_whiteout_denied)
+{
+	/* The affected file is a FIFO. */
+	ASSERT_EQ(0, unlink(file1_s3d3));
+	ASSERT_EQ(0, mknod(file1_s3d3, S_IFIFO | 0600, 0));
+
+	/* Deny MAKE_REG, but allow MAKE_FIFO. */
+	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, NULL);
+
+	/*
+	 * Try to rename a file with RENAME_WHITEOUT.
+	 * file1_s3d3 is in dir_s3d2 (tmpfs), so it supports RENAME_WHITEOUT.
+	 * Denied, because whiteout creation is guarded with MAKE_REG.
+	 */
+	EXPECT_EQ(-1, renameat2(AT_FDCWD, file1_s3d3, AT_FDCWD,
+				TMP_DIR "/s3d1/s3d2/s3d3/f2", RENAME_WHITEOUT));
+	EXPECT_EQ(EACCES, errno);
+}
+
+static bool is_whiteout(const char *const path)
+{
+	struct stat st;
+
+	if (stat(path, &st) == -1)
+		return false;
+
+	return S_ISCHR(st.st_mode) && st.st_rdev == makedev(0, 0);
+}
+
+static bool is_fifo(const char *const path)
+{
+	struct stat st;
+
+	return stat(path, &st) == 0 && S_ISFIFO(st.st_mode);
+}
+
+TEST_F_FORK(layout1, rename_whiteout_allowed)
+{
+	const struct rule rules[] = {
+		{
+			.path = dir_s3d3,
+			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
+		},
+		{},
+	};
+
+	/* The affected file is a FIFO. */
+	ASSERT_EQ(0, unlink(file1_s3d3));
+	ASSERT_EQ(0, mknod(file1_s3d3, S_IFIFO | 0600, 0));
+
+	/* Allow MAKE_REG below dir_s3d3. */
+	enforce_fs(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, rules);
+
+	/*
+	 * Rename a file with RENAME_WHITEOUT within the same directory.
+	 * Allowed, because MAKE_REG is granted for the whiteout object which
+	 * gets created in the source location.
+	 */
+	EXPECT_EQ(0, renameat2(AT_FDCWD, file1_s3d3, AT_FDCWD,
+			       TMP_DIR "/s3d1/s3d2/s3d3/f2", RENAME_WHITEOUT));
+
+	/* A whiteout object took the place of the moved FIFO. */
+	EXPECT_TRUE(is_whiteout(file1_s3d3));
+	EXPECT_TRUE(is_fifo(TMP_DIR "/s3d1/s3d2/s3d3/f2"));
+}
+
+TEST_F_FORK(layout1, rename_whiteout_reparenting)
+{
+	const struct rule rules[] = {
+		{
+			.path = dir_s3d2,
+			.access = LANDLOCK_ACCESS_FS_REFER,
+		},
+		{
+			.path = dir_s3d3,
+			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
+		},
+		{},
+	};
+
+	/* The moved files are FIFOs. */
+	ASSERT_EQ(0, unlink(file1_s3d3));
+	ASSERT_EQ(0, mknod(file1_s3d3, S_IFIFO | 0600, 0));
+	ASSERT_EQ(0, unlink(file1_s3d4));
+	ASSERT_EQ(0, mknod(file1_s3d4, S_IFIFO | 0600, 0));
+
+	/* Allow REFER below dir_s3d2, but MAKE_REG only below dir_s3d3. */
+	enforce_fs(_metadata,
+		   LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REFER,
+		   rules);
+
+	/*
+	 * The whiteout object is created in the source directory: Moving the
+	 * FIFO out of dir_s3d4 is denied because MAKE_REG is not granted
+	 * there, even though it is granted in the destination directory
+	 * dir_s3d3.
+	 */
+	EXPECT_EQ(-1, renameat2(AT_FDCWD, file1_s3d4, AT_FDCWD,
+				TMP_DIR "/s3d1/s3d2/s3d3/f2", RENAME_WHITEOUT));
+	EXPECT_EQ(EACCES, errno);
+
+	/*
+	 * Moving the FIFO out of dir_s3d3 is allowed, because MAKE_REG is
+	 * granted there for the created whiteout object.
+	 */
+	EXPECT_EQ(0, renameat2(AT_FDCWD, file1_s3d3, AT_FDCWD,
+			       TMP_DIR "/s3d1/s3d2/s3d4/f2", RENAME_WHITEOUT));
+
+	/* A whiteout object took the place of the moved FIFO. */
+	EXPECT_TRUE(is_whiteout(file1_s3d3));
+	EXPECT_TRUE(is_fifo(TMP_DIR "/s3d1/s3d2/s3d4/f2"));
+}
+
+TEST_F_FORK(layout1, rename_whiteout_exchange)
+{
+	const char *const whiteout_s3d3 = TMP_DIR "/s3d1/s3d2/s3d3/f2";
+	const struct rule rules[] = {
+		{
+			.path = dir_s3d2,
+			.access = LANDLOCK_ACCESS_FS_REFER,
+		},
+		{
+			.path = dir_s3d3,
+			.access = LANDLOCK_ACCESS_FS_MAKE_REG,
+		},
+		{},
+	};
+
+	/* The exchanged files are FIFOs and an existing whiteout object. */
+	ASSERT_EQ(0, unlink(file1_s3d3));
+	ASSERT_EQ(0, mknod(file1_s3d3, S_IFIFO | 0600, 0));
+	ASSERT_EQ(0, mknod(whiteout_s3d3, S_IFCHR | 0600, makedev(0, 0)));
+	ASSERT_EQ(0, unlink(file1_s3d4));
+	ASSERT_EQ(0, mknod(file1_s3d4, S_IFIFO | 0600, 0));
+
+	/* Allow REFER below dir_s3d2, but MAKE_REG only below dir_s3d3. */
+	enforce_fs(_metadata,
+		   LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REFER,
+		   rules);
+
+	/*
+	 * With RENAME_EXCHANGE, the whiteout object moves into the source
+	 * directory of the rename: Exchanging the FIFO in dir_s3d4 with the
+	 * whiteout object is denied because MAKE_REG is not granted in
+	 * dir_s3d4, even though it is granted in the whiteout object's own
+	 * directory dir_s3d3.
+	 */
+	EXPECT_EQ(-1, renameat2(AT_FDCWD, file1_s3d4, AT_FDCWD, whiteout_s3d3,
+				RENAME_EXCHANGE));
+	EXPECT_EQ(EACCES, errno);
+
+	/*
+	 * Exchanging the FIFO in dir_s3d3 with the whiteout object is
+	 * allowed, because MAKE_REG is granted in the directory into which
+	 * the whiteout object moves.
+	 */
+	EXPECT_EQ(0, renameat2(AT_FDCWD, file1_s3d3, AT_FDCWD, whiteout_s3d3,
+			       RENAME_EXCHANGE));
+
+	/* The FIFO and the whiteout object swapped places. */
+	EXPECT_TRUE(is_whiteout(file1_s3d3));
+	EXPECT_TRUE(is_fifo(whiteout_s3d3));
+}
+
 TEST_F_FORK(layout1, rename_dir)
 {
 	const struct rule rules[] = {
@@ -3260,6 +3449,18 @@ TEST_F_FORK(layout1, make_char)
 		       makedev(1, 3));
 }
 
+TEST_F_FORK(layout1, make_whiteout)
+{
+	/*
+	 * Creates a whiteout object (creation guarded by MAKE_REG).
+	 *
+	 * Contrary to the other character devices, this does not require
+	 * CAP_MKNOD, cf. vfs_mknod().
+	 */
+	test_make_file(_metadata, LANDLOCK_ACCESS_FS_MAKE_REG, S_IFCHR,
+		       makedev(0, 0));
+}
+
 TEST_F_FORK(layout1, make_block)
 {
 	/* Creates a /dev/loop0 device. */
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 011/877] sunvdc: fix -EIO issue due to lack of retries
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (9 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 010/877] selftests/landlock: Add tests for whiteout object creation Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 012/877] net: cpsw_new: Execute ndo_set_rx_mode callback in a work queue Greg Kroah-Hartman
                   ` (873 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, John Paul Adrian Glaubitz,
	Stian Halseth, Jens Axboe, Sasha Levin

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

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

From: Jens Axboe <axboe@kernel.dk>

[ Upstream commit 5067d4ba713961d8ccea1e06cd4c453793f3121e ]

John reports that since commit:

a11f6ca9aef9 ("sunvdc: Do not spin in an infinite loop when vio_ldc_send() returns EAGAIN")

users of Linux inside Solaris ldom see occasional -EIO errors because
the request send loop now times out. The current loop does 10 retries,
and inside vio_ldc_send() a further 1000 1usec retries are done as well.
Even with 10.5 msec of busy loop retries that's apparently not enough to
always succeed.

Rather than introduce continued busy looping, requeue the request and
have the delayed queue kicking retry the request after another 10ms.
This obviously isn't ideal, but there's seemingly no way to wait for
this type of event. And if 10ms of busy looping was not enough to make
progress, then presumably this is an edge condition and we just need to
guarantee to make forward progress at some later point in time. That's
more suitably done through letting the CPU tend to other work, rather
than sitting in a tight loop retrying.

[stian: rebased on top of the cookie-unmap fix, without which every
 requeued attempt leaks LDC map table entries; tested on an
 UltraSPARC T4 LDOM where the vdc_tx_trigger failure condition was
 reproduced and absorbed by the requeue with no I/O error]

Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Link: https://lore.kernel.org/all/20251006100226.4246-2-glaubitz@physik.fu-berlin.de/
Link: https://lore.kernel.org/all/418310b3-2b77-4534-b2fd-27dcc11e333c@kernel.dk/
Signed-off-by: Stian Halseth <stian@itx.no>
Link: https://patch.msgid.link/20260901173947.3292110-3-stian@itx.no
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/block/sunvdc.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 97fe566465d79..16953341e5013 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -557,6 +557,7 @@ static blk_status_t vdc_queue_rq(struct blk_mq_hw_ctx *hctx,
 	struct vdc_port *port = hctx->queue->queuedata;
 	struct vio_dring_state *dr;
 	unsigned long flags;
+	int ret;
 
 	dr = &port->vio.drings[VIO_DRIVER_TX_RING];
 
@@ -578,7 +579,13 @@ static blk_status_t vdc_queue_rq(struct blk_mq_hw_ctx *hctx,
 		return BLK_STS_DEV_RESOURCE;
 	}
 
-	if (__send_request(bd->rq) < 0) {
+	ret = __send_request(bd->rq);
+	if (ret == -EAGAIN) {
+		spin_unlock_irqrestore(&port->vio.lock, flags);
+		/* already spun for 10msec, defer 10msec and retry */
+		blk_mq_delay_kick_requeue_list(hctx->queue, 10);
+		return BLK_STS_DEV_RESOURCE;
+	} else if (ret < 0) {
 		spin_unlock_irqrestore(&port->vio.lock, flags);
 		return BLK_STS_IOERR;
 	}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 012/877] net: cpsw_new: Execute ndo_set_rx_mode callback in a work queue
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (10 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 011/877] sunvdc: fix -EIO issue due to lack of retries Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 013/877] net: cpsw: " Greg Kroah-Hartman
                   ` (872 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Kevin Hao, Jakub Kicinski,
	Sasha Levin

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

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

From: Kevin Hao <haokexin@gmail.com>

commit c0b5dc73a38f954e780f93a549b8fe225235c07a upstream.

Commit 1767bb2d47b7 ("ipv6: mcast: Don't hold RTNL for
IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP.") removed the RTNL lock for
IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP operations. However, this
change triggered the following call trace on my BeagleBone Black board:
  WARNING: net/8021q/vlan_core.c:236 at vlan_for_each+0x120/0x124, CPU#0: rpcbind/496
  RTNL: assertion failed at net/8021q/vlan_core.c (236)
  Modules linked in:
  CPU: 0 UID: 997 PID: 496 Comm: rpcbind Not tainted 6.19.0-rc6-next-20260122-yocto-standard+ #8 PREEMPT
  Hardware name: Generic AM33XX (Flattened Device Tree)
  Call trace:
   unwind_backtrace from show_stack+0x28/0x2c
   show_stack from dump_stack_lvl+0x30/0x38
   dump_stack_lvl from __warn+0xb8/0x11c
   __warn from warn_slowpath_fmt+0x130/0x194
   warn_slowpath_fmt from vlan_for_each+0x120/0x124
   vlan_for_each from cpsw_add_mc_addr+0x54/0xd8
   cpsw_add_mc_addr from __hw_addr_ref_sync_dev+0xc4/0xec
   __hw_addr_ref_sync_dev from __dev_mc_add+0x78/0x88
   __dev_mc_add from igmp6_group_added+0x84/0xec
   igmp6_group_added from __ipv6_dev_mc_inc+0x1fc/0x2f0
   __ipv6_dev_mc_inc from __ipv6_sock_mc_join+0x124/0x1b4
   __ipv6_sock_mc_join from do_ipv6_setsockopt+0x84c/0x1168
   do_ipv6_setsockopt from ipv6_setsockopt+0x88/0xc8
   ipv6_setsockopt from do_sock_setsockopt+0xe8/0x19c
   do_sock_setsockopt from __sys_setsockopt+0x84/0xac
   __sys_setsockopt from ret_fast_syscall+0x0/0x5

This trace occurs because vlan_for_each() is called within
cpsw_ndo_set_rx_mode(), which expects the RTNL lock to be held.
Since modifying vlan_for_each() to operate without the RTNL lock is not
straightforward, and because ndo_set_rx_mode() is invoked both with and
without the RTNL lock across different code paths, simply adding
rtnl_lock() in cpsw_ndo_set_rx_mode() is not a viable solution.

To resolve this issue, we opt to execute the actual processing within
a work queue, following the approach used by the icssg-prueth driver.

Fixes: 1767bb2d47b7 ("ipv6: mcast: Don't hold RTNL for IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP.")
Signed-off-by: Kevin Hao <haokexin@gmail.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260203-bbb-v5-1-ea0ea217a85c@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/ti/cpsw_new.c  | 35 ++++++++++++++++++++++++-----
 drivers/net/ethernet/ti/cpsw_priv.h |  1 +
 2 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c
index 468eaa6f785e6..c2041e46b83d6 100644
--- a/drivers/net/ethernet/ti/cpsw_new.c
+++ b/drivers/net/ethernet/ti/cpsw_new.c
@@ -248,16 +248,22 @@ static int cpsw_purge_all_mc(struct net_device *ndev, const u8 *addr, int num)
 	return 0;
 }
 
-static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
+static void cpsw_ndo_set_rx_mode_work(struct work_struct *work)
 {
-	struct cpsw_priv *priv = netdev_priv(ndev);
+	struct cpsw_priv *priv = container_of(work, struct cpsw_priv, rx_mode_work);
 	struct cpsw_common *cpsw = priv->cpsw;
+	struct net_device *ndev = priv->ndev;
+
+	rtnl_lock();
+	if (!netif_running(ndev))
+		goto unlock_rtnl;
 
+	netif_addr_lock_bh(ndev);
 	if (ndev->flags & IFF_PROMISC) {
 		/* Enable promiscuous mode */
 		cpsw_set_promiscious(ndev, true);
 		cpsw_ale_set_allmulti(cpsw->ale, IFF_ALLMULTI, priv->emac_port);
-		return;
+		goto unlock_addr;
 	}
 
 	/* Disable promiscuous mode */
@@ -270,6 +276,18 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
 	/* add/remove mcast address either for real netdev or for vlan */
 	__hw_addr_ref_sync_dev(&ndev->mc, ndev, cpsw_add_mc_addr,
 			       cpsw_del_mc_addr);
+
+unlock_addr:
+	netif_addr_unlock_bh(ndev);
+unlock_rtnl:
+	rtnl_unlock();
+}
+
+static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
+{
+	struct cpsw_priv *priv = netdev_priv(ndev);
+
+	schedule_work(&priv->rx_mode_work);
 }
 
 static unsigned int cpsw_rxbuf_total_len(unsigned int len)
@@ -1391,6 +1409,7 @@ static int cpsw_create_ports(struct cpsw_common *cpsw)
 		priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
 		priv->emac_port = i + 1;
 		priv->tx_packet_min = CPSW_MIN_PACKET_SIZE;
+		INIT_WORK(&priv->rx_mode_work, cpsw_ndo_set_rx_mode_work);
 
 		if (is_valid_ether_addr(slave_data->mac_addr)) {
 			ether_addr_copy(priv->mac_addr, slave_data->mac_addr);
@@ -1440,14 +1459,18 @@ static int cpsw_create_ports(struct cpsw_common *cpsw)
 
 static void cpsw_unregister_ports(struct cpsw_common *cpsw)
 {
+	struct net_device *ndev;
+	struct cpsw_priv *priv;
 	int i = 0;
 
 	for (i = 0; i < cpsw->data.slaves; i++) {
-		if (!cpsw->slaves[i].ndev ||
-		    cpsw->slaves[i].ndev->reg_state != NETREG_REGISTERED)
+		ndev = cpsw->slaves[i].ndev;
+		if (!ndev || ndev->reg_state != NETREG_REGISTERED)
 			continue;
 
-		unregister_netdev(cpsw->slaves[i].ndev);
+		priv = netdev_priv(ndev);
+		unregister_netdev(ndev);
+		disable_work_sync(&priv->rx_mode_work);
 	}
 }
 
diff --git a/drivers/net/ethernet/ti/cpsw_priv.h b/drivers/net/ethernet/ti/cpsw_priv.h
index 1f448290b9f4b..bacaa855e6148 100644
--- a/drivers/net/ethernet/ti/cpsw_priv.h
+++ b/drivers/net/ethernet/ti/cpsw_priv.h
@@ -391,6 +391,7 @@ struct cpsw_priv {
 	u32 tx_packet_min;
 	struct cpsw_ale_ratelimit ale_bc_ratelimit;
 	struct cpsw_ale_ratelimit ale_mc_ratelimit;
+	struct work_struct rx_mode_work;
 };
 
 #define ndev_to_cpsw(ndev) (((struct cpsw_priv *)netdev_priv(ndev))->cpsw)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 013/877] net: cpsw: Execute ndo_set_rx_mode callback in a work queue
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (11 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 012/877] net: cpsw_new: Execute ndo_set_rx_mode callback in a work queue Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 014/877] ipv6: mcast: Use in6_dev_get() in ipv6_dev_mc_dec() Greg Kroah-Hartman
                   ` (871 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Kevin Hao, Jakub Kicinski,
	Sasha Levin

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

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

From: Kevin Hao <haokexin@gmail.com>

commit 0b8c878d117319f2be34c8391a77e0f4d5c94d79 upstream.

Commit 1767bb2d47b7 ("ipv6: mcast: Don't hold RTNL for
IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP.") removed the RTNL lock for
IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP operations. However, this
change triggered the following call trace on my BeagleBone Black board:
  WARNING: net/8021q/vlan_core.c:236 at vlan_for_each+0x120/0x124, CPU#0: rpcbind/481
  RTNL: assertion failed at net/8021q/vlan_core.c (236)
  Modules linked in:
  CPU: 0 UID: 997 PID: 481 Comm: rpcbind Not tainted 6.19.0-rc7-next-20260130-yocto-standard+ #35 PREEMPT
  Hardware name: Generic AM33XX (Flattened Device Tree)
  Call trace:
   unwind_backtrace from show_stack+0x28/0x2c
   show_stack from dump_stack_lvl+0x30/0x38
   dump_stack_lvl from __warn+0xb8/0x11c
   __warn from warn_slowpath_fmt+0x130/0x194
   warn_slowpath_fmt from vlan_for_each+0x120/0x124
   vlan_for_each from cpsw_add_mc_addr+0x54/0x98
   cpsw_add_mc_addr from __hw_addr_ref_sync_dev+0xc4/0xec
   __hw_addr_ref_sync_dev from __dev_mc_add+0x78/0x88
   __dev_mc_add from igmp6_group_added+0x84/0xec
   igmp6_group_added from __ipv6_dev_mc_inc+0x1fc/0x2f0
   __ipv6_dev_mc_inc from __ipv6_sock_mc_join+0x124/0x1b4
   __ipv6_sock_mc_join from do_ipv6_setsockopt+0x84c/0x1168
   do_ipv6_setsockopt from ipv6_setsockopt+0x88/0xc8
   ipv6_setsockopt from do_sock_setsockopt+0xe8/0x19c
   do_sock_setsockopt from __sys_setsockopt+0x84/0xac
   __sys_setsockopt from ret_fast_syscall+0x0/0x54

This trace occurs because vlan_for_each() is called within
cpsw_ndo_set_rx_mode(), which expects the RTNL lock to be held.
Since modifying vlan_for_each() to operate without the RTNL lock is not
straightforward, and because ndo_set_rx_mode() is invoked both with and
without the RTNL lock across different code paths, simply adding
rtnl_lock() in cpsw_ndo_set_rx_mode() is not a viable solution.

To resolve this issue, we opt to execute the actual processing within
a work queue, following the approach used by the icssg-prueth driver.

Please note: To reproduce this issue, I manually reverted the changes to
am335x-bone-common.dtsi from commit c477358e66a3 ("ARM: dts: am335x-bone:
switch to new cpsw switch drv") in order to revert to the legacy cpsw
driver.

Fixes: 1767bb2d47b7 ("ipv6: mcast: Don't hold RTNL for IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP.")
Signed-off-by: Kevin Hao <haokexin@gmail.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260203-bbb-v5-2-ea0ea217a85c@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/ti/cpsw.c | 41 +++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index c0a5abd8d9a8e..2968b5fbe428c 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -305,12 +305,19 @@ static int cpsw_purge_all_mc(struct net_device *ndev, const u8 *addr, int num)
 	return 0;
 }
 
-static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
+static void cpsw_ndo_set_rx_mode_work(struct work_struct *work)
 {
-	struct cpsw_priv *priv = netdev_priv(ndev);
+	struct cpsw_priv *priv = container_of(work, struct cpsw_priv, rx_mode_work);
 	struct cpsw_common *cpsw = priv->cpsw;
+	struct net_device *ndev = priv->ndev;
 	int slave_port = -1;
 
+	rtnl_lock();
+	if (!netif_running(ndev))
+		goto unlock_rtnl;
+
+	netif_addr_lock_bh(ndev);
+
 	if (cpsw->data.dual_emac)
 		slave_port = priv->emac_port + 1;
 
@@ -318,7 +325,7 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
 		/* Enable promiscuous mode */
 		cpsw_set_promiscious(ndev, true);
 		cpsw_ale_set_allmulti(cpsw->ale, IFF_ALLMULTI, slave_port);
-		return;
+		goto unlock_addr;
 	} else {
 		/* Disable promiscuous mode */
 		cpsw_set_promiscious(ndev, false);
@@ -331,6 +338,18 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
 	/* add/remove mcast address either for real netdev or for vlan */
 	__hw_addr_ref_sync_dev(&ndev->mc, ndev, cpsw_add_mc_addr,
 			       cpsw_del_mc_addr);
+
+unlock_addr:
+	netif_addr_unlock_bh(ndev);
+unlock_rtnl:
+	rtnl_unlock();
+}
+
+static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
+{
+	struct cpsw_priv *priv = netdev_priv(ndev);
+
+	schedule_work(&priv->rx_mode_work);
 }
 
 static unsigned int cpsw_rxbuf_total_len(unsigned int len)
@@ -1444,6 +1463,7 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv)
 	priv_sl2->ndev = ndev;
 	priv_sl2->dev  = &ndev->dev;
 	priv_sl2->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
+	INIT_WORK(&priv_sl2->rx_mode_work, cpsw_ndo_set_rx_mode_work);
 
 	if (is_valid_ether_addr(data->slave_data[1].mac_addr)) {
 		memcpy(priv_sl2->mac_addr, data->slave_data[1].mac_addr,
@@ -1625,6 +1645,7 @@ static int cpsw_probe(struct platform_device *pdev)
 	priv->dev  = dev;
 	priv->msg_enable = netif_msg_init(debug_level, CPSW_DEBUG);
 	priv->emac_port = 0;
+	INIT_WORK(&priv->rx_mode_work, cpsw_ndo_set_rx_mode_work);
 
 	if (is_valid_ether_addr(data->slave_data[0].mac_addr)) {
 		memcpy(priv->mac_addr, data->slave_data[0].mac_addr, ETH_ALEN);
@@ -1727,6 +1748,8 @@ static int cpsw_probe(struct platform_device *pdev)
 static void cpsw_remove(struct platform_device *pdev)
 {
 	struct cpsw_common *cpsw = platform_get_drvdata(pdev);
+	struct net_device *ndev;
+	struct cpsw_priv *priv;
 	int i, ret;
 
 	ret = pm_runtime_resume_and_get(&pdev->dev);
@@ -1739,9 +1762,15 @@ static void cpsw_remove(struct platform_device *pdev)
 		return;
 	}
 
-	for (i = 0; i < cpsw->data.slaves; i++)
-		if (cpsw->slaves[i].ndev)
-			unregister_netdev(cpsw->slaves[i].ndev);
+	for (i = 0; i < cpsw->data.slaves; i++) {
+		ndev = cpsw->slaves[i].ndev;
+		if (!ndev)
+			continue;
+
+		priv = netdev_priv(ndev);
+		unregister_netdev(ndev);
+		disable_work_sync(&priv->rx_mode_work);
+	}
 
 	cpts_release(cpsw->cpts);
 	cpdma_ctlr_destroy(cpsw->dma);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 014/877] ipv6: mcast: Use in6_dev_get() in ipv6_dev_mc_dec().
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (12 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 013/877] net: cpsw: " Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 015/877] ipv6: mcast: Dont hold RTNL for IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP Greg Kroah-Hartman
                   ` (870 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Eric Dumazet,
	Jakub Kicinski, Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit e01b193e0b50ae849bf60067e111446f19ee2f20 ]

As well as __ipv6_dev_mc_inc(), all code in __ipv6_dev_mc_dec() are
protected by inet6_dev->mc_lock, and RTNL is not needed.

Let's use in6_dev_get() in ipv6_dev_mc_dec() and remove ASSERT_RTNL()
in __ipv6_dev_mc_dec().

Now, we can remove the RTNL comment above addrconf_leave_solict() too.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250702230210.3115355-6-kuni1840@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv6/addrconf.c |  3 +--
 net/ipv6/mcast.c    | 14 ++++++--------
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index ef938fb1d7549..fb239e8f83593 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2255,12 +2255,11 @@ void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr)
 	ipv6_dev_mc_inc(dev, &maddr);
 }
 
-/* caller must hold RTNL */
 void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)
 {
 	struct in6_addr maddr;
 
-	if (idev->dev->flags&(IFF_LOOPBACK|IFF_NOARP))
+	if (READ_ONCE(idev->dev->flags) & (IFF_LOOPBACK | IFF_NOARP))
 		return;
 
 	addrconf_addr_solict_mult(addr, &maddr);
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index c060954c52757..212c2d8efe0f5 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -972,9 +972,8 @@ int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr)
 {
 	struct ifmcaddr6 *ma, __rcu **map;
 
-	ASSERT_RTNL();
-
 	mutex_lock(&idev->mc_lock);
+
 	for (map = &idev->mc_list;
 	     (ma = mc_dereference(*map, idev));
 	     map = &ma->next) {
@@ -1003,13 +1002,12 @@ int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr)
 	struct inet6_dev *idev;
 	int err;
 
-	ASSERT_RTNL();
-
-	idev = __in6_dev_get(dev);
+	idev = in6_dev_get(dev);
 	if (!idev)
-		err = -ENODEV;
-	else
-		err = __ipv6_dev_mc_dec(idev, addr);
+		return -ENODEV;
+
+	err = __ipv6_dev_mc_dec(idev, addr);
+	in6_dev_put(idev);
 
 	return err;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 015/877] ipv6: mcast: Dont hold RTNL for IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP.
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (13 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 014/877] ipv6: mcast: Use in6_dev_get() in ipv6_dev_mc_dec() Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 016/877] ipv6: mcast: Dont hold RTNL for IPV6_DROP_MEMBERSHIP and MCAST_LEAVE_GROUP Greg Kroah-Hartman
                   ` (869 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Eric Dumazet,
	Jakub Kicinski, Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit 1767bb2d47b715a106287a8f963d9ec6cbab4e69 ]

In __ipv6_sock_mc_join(), per-socket mld data is protected by lock_sock(),
and only __dev_get_by_index() requires RTNL.

Let's use dev_get_by_index() and drop RTNL for IPV6_ADD_MEMBERSHIP and
MCAST_JOIN_GROUP.

Note that we must call rt6_lookup() and dev_hold() under RCU.

If rt6_lookup() returns an entry from the exception table, dst_dev_put()
could change rt->dev.dst to loopback concurrently, and the original device
could lose the refcount before dev_hold() and unblock device registration.

dst_dev_put() is called from NETDEV_UNREGISTER and synchronize_net() follows
it, so as long as rt6_lookup() and dev_hold() are called within the same
RCU critical section, the dev is alive.

Even if the race happens, they are synchronised by idev->dead and mcast
addresses are cleaned up.

For the racy access to rt->dst.dev, we use dst_dev().

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250702230210.3115355-7-kuni1840@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv6/ipv6_sockglue.c |  2 --
 net/ipv6/mcast.c         | 24 +++++++++++++-----------
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index c2ea92c0f9166..385321a43a19b 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -121,11 +121,9 @@ static bool setsockopt_needs_rtnl(int optname)
 {
 	switch (optname) {
 	case IPV6_ADDRFORM:
-	case IPV6_ADD_MEMBERSHIP:
 	case IPV6_DROP_MEMBERSHIP:
 	case IPV6_JOIN_ANYCAST:
 	case IPV6_LEAVE_ANYCAST:
-	case MCAST_JOIN_GROUP:
 	case MCAST_LEAVE_GROUP:
 	case MCAST_JOIN_SOURCE_GROUP:
 	case MCAST_LEAVE_SOURCE_GROUP:
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 212c2d8efe0f5..61046543302d4 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -172,14 +172,12 @@ static int unsolicited_report_interval(struct inet6_dev *idev)
 static int __ipv6_sock_mc_join(struct sock *sk, int ifindex,
 			       const struct in6_addr *addr, unsigned int mode)
 {
-	struct net_device *dev = NULL;
-	struct ipv6_mc_socklist *mc_lst;
 	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct ipv6_mc_socklist *mc_lst;
 	struct net *net = sock_net(sk);
+	struct net_device *dev = NULL;
 	int err;
 
-	ASSERT_RTNL();
-
 	if (!ipv6_addr_is_multicast(addr))
 		return -EINVAL;
 
@@ -199,13 +197,18 @@ static int __ipv6_sock_mc_join(struct sock *sk, int ifindex,
 
 	if (ifindex == 0) {
 		struct rt6_info *rt;
+
+		rcu_read_lock();
 		rt = rt6_lookup(net, addr, NULL, 0, NULL, 0);
 		if (rt) {
-			dev = rt->dst.dev;
+			dev = dst_dev(&rt->dst);
+			dev_hold(dev);
 			ip6_rt_put(rt);
 		}
-	} else
-		dev = __dev_get_by_index(net, ifindex);
+		rcu_read_unlock();
+	} else {
+		dev = dev_get_by_index(net, ifindex);
+	}
 
 	if (!dev) {
 		sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
@@ -216,12 +219,11 @@ static int __ipv6_sock_mc_join(struct sock *sk, int ifindex,
 	mc_lst->sfmode = mode;
 	RCU_INIT_POINTER(mc_lst->sflist, NULL);
 
-	/*
-	 *	now add/increase the group membership on the device
-	 */
-
+	/* now add/increase the group membership on the device */
 	err = __ipv6_dev_mc_inc(dev, addr, mode);
 
+	dev_put(dev);
+
 	if (err) {
 		sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
 		return err;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 016/877] ipv6: mcast: Dont hold RTNL for IPV6_DROP_MEMBERSHIP and MCAST_LEAVE_GROUP.
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (14 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 015/877] ipv6: mcast: Dont hold RTNL for IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 017/877] ipv6: mcast: Dont hold RTNL for MCAST_ socket options Greg Kroah-Hartman
                   ` (868 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Eric Dumazet,
	Jakub Kicinski, Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit 2ceb71ce7d34e751f91bbca9da3513a2bc29089c ]

In __ipv6_sock_mc_drop(), per-socket mld data is protected by lock_sock(),
and only __dev_get_by_index() and __in6_dev_get() require RTNL.

Let's use dev_get_by_index() and in6_dev_get() and drop RTNL for
IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP.

Note that __ipv6_sock_mc_drop() is factorised to reuse in the next patch.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250702230210.3115355-8-kuni1840@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv6/ipv6_sockglue.c |  2 --
 net/ipv6/mcast.c         | 47 +++++++++++++++++++++++-----------------
 2 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 385321a43a19b..ab6987e72e3a7 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -121,10 +121,8 @@ static bool setsockopt_needs_rtnl(int optname)
 {
 	switch (optname) {
 	case IPV6_ADDRFORM:
-	case IPV6_DROP_MEMBERSHIP:
 	case IPV6_JOIN_ANYCAST:
 	case IPV6_LEAVE_ANYCAST:
-	case MCAST_LEAVE_GROUP:
 	case MCAST_JOIN_SOURCE_GROUP:
 	case MCAST_LEAVE_SOURCE_GROUP:
 	case MCAST_BLOCK_SOURCE:
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 61046543302d4..2f485e58a7d49 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -250,14 +250,36 @@ int ipv6_sock_mc_join_ssm(struct sock *sk, int ifindex,
 /*
  *	socket leave on multicast group
  */
+static void __ipv6_sock_mc_drop(struct sock *sk, struct ipv6_mc_socklist *mc_lst)
+{
+	struct net *net = sock_net(sk);
+	struct net_device *dev;
+
+	dev = dev_get_by_index(net, mc_lst->ifindex);
+	if (dev) {
+		struct inet6_dev *idev = in6_dev_get(dev);
+
+		ip6_mc_leave_src(sk, mc_lst, idev);
+
+		if (idev) {
+			__ipv6_dev_mc_dec(idev, &mc_lst->addr);
+			in6_dev_put(idev);
+		}
+
+		dev_put(dev);
+	} else {
+		ip6_mc_leave_src(sk, mc_lst, NULL);
+	}
+
+	atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
+	kfree_rcu(mc_lst, rcu);
+}
+
 int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
 {
 	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct ipv6_mc_socklist *mc_lst;
 	struct ipv6_mc_socklist __rcu **lnk;
-	struct net *net = sock_net(sk);
-
-	ASSERT_RTNL();
+	struct ipv6_mc_socklist *mc_lst;
 
 	if (!ipv6_addr_is_multicast(addr))
 		return -EINVAL;
@@ -267,23 +289,8 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
 	      lnk = &mc_lst->next) {
 		if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
 		    ipv6_addr_equal(&mc_lst->addr, addr)) {
-			struct net_device *dev;
-
 			*lnk = mc_lst->next;
-
-			dev = __dev_get_by_index(net, mc_lst->ifindex);
-			if (dev) {
-				struct inet6_dev *idev = __in6_dev_get(dev);
-
-				ip6_mc_leave_src(sk, mc_lst, idev);
-				if (idev)
-					__ipv6_dev_mc_dec(idev, &mc_lst->addr);
-			} else {
-				ip6_mc_leave_src(sk, mc_lst, NULL);
-			}
-
-			atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
-			kfree_rcu(mc_lst, rcu);
+			__ipv6_sock_mc_drop(sk, mc_lst);
 			return 0;
 		}
 	}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 017/877] ipv6: mcast: Dont hold RTNL for MCAST_ socket options.
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (15 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 016/877] ipv6: mcast: Dont hold RTNL for IPV6_DROP_MEMBERSHIP and MCAST_LEAVE_GROUP Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 018/877] ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source() Greg Kroah-Hartman
                   ` (867 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Eric Dumazet,
	Jakub Kicinski, Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit e6e14d582dd2cbee362c48a1865f8d03ca0a5611 ]

In ip6_mc_source() and ip6_mc_msfilter(), per-socket mld data is
protected by lock_sock() and inet6_dev->mc_lock is also held for
some per-interface functions.

ip6_mc_find_dev_rtnl() only depends on RTNL.  If we want to remove
it, we need to check inet6_dev->dead under mc_lock to close the race
with addrconf_ifdown(), as mentioned earlier.

Let's do that and drop RTNL for the rest of MCAST_ socket options.

Note that ip6_mc_msfilter() has unnecessary lock dances and they
are integrated into one to avoid the last-minute error and simplify
the error handling.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20250702230210.3115355-10-kuni1840@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv6/ipv6_sockglue.c |  5 ---
 net/ipv6/mcast.c         | 74 ++++++++++++++++++++++++----------------
 2 files changed, 45 insertions(+), 34 deletions(-)

diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index ab6987e72e3a7..0f1242138d176 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -123,11 +123,6 @@ static bool setsockopt_needs_rtnl(int optname)
 	case IPV6_ADDRFORM:
 	case IPV6_JOIN_ANYCAST:
 	case IPV6_LEAVE_ANYCAST:
-	case MCAST_JOIN_SOURCE_GROUP:
-	case MCAST_LEAVE_SOURCE_GROUP:
-	case MCAST_BLOCK_SOURCE:
-	case MCAST_UNBLOCK_SOURCE:
-	case MCAST_MSFILTER:
 		return true;
 	}
 	return false;
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 2f485e58a7d49..02919944d5570 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -299,31 +299,36 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
 }
 EXPORT_SYMBOL(ipv6_sock_mc_drop);
 
-static struct inet6_dev *ip6_mc_find_dev_rtnl(struct net *net,
-					      const struct in6_addr *group,
-					      int ifindex)
+static struct inet6_dev *ip6_mc_find_dev(struct net *net,
+					 const struct in6_addr *group,
+					 int ifindex)
 {
 	struct net_device *dev = NULL;
-	struct inet6_dev *idev = NULL;
+	struct inet6_dev *idev;
 
 	if (ifindex == 0) {
-		struct rt6_info *rt = rt6_lookup(net, group, NULL, 0, NULL, 0);
+		struct rt6_info *rt;
 
+		rcu_read_lock();
+		rt = rt6_lookup(net, group, NULL, 0, NULL, 0);
 		if (rt) {
-			dev = rt->dst.dev;
+			dev = dst_dev(&rt->dst);
+			dev_hold(dev);
 			ip6_rt_put(rt);
 		}
+		rcu_read_unlock();
 	} else {
-		dev = __dev_get_by_index(net, ifindex);
+		dev = dev_get_by_index(net, ifindex);
 	}
-
 	if (!dev)
 		return NULL;
-	idev = __in6_dev_get(dev);
+
+	idev = in6_dev_get(dev);
+	dev_put(dev);
+
 	if (!idev)
 		return NULL;
-	if (idev->dead)
-		return NULL;
+
 	return idev;
 }
 
@@ -371,16 +376,16 @@ void ipv6_sock_mc_close(struct sock *sk)
 }
 
 int ip6_mc_source(int add, int omode, struct sock *sk,
-	struct group_source_req *pgsr)
+		  struct group_source_req *pgsr)
 {
+	struct ipv6_pinfo *inet6 = inet6_sk(sk);
 	struct in6_addr *source, *group;
+	struct net *net = sock_net(sk);
 	struct ipv6_mc_socklist *pmc;
-	struct inet6_dev *idev;
-	struct ipv6_pinfo *inet6 = inet6_sk(sk);
 	struct ip6_sf_socklist *psl;
-	struct net *net = sock_net(sk);
-	int i, j, rv;
+	struct inet6_dev *idev;
 	int leavegroup = 0;
+	int i, j, rv;
 	int err;
 
 	source = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr;
@@ -389,13 +394,19 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
 	if (!ipv6_addr_is_multicast(group))
 		return -EINVAL;
 
-	idev = ip6_mc_find_dev_rtnl(net, group, pgsr->gsr_interface);
+	idev = ip6_mc_find_dev(net, group, pgsr->gsr_interface);
 	if (!idev)
 		return -ENODEV;
 
+	mutex_lock(&idev->mc_lock);
+
+	if (idev->dead) {
+		err = -ENODEV;
+		goto done;
+	}
+
 	err = -EADDRNOTAVAIL;
 
-	mutex_lock(&idev->mc_lock);
 	for_each_pmc_socklock(inet6, sk, pmc) {
 		if (pgsr->gsr_interface && pmc->ifindex != pgsr->gsr_interface)
 			continue;
@@ -492,6 +503,7 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
 	ip6_mc_add_src(idev, group, omode, 1, source, 1);
 done:
 	mutex_unlock(&idev->mc_lock);
+	in6_dev_put(idev);
 	if (leavegroup)
 		err = ipv6_sock_mc_drop(sk, pgsr->gsr_interface, group);
 	return err;
@@ -500,12 +512,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
 int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf,
 		    struct sockaddr_storage *list)
 {
-	const struct in6_addr *group;
-	struct ipv6_mc_socklist *pmc;
-	struct inet6_dev *idev;
 	struct ipv6_pinfo *inet6 = inet6_sk(sk);
 	struct ip6_sf_socklist *newpsl, *psl;
 	struct net *net = sock_net(sk);
+	const struct in6_addr *group;
+	struct ipv6_mc_socklist *pmc;
+	struct inet6_dev *idev;
 	int leavegroup = 0;
 	int i, err;
 
@@ -517,10 +529,17 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf,
 	    gsf->gf_fmode != MCAST_EXCLUDE)
 		return -EINVAL;
 
-	idev = ip6_mc_find_dev_rtnl(net, group, gsf->gf_interface);
+	idev = ip6_mc_find_dev(net, group, gsf->gf_interface);
 	if (!idev)
 		return -ENODEV;
 
+	mutex_lock(&idev->mc_lock);
+
+	if (idev->dead) {
+		err = -ENODEV;
+		goto done;
+	}
+
 	err = 0;
 
 	if (gsf->gf_fmode == MCAST_INCLUDE && gsf->gf_numsrc == 0) {
@@ -553,24 +572,19 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf,
 			psin6 = (struct sockaddr_in6 *)list;
 			newpsl->sl_addr[i] = psin6->sin6_addr;
 		}
-		mutex_lock(&idev->mc_lock);
+
 		err = ip6_mc_add_src(idev, group, gsf->gf_fmode,
 				     newpsl->sl_count, newpsl->sl_addr, 0);
 		if (err) {
-			mutex_unlock(&idev->mc_lock);
 			sock_kfree_s(sk, newpsl, struct_size(newpsl, sl_addr,
 							     newpsl->sl_max));
 			goto done;
 		}
-		mutex_unlock(&idev->mc_lock);
 	} else {
 		newpsl = NULL;
-		mutex_lock(&idev->mc_lock);
 		ip6_mc_add_src(idev, group, gsf->gf_fmode, 0, NULL, 0);
-		mutex_unlock(&idev->mc_lock);
 	}
 
-	mutex_lock(&idev->mc_lock);
 	psl = sock_dereference(pmc->sflist, sk);
 	if (psl) {
 		ip6_mc_del_src(idev, group, pmc->sfmode,
@@ -580,12 +594,14 @@ int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf,
 	} else {
 		ip6_mc_del_src(idev, group, pmc->sfmode, 0, NULL, 0);
 	}
+
 	rcu_assign_pointer(pmc->sflist, newpsl);
-	mutex_unlock(&idev->mc_lock);
 	kfree_rcu(psl, rcu);
 	pmc->sfmode = gsf->gf_fmode;
 	err = 0;
 done:
+	mutex_unlock(&idev->mc_lock);
+	in6_dev_put(idev);
 	if (leavegroup)
 		err = ipv6_sock_mc_drop(sk, gsf->gf_interface, group);
 	return err;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 018/877] ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (16 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 017/877] ipv6: mcast: Dont hold RTNL for MCAST_ socket options Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 019/877] media: video-i2c: fix buffer queue ordering Greg Kroah-Hartman
                   ` (866 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Taehee Yoo,
	Ido Schimmel, Jakub Kicinski, Sasha Levin

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

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

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit c073d1b070f171d206b19c98d71739a97f15b3f1 ]

pmc->sflist is read locklessly under rcu_read_lock() by
inet6_mc_check() during packet reception in the UDP and RAW
multicast receive paths.

ip6_mc_source() mutated psl->sl_addr and psl->sl_count in-place
when adding or removing a source filter. Additionally, when expanding
the filter buffer, newpsl was published via rcu_assign_pointer()
before writing the new source into the array.

Because 16-byte struct in6_addr writes are not atomic and array
shifting is not synchronized with RCU readers, concurrent readers in
inet6_mc_check() could read torn IPv6 addresses or observe
duplicated/missed source entries.

Fix this by switching ip6_mc_source() to copy-on-write RCU updates:
allocate and fully populate newpsl before publishing it via
rcu_assign_pointer(), and reclaim the old filter via kfree_rcu(),
matching ip6_mc_msfilter().

Also remove the now unused IP6_SFBLOCK macro.

Fixes: 882ba1f73c06 ("mld: convert ipv6_mc_socklist->sflist to RCU")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Taehee Yoo <ap420073@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260828084531.1826790-3-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/net/if_inet6.h |  2 -
 net/ipv6/mcast.c       | 98 ++++++++++++++++++++++++------------------
 2 files changed, 56 insertions(+), 44 deletions(-)

diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 238ad3349456a..795fb41b45f5d 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -88,8 +88,6 @@ struct ip6_sf_socklist {
 	struct in6_addr		sl_addr[] __counted_by(sl_max);
 };
 
-#define IP6_SFBLOCK	10	/* allocate this many at once */
-
 struct ipv6_mc_socklist {
 	struct in6_addr		addr;
 	int			ifindex;
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 02919944d5570..d0eefadea5c33 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -380,12 +380,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
 {
 	struct ipv6_pinfo *inet6 = inet6_sk(sk);
 	struct in6_addr *source, *group;
+	struct ip6_sf_socklist *newpsl, *psl;
 	struct net *net = sock_net(sk);
 	struct ipv6_mc_socklist *pmc;
-	struct ip6_sf_socklist *psl;
 	struct inet6_dev *idev;
 	int leavegroup = 0;
-	int i, j, rv;
+	int i, j;
 	int err;
 
 	source = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr;
@@ -434,13 +434,11 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
 	if (!add) {
 		if (!psl)
 			goto done;	/* err = -EADDRNOTAVAIL */
-		rv = !0;
 		for (i = 0; i < psl->sl_count; i++) {
-			rv = !ipv6_addr_equal(&psl->sl_addr[i], source);
-			if (rv == 0)
+			if (ipv6_addr_equal(&psl->sl_addr[i], source))
 				break;
 		}
-		if (rv)		/* source not found */
+		if (i == psl->sl_count)		/* source not found */
 			goto done;	/* err = -EADDRNOTAVAIL */
 
 		/* special case - (INCLUDE, empty) == LEAVE_GROUP */
@@ -449,58 +447,74 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
 			goto done;
 		}
 
+		atomic_sub(struct_size(psl, sl_addr, psl->sl_max),
+			   &sk->sk_omem_alloc);
+
+		if (psl->sl_count == 1) {
+			newpsl = NULL;
+		} else {
+			newpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr,
+							      psl->sl_count - 1),
+					      GFP_KERNEL);
+			if (!newpsl) {
+				atomic_add(struct_size(psl, sl_addr, psl->sl_max),
+					   &sk->sk_omem_alloc);
+				err = -ENOBUFS;
+				goto done;
+			}
+			newpsl->sl_max = psl->sl_count - 1;
+			newpsl->sl_count = psl->sl_count - 1;
+			for (j = 0; j < i; j++)
+				newpsl->sl_addr[j] = psl->sl_addr[j];
+			for (j = i + 1; j < psl->sl_count; j++)
+				newpsl->sl_addr[j - 1] = psl->sl_addr[j];
+		}
+
 		/* update the interface filter */
 		ip6_mc_del_src(idev, group, omode, 1, source, 1);
 
-		for (j = i+1; j < psl->sl_count; j++)
-			psl->sl_addr[j-1] = psl->sl_addr[j];
-		psl->sl_count--;
+		rcu_assign_pointer(pmc->sflist, newpsl);
+		kfree_rcu(psl, rcu);
 		err = 0;
 		goto done;
 	}
 	/* else, add a new source to the filter */
 
-	if (psl && psl->sl_count >= sysctl_mld_max_msf) {
+	if (psl && psl->sl_count >= READ_ONCE(sysctl_mld_max_msf)) {
 		err = -ENOBUFS;
 		goto done;
 	}
-	if (!psl || psl->sl_count == psl->sl_max) {
-		struct ip6_sf_socklist *newpsl;
-		int count = IP6_SFBLOCK;
-
-		if (psl)
-			count += psl->sl_max;
-		newpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr, count),
-				      GFP_KERNEL);
-		if (!newpsl) {
-			err = -ENOBUFS;
-			goto done;
-		}
-		newpsl->sl_max = count;
-		newpsl->sl_count = count - IP6_SFBLOCK;
-		if (psl) {
-			for (i = 0; i < psl->sl_count; i++)
-				newpsl->sl_addr[i] = psl->sl_addr[i];
-			atomic_sub(struct_size(psl, sl_addr, psl->sl_max),
-				   &sk->sk_omem_alloc);
+	if (psl) {
+		for (i = 0; i < psl->sl_count; i++) {
+			if (ipv6_addr_equal(&psl->sl_addr[i], source))
+				goto done; /* err = -EADDRNOTAVAIL */
 		}
-		rcu_assign_pointer(pmc->sflist, newpsl);
-		kfree_rcu(psl, rcu);
-		psl = newpsl;
 	}
-	rv = 1;	/* > 0 for insert logic below if sl_count is 0 */
-	for (i = 0; i < psl->sl_count; i++) {
-		rv = !ipv6_addr_equal(&psl->sl_addr[i], source);
-		if (rv == 0) /* There is an error in the address. */
-			goto done;
+
+	i = psl ? psl->sl_count + 1 : 1;
+	newpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr, i),
+			      GFP_KERNEL);
+	if (!newpsl) {
+		err = -ENOBUFS;
+		goto done;
 	}
-	for (j = psl->sl_count-1; j >= i; j--)
-		psl->sl_addr[j+1] = psl->sl_addr[j];
-	psl->sl_addr[i] = *source;
-	psl->sl_count++;
-	err = 0;
+	newpsl->sl_max = i;
+	newpsl->sl_count = i;
+	if (psl) {
+		for (j = 0; j < psl->sl_count; j++)
+			newpsl->sl_addr[j] = psl->sl_addr[j];
+	}
+	newpsl->sl_addr[i - 1] = *source;
+
 	/* update the interface list */
 	ip6_mc_add_src(idev, group, omode, 1, source, 1);
+
+	if (psl)
+		atomic_sub(struct_size(psl, sl_addr, psl->sl_max),
+			   &sk->sk_omem_alloc);
+	rcu_assign_pointer(pmc->sflist, newpsl);
+	kfree_rcu(psl, rcu);
+	err = 0;
 done:
 	mutex_unlock(&idev->mc_lock);
 	in6_dev_put(idev);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 019/877] media: video-i2c: fix buffer queue ordering
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (17 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 018/877] ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source() Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 020/877] ipv6: Select best matching nexthop object in fib6_table_lookup() Greg Kroah-Hartman
                   ` (865 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Arash Golgol, Hans Verkuil,
	Sasha Levin

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

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

From: Arash Golgol <arash.golgol@gmail.com>

[ Upstream commit bc4574c265ed738849e46d942617100580fcedd2 ]

Queued buffers are added to the tail of vid_cap_active in
buffer_queue(), but the capture kthread also retrieves buffers from
the tail of the list.

This makes the queue behave as LIFO instead of FIFO when multiple
buffers are queued.

Fix this by retrieving buffers from the head of the list.

Signed-off-by: Arash Golgol <arash.golgol@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/media/i2c/video-i2c.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/media/i2c/video-i2c.c b/drivers/media/i2c/video-i2c.c
index a091fd6d3e607..a4ddc10c5f22e 100644
--- a/drivers/media/i2c/video-i2c.c
+++ b/drivers/media/i2c/video-i2c.c
@@ -465,8 +465,9 @@ static int video_i2c_thread_vid_cap(void *priv)
 		spin_lock(&data->slock);
 
 		if (!list_empty(&data->vid_cap_active)) {
-			vid_cap_buf = list_last_entry(&data->vid_cap_active,
-						 struct video_i2c_buffer, list);
+			vid_cap_buf = list_first_entry(&data->vid_cap_active,
+						       struct video_i2c_buffer,
+						       list);
 			list_del(&vid_cap_buf->list);
 		}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 020/877] ipv6: Select best matching nexthop object in fib6_table_lookup()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (18 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 019/877] media: video-i2c: fix buffer queue ordering Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 021/877] ipv6: Honor oif when choosing nexthop for locally generated traffic Greg Kroah-Hartman
                   ` (864 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ido Schimmel, David Ahern,
	Jakub Kicinski, Sasha Levin

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

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

From: Ido Schimmel <idosch@nvidia.com>

[ Upstream commit 484bb9d164df397a53e0f533b262b27b1590efcb ]

Currently, when using multipath routes without nexthop objects,
fib6_table_lookup() selects the nexthop with the highest score. This
means that when both a source address and an oif are specified, the
nexthop that is chosen is the one that matches in terms of oif:

 # sysctl -wq net.ipv6.conf.all.forwarding=1
 # ip address add 2001:db8:2::1/64 dev lo
 # ip route add 2001:db8:10::/64 nexthop via fe80::1 dev dummy1 nexthop via fe80::2 dev dummy2

 # perf record -e fib6:fib6_table_lookup -- bash -c "for i in {1..100}; do ip route get 2001:db8:10::${i} from 2001:db8:2::1 oif dummy1; done > /dev/null"
 # perf script | grep -o dummy[0-9] | sort | uniq -c
     100 dummy1
 # perf record -e fib6:fib6_table_lookup -- bash -c "for i in {1..100}; do ip route get 2001:db8:10::${i} from 2001:db8:2::1 oif dummy2; done > /dev/null"
 # perf script | grep -o dummy[0-9] | sort | uniq -c
     100 dummy2

When using nexthop objects, fib6_table_lookup() selects the first
matching nexthop and not necessarily the one with the highest score:

 # ip nexthop add id 1 via fe80::1 dev dummy1
 # ip nexthop add id 2 via fe80::2 dev dummy2
 # ip nexthop add id 3 group 1/2
 # ip route add 2001:db8:20::/64 nhid 3

 # perf record -e fib6:fib6_table_lookup -- bash -c "for i in {1..100}; do ip route get 2001:db8:20::${i} from 2001:db8:2::1 oif dummy1; done > /dev/null"
 # perf script | grep -o dummy[0-9] | sort | uniq -c
     100 dummy1
 # perf record -e fib6:fib6_table_lookup -- bash -c "for i in {1..100}; do ip route get 2001:db8:20::${i} from 2001:db8:2::1 oif dummy2; done > /dev/null"
 # perf script | grep -o dummy[0-9] | sort | uniq -c
     100 dummy1

This is not very significant right now because the nexthop is later
overwritten during path selection in fib6_select_path(). However, the
next patch is going to skip path selection when we have an oif match
during output route lookup.

As a preparation for this change, align the nexthop object behavior with
the legacy one and make sure that fib6_table_lookup() always selects the
best matching nexthop. Do that by always returning 0 from
rt6_nh_find_match() in order not to terminate the loop in
nexthop_for_each_fib6_nh() and storing in arg->nh the best matching
nexthop so far.

Behavior after the change:

 # perf record -e fib6:fib6_table_lookup -- bash -c "for i in {1..100}; do ip route get 2001:db8:20::${i} from 2001:db8:2::1 oif dummy1; done > /dev/null"
 # perf script | grep -o dummy[0-9] | sort | uniq -c
     100 dummy1
 # perf record -e fib6:fib6_table_lookup -- bash -c "for i in {1..100}; do ip route get 2001:db8:20::${i} from 2001:db8:2::1 oif dummy2; done > /dev/null"
 # perf script | grep -o dummy[0-9] | sort | uniq -c
     100 dummy2

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20260611154605.992528-2-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv6/route.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 19c970978e863..b30cb180009b1 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -820,9 +820,11 @@ static int rt6_nh_find_match(struct fib6_nh *nh, void *_arg)
 {
 	struct fib6_nh_frl_arg *arg = _arg;
 
-	arg->nh = nh;
-	return find_match(nh, arg->flags, arg->oif, arg->strict,
-			  arg->mpri, arg->do_rr);
+	if (find_match(nh, arg->flags, arg->oif, arg->strict, arg->mpri,
+		       arg->do_rr))
+		arg->nh = nh;
+
+	return 0;
 }
 
 static void __find_rr_leaf(struct fib6_info *f6i_start,
@@ -862,11 +864,10 @@ static void __find_rr_leaf(struct fib6_info *f6i_start,
 				res->nh = nexthop_fib6_nh(f6i->nh);
 				return;
 			}
-			if (nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_find_match,
-						     &arg)) {
-				matched = true;
-				nh = arg.nh;
-			}
+			nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_find_match,
+						 &arg);
+			matched = !!arg.nh;
+			nh = arg.nh;
 		} else {
 			nh = f6i->fib6_nh;
 			if (find_match(nh, f6i->fib6_flags, oif, strict,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 021/877] ipv6: Honor oif when choosing nexthop for locally generated traffic
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (19 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 020/877] ipv6: Select best matching nexthop object in fib6_table_lookup() Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 022/877] pidfd: hold exec_update_lock around namespace ioctl Greg Kroah-Hartman
                   ` (863 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, David Ahern, Ido Schimmel,
	Jakub Kicinski, Sasha Levin

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

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

From: Ido Schimmel <idosch@nvidia.com>

[ Upstream commit d25e7e9d8a6c1e2afb854613e417c6aa1a28ce6f ]

Commit 741a11d9e410 ("net: ipv6: Add RT6_LOOKUP_F_IFACE flag if oif is
set") made the kernel honor the oif parameter when specified as part of
output route lookup:

 # ip route add 2001:db8:1::/64 dev dummy1
 # ip route add ::/0 dev dummy2
 # ip route get 2001:db8:1::1 oif dummy2 fibmatch
 default dev dummy2 metric 1024 pref medium

Due to regression reports, the behavior was partially reverted in commit
d46a9d678e4c ("net: ipv6: Dont add RT6_LOOKUP_F_IFACE flag if saddr
set") to only honor the oif if source address is not specified:

 # ip route get 2001:db8:1::1 from 2001:db8:2::1 oif dummy2 fibmatch
 2001:db8:1::/64 dev dummy1 metric 1024 pref medium

That is, when source address is specified, the kernel will choose the
most specific route even if its nexthop device does not match the
specified oif.

This creates a problem for multipath routes. After looking up a route,
when source address is not specified, the kernel will choose a nexthop
whose nexthop device matches the specified oif:

 # sysctl -wq net.ipv6.conf.all.forwarding=1
 # ip route add 2001:db8:10::/64 nexthop via fe80::1 dev dummy1 nexthop via fe80::2 dev dummy2
 # for i in {1..100}; do ip route get 2001:db8:10::${i} oif dummy2; done | grep -o dummy[0-9] | sort | uniq -c
      100 dummy2

But will disregard the oif when source address is specified despite the
fact that a matching nexthop exists:

 # for i in {1..100}; do ip route get 2001:db8:10::${i} from 2001:db8:2::1 oif dummy2; done | grep -o dummy[0-9] | sort | uniq -c
      53 dummy1
      47 dummy2

This behavior differs from IPv4:

 # ip address add 192.0.2.1/32 dev lo
 # ip route add 198.51.100.0/24 nexthop via inet6 fe80::1 dev dummy1 nexthop via inet6 fe80::2 dev dummy2
 # for i in {1..100}; do ip route get 198.51.100.${i} from 192.0.2.1 oif dummy2; done | grep -o dummy[0-9] | sort | uniq -c
     100 dummy2

What happens is that fib6_table_lookup() returns a route with a matching
nexthop device (assuming it exists):

 # perf record -e fib6:fib6_table_lookup -- bash -c "for i in {1..100}; do ip route get 2001:db8:10::${i} from 2001:db8:2::1 oif dummy2; done > /dev/null"
 # perf script | grep -o dummy[0-9] | sort | uniq -c
      100 dummy2

But it is later overwritten during path selection in fib6_select_path()
which instead chooses a nexthop according to the calculated hash.

Solve this by telling fib6_select_path() to skip path selection if we
have an oif match during output route lookup (iif being
LOOPBACK_IFINDEX).

Behavior after the change:

 # sysctl -wq net.ipv6.conf.all.forwarding=1
 # ip route add 2001:db8:10::/64 nexthop via fe80::1 dev dummy1 nexthop via fe80::2 dev dummy2
 # for i in {1..100}; do ip route get 2001:db8:10::${i} from 2001:db8:2::1 oif dummy2; done | grep -o dummy[0-9] | sort | uniq -c
     100 dummy2

Note that enabling forwarding is only needed because we did not add
neighbor entries for the gateway addresses. When forwarding is disabled
and CONFIG_IPV6_ROUTER_PREF is not enabled in kernel config, the kernel
will treat non-existing neighbor entries as errors and perform
round-robin between the nexthops:

 # sysctl -wq net.ipv6.conf.all.forwarding=0
 # for i in {1..100}; do ip route get 2001:db8:10::${i} from 2001:db8:2::1 oif dummy2; done | grep -o dummy[0-9] | sort | uniq -c
      50 dummy1
      50 dummy2

Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260611154605.992528-3-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv6/route.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b30cb180009b1..15f02882be040 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2269,6 +2269,7 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
 {
 	struct fib6_result res = {};
 	struct rt6_info *rt = NULL;
+	bool have_oif_match;
 	int strict = 0;
 
 	WARN_ON_ONCE((flags & RT6_LOOKUP_F_DST_NOREF) &&
@@ -2285,7 +2286,9 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
 	if (res.f6i == net->ipv6.fib6_null_entry)
 		goto out;
 
-	fib6_select_path(net, &res, fl6, oif, false, skb, strict);
+	have_oif_match = fl6->flowi6_iif == LOOPBACK_IFINDEX &&
+			 oif == res.nh->fib_nh_dev->ifindex;
+	fib6_select_path(net, &res, fl6, oif, have_oif_match, skb, strict);
 
 	/*Search through exception table */
 	rt = rt6_find_cached_rt(&res, &fl6->daddr, &fl6->saddr);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 022/877] pidfd: hold exec_update_lock around namespace ioctl
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (20 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 021/877] ipv6: Honor oif when choosing nexthop for locally generated traffic Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 023/877] xfrm: avoid RCU warnings around the per-netns netlink socket Greg Kroah-Hartman
                   ` (862 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Chen Linxuan,
	Christian Brauner (Amutable), Sasha Levin

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

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

From: Chen Linxuan <me@black-desk.cn>

[ Upstream commit 9688a46802939da28f00cb40e8129615d5d4af39 ]

The PIDFD_GET_*_NAMESPACE ioctls in pidfd_ioctl() perform a filesystem
credentials ptrace access check before handing out a namespace file
descriptor.  The accompanying comment states that the code "mirrors nsfs
behavior", but, unlike the corresponding procfs paths, it does so without
holding the target task's exec_update_lock.

proc_ns_get_link() and proc_ns_readlink() both take exec_update_lock for
reading around the ptrace check and the namespace lookup, so that the
credentials used for the access decision match those of the task when its
namespace is read.  Without it, a caller can pass the check against the
target's old credentials and then read the namespace after the target has
execve()'d a setuid binary and committed new credentials -- accessing
namespace information it should have been denied.

Hold exec_update_lock for reading around the ptrace check and the
namespace lookup so that pidfd truly mirrors nsfs behavior, as the comment
already claims.  open_namespace() itself runs outside the lock: once a
namespace reference is obtained it carries its own refcount and is opened
with the caller's own credentials, so a concurrent execve() on the target
can no longer affect the outcome.

Fixes: 5b08bd408534 ("pidfs: allow retrieval of namespace file descriptors")
Cc: stable@vger.kernel.org
Signed-off-by: Chen Linxuan <me@black-desk.cn>
Link: https://patch.msgid.link/20260731-pidfd-exec-update-lock-v1-1-b388f2f3a8b0@black-desk.cn
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/pidfs.c | 43 +++++++++++++++++++++++++++++++------------
 1 file changed, 31 insertions(+), 12 deletions(-)

diff --git a/fs/pidfs.c b/fs/pidfs.c
index 5a8d8eb8df23b..b2dc613a64f6f 100644
--- a/fs/pidfs.c
+++ b/fs/pidfs.c
@@ -122,6 +122,7 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	struct pid *pid = pidfd_pid(file);
 	struct ns_common *ns_common = NULL;
 	struct pid_namespace *pid_ns;
+	int error;
 
 	if (arg)
 		return -EINVAL;
@@ -130,20 +131,33 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	if (!task)
 		return -ESRCH;
 
+	/*
+	 * We're trying to open a file descriptor to the namespace so perform a
+	 * filesystem cred ptrace check. Hold @task's exec_update_lock for the
+	 * duration of the ptrace check and the namespace lookup so that the
+	 * credentials used for the access decision match those of @task at the
+	 * time its namespace is read, preventing a concurrent execve() from
+	 * swapping the task's credentials in between the check and the use. We
+	 * mirror nsfs behavior.
+	 */
+	error = down_read_killable(&task->signal->exec_update_lock);
+	if (error)
+		return error;
+
+	if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {
+		error = -EACCES;
+		goto out_unlock;
+	}
+
 	scoped_guard(task_lock, task) {
 		nsp = task->nsproxy;
 		if (nsp)
 			get_nsproxy(nsp);
 	}
-	if (!nsp)
-		return -ESRCH; /* just pretend it didn't exist */
-
-	/*
-	 * We're trying to open a file descriptor to the namespace so perform a
-	 * filesystem cred ptrace check. Also, we mirror nsfs behavior.
-	 */
-	if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS))
-		return -EACCES;
+	if (!nsp) {
+		error = -ESRCH; /* just pretend it didn't exist */
+		goto out_unlock;
+	}
 
 	switch (cmd) {
 	/* Namespaces that hang of nsproxy. */
@@ -211,11 +225,16 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 		}
 		break;
 	default:
-		return -ENOIOCTLCMD;
+		error = -ENOIOCTLCMD;
 	}
 
-	if (!ns_common)
-		return -EOPNOTSUPP;
+	if (!error && !ns_common)
+		error = -EOPNOTSUPP;
+
+out_unlock:
+	up_read(&task->signal->exec_update_lock);
+	if (error)
+		return error;
 
 	/* open_namespace() unconditionally consumes the reference */
 	return open_namespace(ns_common);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 023/877] xfrm: avoid RCU warnings around the per-netns netlink socket
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (21 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 022/877] pidfd: hold exec_update_lock around namespace ioctl Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 024/877] xfrm: fix compat ALLOCSPI request use-after-free Greg Kroah-Hartman
                   ` (861 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sabrina Dubroca, Simon Horman,
	Steffen Klassert, Sasha Levin

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

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

From: Sabrina Dubroca <sd@queasysnail.net>

[ Upstream commit d87f8bc47fbf012a7f115e311d0603d97e47c34c ]

net->xfrm.nlsk is used in 2 types of contexts:
 - fully under RCU, with rcu_read_lock + rcu_dereference and a NULL check
 - in the netlink handlers, with requests coming from a userspace socket

In the 2nd case, net->xfrm.nlsk is guaranteed to stay non-NULL and the
object is alive, since we can't enter the netns destruction path while
the user socket holds a reference on the netns.

After adding the __rcu annotation to netns_xfrm.nlsk (which silences
sparse warnings in the RCU users and __net_init code), we need to tell
sparse that the 2nd case is safe. Add a helper for that.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Stable-dep-of: d1ebd9081879 ("xfrm: fix compat ALLOCSPI request use-after-free")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/net/netns/xfrm.h |  2 +-
 net/xfrm/xfrm_user.c     | 25 +++++++++++++++++--------
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h
index 23dd647fe0248..b73983a17e088 100644
--- a/include/net/netns/xfrm.h
+++ b/include/net/netns/xfrm.h
@@ -59,7 +59,7 @@ struct netns_xfrm {
 	struct list_head	inexact_bins;
 
 
-	struct sock		*nlsk;
+	struct sock		__rcu *nlsk;
 	struct sock		*nlsk_stash;
 
 	u32			sysctl_aevent_etime;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 904c9328852f0..c37f8e518f1e3 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -35,6 +35,15 @@
 #endif
 #include <linux/unaligned.h>
 
+static struct sock *xfrm_net_nlsk(const struct net *net, const struct sk_buff *skb)
+{
+	/* get the source of this request, see netlink_unicast_kernel */
+	const struct sock *sk = NETLINK_CB(skb).sk;
+
+	/* sk is refcounted, the netns stays alive and nlsk with it */
+	return rcu_dereference_protected(net->xfrm.nlsk, sk->sk_net_refcnt);
+}
+
 static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type,
 			  struct netlink_ext_ack *extack)
 {
@@ -1662,7 +1671,7 @@ static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
 	err = build_spdinfo(r_skb, net, sportid, seq, *flags);
 	BUG_ON(err < 0);
 
-	return nlmsg_unicast(net->xfrm.nlsk, r_skb, sportid);
+	return nlmsg_unicast(xfrm_net_nlsk(net, skb), r_skb, sportid);
 }
 
 static inline unsigned int xfrm_sadinfo_msgsize(void)
@@ -1722,7 +1731,7 @@ static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
 	err = build_sadinfo(r_skb, net, sportid, seq, *flags);
 	BUG_ON(err < 0);
 
-	return nlmsg_unicast(net->xfrm.nlsk, r_skb, sportid);
+	return nlmsg_unicast(xfrm_net_nlsk(net, skb), r_skb, sportid);
 }
 
 static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -1742,7 +1751,7 @@ static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
 	if (IS_ERR(resp_skb)) {
 		err = PTR_ERR(resp_skb);
 	} else {
-		err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).portid);
+		err = nlmsg_unicast(xfrm_net_nlsk(net, skb), resp_skb, NETLINK_CB(skb).portid);
 	}
 	xfrm_state_put(x);
 out_noput:
@@ -1833,7 +1842,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
 		}
 	}
 
-	err = nlmsg_unicast(net->xfrm.nlsk, resp_skb, NETLINK_CB(skb).portid);
+	err = nlmsg_unicast(xfrm_net_nlsk(net, skb), resp_skb, NETLINK_CB(skb).portid);
 
 out:
 	xfrm_state_put(x);
@@ -2476,7 +2485,7 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
 	r_up->out = READ_ONCE(net->xfrm.policy_default[XFRM_POLICY_OUT]);
 	nlmsg_end(r_skb, r_nlh);
 
-	return nlmsg_unicast(net->xfrm.nlsk, r_skb, portid);
+	return nlmsg_unicast(xfrm_net_nlsk(net, skb), r_skb, portid);
 }
 
 static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -2542,7 +2551,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 		if (IS_ERR(resp_skb)) {
 			err = PTR_ERR(resp_skb);
 		} else {
-			err = nlmsg_unicast(net->xfrm.nlsk, resp_skb,
+			err = nlmsg_unicast(xfrm_net_nlsk(net, skb), resp_skb,
 					    NETLINK_CB(skb).portid);
 		}
 	} else {
@@ -2721,7 +2730,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
 		return err;
 	}
 
-	err = nlmsg_unicast(net->xfrm.nlsk, r_skb, NETLINK_CB(skb).portid);
+	err = nlmsg_unicast(xfrm_net_nlsk(net, skb), r_skb, NETLINK_CB(skb).portid);
 	spin_unlock_bh(&x->lock);
 	xfrm_state_put(x);
 	return err;
@@ -3393,7 +3402,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
 			goto err;
 		}
 
-		err = netlink_dump_start(net->xfrm.nlsk, skb, nlh, &c);
+		err = netlink_dump_start(xfrm_net_nlsk(net, skb), skb, nlh, &c);
 		goto err;
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 024/877] xfrm: fix compat ALLOCSPI request use-after-free
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (22 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 023/877] xfrm: avoid RCU warnings around the per-netns netlink socket Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 025/877] xfrm: add missing rcu_read_lock(), skb_dst_force() and dev_hold() for xfrm_trans_reinject() Greg Kroah-Hartman
                   ` (860 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kyle Zeng, David Lee,
	Steffen Klassert, Sasha Levin

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

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

From: Kyle Zeng <kylebot@openai.com>

[ Upstream commit d1ebd9081879fd9ae9c8fb7e8928f19cc88ae320 ]

xfrm_state_netlink() builds the ALLOCSPI response with
dump_one_state(), which already calls alloc_compat() with the response
skb and header.

xfrm_alloc_userspi() then calls alloc_compat() again, but passes the
original request skb and its header. For a compat request, the
translator therefore interprets the 228-byte compat xfrm_userspi_info
as the 232-byte native layout and reads four bytes past the declared
payload. It also publishes the translated child through the request's
frag_list.

A multicast clone of the request shares skb_shared_info and can observe
that child. xfrm_user_rcv_msg() frees it after the request handler
returns, racing a compat receiver which may still be copying from it and
resulting in a use-after-free.

Remove the redundant conversion. The response keeps its correct compat
translation from dump_one_state(), and no child is attached to the
inbound request.

Fixes: 5f3eea6b7e8f ("xfrm/compat: Attach xfrm dumps to 64=>32 bit translator")
Assisted-by: Codex:gpt-5.6-sol Codex:gpt-5.5-cyber
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Co-developed-by: David Lee <david.lee@trailofbits.com>
Signed-off-by: David Lee <david.lee@trailofbits.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/xfrm/xfrm_user.c | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index c37f8e518f1e3..c1e753d554e75 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1765,7 +1765,6 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
 	struct net *net = sock_net(skb->sk);
 	struct xfrm_state *x;
 	struct xfrm_userspi_info *p;
-	struct xfrm_translator *xtr;
 	struct sk_buff *resp_skb;
 	xfrm_address_t *daddr;
 	int family;
@@ -1831,17 +1830,6 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
 		goto out;
 	}
 
-	xtr = xfrm_get_translator();
-	if (xtr) {
-		err = xtr->alloc_compat(skb, nlmsg_hdr(skb));
-
-		xfrm_put_translator(xtr);
-		if (err) {
-			kfree_skb(resp_skb);
-			goto out;
-		}
-	}
-
 	err = nlmsg_unicast(xfrm_net_nlsk(net, skb), resp_skb, NETLINK_CB(skb).portid);
 
 out:
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 025/877] xfrm: add missing rcu_read_lock(), skb_dst_force() and dev_hold() for xfrm_trans_reinject()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (23 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 024/877] xfrm: fix compat ALLOCSPI request use-after-free Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 026/877] esp: downgrade zerocopy managed frags before mutating skb frags Greg Kroah-Hartman
                   ` (859 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot, Eric Dumazet,
	Steffen Klassert, Liu Jian, Sasha Levin

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

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

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit d2f5082f9e84653fa1a9e8aebaaff23e688f5e19 ]

syzbot reported a suspicious RCU usage warning in ip6_pkt_drop():

  WARNING: suspicious RCU usage in ip6_pkt_drop
  include/net/addrconf.h:389 suspicious rcu_dereference_check() usage!

  Call Trace:
   __in6_dev_get_safely include/net/addrconf.h:389 [inline]
   ip6_pkt_drop+0x596/0x610 net/ipv6/route.c:4620
   ip6_pkt_discard+0x1c/0x30 net/ipv6/route.c:4651
   xfrm_trans_reinject+0x324/0x630 net/xfrm/xfrm_input.c:806
   process_one_work kernel/workqueue.c:3322 [inline]
   process_scheduled_works+0xa8e/0x14e0 kernel/workqueue.c:3405
   worker_thread+0xa47/0xfb0 kernel/workqueue.c:3486

When commit 4f4920669d21 ("xfrm: Reinject transport-mode packets through
workqueue") converted xfrm_trans_reinject from a tasklet to a workqueue,
the reinjection loop ceased running in softirq context. Workqueue workers
run in process context where local_bh_disable() does not enter an RCU
read-side critical section under CONFIG_PREEMPT_RCU.

Because finish callbacks (such as ip6_rcv_finish) expect to run under an
RCU read lock (performing route lookups, l3mdev lookups, and accessing
RCU-protected data structures), invoking them in workqueue context without
rcu_read_lock() triggers RCU lockdep warnings.

Furthermore, packets queued to the workqueue via xfrm_trans_queue_net()
may carry non-refcounted (noref) dst entries (e.g. from ip_route_input_noref).
Additionally, on netdevice unregistration, dst_dev_put() replaces dst->dev
with blackhole_netdev, so dst entries do not keep skb->dev alive while
queued in the workqueue.

Fix these issues by:
1. Calling skb_dst_force(skb) in xfrm_trans_queue_net() while still in the
   caller's RCU section to ensure dst is reference-counted before queuing.
2. Holding a reference on skb->dev via dev_hold()/dev_put() across workqueue
   deferral so skb->dev remains valid during finish() callback processing.
3. Acquiring rcu_read_lock() around the finish callback invocation loop in
   xfrm_trans_reinject().

Fixes: 4f4920669d21 ("xfrm: Reinject transport-mode packets through workqueue")
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Steffen Klassert <steffen.klassert@secunet.com>
Cc: Liu Jian <liujian56@huawei.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/xfrm/xfrm_input.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 5d3633ce6ba32..1be187b980461 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -778,12 +778,17 @@ static void xfrm_trans_reinject(struct work_struct *work)
 	spin_unlock_bh(&trans->queue_lock);
 
 	local_bh_disable();
+	rcu_read_lock();
 	while ((skb = __skb_dequeue(&queue))) {
 		struct net *net = XFRM_TRANS_SKB_CB(skb)->net;
+		struct net_device *dev = skb->dev;
 
 		XFRM_TRANS_SKB_CB(skb)->finish(net, NULL, skb);
+		if (dev)
+			dev_put(dev);
 		put_net(net);
 	}
+	rcu_read_unlock();
 	local_bh_enable();
 }
 
@@ -799,12 +804,18 @@ int xfrm_trans_queue_net(struct net *net, struct sk_buff *skb,
 	if (skb_queue_len(&trans->queue) >= READ_ONCE(net_hotdata.max_backlog))
 		return -ENOBUFS;
 
+	if (skb_dst(skb) && !skb_dst_force(skb))
+		return -EHOSTUNREACH;
+
 	BUILD_BUG_ON(sizeof(struct xfrm_trans_cb) > sizeof(skb->cb));
 
 	hold_net = maybe_get_net(net);
 	if (!hold_net)
 		return -ENODEV;
 
+	if (skb->dev)
+		dev_hold(skb->dev);
+
 	XFRM_TRANS_SKB_CB(skb)->finish = finish;
 	XFRM_TRANS_SKB_CB(skb)->net = hold_net;
 	spin_lock_bh(&trans->queue_lock);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 026/877] esp: downgrade zerocopy managed frags before mutating skb frags
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (24 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 025/877] xfrm: add missing rcu_read_lock(), skb_dst_force() and dev_hold() for xfrm_trans_reinject() Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 027/877] ARM: socfpga: select the PL310 erratum 753970 workaround Greg Kroah-Hartman
                   ` (858 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Maher Azzouzi, Steffen Klassert,
	Sasha Levin

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

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

From: Maher Azzouzi <maherazz04@gmail.com>

[ Upstream commit f89416eb3db151170a6f3c6dfc5239d26cdce4d2 ]

On the out-of-place output path (esp->inplace == false) ESP rewrites the
skb frag array: esp_output_head() appends a trailer frag and
esp_output_tail() replaces the frags with a destination page, both
referenced with get_page().

When the skb carries zerocopy managed frags (SKBFL_MANAGED_FRAG_REFS) the
payload frags are owned by the ubuf and must not be referenced or
unreferenced individually, but ESP mutates the frag array without ever
downgrading the skb.  This breaks the managed-frag invariant two ways:

  - esp_ssg_unref() walks the source scatterlist and drops a page
    reference for every frag, including the ubuf-owned payload frags,
    pushing their refcount below the GUP pin bias while the pages are
    still pinned, i.e. a use-after-free of the zerocopy pages;

  - esp_output_tail() installs its destination page as frag 0 with
    get_page() but leaves SKBFL_MANAGED_FRAG_REFS set, so
    skb_release_data() takes the skip_unref branch and never drops that
    reference, leaking the x->xfrag page at packet rate.

Fix this the way every other frag-mutating site does (__ip_append_data(),
__ip6_append_data(), tcp_sendmsg_locked()) and call
skb_zcopy_downgrade_managed() before ESP touches the frag array: it takes
a real reference on each existing frag and clears SKBFL_MANAGED_FRAG_REFS,
so the per-frag unref in esp_ssg_unref() and the frag release in
skb_release_data() are both balanced and no mixed-ownership frag array is
left behind.

Fixes: 753f1ca4e1e5 ("net: introduce managed frags infrastructure")
Signed-off-by: Maher Azzouzi <maherazz04@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv4/esp4.c | 6 ++++++
 net/ipv6/esp6.c | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 6c8c789ded0e4..fb78dc6b7e148 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -438,6 +438,12 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
 
 			esp->inplace = false;
 
+			/* Take real page refs and clear SKBFL_MANAGED_FRAG_REFS before
+			 * we mutate the frag array, so the per-frag unref stays balanced
+			 * for zerocopy managed frags (see __ip_append_data()).
+			 */
+			skb_zcopy_downgrade_managed(skb);
+
 			allocsize = ALIGN(tailen, L1_CACHE_BYTES);
 
 			spin_lock_bh(&x->lock);
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 80981596236ab..7411aac0707b2 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -467,6 +467,12 @@ int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
 
 			esp->inplace = false;
 
+			/* Take real page refs and clear SKBFL_MANAGED_FRAG_REFS before
+			 * we mutate the frag array, so the per-frag unref stays balanced
+			 * for zerocopy managed frags (see __ip_append_data()).
+			 */
+			skb_zcopy_downgrade_managed(skb);
+
 			allocsize = ALIGN(tailen, L1_CACHE_BYTES);
 
 			spin_lock_bh(&x->lock);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 027/877] ARM: socfpga: select the PL310 erratum 753970 workaround
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (25 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 026/877] esp: downgrade zerocopy managed frags before mutating skb frags Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 028/877] RDMA/siw: Clear association under lock if siw_qp_modify fails in siw_accept Greg Kroah-Hartman
                   ` (857 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, Dinh Nguyen,
	Sasha Levin

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

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

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit cfc1e9a543e3589ba200795b6e7fd8ef4314efdf ]

ARCH_INTEL_SOCFPGA selects CACHE_L2X0 and several PL310 erratum
workarounds. The 753970 workaround is still conditioned on PL310, but that
Kconfig symbol no longer exists, so this one selection is always disabled.

Select PL310_ERRATA_753970 directly, consistently with the other PL310
workarounds required by the platform.

Fixes: fbc125afdc50 ("ARM: socfpga: Turn on ARM errata for L2 cache")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/arm/mach-socfpga/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index eb72c240c2486..528c5c1368c37 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -16,7 +16,7 @@ menuconfig ARCH_INTEL_SOCFPGA
 	select ARM_ERRATA_775420
 	select PL310_ERRATA_588369
 	select PL310_ERRATA_727915
-	select PL310_ERRATA_753970 if PL310
+	select PL310_ERRATA_753970
 	select PL310_ERRATA_769419
 	select RESET_CONTROLLER
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 028/877] RDMA/siw: Clear association under lock if siw_qp_modify fails in siw_accept
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (26 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 027/877] ARM: socfpga: select the PL310 erratum 753970 workaround Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 029/877] RDMA/rxe: validate access flags before swapping the MRs PD Greg Kroah-Hartman
                   ` (856 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Shuangpeng Bai, Guoqing Jiang,
	Bernard Metzler, Leon Romanovsky, Sasha Levin

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

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

From: Guoqing Jiang <guoqing.jiang@linux.dev>

[ Upstream commit 32cd87f54dd1070020e664ccb0312a9f0fea79b4 ]

We need to clear cep before release state_lock as siw_qp_llp_close and
siw_qp_modify->siw_qp_llp_close did.

Otherwise if siw_qp_modify() fails in siw_accept(), the QP's state_lock
is released before the error path cleanup. A concurrent ibv_modify_qp()
transitioning the QP to ERROR can race in this window:

  siw_accept()                       ibv_modify_qp(ERROR)
  ----------------------             ----------------------
  siw_qp_modify() fails
  up_write(&qp->state_lock)
                                     down_write(&qp->state_lock)
                                     nextstate_from_idle():
				     if (qp->cep)
                                       siw_cep_put(qp->cep) <- frees cep
                                       qp->cep = NULL
  goto error
    cep->qp = NULL                   <- UAF

Clear qp->cep and drop the association reference taken by siw_cep_get(),
all under the write lock held from the initial down_write(&qp->state_lock).
Thread B therefore sees qp->cep == NULL, skips its own put, and cannot free
the cep before siw_accept() is done with it.

Fixes: 6c52fdc244b5 ("rdma/siw: connection management")
Reported-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
Link: https://lore.kernel.org/linux-rdma/d6fbe475-a5c2-f975-99b0-a0bd6b6d10e8@linux.dev/T/#m5876c1ff2de8686a9a1173b8f1aa0ff5363a785c
Signed-off-by: Guoqing Jiang <guoqing.jiang@linux.dev>
Link: https://patch.msgid.link/20260827125553.12831-1-guoqing.jiang@linux.dev
Acked-by: Bernard Metzler <bernard.metzler@linux.dev>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/sw/siw/siw_cm.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c
index bb7d909639071..04fabab440581 100644
--- a/drivers/infiniband/sw/siw/siw_cm.c
+++ b/drivers/infiniband/sw/siw/siw_cm.c
@@ -1669,9 +1669,12 @@ int siw_accept(struct iw_cm_id *id, struct iw_cm_conn_param *params)
 			   SIW_QP_ATTR_STATE | SIW_QP_ATTR_LLP_HANDLE |
 				   SIW_QP_ATTR_ORD | SIW_QP_ATTR_IRD |
 				   SIW_QP_ATTR_MPA);
+	if (rv) {
+		qp->cep = NULL;
+		siw_cep_put(cep);
+		goto error_unlock;
+	}
 	up_write(&qp->state_lock);
-	if (rv)
-		goto error;
 
 	siw_dbg_cep(cep, "[QP %u]: send mpa reply, %d byte pdata\n",
 		    qp_id(qp), params->private_data_len);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 029/877] RDMA/rxe: validate access flags before swapping the MRs PD
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (27 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 028/877] RDMA/siw: Clear association under lock if siw_qp_modify fails in siw_accept Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 030/877] RDMA/rxe: Fix integer overflow in mr_check_range() leading to OOB access Greg Kroah-Hartman
                   ` (855 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Zhu Yanjun,
	Leon Romanovsky, Sasha Levin

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

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

From: Norbert Szetei <norbert@doyensec.com>

[ Upstream commit ae36a5b609ae79f4de966328b78d2584be9719a4 ]

rxe_rereg_user_mr() reassigns mr->ibmr.pd first and only then
validates the IB_MR_REREG_ACCESS argument:

	if (flags & IB_MR_REREG_PD) {
		rxe_put(old_pd);
		rxe_get(pd);
		mr->ibmr.pd = ibpd;
	}

	if (flags & IB_MR_REREG_ACCESS) {
		if (access & ~RXE_ACCESS_SUPPORTED_MR)
			return ERR_PTR(-EOPNOTSUPP);
		mr->access = access;
	}

Both flags pass the entry check because RXE_MR_REREG_SUPPORTED is
IB_MR_REREG_PD | IB_MR_REREG_ACCESS, so a caller can reach the access
check with mr->ibmr.pd already reassigned.

mr->ibmr.pd is owned by the core, which adjusts pd->usecnt only on the
success path: ib_uverbs_rereg_mr() jumps to put_new_uobj on a driver error
without undoing the reassignment, so mr->pd == new_pd while the usecnts
still charge the MR to orig_pd. ib_dereg_mr_user() then decrements
new_pd, whose count can reach zero while a memory window still references
it; uverbs_free_pd() frees the PD on that count alone and rxe_mw_cleanup()
writes to freed memory:

  BUG: KASAN: slab-use-after-free in __rxe_put+0x31/0xa0
  Write of size 4 at addr ffff8881301dd690 by task rxe_poc/591
   __rxe_put+0x31/0xa0
   rxe_mw_cleanup+0x42/0x200
   __rxe_cleanup+0x115/0x370
   rxe_dealloc_mw+0x4c/0x80
  Allocated by task 591:
   ib_uverbs_alloc_pd+0x258/0x540
  Freed by task 591:
   ib_dealloc_pd_user+0x174/0x210
   uverbs_free_pd+0x8d/0xc0
   ib_uverbs_dealloc_pd+0x18e/0x1d0

Validate the access flags before mutating any state so the callback either
applies every requested change or none.

Fixes: 544c7f62cf32 ("RDMA/rxe: Implement rereg_user_mr")
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Link: https://patch.msgid.link/46E1D5C0-24BE-4D01-BDB3-634FE09B22C5@doyensec.com
Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/sw/rxe/rxe_verbs.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c
index 9466fed6726b4..da3bad301efab 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.c
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.c
@@ -1326,19 +1326,20 @@ static struct ib_mr *rxe_rereg_user_mr(struct ib_mr *ibmr, int flags,
 	if (err)
 		return ERR_PTR(err);
 
+	if ((flags & IB_MR_REREG_ACCESS) &&
+	    (access & ~RXE_ACCESS_SUPPORTED_MR)) {
+		rxe_err_mr(mr, "access = %#x not supported\n", access);
+		return ERR_PTR(-EOPNOTSUPP);
+	}
+
 	if (flags & IB_MR_REREG_PD) {
 		rxe_put(old_pd);
 		rxe_get(pd);
 		mr->ibmr.pd = ibpd;
 	}
 
-	if (flags & IB_MR_REREG_ACCESS) {
-		if (access & ~RXE_ACCESS_SUPPORTED_MR) {
-			rxe_err_mr(mr, "access = %#x not supported\n", access);
-			return ERR_PTR(-EOPNOTSUPP);
-		}
+	if (flags & IB_MR_REREG_ACCESS)
 		mr->access = access;
-	}
 
 	return NULL;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 030/877] RDMA/rxe: Fix integer overflow in mr_check_range() leading to OOB access
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (28 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 029/877] RDMA/rxe: validate access flags before swapping the MRs PD Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 031/877] firmware: arm_scpi: reject DVFS OPP count above MAX_DVFS_OPPS Greg Kroah-Hartman
                   ` (854 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Gang Yan, Zhu Yanjun, Shukai Ni,
	Leon Romanovsky, Sasha Levin

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

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

From: Gang Yan <yangang@kylinos.cn>

[ Upstream commit d10e2a08799e858d3e71ea4169bcd018f216d444 ]

mr_check_range() validates that [iova, iova+length) falls within the
registered MR range using wraparound-prone arithmetic:

    if (iova < mr->ibmr.iova ||
        iova + length > mr->ibmr.iova + mr->ibmr.length)

A remote peer can craft an RDMA-Write/Read RETH so that iova + length
wraps to 0 (e.g. iova=0xfffffffffffffff8, length=8), bypassing the
check. rxe_mr_iova_to_index() then computes a huge index (int idx, only
guarded by WARN_ON) and rxe_mr_copy_xarray() dereferences
mr->page_info[huge], causing an out-of-bounds read/write and a kernel
oops that is triggerable by an unauthenticated remote peer.

Rewrite the check in overflow-safe form; the first two clauses guarantee
that the subsequent subtractions do not underflow:

    if (iova < mr->ibmr.iova ||
        length > mr->ibmr.length ||
        iova - mr->ibmr.iova > mr->ibmr.length - length)

With the fix, mr_check_range() returns -EINVAL for the crafted iova and
the responder reports REMOTE_ACCESS_ERROR instead of triggering the OOB.

Fixes: 8700e3e7c485 ("Soft RoCE driver")
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Link: https://patch.msgid.link/20260814093740.292954-1-gang.yan@linux.dev
Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
Reviewed-by: Shukai Ni <shukai.ni@kuleuven.be>
Tested-by: Shukai Ni <shukai.ni@kuleuven.be>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/sw/rxe/rxe_mr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c
index da3dee520876a..83e325b76f67d 100644
--- a/drivers/infiniband/sw/rxe/rxe_mr.c
+++ b/drivers/infiniband/sw/rxe/rxe_mr.c
@@ -33,7 +33,8 @@ int mr_check_range(struct rxe_mr *mr, u64 iova, size_t length)
 	case IB_MR_TYPE_USER:
 	case IB_MR_TYPE_MEM_REG:
 		if (iova < mr->ibmr.iova ||
-		    iova + length > mr->ibmr.iova + mr->ibmr.length) {
+		    length > mr->ibmr.length ||
+		    iova - mr->ibmr.iova > mr->ibmr.length - length) {
 			rxe_dbg_mr(mr, "iova/length out of range\n");
 			return -EINVAL;
 		}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 031/877] firmware: arm_scpi: reject DVFS OPP count above MAX_DVFS_OPPS
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (29 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 030/877] RDMA/rxe: Fix integer overflow in mr_check_range() leading to OOB access Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 032/877] clk: scpi: bound-check DVFS index in scpi_dvfs_recalc_rate Greg Kroah-Hartman
                   ` (853 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Xixin Liu, Sudeep Holla, Sasha Levin

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

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

From: Xixin Liu <liuxixin@kylinos.cn>

[ Upstream commit 32471d84a487c7fd74532bc96be56f8028cf4a3f ]

scpi_dvfs_get_info() already rejected a zero opp_count, but still trusted
any larger value from the SCP firmware. The shared-memory reply only holds
MAX_DVFS_OPPS entries in buf.opps[]; a bigger count over-reads that array
and then sizes the allocated OPP table incorrectly (garbage OPPs / OOB).
The missing upper bound dates back to the original SCPI DVFS support.

Reject zero and out-of-range counts in one check and return -EINVAL.

Fixes: 8cb7cf56c9fe ("firmware: add support for ARM System Control and Power Interface(SCPI) protocol")
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
Link: https://patch.msgid.link/022802f0b38f.v2.1785200642.git.liuxixin@kylinos.cn
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/firmware/arm_scpi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
index 2d33771917bb4..ec6f3d0cdd6a1 100644
--- a/drivers/firmware/arm_scpi.c
+++ b/drivers/firmware/arm_scpi.c
@@ -631,8 +631,8 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain)
 	if (ret)
 		return ERR_PTR(ret);
 
-	if (!buf.opp_count)
-		return ERR_PTR(-ENOENT);
+	if (!buf.opp_count || buf.opp_count > MAX_DVFS_OPPS)
+		return ERR_PTR(-EINVAL);
 
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
 	if (!info)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 032/877] clk: scpi: bound-check DVFS index in scpi_dvfs_recalc_rate
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (30 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 031/877] firmware: arm_scpi: reject DVFS OPP count above MAX_DVFS_OPPS Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 033/877] RDMA/rxe: insert mcg into mcg_tree only after rxe_mcast_add() succeeds Greg Kroah-Hartman
                   ` (852 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Xixin Liu, Sudeep Holla, Sasha Levin

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

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

From: Xixin Liu <liuxixin@kylinos.cn>

[ Upstream commit 70f4b78d560e592cbf3325b162424737d032fc1d ]

dvfs_get_idx() may return an out-of-range index if the SCP firmware is
buggy or returns a stale value. Only negative indexes were rejected, so a
large index walked past info->opps and could treat garbage as a clock rate
(KASAN OOB / wrong frequency to consumers). The missing upper bound dates
back to the original SCPI clock driver.

Treat indexes >= opp count as invalid and return 0, same as idx < 0.

Fixes: cd52c2a4b5c4 ("clk: add support for clocks provided by SCP(System Control Processor)")
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
Link: https://patch.msgid.link/04f9ab766e07.v2.1785200642.git.liuxixin@kylinos.cn
Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/clk/clk-scpi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c
index 50ac1cd255785..598dc1fd99ade 100644
--- a/drivers/clk/clk-scpi.c
+++ b/drivers/clk/clk-scpi.c
@@ -85,7 +85,7 @@ static unsigned long scpi_dvfs_recalc_rate(struct clk_hw *hw,
 	int idx = clk->scpi_ops->dvfs_get_idx(clk->id);
 	const struct scpi_opp *opp;
 
-	if (idx < 0)
+	if (idx < 0 || idx >= clk->info->count)
 		return 0;
 
 	opp = clk->info->opps + idx;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 033/877] RDMA/rxe: insert mcg into mcg_tree only after rxe_mcast_add() succeeds
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (31 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 032/877] clk: scpi: bound-check DVFS index in scpi_dvfs_recalc_rate Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 034/877] RDMA/core: Reject unregistering netdevs in ib_get_eth_speed Greg Kroah-Hartman
                   ` (851 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Michael Bommarito, Zhu Yanjun,
	Leon Romanovsky, Sasha Levin

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

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

From: Michael Bommarito <michael.bommarito@gmail.com>

[ Upstream commit 1caceeb2d74bbe88223aea55eb8626b4c5f076fd ]

rxe_get_mcg() publishes a newly allocated multicast group in
rxe->mcg_tree before programming the backing Ethernet multicast address
with rxe_mcast_add(), which runs outside mcg_lock. A local userspace
RDMA client reaches this path with ATTACH_MCAST on a UD QP; if
rxe_mcast_add() then returns an error (for example -ENODEV when the
backing netdev has been removed, or a propagated dev_mc_add() error),
the unwind frees the published group without removing it from the tree.
A later lookup of the same MGID dereferences the freed struct rxe_mcg
from __rxe_lookup_mcg().

Fix this by keeping the new mcg private until rxe_mcast_add() succeeds.
Split the tree publication into __rxe_publish_mcg(), call rxe_mcast_add()
before taking the tree reference, and free the still-private mcg on
failure. Because the group is never visible in mcg_tree until the
multicast address is programmed, no concurrent caller can look it up or
attach a QP to a group that is about to be torn down, so the error path
needs no conditional unwind. If another caller publishes the same MGID
while the address is being programmed, the post-add re-check under
mcg_lock finds the winner; this caller then drops its private object and
balances its own rxe_mcast_add() with rxe_mcast_del() before returning
the winner.

Reproduced by forcing the rxe_mcast_add() error return under KASAN:
without the change the next attach to the same MGID reports a
slab-use-after-free in __rxe_lookup_mcg(); with it the forced failure
returns cleanly. A no-injection attach/detach regression, including a
two-QP shared join/leave and re-attach, stays KASAN- and leak-clean.

Fixes: a926a903b7dc ("RDMA/rxe: Do not call  dev_mc_add/del() under a spinlock")
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Link: https://patch.msgid.link/20260617022728.2770116-1-michael.bommarito@gmail.com
Reviewed-by: Zhu Yanjun <yanjun.zhu@linux.dev>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/sw/rxe/rxe_mcast.c | 50 +++++++++++++++++++--------
 1 file changed, 36 insertions(+), 14 deletions(-)

diff --git a/drivers/infiniband/sw/rxe/rxe_mcast.c b/drivers/infiniband/sw/rxe/rxe_mcast.c
index 07ff47bae31df..c14680c9a5362 100644
--- a/drivers/infiniband/sw/rxe/rxe_mcast.c
+++ b/drivers/infiniband/sw/rxe/rxe_mcast.c
@@ -175,7 +175,9 @@ struct rxe_mcg *rxe_lookup_mcg(struct rxe_dev *rxe, union ib_gid *mgid)
  * @mgid: multicast address as a gid
  * @mcg: new mcg object
  *
- * Context: caller should hold rxe->mcg lock
+ * Initializes the mcg fields. The mcg is private and not yet visible in
+ * mcg_tree, so this may run without rxe->mcg_lock; __rxe_publish_mcg()
+ * makes it visible under the lock once it is ready.
  */
 static void __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid,
 			   struct rxe_mcg *mcg)
@@ -184,13 +186,22 @@ static void __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid,
 	memcpy(&mcg->mgid, mgid, sizeof(mcg->mgid));
 	INIT_LIST_HEAD(&mcg->qp_list);
 	mcg->rxe = rxe;
+}
 
-	/* caller holds a ref on mcg but that will be
-	 * dropped when mcg goes out of scope. We need to take a ref
-	 * on the pointer that will be saved in the red-black tree
-	 * by __rxe_insert_mcg and used to lookup mcg from mgid later.
-	 * Inserting mcg makes it visible to outside so this should
-	 * be done last after the object is ready.
+/**
+ * __rxe_publish_mcg - make a fully initialized mcg visible in mcg_tree
+ * @mcg: the mcg object
+ *
+ * Context: caller must hold rxe->mcg_lock and a reference on mcg
+ */
+static void __rxe_publish_mcg(struct rxe_mcg *mcg)
+{
+	/* caller holds a ref on mcg but that will be dropped when mcg goes
+	 * out of scope. We need to take a ref on the pointer that will be
+	 * saved in the red-black tree by __rxe_insert_mcg and used to lookup
+	 * mcg from mgid later. Inserting mcg makes it visible to outside so
+	 * this is done last after the object is ready and the multicast
+	 * address has been programmed.
 	 */
 	kref_get(&mcg->ref_cnt);
 	__rxe_insert_mcg(mcg);
@@ -228,26 +239,37 @@ static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid)
 		err = -ENOMEM;
 		goto err_dec;
 	}
+	__rxe_init_mcg(rxe, mgid, mcg);
+
+	/* program the multicast address while mcg is still private, before
+	 * it is inserted into mcg_tree. dev_mc_add() may sleep so this must
+	 * run outside mcg_lock. On failure mcg was never published, so a
+	 * plain free is correct and the tree is untouched.
+	 */
+	err = rxe_mcast_add(rxe, mgid);
+	if (err) {
+		kfree(mcg);
+		goto err_dec;
+	}
 
 	spin_lock_bh(&rxe->mcg_lock);
-	/* re-check to see if someone else just added it */
+	/* re-check to see if someone else just added it while we were adding
+	 * the multicast address; if so use theirs and drop ours
+	 */
 	tmp = __rxe_lookup_mcg(rxe, mgid);
 	if (tmp) {
 		spin_unlock_bh(&rxe->mcg_lock);
+		rxe_mcast_del(rxe, mgid);
 		atomic_dec(&rxe->mcg_num);
 		kfree(mcg);
 		return tmp;
 	}
 
-	__rxe_init_mcg(rxe, mgid, mcg);
+	__rxe_publish_mcg(mcg);
 	spin_unlock_bh(&rxe->mcg_lock);
 
-	/* add mcast address outside of lock */
-	err = rxe_mcast_add(rxe, mgid);
-	if (!err)
-		return mcg;
+	return mcg;
 
-	kfree(mcg);
 err_dec:
 	atomic_dec(&rxe->mcg_num);
 	return ERR_PTR(err);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 034/877] RDMA/core: Reject unregistering netdevs in ib_get_eth_speed
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (32 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 033/877] RDMA/rxe: insert mcg into mcg_tree only after rxe_mcast_add() succeeds Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 035/877] IB/iser: reject a remote invalidation of an unregistered direction Greg Kroah-Hartman
                   ` (850 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+5fe14f2ff4ccbace9a26,
	Krystian Kaniewski, Leon Romanovsky, Sasha Levin

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

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

From: Krystian Kaniewski <krystianmkaniewski@gmail.com>

[ Upstream commit ef9fbe1b93f3b617b96e86d5cd76b3fa44514cb5 ]

ib_device_get_netdev() intentionally returns a referenced net_device even
when it is unregistering, so matching and cleanup callers can still find
the association. The reference keeps struct net_device allocated, but does
not guarantee that the device remains operational.

ib_get_eth_speed() uses the returned device operationally by invoking its
ethtool callback. Although that call is made under RTNL, the function does
not verify the registration state first. An asynchronous RDMA port query
can therefore call into a netdev after NETDEV_UNREGISTER and ndo_uninit
have completed.

Check for NETREG_REGISTERED while holding RTNL and return -ENODEV for a
device which is being unregistered. Keeping RTNL across the check and the
ethtool operation prevents unregister from starting between them.

Keep the speed fallback and warning under RTNL as well, so the warning can
safely read netdev->name. Drop the netdev reference before releasing RTNL
once all accesses to the device are complete.

Fixes: d41861942fc5 ("IB/core: Add generic function to extract IB speed from netdev")
Reported-by: syzbot+5fe14f2ff4ccbace9a26@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=5fe14f2ff4ccbace9a26
Signed-off-by: Krystian Kaniewski <krystianmkaniewski@gmail.com>
Link: https://patch.msgid.link/20260812081708.32468-1-krystianmkaniewski@gmail.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/core/verbs.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index d0bd57ac7c6aa..d6fd7db5cbbd7 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -2000,11 +2000,13 @@ int ib_get_eth_speed(struct ib_device *dev, u32 port_num, u16 *speed, u8 *width)
 		return -ENODEV;
 
 	rtnl_lock();
-	rc = __ethtool_get_link_ksettings(netdev, &lksettings);
-	rtnl_unlock();
-
-	dev_put(netdev);
+	if (READ_ONCE(netdev->reg_state) != NETREG_REGISTERED) {
+		dev_put(netdev);
+		rtnl_unlock();
+		return -ENODEV;
+	}
 
+	rc = __ethtool_get_link_ksettings(netdev, &lksettings);
 	if (!rc && lksettings.base.speed != (u32)SPEED_UNKNOWN) {
 		netdev_speed = lksettings.base.speed;
 	} else {
@@ -2013,6 +2015,8 @@ int ib_get_eth_speed(struct ib_device *dev, u32 port_num, u16 *speed, u8 *width)
 			pr_warn("%s speed is unknown, defaulting to %u\n",
 				netdev->name, netdev_speed);
 	}
+	dev_put(netdev);
+	rtnl_unlock();
 
 	ib_get_width_and_speed(netdev_speed, lksettings.lanes,
 			       speed, width);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 035/877] IB/iser: reject a remote invalidation of an unregistered direction
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (33 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 034/877] RDMA/core: Reject unregistering netdevs in ib_get_eth_speed Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 036/877] IB/isert: wait for deferred control PDU completions before releasing the connection Greg Kroah-Hartman
                   ` (849 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yehyeong Lee, Max Gurtovoy,
	Leon Romanovsky, Sasha Levin

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

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

From: Yehyeong Lee <yhlee@isslab.korea.ac.kr>

[ Upstream commit d85f0f0a7c85756fc992c70d869706f19dac9259 ]

A write command whose data is sent entirely as immediate data is not
registered.  iser_reg_mem_fastreg() takes the DMA key path and leaves
rdma_reg[ISER_DIR_OUT].desc at NULL, while iser_dma_map_task_data() has
already set dir[ISER_DIR_OUT].

iser_check_remote_inv() looks at dir[] alone and hands the descriptor to
iser_inv_desc(), which reads desc->sig_protected.  A target that answers
such a command with IB_WR_SEND_WITH_INV faults the initiator.
Leaving those commands unregistered is deliberate.

The same function already terminates the connection when a target sends
a remote invalidation the initiator did not ask for.  A target that
invalidates a direction that was never registered is in the same class,
so give it the same answer.

  Oops: general protection fault, probably for non-canonical address 0xdffffc0000000004: 0000 [#1] SMP KASAN NOPTI
  KASAN: null-ptr-deref in range [0x0000000000000020-0x0000000000000027]
  CPU: 0 UID: 0 PID: 40 Comm: kworker/u8:2 Not tainted 7.2.0-rc5-ISERHOST-gf5098b6bae76-dirty #3 PREEMPT(lazy)
  Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
  Workqueue: rxe_wq do_work
  RIP: 0010:iser_task_rsp+0x6d6/0xec0
  Code: 48 c1 ea 03 80 3c 02 00 0f 85 ba 06 00 00 48 8b 9b 78 01 00 00 48 b8 00 00 00 00 00 fc ff df 48 8d 7b 20 48 89 fa 48 c1 ea 03 <0f> b6 04 02 84 c0 74 06 0f 8e 76 06 00 00 80 7b 20 00 0f 84 3d 04
  RSP: 0018:ffff88811b008db8 EFLAGS: 00010202
  RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000001848
  RDX: 0000000000000004 RSI: 1ffff11021587b12 RDI: 0000000000000020
  RBP: ffff88810adc1ae4 R08: ffff888109b7f860 R09: ffffffff90a922c0
  R10: ffff88810adc1a1c R11: 000000000000003c R12: ffff888109b7f800
  R13: ffff88810adc1acc R14: ffff888109b7f820 R15: 0000000000000000
  FS:  0000000000000000(0000) GS:ffff88818a676000(0000) knlGS:0000000000000000
  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  CR2: 00000000005afe2b CR3: 000000010af23005 CR4: 0000000000770ef0
  PKRU: 55555554
  Call Trace:
   <IRQ>
   __ib_process_cq+0xe1/0x390
   ib_poll_handler+0x6e/0x200
   irq_poll_softirq+0x1df/0x480
   ? clockevents_program_event+0x2ba/0x860
   ? __pfx_irq_poll_softirq+0x10/0x10
   handle_softirqs+0x18e/0x590
   ? __pfx_handle_softirqs+0x10/0x10
   ? __hrtimer_rearm_deferred+0x156/0x450
   do_softirq+0x3b/0x60
   </IRQ>
   <TASK>
   __local_bh_enable_ip+0x61/0x70
   __alloc_skb+0x732/0x890
   ? _raw_spin_lock_irqsave+0x85/0xe0
   ? __pfx___alloc_skb+0x10/0x10
   ? _raw_read_unlock_irqrestore+0x16/0x50
   rxe_init_packet+0x16b/0x4f0
   prepare_ack_packet+0xb8/0x830
   rxe_receiver+0x499/0x9980
   ? __pfx_rxe_receiver+0x10/0x10
   ? rxe_completer+0x29e5/0x38c0
   ? hrtimer_start_range_ns_common+0x75f/0x1730
   ? hrtimer_start_range_ns+0xa6/0x2c0
   ? __pfx__raw_spin_lock_irqsave+0x10/0x10
   ? __pfx_rxe_receiver+0x10/0x10
   do_work+0x144/0x470
   process_one_work+0x633/0x1030
   ? assign_work+0x11d/0x370
   worker_thread+0x45b/0xd10
   ? __pfx_worker_thread+0x10/0x10
   kthread+0x2c6/0x3b0
   ? recalc_sigpending+0x15c/0x1e0
   ? __pfx_kthread+0x10/0x10
   ret_from_fork+0x36e/0x5a0
   ? __pfx_ret_from_fork+0x10/0x10
   ? __switch_to+0x572/0xdd0
   ? __pfx_kthread+0x10/0x10
   ret_from_fork_asm+0x1a/0x30
   </TASK>
  Modules linked in:
  ---[ end trace 0000000000000000 ]---

Fixes: 59caaed7a72a ("IB/iser: Support the remote invalidation exception")
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Link: https://patch.msgid.link/20260819010804.641772-1-yhlee@isslab.korea.ac.kr
Reviewed-by: Max Gurtovoy <mgurtovoy@nvidia.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/ulp/iser/iser_initiator.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c
index f5f090dc4f1eb..cf234ddbaaad5 100644
--- a/drivers/infiniband/ulp/iser/iser_initiator.c
+++ b/drivers/infiniband/ulp/iser/iser_initiator.c
@@ -599,11 +599,8 @@ static int iser_check_remote_inv(struct iser_conn *iser_conn, struct ib_wc *wc,
 		iser_dbg("conn %p: remote invalidation for rkey %#x\n",
 			 iser_conn, rkey);
 
-		if (unlikely(!iser_conn->snd_w_inv)) {
-			iser_err("conn %p: unexpected remote invalidation, terminating connection\n",
-				 iser_conn);
-			return -EPROTO;
-		}
+		if (unlikely(!iser_conn->snd_w_inv))
+			goto bad_inv;
 
 		task = iscsi_itt_to_ctask(iser_conn->iscsi_conn, hdr->itt);
 		if (likely(task)) {
@@ -612,12 +609,16 @@ static int iser_check_remote_inv(struct iser_conn *iser_conn, struct ib_wc *wc,
 
 			if (iser_task->dir[ISER_DIR_IN]) {
 				desc = iser_task->rdma_reg[ISER_DIR_IN].desc;
+				if (unlikely(!desc))
+					goto bad_inv;
 				if (unlikely(iser_inv_desc(desc, rkey)))
 					return -EINVAL;
 			}
 
 			if (iser_task->dir[ISER_DIR_OUT]) {
 				desc = iser_task->rdma_reg[ISER_DIR_OUT].desc;
+				if (unlikely(!desc))
+					goto bad_inv;
 				if (unlikely(iser_inv_desc(desc, rkey)))
 					return -EINVAL;
 			}
@@ -628,6 +629,11 @@ static int iser_check_remote_inv(struct iser_conn *iser_conn, struct ib_wc *wc,
 	}
 
 	return 0;
+
+bad_inv:
+	iser_err("conn %p: unexpected remote invalidation, terminating connection\n",
+		 iser_conn);
+	return -EPROTO;
 }
 
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 036/877] IB/isert: wait for deferred control PDU completions before releasing the connection
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (34 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 035/877] IB/iser: reject a remote invalidation of an unregistered direction Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 037/877] RDMA/mad: Fix receive buffer leak when PKey enforcement fails Greg Kroah-Hartman
                   ` (848 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yehyeong Lee, Leon Romanovsky,
	Sasha Levin

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

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

From: Yehyeong Lee <yhlee@isslab.korea.ac.kr>

[ Upstream commit a8fe3dfce8c0d8a76dc3d8486a5bff5feebe156f ]

isert_send_done() hands ISTATE_SEND_TASKMGTRSP, ISTATE_SEND_REJECT and
ISTATE_SEND_TEXTRSP completions off to isert_comp_wq and returns.  The work
item then runs isert_completion_put() -> isert_put_cmd(), which reads
isert_conn->conn and takes conn->cmd_lock.

Nothing orders that work item against teardown.  isert_wait_conn() queues
isert_release_work, which frees isert_conn, and iscsit_close_connection()
frees the iscsit_conn right after it returns, so the queued work can run
against freed memory.

Count the deferred control PDU completions per connection and let
isert_wait_conn() wait for them before the release work is queued.

ISTATE_SEND_LOGOUTRSP is deliberately not counted: that branch runs
iscsit_logout_post_handler(), which ends up waiting for
conn->conn_wait_comp, and that completion is only sent by
iscsit_close_connection() after it has called iscsit_wait_conn().
Waiting for it here would deadlock.  Its wait stays the existing
isert_wait4logout().

The splat below is from a kernel with tracing printk()s and an msleep(200)
injected into isert_do_control_comp() to widen the window:

  BUG: KASAN: slab-use-after-free in isert_put_cmd+0x53d/0x620
  Read of size 8 at addr ffff8881054f1038 by task kworker/u17:1/182

  CPU: 0 UID: 0 PID: 182 Comm: kworker/u17:1 Tainted: G    B               7.2.0-rc5-TWIDE-gb8babf08acc7 #1 PREEMPT(lazy)
  Tainted: [B]=BAD_PAGE
  Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
  Workqueue: isert_comp_wq isert_do_control_comp
  Call Trace:
   <TASK>
   dump_stack_lvl+0x53/0x70
   print_report+0xd0/0x630
   ? __pfx__raw_spin_lock_irqsave+0x10/0x10
   ? _raw_spin_unlock_irqrestore+0x3e/0x70
   ? isert_put_cmd+0x53d/0x620
   kasan_report+0xce/0x100
   ? isert_put_cmd+0x53d/0x620
   isert_put_cmd+0x53d/0x620
   ? isert_completion_put+0x305/0x330
   ? isert_do_control_comp+0x2ef/0x310
   process_one_work+0x633/0x1030
   ? assign_work+0x11d/0x370
   worker_thread+0x45b/0xd10
   ? __pfx_worker_thread+0x10/0x10
   ? __pfx_worker_thread+0x10/0x10
   kthread+0x2c6/0x3b0
   ? recalc_sigpending+0x15c/0x1e0
   ? __pfx_kthread+0x10/0x10
   ret_from_fork+0x36e/0x5a0
   ? __pfx_ret_from_fork+0x10/0x10
   ? __switch_to+0x572/0xdd0
   ? __pfx_kthread+0x10/0x10
   ret_from_fork_asm+0x1a/0x30
   </TASK>

  Allocated by task 48:
   kasan_save_stack+0x33/0x60
   kasan_save_track+0x14/0x30
   __kasan_kmalloc+0x8f/0xa0
   __kmalloc_cache_noprof+0x158/0x370
   isert_cma_handler+0x1e3/0x2ae0
   cma_cm_event_handler+0x3e/0x240
   cma_ib_req_handler+0x17d9/0x4490
   cm_process_work+0x41/0x330
   cm_work_handler+0x5727/0xc160
   process_one_work+0x633/0x1030
   worker_thread+0x45b/0xd10
   kthread+0x2c6/0x3b0
   ret_from_fork+0x36e/0x5a0
   ret_from_fork_asm+0x1a/0x30

  Freed by task 184:
   kasan_save_stack+0x33/0x60
   kasan_save_track+0x14/0x30
   kasan_save_free_info+0x3b/0x60
   __kasan_slab_free+0x43/0x70
   kfree+0x121/0x380
   iscsit_close_connection+0x7cf/0x1e60
   iscsit_take_action_for_connection_exit+0x1b6/0x360
   iscsi_target_tx_thread+0x472/0x690
   kthread+0x2c6/0x3b0
   ret_from_fork+0x36e/0x5a0
   ret_from_fork_asm+0x1a/0x30

Fixes: b8d26b3be8b3 ("iser-target: Add iSCSI Extensions for RDMA (iSER) target driver")
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Link: https://patch.msgid.link/20260821080620.1694119-1-yhlee@isslab.korea.ac.kr
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/ulp/isert/ib_isert.c | 22 ++++++++++++++++++++++
 drivers/infiniband/ulp/isert/ib_isert.h |  2 ++
 2 files changed, 24 insertions(+)

diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 6483a55170cd1..b3fc753982a38 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -21,6 +21,7 @@
 #include <target/target_core_fabric.h>
 #include <target/iscsi/iscsi_transport.h>
 #include <linux/semaphore.h>
+#include <linux/wait_bit.h>
 
 #include "ib_isert.h"
 
@@ -311,6 +312,7 @@ isert_init_conn(struct isert_conn *isert_conn)
 	init_completion(&isert_conn->login_req_comp);
 	init_waitqueue_head(&isert_conn->rem_wait);
 	kref_init(&isert_conn->kref);
+	atomic_set(&isert_conn->ctrl_comp_cnt, 0);
 	mutex_init(&isert_conn->mutex);
 	INIT_WORK(&isert_conn->release_work, isert_release_work);
 }
@@ -1697,6 +1699,8 @@ isert_do_control_comp(struct work_struct *work)
 	struct isert_conn *isert_conn = isert_cmd->conn;
 	struct ib_device *ib_dev = isert_conn->cm_id->device;
 	struct iscsit_cmd *cmd = isert_cmd->iscsit_cmd;
+	/* The switch below may free isert_cmd. */
+	bool counted = isert_cmd->ctrl_counted;
 
 	isert_dbg("Cmd %p i_state %d\n", isert_cmd, cmd->i_state);
 
@@ -1718,6 +1722,14 @@ isert_do_control_comp(struct work_struct *work)
 		dump_stack();
 		break;
 	}
+
+	/*
+	 * The count is what keeps isert_conn alive, so drop it last.  The wait
+	 * queue lives in the global hash table, not in isert_conn, so this is
+	 * safe even if the waiter has already freed the connection.
+	 */
+	if (counted && atomic_dec_and_test(&isert_conn->ctrl_comp_cnt))
+		wake_up_var(&isert_conn->ctrl_comp_cnt);
 }
 
 static void
@@ -1761,6 +1773,12 @@ isert_send_done(struct ib_cq *cq, struct ib_wc *wc)
 	case ISTATE_SEND_TEXTRSP:
 		isert_unmap_tx_desc(tx_desc, ib_dev);
 
+		/* Paired with the wait in isert_wait_conn(). */
+		isert_cmd->ctrl_counted =
+			isert_cmd->iscsit_cmd->i_state != ISTATE_SEND_LOGOUTRSP;
+		if (isert_cmd->ctrl_counted)
+			atomic_inc(&isert_conn->ctrl_comp_cnt);
+
 		INIT_WORK(&isert_cmd->comp_work, isert_do_control_comp);
 		queue_work(isert_comp_wq, &isert_cmd->comp_work);
 		return;
@@ -2605,6 +2623,10 @@ static void isert_wait_conn(struct iscsit_conn *conn)
 	isert_wait4cmds(conn);
 	isert_wait4logout(isert_conn);
 
+	/* Paired with the count taken in isert_send_done(). */
+	wait_var_event(&isert_conn->ctrl_comp_cnt,
+		       !atomic_read(&isert_conn->ctrl_comp_cnt));
+
 	queue_work(isert_release_wq, &isert_conn->release_work);
 }
 
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h
index 0bac5aa66c802..519b17e54bd34 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.h
+++ b/drivers/infiniband/ulp/isert/ib_isert.h
@@ -153,6 +153,7 @@ struct isert_cmd {
 	struct work_struct	comp_work;
 	struct scatterlist	sg;
 	bool			ctx_init_done;
+	bool			ctrl_counted;
 };
 
 static inline struct isert_cmd *tx_desc_to_cmd(struct iser_tx_desc *desc)
@@ -187,6 +188,7 @@ struct isert_conn {
 	struct mutex		mutex;
 	struct kref		kref;
 	struct work_struct	release_work;
+	atomic_t		ctrl_comp_cnt;
 	bool                    logout_posted;
 	bool                    snd_w_inv;
 	wait_queue_head_t	rem_wait;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 037/877] RDMA/mad: Fix receive buffer leak when PKey enforcement fails
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (35 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 036/877] IB/isert: wait for deferred control PDU completions before releasing the connection Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 038/877] RDMA/irdma: Enforce local fence for IB_WR_REG_MR Greg Kroah-Hartman
                   ` (847 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Li RongQing, Leon Romanovsky,
	Sasha Levin

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

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

From: Li RongQing <lirongqing@baidu.com>

[ Upstream commit 3476c28c9addfa253f505e6bd87f1f5598b961d0 ]

ib_mad_complete_recv() initializes mad_recv_wc->rmpp_list and then runs
ib_mad_enforce_security() before linking recv_buf onto that list.  On
failure it calls ib_free_recv_mad(), which only walks rmpp_list and frees
the ib_mad_private of every buffer found there.  As the list is still
empty at that point, nothing is freed at all.

The caller cannot clean up either: ib_mad_recv_done() sets recv to NULL
right after ib_mad_complete_recv() returns, assuming the MAD layer took
ownership of the buffer.  Every MAD that fails the PKey check therefore
leaks one ib_mad_private (about 300 bytes per IB port MAD, ~2K for OPA),
and a remote node can trigger this repeatedly by sending MADs with a
wrong PKey.

Link recv_buf onto rmpp_list right after the list is initialized, so the
error path has something to free.

Fixes: 47a2b338fe63 ("IB/core: Enforce security on management datagrams")
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Link: https://patch.msgid.link/20260826073216.2367-1-lirongqing@baidu.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/core/mad.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 96c1fd8039fb5..21f482e0243f2 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -1805,6 +1805,8 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
 	int ret;
 
 	INIT_LIST_HEAD(&mad_recv_wc->rmpp_list);
+	list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
+
 	ret = ib_mad_enforce_security(mad_agent_priv,
 				      mad_recv_wc->wc->pkey_index);
 	if (ret) {
@@ -1813,7 +1815,6 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
 		return;
 	}
 
-	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);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 038/877] RDMA/irdma: Enforce local fence for IB_WR_REG_MR
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (36 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 037/877] RDMA/mad: Fix receive buffer leak when PKey enforcement fails Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 039/877] RDMA/rtrs-clt: Fix CQ pool leak when connect is interrupted Greg Kroah-Hartman
                   ` (846 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jacob Moroni, Leon Romanovsky,
	Sasha Levin

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

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

From: Jacob Moroni <jmoroni@google.com>

[ Upstream commit 3fb905f07ea45b31c8f67ba6e4668de46f527e65 ]

Enforce local fence for IB_WR_REG_MR to avoid spurious
FASTREG_VALID_MKEY async events during heavy invalidation
and registration activity.

Commit 69e8e429bca2 ("RDMA/irdma: Enforce local fence for LOCAL_INV WRs")
was very similar, but was not sufficient to prevent all occurrences
of these async events.

Fixes: b48c24c2d710 ("RDMA/irdma: Implement device supported verb APIs")
Signed-off-by: Jacob Moroni <jmoroni@google.com>
Link: https://patch.msgid.link/20260901160014.2026285-1-jmoroni@google.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/hw/irdma/verbs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c
index d8e101fc74ff7..97fa345635524 100644
--- a/drivers/infiniband/hw/irdma/verbs.c
+++ b/drivers/infiniband/hw/irdma/verbs.c
@@ -3571,7 +3571,7 @@ static int irdma_post_send(struct ib_qp *ibqp,
 			stag_info.total_len = iwmr->ibmr.length;
 			stag_info.reg_addr_pa = *palloc->level1.addr;
 			stag_info.first_pm_pbl_index = palloc->level1.idx;
-			stag_info.local_fence = ib_wr->send_flags & IB_SEND_FENCE;
+			stag_info.local_fence = true;
 			if (iwmr->npages > IRDMA_MIN_PAGES_PER_FMR)
 				stag_info.chunk_size = 1;
 			err = irdma_sc_mr_fast_register(&iwqp->sc_qp, &stag_info,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 039/877] RDMA/rtrs-clt: Fix CQ pool leak when connect is interrupted
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (37 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 038/877] RDMA/irdma: Enforce local fence for IB_WR_REG_MR Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 040/877] dmaengine: sprd: Fix runtime PM reference leak in probe Greg Kroah-Hartman
                   ` (845 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+d396918a29afb8543e1c,
	Quanye Yang, Jack Wang, Leon Romanovsky, Sasha Levin

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

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

From: Quanye Yang <quanyeyang@proton.me>

[ Upstream commit 2ae16aaa78b5edc6e6d0904c84fd9cdfb762bcda ]

The client borrows shared CQ credits in the ADDR_RESOLVED handler via
ib_cq_pool_get(), before the peer is connected. create_cm() can return
-ERESTARTSYS from wait_event_interruptible_timeout() without destroying
the CM ID. The init_conns() and stop-and-destroy paths then call
destroy_con_cq_qp() while cq is still NULL (no PUT) and only afterwards
rdma_destroy_id().

CMA serializes the handler against rdma_destroy_id() with handler_mutex,
but that does not order the GET against destroy_con_cq_qp(). If
ADDR_RESOLVED has already passed the DESTROYING check, it can take
con_mutex, GET credits, and then lose the con to kfree. Device
unregister later hits WARN_ON(cq->cqe_used) in ib_cq_pool_cleanup().

Set a per-connection flag under con_mutex before CQ/QP teardown so a
racing ADDR_RESOLVED cannot borrow credits after teardown has begun.

Reported-by: syzbot+d396918a29afb8543e1c@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=d396918a29afb8543e1c
Fixes: 3b89e92c2a95 ("RDMA/rtrs: Use new shared CQ mechanism")
Signed-off-by: Quanye Yang <quanyeyang@proton.me>
Link: https://patch.msgid.link/20260830-rdma-rtrs-clt-cq-pool-leak-v1-1-b169434fd3df@proton.me
Reviewed-by: Jack Wang <jinpu.wang@cloud.ionos.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/ulp/rtrs/rtrs-clt.c | 8 ++++++++
 drivers/infiniband/ulp/rtrs/rtrs-clt.h | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
index 8fa1d72bd20a4..fea3b17611c50 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
@@ -1738,6 +1738,8 @@ static void destroy_con_cq_qp(struct rtrs_clt_con *con)
 	/*
 	 * Be careful here: destroy_con_cq_qp() can be called even
 	 * create_con_cq_qp() failed, see comments there.
+	 * Caller must set con->destroyed under this lock first so a
+	 * racing ADDR_RESOLVED cannot ib_cq_pool_get() after we PUT/SKIP.
 	 */
 	lockdep_assert_held(&con->con_mutex);
 	rtrs_cq_qp_destroy(&con->c);
@@ -1772,6 +1774,10 @@ static int rtrs_rdma_addr_resolved(struct rtrs_clt_con *con)
 	int err;
 
 	mutex_lock(&con->con_mutex);
+	if (con->destroyed) {
+		mutex_unlock(&con->con_mutex);
+		return -ECONNABORTED;
+	}
 	err = create_con_cq_qp(con);
 	mutex_unlock(&con->con_mutex);
 	if (err) {
@@ -2202,6 +2208,7 @@ static void rtrs_clt_stop_and_destroy_conns(struct rtrs_clt_path *clt_path)
 			break;
 		con = to_clt_con(clt_path->s.con[cid]);
 		mutex_lock(&con->con_mutex);
+		con->destroyed = true;
 		destroy_con_cq_qp(con);
 		mutex_unlock(&con->con_mutex);
 		destroy_cm(con);
@@ -2368,6 +2375,7 @@ static int init_conns(struct rtrs_clt_path *clt_path)
 		if (con->c.cm_id) {
 			stop_cm(con);
 			mutex_lock(&con->con_mutex);
+			con->destroyed = true;
 			destroy_con_cq_qp(con);
 			mutex_unlock(&con->con_mutex);
 			destroy_cm(con);
diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.h b/drivers/infiniband/ulp/rtrs/rtrs-clt.h
index 0f57759b3080f..e1e7c7adc9470 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.h
+++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.h
@@ -75,6 +75,8 @@ struct rtrs_clt_con {
 	unsigned int		cpu;
 	struct mutex		con_mutex;
 	int			cm_err;
+	/* Set under con_mutex before CQ/QP teardown. */
+	bool			destroyed;
 };
 
 /**
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 040/877] dmaengine: sprd: Fix runtime PM reference leak in probe
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (38 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 039/877] RDMA/rtrs-clt: Fix CQ pool leak when connect is interrupted Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 041/877] wifi: virt_wifi: free skb when disconnected Greg Kroah-Hartman
                   ` (844 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ruoyu Wang, Frank Li, Baolin Wang,
	Vinod Koul, Sasha Levin

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

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

From: Ruoyu Wang <ruoyuw560@gmail.com>

[ Upstream commit a7df136ec529ee49a789c5029bc37b98b0d4bedd ]

pm_runtime_get_sync() increments a device's usage counter even when it
fails. sprd_dma_probe() currently jumps directly to controller clock
cleanup on that error, bypassing both pm_runtime_put_noidle() and
pm_runtime_disable(). This can happen if the preceding unchecked
pm_runtime_set_active() fails and the following runtime-resume attempt
also returns an error.

Enter the existing runtime-PM unwind path instead. This drops the
reference without idling the partially initialized device, disables
runtime PM, and then releases the controller clocks. The success path
and propagated error code are unchanged.

This issue was found by a static analysis checker and confirmed by manual
source review.

Fixes: 9b3b8171f7f4 ("dmaengine: sprd: Add Spreadtrum DMA driver")
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Link: https://patch.msgid.link/20260813153149.3953497-1-ruoyuw560@gmail.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/dma/sprd-dma.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c
index 3f54ff37c5e05..f000d5a5add52 100644
--- a/drivers/dma/sprd-dma.c
+++ b/drivers/dma/sprd-dma.c
@@ -1212,7 +1212,7 @@ static int sprd_dma_probe(struct platform_device *pdev)
 
 	ret = pm_runtime_get_sync(&pdev->dev);
 	if (ret < 0)
-		goto err_rpm;
+		goto err_register;
 
 	ret = dma_async_device_register(&sdev->dma_dev);
 	if (ret < 0) {
@@ -1234,7 +1234,6 @@ static int sprd_dma_probe(struct platform_device *pdev)
 err_register:
 	pm_runtime_put_noidle(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-err_rpm:
 	sprd_dma_disable(sdev);
 	return ret;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 041/877] wifi: virt_wifi: free skb when disconnected
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (39 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 040/877] dmaengine: sprd: Fix runtime PM reference leak in probe Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 042/877] wifi: mwifiex: fix IRQ leak using wrong index in MSI-X error path Greg Kroah-Hartman
                   ` (843 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mariano Baragiola, Johannes Berg,
	Sasha Levin

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

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

From: Mariano Baragiola <mbaragiola@linux.com>

[ Upstream commit f9edf7cf63b96d2b776fca8d258d3c5256e40c8e ]

When the simulated link is disconnected, virt_wifi_start_xmit() returns
NET_XMIT_DROP without freeing the skb. dev_hard_start_xmit() treats this
return value as consumed, so every packet sent while disconnected leaks its
skb.

Free the skb before returning the drop status.

Fixes: c7cdba31ed8b ("mac80211-next: rtnetlink wifi simulation device")
Signed-off-by: Mariano Baragiola <mbaragiola@linux.com>
Link: https://patch.msgid.link/20260809124947.3590270-1-mbaragiola@linux.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/wireless/virtual/virt_wifi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/virtual/virt_wifi.c b/drivers/net/wireless/virtual/virt_wifi.c
index 976edacb689de..056d375e3f41f 100644
--- a/drivers/net/wireless/virtual/virt_wifi.c
+++ b/drivers/net/wireless/virtual/virt_wifi.c
@@ -432,6 +432,7 @@ static netdev_tx_t virt_wifi_start_xmit(struct sk_buff *skb,
 	priv->tx_packets++;
 	if (!priv->is_connected) {
 		priv->tx_failed++;
+		dev_kfree_skb_any(skb);
 		return NET_XMIT_DROP;
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 042/877] wifi: mwifiex: fix IRQ leak using wrong index in MSI-X error path
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (40 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 041/877] wifi: virt_wifi: free skb when disconnected Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 043/877] wifi: libipw: reject too-short beacon and probe responses Greg Kroah-Hartman
                   ` (842 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Peng Hao, Johannes Berg, Sasha Levin

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

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

From: Peng Hao <flyingpenghao@gmail.com>

[ Upstream commit a3d722190cdef18da4878b5efc27c3c386dda248 ]

mwifiex_pcie_request_irq() registers each MSI-X vector with a per-index
dev_id (&card->msix_ctx[i]). On a request_irq() failure the cleanup loop
"for (j = 0; j < i; j++)" frees msix_entries[j].vector but passes the
failed index's &card->msix_ctx[i] as the dev_id. free_irq() matches on
(irq, dev_id), so it fails to find the action registered with
&card->msix_ctx[j]: the already-requested IRQ j is not freed (leaked) and
free_irq() warns about freeing a non-existent IRQ. Use &card->msix_ctx[j].

Fixes: 99074fc1e67b ("mwifiex: enable pcie MSIx interrupt mode support")
Signed-off-by: Peng Hao <flyingpeng@tencent.com>
Link: https://patch.msgid.link/20260828111531.56723-1-flyingpeng@tencent.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/wireless/marvell/mwifiex/pcie.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 5f997becdbaa2..d36d431f53679 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -3068,7 +3068,7 @@ static int mwifiex_pcie_request_irq(struct mwifiex_adapter *adapter)
 					    ret);
 				for (j = 0; j < i; j++)
 					free_irq(card->msix_entries[j].vector,
-						 &card->msix_ctx[i]);
+						 &card->msix_ctx[j]);
 				pci_disable_msix(pdev);
 			} else {
 				mwifiex_dbg(adapter, MSG, "MSIx enabled!");
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 043/877] wifi: libipw: reject too-short beacon and probe responses
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (41 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 042/877] wifi: mwifiex: fix IRQ leak using wrong index in MSI-X error path Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 044/877] wifi: libipw: reject too-short association responses Greg Kroah-Hartman
                   ` (841 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Shmulik Cohen, Johannes Berg,
	Sasha Levin

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

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

From: Shmulik Cohen <anuk909@gmail.com>

[ Upstream commit 5ce5721e8cbe3e80db8f43851cc2a2a92485ef4b ]

libipw_process_probe_response() and the libipw_network_init() call it
makes assume the frame contains the full 36-byte beacon and probe
response prefix, but the ipw2100 and ipw2200 receive paths only
establish that a management frame carries the generic 24-byte
three-address header.

libipw_network_init() then computes the information element length as

	stats->len - sizeof(*beacon)

stats->len is a u16 and sizeof() has type size_t, so the subtraction is
evaluated as size_t and wraps instead of going negative.  Truncating
that to the u16 length parameter of libipw_parse_info_param() yields
65524 for a 24-byte beacon, and the parser then walks the receive
buffer as if it held almost 64 KiB of information elements, reading
past the allocation.

Reject the frame before any fixed field is touched.

Found by an AI-assisted review of length arithmetic in management frame
parsers.  Verified with a KUnit case under Generic KASAN on arm64 under
QEMU; I do not have the hardware, so it is not tested on a real device.

Fixes: b453872c35cf ("[NET] ieee80211 subsystem")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Shmulik Cohen <anuk909@gmail.com>
Link: https://patch.msgid.link/20260812190412.18333-2-anuk909@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/wireless/intel/ipw2x00/libipw_rx.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
index 2220a9814c8a6..33f5dbe274c74 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
@@ -1514,6 +1514,9 @@ static void libipw_process_probe_response(struct libipw_device
 #endif
 	unsigned long flags;
 
+	if (stats->len < sizeof(*beacon))
+		return;
+
 	LIBIPW_DEBUG_SCAN("'%*pE' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
 		     info_element->len, info_element->data,
 		     beacon->header.addr3,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 044/877] wifi: libipw: reject too-short association responses
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (42 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 043/877] wifi: libipw: reject too-short beacon and probe responses Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 045/877] IB/IPoIB: Avoid restoring OPER_UP after multicast flush Greg Kroah-Hartman
                   ` (840 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Shmulik Cohen, Johannes Berg,
	Sasha Levin

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

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

From: Shmulik Cohen <anuk909@gmail.com>

[ Upstream commit adb7118b7d2cfd7e8213c17d7d2829f353017754 ]

libipw_handle_assoc_resp() reads the capability, status and aid fields
of the 30-byte association response prefix and then computes the
information element length as

	stats->len - sizeof(*frame)

stats->len is a u16 and sizeof() has type size_t, so the subtraction is
evaluated as size_t and wraps instead of going negative.  Truncating
that to the u16 length parameter of libipw_parse_info_param() turns a
frame shorter than the fixed fields into a length near 64 KiB, and the
parser then reads past the receive buffer.

Both the ipw2100 and ipw2200 management receive paths reach this
function having established only that the frame carries the generic
24-byte three-address header.

Reject the frame before any fixed field is touched.

Found by an AI-assisted review of length arithmetic in management frame
parsers.  Verified with a KUnit case under Generic KASAN on arm64 under
QEMU; I do not have the hardware, so it is not tested on a real device.

Fixes: 9e8571affd1c ("[PATCH] ieee80211: Add QoS (WME) support to the ieee80211 subsystem")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Shmulik Cohen <anuk909@gmail.com>
Link: https://patch.msgid.link/20260812190412.18333-3-anuk909@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/wireless/intel/ipw2x00/libipw_rx.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
index 33f5dbe274c74..762ed2704bf65 100644
--- a/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/intel/ipw2x00/libipw_rx.c
@@ -1302,6 +1302,9 @@ static int libipw_handle_assoc_resp(struct libipw_device *ieee, struct libipw_as
 	struct libipw_network *network = &network_resp;
 	struct net_device *dev = ieee->dev;
 
+	if (stats->len < sizeof(*frame))
+		return 1;
+
 	network->flags = 0;
 	network->qos_data.active = 0;
 	network->qos_data.supported = 0;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 045/877] IB/IPoIB: Avoid restoring OPER_UP after multicast flush
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (43 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 044/877] wifi: libipw: reject too-short association responses Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 046/877] wifi: cfg80211: dont get the radio mask for netdev-less wdevs Greg Kroah-Hartman
                   ` (839 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ben Davies, Carolina Jubran,
	Cosmin Ratiu, Edward Srouji, Leon Romanovsky, Sasha Levin

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

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

From: Carolina Jubran <cjubran@nvidia.com>

[ Upstream commit 9a141d3dc869d18b2eab35e999f4790a9b84e40f ]

ipoib_ib_dev_flush_light() temporarily clears IPOIB_FLAG_OPER_UP to
prevent multicast joins while ipoib_mcast_dev_flush() is running, and
restores the flag afterwards if it was previously set.

This restore races with ipoib_ib_dev_down(). If the interface is brought
down while the flush is in progress, ipoib_ib_dev_down() clears
IPOIB_FLAG_OPER_UP, but the flush path may set it again after the device
has already gone down.

Since commit 894021a75291 ("IB/ipoib: Make the carrier_on_task race
aware"), ipoib_mcast_carrier_on_task() relies on IPOIB_FLAG_OPER_UP
being cleared to terminate its rtnl_trylock() retry loop. If the flag is
left set after shutdown, the workqueue retries forever, causing teardown
to deadlock when ipoib_ndo_uninit() waits in destroy_workqueue() while
holding RTNL.

Instead of overloading IPOIB_FLAG_OPER_UP to block multicast joins
during a light flush, introduce a dedicated IPOIB_FLAG_MCAST_FLUSH flag.
Use it together with IPOIB_FLAG_OPER_UP to determine whether multicast
joins are allowed, avoiding the race with device shutdown.

Fixes: 344bacca8cd8 ("IB/ipoib: Don't allow MC joins during light MC flush")
Reported-by: Ben Davies <ben.davies@gresearch.co.uk>
Signed-off-by: Carolina Jubran <cjubran@nvidia.com>
Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
Signed-off-by: Edward Srouji <edwards@nvidia.com>
Link: https://patch.msgid.link/20260902-avoid-rest-oper-up-v1-1-04fcd4916cae@nvidia.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/ulp/ipoib/ipoib.h           |  7 +++++++
 drivers/infiniband/ulp/ipoib/ipoib_ib.c        | 12 +++++++-----
 drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 16 ++++++++--------
 3 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index abe0522b7df46..ee23b8d37b977 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -87,6 +87,7 @@ enum {
 	IPOIB_FLAG_INITIALIZED	  = 1,
 	IPOIB_FLAG_ADMIN_UP	  = 2,
 	IPOIB_PKEY_ASSIGNED	  = 3,
+	IPOIB_FLAG_MCAST_FLUSH	  = 4,
 	IPOIB_FLAG_SUBINTERFACE	  = 5,
 	IPOIB_STOP_REAPER	  = 7,
 	IPOIB_FLAG_ADMIN_CM	  = 9,
@@ -419,6 +420,12 @@ struct ipoib_dev_priv {
 	const struct net_device_ops	*rn_ops;
 };
 
+static inline bool ipoib_mcast_allowed(struct ipoib_dev_priv *priv)
+{
+	return test_bit(IPOIB_FLAG_OPER_UP, &priv->flags) &&
+	       !test_bit(IPOIB_FLAG_MCAST_FLUSH, &priv->flags);
+}
+
 struct ipoib_ah {
 	struct net_device *dev;
 	struct ib_ah	  *ah;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index 5cde275daa941..76850a7d300bb 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -1235,17 +1235,19 @@ static void __ipoib_ib_dev_flush(struct ipoib_dev_priv *priv,
 	}
 
 	if (level == IPOIB_FLUSH_LIGHT) {
-		int oper_up;
 		ipoib_mark_paths_invalid(dev);
-		/* Set IPoIB operation as down to prevent races between:
+		/* Set MCAST_FLUSH to prevent races between:
 		 * the flush flow which leaves MCG and on the fly joins
 		 * which can happen during that time. mcast restart task
 		 * should deal with join requests we missed.
+		 *
+		 * Do not clear OPER_UP for this; restoring it races with
+		 * ipoib_ib_dev_down() and can leave OPER_UP set after the
+		 * device is down.
 		 */
-		oper_up = test_and_clear_bit(IPOIB_FLAG_OPER_UP, &priv->flags);
+		set_bit(IPOIB_FLAG_MCAST_FLUSH, &priv->flags);
 		ipoib_mcast_dev_flush(dev);
-		if (oper_up)
-			set_bit(IPOIB_FLAG_OPER_UP, &priv->flags);
+		clear_bit(IPOIB_FLAG_MCAST_FLUSH, &priv->flags);
 		ipoib_reap_dead_ahs(priv);
 	}
 
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 8a4ab9ff0a681..4f7639bbc7dc5 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -74,7 +74,7 @@ static void __ipoib_mcast_schedule_join_thread(struct ipoib_dev_priv *priv,
 					       struct ipoib_mcast *mcast,
 					       bool delay)
 {
-	if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
+	if (!ipoib_mcast_allowed(priv))
 		return;
 
 	/*
@@ -469,7 +469,7 @@ static int ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast)
 	int ret = 0;
 
 	if (!priv->broadcast ||
-	    !test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
+	    !ipoib_mcast_allowed(priv))
 		return -EINVAL;
 
 	init_completion(&mcast->done);
@@ -555,7 +555,7 @@ void ipoib_mcast_join_task(struct work_struct *work)
 	unsigned long delay_until = 0;
 	struct ipoib_mcast *mcast = NULL;
 
-	if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
+	if (!ipoib_mcast_allowed(priv))
 		return;
 
 	if (ib_query_port(priv->ca, priv->port, &port_attr)) {
@@ -577,7 +577,7 @@ void ipoib_mcast_join_task(struct work_struct *work)
 	netif_addr_unlock_bh(dev);
 
 	spin_lock_irq(&priv->lock);
-	if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
+	if (!ipoib_mcast_allowed(priv))
 		goto out;
 
 	if (!priv->broadcast) {
@@ -749,7 +749,7 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb)
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags)		||
+	if (!ipoib_mcast_allowed(priv)				||
 	    !priv->broadcast					||
 	    !test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) {
 		++dev->stats.tx_dropped;
@@ -871,7 +871,7 @@ void ipoib_mcast_restart_task(struct work_struct *work)
 	LIST_HEAD(remove_list);
 	struct ib_sa_mcmember_rec rec;
 
-	if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
+	if (!ipoib_mcast_allowed(priv))
 		/*
 		 * shortcut...on shutdown flush is called next, just
 		 * let it do all the work
@@ -965,9 +965,9 @@ void ipoib_mcast_restart_task(struct work_struct *work)
 	ipoib_mcast_remove_list(&remove_list);
 
 	/*
-	 * Double check that we are still up
+	 * Double check that we are still up and not flushing
 	 */
-	if (test_bit(IPOIB_FLAG_OPER_UP, &priv->flags)) {
+	if (ipoib_mcast_allowed(priv)) {
 		spin_lock_irq(&priv->lock);
 		__ipoib_mcast_schedule_join_thread(priv, NULL, 0);
 		spin_unlock_irq(&priv->lock);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 046/877] wifi: cfg80211: dont get the radio mask for netdev-less wdevs
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (44 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 045/877] IB/IPoIB: Avoid restoring OPER_UP after multicast flush Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 047/877] wifi: cfg80211: check IP header size in cfg80211_classify8021d() Greg Kroah-Hartman
                   ` (838 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+abff43d2d045e37c0bb2,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit a7783e585360ee05dfe21d3173dbbe985c94f29e ]

cfg80211_calculate_bi_data() calls rdev_get_radio_mask() with
wdev->netdev, which can be NULL and then crashes in mac80211.

To avoid that, invert the order of checks since wdev->netdev
is always valid for beaconing interfaces.

Assisted-by: LLM
Fixes: abb4cfe3661a ("wifi: cfg80211: extend interface combination check for multi-radio")
Reported-by: syzbot+abff43d2d045e37c0bb2@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=abff43d2d045e37c0bb2
Link: https://patch.msgid.link/20260904165614.2056a8b7dc91.I7412c5062d8166ad6c81ee7252cec49dea19a60f@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/wireless/util.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/net/wireless/util.c b/net/wireless/util.c
index 8478f3a0e9402..f565fb5ddd44a 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -2355,16 +2355,15 @@ static void cfg80211_calculate_bi_data(struct wiphy *wiphy, u32 new_beacon_int,
 		if (wdev->valid_links)
 			continue;
 
+		wdev_bi = cfg80211_wdev_bi(wdev);
+		if (!wdev_bi)
+			continue;
+
 		/* skip wdevs not active on the given wiphy radio */
 		if (radio_idx >= 0 &&
 		    !(rdev_get_radio_mask(rdev, wdev->netdev) & BIT(radio_idx)))
 			continue;
 
-		wdev_bi = cfg80211_wdev_bi(wdev);
-
-		if (!wdev_bi)
-			continue;
-
 		if (!*beacon_int_gcd) {
 			*beacon_int_gcd = wdev_bi;
 			continue;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 047/877] wifi: cfg80211: check IP header size in cfg80211_classify8021d()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (45 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 046/877] wifi: cfg80211: dont get the radio mask for netdev-less wdevs Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:15 ` [PATCH 6.12 048/877] soundwire: cadence_master: wait and cancel cdns->work before clock stop Greg Kroah-Hartman
                   ` (837 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+878ddc3962f792e9af59,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit 48b2c5c628b09cf36cbeca53e0432fc2a7518be7 ]

A frame that looks like IP can be transmitted, but be too short, so
the DS field is read incorrectly:

  BUG: KMSAN: uninit-value in cfg80211_classify8021d+0x99d/0x12b0 net/wireless/util.c:1027
   cfg80211_classify8021d+0x99d/0x12b0 net/wireless/util.c:1027
   ieee80211_select_queue+0x37a/0x9e0 net/mac80211/wme.c:180
   __ieee80211_subif_start_xmit+0x60f/0x1d90 net/mac80211/tx.c:4304
   ieee80211_subif_start_xmit+0xa8/0x6d0 net/mac80211/tx.c:4538
   ...
   packet_sendmsg+0x9173/0xa2a0 net/packet/af_packet.c:3108

Use skb_header_pointer() like the MPLS case.

Assisted-by: LLM
Fixes: e31a16d6f64e ("wireless: move some utility functions from mac80211 to cfg80211")
Reported-by: syzbot+878ddc3962f792e9af59@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=878ddc3962f792e9af59
Link: https://patch.msgid.link/20260904165614.5e61a4c80b92.I37d68d3f406cb3b90b32e6943418d66070b65197@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/wireless/util.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/net/wireless/util.c b/net/wireless/util.c
index f565fb5ddd44a..f9e0ec311982e 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -989,12 +989,30 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb,
 	}
 
 	switch (skb->protocol) {
-	case htons(ETH_P_IP):
-		dscp = ipv4_get_dsfield(ip_hdr(skb)) & 0xfc;
+	case htons(ETH_P_IP): {
+		const struct iphdr *iph;
+		struct iphdr _iph;
+
+		iph = skb_header_pointer(skb, sizeof(struct ethhdr),
+					 sizeof(*iph), &_iph);
+		if (!iph)
+			return 0;
+
+		dscp = ipv4_get_dsfield(iph) & 0xfc;
 		break;
-	case htons(ETH_P_IPV6):
-		dscp = ipv6_get_dsfield(ipv6_hdr(skb)) & 0xfc;
+	}
+	case htons(ETH_P_IPV6): {
+		const struct ipv6hdr *ip6h;
+		struct ipv6hdr _ip6h;
+
+		ip6h = skb_header_pointer(skb, sizeof(struct ethhdr),
+					  sizeof(*ip6h), &_ip6h);
+		if (!ip6h)
+			return 0;
+
+		dscp = ipv6_get_dsfield(ip6h) & 0xfc;
 		break;
+	}
 	case htons(ETH_P_MPLS_UC):
 	case htons(ETH_P_MPLS_MC): {
 		struct mpls_label mpls_tmp, *mpls;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 048/877] soundwire: cadence_master: wait and cancel cdns->work before clock stop
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (46 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 047/877] wifi: cfg80211: check IP header size in cfg80211_classify8021d() Greg Kroah-Hartman
@ 2026-09-30 15:15 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 049/877] MIPS: Octeon: apply USB FDT fixups also when USB is modular Greg Kroah-Hartman
                   ` (836 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:15 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bard Liao, David Lin, Shuming Fan,
	Pierre-Louis Bossart, Vinod Koul, Sasha Levin

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

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

From: Bard Liao <yung-chuan.liao@linux.intel.com>

[ Upstream commit aba7b41faeecb7692458095ce6fafc341fe0b80e ]

A peripheral event could happen during the clock stop process. We need
to wait for the event be handled before stopping the bus clock.
Otherwise, we will get the IO transfer timed out issue.

Fixes: af4cc917826f ("soundwire: cadence: mask Slave interrupt before stopping clock")
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: David Lin <david.lin@intel.com>
Reviewed-by: Shuming Fan <shumingf@realtek.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Link: https://patch.msgid.link/20260901031019.233254-1-yung-chuan.liao@linux.intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/soundwire/cadence_master.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c
index a503ef606a62c..1557d6b044491 100644
--- a/drivers/soundwire/cadence_master.c
+++ b/drivers/soundwire/cadence_master.c
@@ -1670,6 +1670,13 @@ int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake)
 		return 0;
 	}
 
+	/*
+	 * wait for any in-flight peripheral event handling to complete before stopping the clock.
+	 * No need to disable peripheral interrupts before canceling the work, as the peripheral
+	 * interrupts are already masked before the work is scheduled.
+	 */
+	cancel_work_sync(&cdns->work);
+
 	/*
 	 * Before entering clock stop we mask the Slave
 	 * interrupts. This helps avoid having to deal with e.g. a
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 049/877] MIPS: Octeon: apply USB FDT fixups also when USB is modular
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (47 preceding siblings ...)
  2026-09-30 15:15 ` [PATCH 6.12 048/877] soundwire: cadence_master: wait and cancel cdns->work before clock stop Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 050/877] dma-coherent: Warn if OF reserved memory is beyond current coherent DMA mask Greg Kroah-Hartman
                   ` (835 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Orgad Shaneh, Thomas Bogendoerfer,
	Sasha Levin

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

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

From: Orgad Shaneh <orgads@gmail.com>

[ Upstream commit 126f16e0a1b353c2ba5c7e2c8626cfa865934f9f ]

The uctl/usbn device-tree fixups in octeon_prune_device_tree() - which
set the board's USB reference-clock frequency and type from
__cvmx_helper_board_usb_get_clock_type() - are guarded by
"#ifdef CONFIG_USB", which is false when USB is built as a module. The
fixups then silently disappear and octeon-hcd sees whatever default the
DTS carries (12MHz crystal in octeon_3xxx.dts), leaving the PHY dead or
the bus erroring on boards with a different reference clock.

Use IS_ENABLED() so USB=m gets the same fixups as USB=y.

Fixes: 7fd57ab9d9cf ("MIPS: Octeon: Fix compile error when USB is not enabled.")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Orgad Shaneh <orgads@gmail.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/mips/cavium-octeon/octeon-platform.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index 5e1dd4e6e82fb..4b5c99e6f5bcc 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -17,7 +17,7 @@
 #include <asm/octeon/octeon.h>
 #include <asm/octeon/cvmx-helper-board.h>
 
-#ifdef CONFIG_USB
+#if IS_ENABLED(CONFIG_USB)
 #include <linux/usb/ehci_def.h>
 #include <linux/usb/ehci_pdriver.h>
 #include <linux/usb/ohci_pdriver.h>
@@ -1080,7 +1080,7 @@ int __init octeon_prune_device_tree(void)
 		;
 	}
 
-#ifdef CONFIG_USB
+#if IS_ENABLED(CONFIG_USB)
 	/* OHCI/UHCI USB */
 	alias_prop = fdt_getprop(initial_boot_params, aliases,
 				 "uctl", NULL);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 050/877] dma-coherent: Warn if OF reserved memory is beyond current coherent DMA mask
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (48 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 049/877] MIPS: Octeon: apply USB FDT fixups also when USB is modular Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 051/877] dma-coherent: report a failed reserved memory assignment Greg Kroah-Hartman
                   ` (834 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Chen-Yu Tsai, Marek Szyprowski,
	Sasha Levin

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

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

From: Chen-Yu Tsai <wenst@chromium.org>

[ Upstream commit 89461db349cc00816c01d55507d511466b3b7151 ]

When a reserved memory region described in the device tree is attached
to a device, it is expected that the device's limitations are correctly
included in that description.

However, if the device driver failed to implement DMA address masking
or addressing beyond the default 32 bits (on arm64), then bad things
could happen because the DMA address was truncated, such as playing
back audio with no actual audio coming out, or DMA overwriting random
blocks of kernel memory.

Check against the coherent DMA mask when the memory regions are attached
to the device. Give a warning when the memory region can not be covered
by the mask.

A warning instead of a hard error was chosen, because it is possible
that existing drivers could be working fine even if they forgot to
extend the coherent DMA mask.

Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/20250421083930.374173-1-wenst@chromium.org
Stable-dep-of: 504981db4f69 ("dma-coherent: report a failed reserved memory assignment")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/dma/coherent.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c
index 3b2bdca9f1d4b..77c8d9487a9ab 100644
--- a/kernel/dma/coherent.c
+++ b/kernel/dma/coherent.c
@@ -336,16 +336,22 @@ static phys_addr_t dma_reserved_default_memory_size __initdata;
 
 static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
 {
-	if (!rmem->priv) {
-		struct dma_coherent_mem *mem;
+	struct dma_coherent_mem *mem = rmem->priv;
 
+	if (!mem) {
 		mem = dma_init_coherent_memory(rmem->base, rmem->base,
 					       rmem->size, true);
 		if (IS_ERR(mem))
 			return PTR_ERR(mem);
 		rmem->priv = mem;
 	}
-	dma_assign_coherent_memory(dev, rmem->priv);
+
+	/* Warn if the device potentially can't use the reserved memory */
+	if (mem->device_base + rmem->size - 1 >
+	    min_not_zero(dev->coherent_dma_mask, dev->bus_dma_limit))
+		dev_warn(dev, "reserved memory is beyond device's set DMA address range\n");
+
+	dma_assign_coherent_memory(dev, mem);
 	return 0;
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 051/877] dma-coherent: report a failed reserved memory assignment
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (49 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 050/877] dma-coherent: Warn if OF reserved memory is beyond current coherent DMA mask Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 052/877] dmaengine: Fix device kref underflow in dma_chan_put() Greg Kroah-Hartman
                   ` (833 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Marek Szyprowski,
	Sasha Levin

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

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

From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>

[ Upstream commit 504981db4f69bdd28054fb98c96a3a67f7248dde ]

rmem_dma_device_init() drops the return value of
dma_assign_coherent_memory() and always reports success. That call fails
with -EBUSY when the device already has a coherent pool, and the file
allows only "*one* such region of memory" per device.

of_reserved_mem_device_init_by_idx() reads the zero as success. It logs
"assigned reserved memory node" for a region that was not assigned and
records the pairing, so of_reserved_mem_device_release() later runs
rmem_dma_device_release() for it. That clears dev->dma_mem without
looking at which region it was called for, dropping the pool the device
did get and leaving it on ordinary memory.

dma_declare_coherent_memory() checks the same call and releases the
memory on failure, and rmem_swiotlb_device_init() propagates its own
errors. Return the error here as well, so a device tree that assigns two
pools to one device fails the probe instead of half working.

Fixes: 7bfa5ab6fa1b ("drivers: dma-coherent: add initialization from device tree")
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Link: https://lore.kernel.org/r/20260905074727.108029-1-donggeunyoo.kernel@gmail.com
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/dma/coherent.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c
index 77c8d9487a9ab..87f2f02e921a6 100644
--- a/kernel/dma/coherent.c
+++ b/kernel/dma/coherent.c
@@ -351,8 +351,7 @@ static int rmem_dma_device_init(struct reserved_mem *rmem, struct device *dev)
 	    min_not_zero(dev->coherent_dma_mask, dev->bus_dma_limit))
 		dev_warn(dev, "reserved memory is beyond device's set DMA address range\n");
 
-	dma_assign_coherent_memory(dev, mem);
-	return 0;
+	return dma_assign_coherent_memory(dev, mem);
 }
 
 static void rmem_dma_device_release(struct reserved_mem *rmem,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 052/877] dmaengine: Fix device kref underflow in dma_chan_put()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (50 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 051/877] dma-coherent: report a failed reserved memory assignment Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 053/877] dmaengine: fix use-after-free in dma_chan_put() and dma_release_channel() Greg Kroah-Hartman
                   ` (832 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Frank Li, Logan Gunthorpe,
	Shivank Garg, Vinod Koul, Sasha Levin

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

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

From: Shivank Garg <shivankg@amd.com>

[ Upstream commit 44dab659064eb5c10adb0306510eebe848ed592d ]

dma_chan_get() takes chan->device->ref only on the slow path:

	/* no kref on fast path */
	if (chan->client_count) {
		__module_get(owner);
		chan->client_count++;
		return 0;
	}
	if (!try_module_get(owner))
		return -ENODEV;
	if (!dma_device_get(chan->device)) { // calls kref_get_unless_zero()

dma_chan_put() drops the ref unconditionally, so every fast-path
get/put pair drops one extra device reference.

The bug fires when two conditions hold together: a non-private
provider has a persistent client holding chan->client_count > 0
and another client cycles dmaengine_get()/dmaengine_put().
When the kref hits zero, the subsequent dma_find_channel() returns
NULL even though the provider module is still loaded.

Fix this by dropping device->ref only on the last put, matching the
single slow-path get.

Fixes: 8ad342a86359 ("dmaengine: Add reference counting to dma_device struct")
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Shivank Garg <shivankg@amd.com>
Link: https://patch.msgid.link/20260822-dmaengine-kref-fix-v5-2-d4a4ee47d927@amd.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/dma/dmaengine.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index e241b7b01233e..ea3ed830061dc 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -513,7 +513,9 @@ static void dma_chan_put(struct dma_chan *chan)
 		chan->route_data = NULL;
 	}
 
-	dma_device_put(chan->device);
+	/* This channel is not in use anymore, drop the device ref */
+	if (!chan->client_count)
+		dma_device_put(chan->device);
 	module_put(dma_chan_to_owner(chan));
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 053/877] dmaengine: fix use-after-free in dma_chan_put() and dma_release_channel()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (51 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 052/877] dmaengine: Fix device kref underflow in dma_chan_put() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 054/877] dmaengine: wait for RCU readers before releasing dma_device Greg Kroah-Hartman
                   ` (831 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Frank Li, Logan Gunthorpe,
	Shivank Garg, Vinod Koul, Sasha Levin

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

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

From: Shivank Garg <shivankg@amd.com>

[ Upstream commit e873c74132f0c5f1452816cd9bb26208f0bba1e1 ]

When dma_device_put() drops the last reference on chan->device->ref,
dma_device_release() runs and may free the dma_device along with its
channels.

dma_chan_put() then still reads chan->device->owner via
dma_chan_to_owner() for the trailing module_put(). KASAN catches it:

	slab-use-after-free in dma_chan_put+0x3e6/0x4c0
	Read of size 8 by task insmod/6319
	Freed by task 6319:
	  kfree+0x225/0x470
	  dma_chan_put+0x395/0x4c0
	  dmaengine_put+0xf8/0x160

Cache the module owner in dma_chan_put() before the put so the trailing
module_put() does not need chan->device.

Fixes: 8ad342a86359 ("dmaengine: Add reference counting to dma_device struct")
Suggested-by: Sashiko <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260518-dmaengine-kref-fix-v1-1-4d6125048fb7@amd.com
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Shivank Garg <shivankg@amd.com>
Link: https://patch.msgid.link/20260822-dmaengine-kref-fix-v5-3-d4a4ee47d927@amd.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/dma/dmaengine.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index ea3ed830061dc..d6a4e914018da 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -493,10 +493,13 @@ static int dma_chan_get(struct dma_chan *chan)
  */
 static void dma_chan_put(struct dma_chan *chan)
 {
+	struct module *owner;
+
 	/* This channel is not in use, bail out */
 	if (!chan->client_count)
 		return;
 
+	owner = dma_chan_to_owner(chan);
 	chan->client_count--;
 
 	/* This channel is not in use anymore, free it */
@@ -516,7 +519,7 @@ static void dma_chan_put(struct dma_chan *chan)
 	/* This channel is not in use anymore, drop the device ref */
 	if (!chan->client_count)
 		dma_device_put(chan->device);
-	module_put(dma_chan_to_owner(chan));
+	module_put(owner);
 }
 
 enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 054/877] dmaengine: wait for RCU readers before releasing dma_device
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (52 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 053/877] dmaengine: fix use-after-free in dma_chan_put() and dma_release_channel() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 055/877] wifi: cfg80211: only group hidden BSSes with beacon entries Greg Kroah-Hartman
                   ` (830 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Frank Li, Logan Gunthorpe,
	Shivank Garg, Vinod Koul, Sasha Levin

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

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

From: Shivank Garg <shivankg@amd.com>

[ Upstream commit dc750422170a563c7a81f6e49d36bb02c62ae37f ]

dma_issue_pending_all() walks the dma_device_list with
list_for_each_entry_rcu() under rcu_read_lock(). dma_device_release()
unlinks the device with list_del_rcu() and then calls
device->device_release() (which in many drivers, such as plx_dma.c,
directly calls kfree()).

Because there is no grace period between unlinking the device and
freeing it, concurrent RCU readers in dma_issue_pending_all() can
access the device after it has been freed.

The lockless walk originally relied on clients holding a dmaengine
reference to pin the provider module, and therefore the device, for as
long as they might traverse the list. Commit 8ad342a86359 ("dmaengine:
Add reference counting to dma_device struct") decoupled the dma_device
lifetime from the module reference, so the device can now be released
while a reader is still walking the list.

Add synchronize_rcu() before the device is freed, so RCU readers are
guaranteed to have finished. Keep it unconditional: providers that do
not implement device_release() free the device themselves once
dma_async_device_unregister() returns. This call will delay for a grace
period with dma_list_mutex held, which is safe and only teardown path is
delayed.

Fixes: 2ba05622b8b1 ("dmaengine: provide a common 'issue_pending_all' implementation")
Suggested-by: Sashiko <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260526-dmaengine-kref-fix-v2-0-3df60afac01d@amd.com
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Signed-off-by: Shivank Garg <shivankg@amd.com>
Link: https://patch.msgid.link/20260822-dmaengine-kref-fix-v5-4-d4a4ee47d927@amd.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/dma/dmaengine.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index d6a4e914018da..9a591bc15a36b 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -426,6 +426,7 @@ static void dma_device_release(struct kref *ref)
 
 	list_del_rcu(&device->global_node);
 	dma_channel_rebalance();
+	synchronize_rcu();
 
 	if (device->device_release)
 		device->device_release(device);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 055/877] wifi: cfg80211: only group hidden BSSes with beacon entries
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (53 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 054/877] dmaengine: wait for RCU readers before releasing dma_device Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 056/877] wifi: cfg80211: dont filter by BSS type when removing stale entries Greg Kroah-Hartman
                   ` (829 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+1a797e1c81be78a2ace7,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit 068843ed0902c552a13860c5ec6b2ca65b57a065 ]

When a probe response for an unknown BSS comes in, __cfg80211_bss_update()
looks for an existing entry with the same BSSID and a hidden (zero-length
or NUL-filled) SSID, and if it finds one it groups them, using the beacon
IEs from the existing entry.

But that could find another entry without a beacon, if it was also from a
probe response (with SSID), so there's a group without beacon elements.

If a beacon with a hidden SSID for that BSSID arrives later,
cfg80211_combine_bsses() goes looking for the probe response entries that
belong to it - i.e. entries with the same BSSID and channel that have no
beacon IEs - and finds those two. They are already grouped with each
other, so it hits its

  WARN_ON_ONCE(bss->pub.hidden_beacon_bss)
  WARN_ON_ONCE(!list_empty(&bss->hidden_list))

which are there because an entry without beacon elements is not supposed
to be part of a group yet.

Only combine entries when a beacon was already received, ones that are
kept separate will be combined when a beacon arrives.

Assisted-by: LLM
Fixes: 4593c4cbe1c9 ("cfg80211: fix BSS list hidden SSID lookup")
Reported-by: syzbot+1a797e1c81be78a2ace7@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1a797e1c81be78a2ace7
Link: https://patch.msgid.link/20260904165614.bcfa64715745.Iad740347c86de56d4ff4f96a95f3c3afc47c42de@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/wireless/scan.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 3c439841578c4..f3b9e7a519ff9 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1960,6 +1960,13 @@ __cfg80211_bss_update(struct cfg80211_registered_device *rdev,
 			if (!hidden)
 				hidden = rb_find_bss(rdev, tmp,
 						     BSS_CMP_HIDE_NUL);
+			/*
+			 * Only group with an entry with beacon data, otherwise
+			 * beacon data can never be filled/updated.
+			 */
+			if (hidden &&
+			    !rcu_access_pointer(hidden->pub.beacon_ies))
+				hidden = NULL;
 			if (hidden) {
 				new->pub.hidden_beacon_bss = &hidden->pub;
 				list_add(&new->hidden_list,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 056/877] wifi: cfg80211: dont filter by BSS type when removing stale entries
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (54 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 055/877] wifi: cfg80211: only group hidden BSSes with beacon entries Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 057/877] wifi: mac80211: dont start a ROC while scanning Greg Kroah-Hartman
                   ` (828 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+dc6f4dce0d707900cdea,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit b377e1000d963e7182a987082b4b06580bd7ac84 ]

When an assoc AP switches to a channel that already has a BSS entry,
cfg80211_update_assoc_bss_entry() removes that entry before rehashing
the real one, since the two would otherwise collide in the BSS rbtree.

The lookup for that entry also required it to match the connection's BSS
type, so an entry advertising e.g. the IBSS capability bit was left in
place, and the following cfg80211_rehash_bss() then ran into it:

  WARN_ON(!cmp)

Changing the type shouldn't really happen, but can be triggered by a
rogue AP/device, so drop the check and remove any entries matching
the comparison.

Assisted-by: LLM
Fixes: 0afd425b1b64 ("cfg80211: fix duplicated scan entries after channel switch")
Reported-by: syzbot+dc6f4dce0d707900cdea@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=dc6f4dce0d707900cdea
Link: https://patch.msgid.link/20260904165614.1f05dae1c546.Ib52d57b57caa912efee020f9d4a033a5160617ce@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/wireless/scan.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index f3b9e7a519ff9..9d21667641a50 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -3398,11 +3398,6 @@ void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
 	cbss->pub.channel = chan;
 
 	list_for_each_entry(bss, &rdev->bss_list, list) {
-		if (!cfg80211_bss_type_match(bss->pub.capability,
-					     bss->pub.channel->band,
-					     wdev->conn_bss_type))
-			continue;
-
 		if (bss == cbss)
 			continue;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 057/877] wifi: mac80211: dont start a ROC while scanning
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (55 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 056/877] wifi: cfg80211: dont filter by BSS type when removing stale entries Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 058/877] wifi: cfg80211: add option for vif allowed radios Greg Kroah-Hartman
                   ` (827 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+c3a167b5615df4ccd7fb,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit 733f0fde95392ed5f61a4e36aee661ea8d0e8581 ]

The ROC work can be pending when a scan starts (which requires
ROC list to be empty, but that's possible), and then a new ROC
can be added to the list and the work will pick it up.

Avoid starting that ROC if a scan made it between things, as
otherwise we'll hit a warning later:

  WARNING: net/mac80211/offchannel.c:404 at ieee80211_start_next_roc+0x256/0x2d0
  Workqueue: events_unbound cfg80211_wiphy_work
  Call Trace:
   __ieee80211_scan_completed+0x4fd/0xe40 net/mac80211/scan.c:537
   ieee80211_scan_work+0x472/0x1ff0 net/mac80211/scan.c:1193
   cfg80211_wiphy_work+0x410/0x570 net/wireless/core.c:513

Assisted-by: LLM
Fixes: aaa016ccd5df ("mac80211: rewrite remain-on-channel logic")
Reported-by: syzbot+c3a167b5615df4ccd7fb@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=c3a167b5615df4ccd7fb
Link: https://patch.msgid.link/20260904165722.f9d5b150edd8.I61bc9de8c8d089096ad695213b9c85c7df38c3bd@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/offchannel.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 29fab7ae47b4c..0d9807526ecbd 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -462,6 +462,13 @@ static void __ieee80211_roc_work(struct ieee80211_local *local)
 		return;
 
 	if (!roc->started) {
+		/*
+		 * The work can be started by a previous ROC work, but a scan
+		 * can get between things; scan finish will retrigger us.
+		 */
+		if (local->scanning)
+			return;
+
 		WARN_ON(!local->emulate_chanctx);
 		_ieee80211_start_next_roc(local);
 	} else {
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 058/877] wifi: cfg80211: add option for vif allowed radios
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (56 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 057/877] wifi: mac80211: dont start a ROC while scanning Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 059/877] wifi: mac80211: use vif radio mask to limit ibss scan frequencies Greg Kroah-Hartman
                   ` (826 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Felix Fietkau, Johannes Berg,
	Sasha Levin

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

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

From: Felix Fietkau <nbd@nbd.name>

[ Upstream commit 3607798ad9bdef35ad08489a8239390fccaac6b5 ]

This allows users to prevent a vif from affecting radios other than the
configured ones. This can be useful in cases where e.g. an AP is running
on one radio, and triggering a scan on another radio should not disturb it.

Changing the allowed radios list for a vif is supported, but only while
it is down.

While it is possible to achieve the same by always explicitly specifying
a frequency list for scan requests and ensuring that the wrong channel/band
is never accidentally set on an unrelated interface, this change makes
multi-radio wiphy setups a lot easier to deal with for CLI users.

By itself, this patch only enforces the radio mask for scanning requests
and remain-on-channel. Follow-up changes build on this to limit configured
frequencies.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/eefcb218780f71a1549875d149f1196486762756.1728462320.git-series.nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Stable-dep-of: a7491b7efbd9 ("wifi: mac80211: don't warn when an IBSS has no channel to scan")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/net/cfg80211.h       | 14 +++++++++
 include/uapi/linux/nl80211.h |  5 +++
 net/wireless/core.c          |  2 ++
 net/wireless/nl80211.c       | 60 +++++++++++++++++++++++++++++++-----
 net/wireless/scan.c          | 10 ++++--
 net/wireless/util.c          | 29 +++++++++++++++++
 6 files changed, 109 insertions(+), 11 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index fcc5934a20c0f..f3915118c15d7 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -6353,6 +6353,7 @@ enum ieee80211_ap_reg_power {
  *	entered.
  * @links.cac_time_ms: CAC time in ms
  * @valid_links: bitmap describing what elements of @links are valid
+ * @radio_mask: Bitmask of radios that this interface is allowed to operate on.
  */
 struct wireless_dev {
 	struct wiphy *wiphy;
@@ -6465,6 +6466,8 @@ struct wireless_dev {
 		unsigned int cac_time_ms;
 	} links[IEEE80211_MLD_MAX_NUM_LINKS];
 	u16 valid_links;
+
+	u32 radio_mask;
 };
 
 static inline const u8 *wdev_address(struct wireless_dev *wdev)
@@ -6650,6 +6653,17 @@ static inline bool cfg80211_channel_is_psc(struct ieee80211_channel *chan)
 bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio,
 				  const struct cfg80211_chan_def *chandef);
 
+/**
+ * cfg80211_wdev_channel_allowed - Check if the wdev may use the channel
+ *
+ * @wdev: the wireless device
+ * @chan: channel to check
+ *
+ * Return: whether or not the wdev may use the channel
+ */
+bool cfg80211_wdev_channel_allowed(struct wireless_dev *wdev,
+				   struct ieee80211_channel *chan);
+
 /**
  * ieee80211_get_response_rate - get basic rate for a given rate
  *
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index c2d7faf8d87fa..8ce0c143e9fde 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -2868,6 +2868,9 @@ enum nl80211_commands {
  *	nested item, it contains attributes defined in
  *	&enum nl80211_if_combination_attrs.
  *
+ * @NL80211_ATTR_VIF_RADIO_MASK: Bitmask of allowed radios (u32).
+ *	A value of 0 means all radios.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3416,6 +3419,8 @@ enum nl80211_attrs {
 	NL80211_ATTR_WIPHY_RADIOS,
 	NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS,
 
+	NL80211_ATTR_VIF_RADIO_MASK,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 8f7f84c5f440b..7c278b8694393 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1456,6 +1456,8 @@ void cfg80211_init_wdev(struct wireless_dev *wdev)
 	/* allow mac80211 to determine the timeout */
 	wdev->ps_timeout = -1;
 
+	wdev->radio_mask = BIT(wdev->wiphy->n_radio) - 1;
+
 	if ((wdev->iftype == NL80211_IFTYPE_STATION ||
 	     wdev->iftype == NL80211_IFTYPE_P2P_CLIENT ||
 	     wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b302caafd4d31..6261befa1e949 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -834,6 +834,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
 	[NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
 	[NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
 	[NL80211_ATTR_ASSOC_SPP_AMSDU] = { .type = NLA_FLAG },
+	[NL80211_ATTR_VIF_RADIO_MASK] = { .type = NLA_U32 },
 };
 
 /* policy for the key attributes */
@@ -3975,7 +3976,8 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
 	    nla_put_u32(msg, NL80211_ATTR_GENERATION,
 			rdev->devlist_generation ^
 			(cfg80211_rdev_list_generation << 2)) ||
-	    nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr))
+	    nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr) ||
+	    nla_put_u32(msg, NL80211_ATTR_VIF_RADIO_MASK, wdev->radio_mask))
 		goto nla_put_failure;
 
 	if (rdev->ops->get_channel && !wdev->valid_links) {
@@ -4296,6 +4298,29 @@ static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
 	return -EOPNOTSUPP;
 }
 
+static int nl80211_parse_vif_radio_mask(struct genl_info *info,
+					u32 *radio_mask)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct nlattr *attr = info->attrs[NL80211_ATTR_VIF_RADIO_MASK];
+	u32 mask, allowed;
+
+	if (!attr) {
+		*radio_mask = 0;
+		return 0;
+	}
+
+	allowed = BIT(rdev->wiphy.n_radio) - 1;
+	mask = nla_get_u32(attr);
+	if (mask & ~allowed)
+		return -EINVAL;
+	if (!mask)
+		mask = allowed;
+	*radio_mask = mask;
+
+	return 1;
+}
+
 static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -4303,6 +4328,8 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
 	int err;
 	enum nl80211_iftype otype, ntype;
 	struct net_device *dev = info->user_ptr[1];
+	struct wireless_dev *wdev = dev->ieee80211_ptr;
+	u32 radio_mask = 0;
 	bool change = false;
 
 	memset(&params, 0, sizeof(params));
@@ -4316,8 +4343,6 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
 	}
 
 	if (info->attrs[NL80211_ATTR_MESH_ID]) {
-		struct wireless_dev *wdev = dev->ieee80211_ptr;
-
 		if (ntype != NL80211_IFTYPE_MESH_POINT)
 			return -EINVAL;
 		if (otype != NL80211_IFTYPE_MESH_POINT)
@@ -4348,6 +4373,12 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
 	if (err > 0)
 		change = true;
 
+	err = nl80211_parse_vif_radio_mask(info, &radio_mask);
+	if (err < 0)
+		return err;
+	if (err && netif_running(dev))
+		return -EBUSY;
+
 	if (change)
 		err = cfg80211_change_iface(rdev, dev, ntype, &params);
 	else
@@ -4356,11 +4387,11 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
 	if (!err && params.use_4addr != -1)
 		dev->ieee80211_ptr->use_4addr = params.use_4addr;
 
-	if (change && !err) {
-		struct wireless_dev *wdev = dev->ieee80211_ptr;
+	if (radio_mask)
+		wdev->radio_mask = radio_mask;
 
+	if (change && !err)
 		nl80211_notify_iface(rdev, wdev, NL80211_CMD_SET_INTERFACE);
-	}
 
 	return err;
 }
@@ -4371,6 +4402,7 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
 	struct vif_params params;
 	struct wireless_dev *wdev;
 	struct sk_buff *msg;
+	u32 radio_mask;
 	int err;
 	enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
 
@@ -4408,6 +4440,10 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
 	if (err < 0)
 		return err;
 
+	err = nl80211_parse_vif_radio_mask(info, &radio_mask);
+	if (err < 0)
+		return err;
+
 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 	if (!msg)
 		return -ENOMEM;
@@ -4449,6 +4485,9 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
 		break;
 	}
 
+	if (radio_mask)
+		wdev->radio_mask = radio_mask;
+
 	if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
 			       rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
 		nlmsg_free(msg);
@@ -9178,6 +9217,9 @@ static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev,
 
 	lockdep_assert_wiphy(wdev->wiphy);
 
+	if (!cfg80211_wdev_channel_allowed(wdev, chan))
+		return false;
+
 	if (!cfg80211_beaconing_iface_active(wdev))
 		return true;
 
@@ -9390,7 +9432,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 			}
 
 			/* ignore disabled channels */
-			if (chan->flags & IEEE80211_CHAN_DISABLED)
+			if (chan->flags & IEEE80211_CHAN_DISABLED ||
+			    !cfg80211_wdev_channel_allowed(wdev, chan))
 				continue;
 
 			request->channels[i] = chan;
@@ -9410,7 +9453,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 
 				chan = &wiphy->bands[band]->channels[j];
 
-				if (chan->flags & IEEE80211_CHAN_DISABLED)
+				if (chan->flags & IEEE80211_CHAN_DISABLED ||
+				    !cfg80211_wdev_channel_allowed(wdev, chan))
 					continue;
 
 				request->channels[i] = chan;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 9d21667641a50..a7d704d0a282a 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -953,7 +953,8 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev)
 		struct ieee80211_channel *chan =
 			ieee80211_get_channel(&rdev->wiphy, ap->center_freq);
 
-		if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
+		if (!chan || chan->flags & IEEE80211_CHAN_DISABLED ||
+		    !cfg80211_wdev_channel_allowed(rdev_req->wdev, chan))
 			continue;
 
 		for (i = 0; i < rdev_req->n_channels; i++) {
@@ -3519,9 +3520,12 @@ int cfg80211_wext_siwscan(struct net_device *dev,
 			continue;
 
 		for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
+			struct ieee80211_channel *chan;
+
 			/* ignore disabled channels */
-			if (wiphy->bands[band]->channels[j].flags &
-						IEEE80211_CHAN_DISABLED)
+			chan = &wiphy->bands[band]->channels[j];
+			if (chan->flags & IEEE80211_CHAN_DISABLED ||
+			    !cfg80211_wdev_channel_allowed(creq->wdev, chan))
 				continue;
 
 			/* If we have a wireless request structure and the
diff --git a/net/wireless/util.c b/net/wireless/util.c
index f9e0ec311982e..8cc205b9f105c 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -2965,3 +2965,32 @@ bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio,
 	return true;
 }
 EXPORT_SYMBOL(cfg80211_radio_chandef_valid);
+
+bool cfg80211_wdev_channel_allowed(struct wireless_dev *wdev,
+				   struct ieee80211_channel *chan)
+{
+	struct wiphy *wiphy = wdev->wiphy;
+	const struct wiphy_radio *radio;
+	struct cfg80211_chan_def chandef;
+	u32 radio_mask;
+	int i;
+
+	radio_mask = wdev->radio_mask;
+	if (!wiphy->n_radio || radio_mask == BIT(wiphy->n_radio) - 1)
+		return true;
+
+	cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
+	for (i = 0; i < wiphy->n_radio; i++) {
+		if (!(radio_mask & BIT(i)))
+			continue;
+
+		radio = &wiphy->radio[i];
+		if (!cfg80211_radio_chandef_valid(radio, &chandef))
+			continue;
+
+		return true;
+	}
+
+	return false;
+}
+EXPORT_SYMBOL(cfg80211_wdev_channel_allowed);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 059/877] wifi: mac80211: use vif radio mask to limit ibss scan frequencies
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (57 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 058/877] wifi: cfg80211: add option for vif allowed radios Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 060/877] wifi: mac80211: dont warn when an IBSS has no channel to scan Greg Kroah-Hartman
                   ` (825 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Felix Fietkau, Johannes Berg,
	Sasha Levin

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

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

From: Felix Fietkau <nbd@nbd.name>

[ Upstream commit 32ee616a7f8c36fa3ab00985ebd038c3487e721f ]

Reject frequencies not supported by any radio that the vif is allowed to
use.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/9d5c0b6b00a7ecef6a0ac6de765c0af00c8bb0e1.1728462320.git-series.nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Stable-dep-of: a7491b7efbd9 ("wifi: mac80211: don't warn when an IBSS has no channel to scan")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/scan.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 8675d2e99c564..07ce9cd35dab2 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -1180,14 +1180,14 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
 				unsigned int n_channels)
 {
 	struct ieee80211_local *local = sdata->local;
-	int ret = -EBUSY, i, n_ch = 0;
+	int i, n_ch = 0;
 	enum nl80211_band band;
 
 	lockdep_assert_wiphy(local->hw.wiphy);
 
 	/* busy scanning */
 	if (local->scan_req)
-		goto unlock;
+		return -EBUSY;
 
 	/* fill internal scan request */
 	if (!channels) {
@@ -1204,7 +1204,9 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
 				    &local->hw.wiphy->bands[band]->channels[i];
 
 				if (tmp_ch->flags & (IEEE80211_CHAN_NO_IR |
-						     IEEE80211_CHAN_DISABLED))
+						     IEEE80211_CHAN_DISABLED) ||
+				    !cfg80211_wdev_channel_allowed(&sdata->wdev,
+								   tmp_ch))
 					continue;
 
 				local->int_scan_req->channels[n_ch] = tmp_ch;
@@ -1213,21 +1215,23 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
 		}
 
 		if (WARN_ON_ONCE(n_ch == 0))
-			goto unlock;
+			return -EINVAL;
 
 		local->int_scan_req->n_channels = n_ch;
 	} else {
 		for (i = 0; i < n_channels; i++) {
 			if (channels[i]->flags & (IEEE80211_CHAN_NO_IR |
-						  IEEE80211_CHAN_DISABLED))
+						  IEEE80211_CHAN_DISABLED) ||
+			    !cfg80211_wdev_channel_allowed(&sdata->wdev,
+							   channels[i]))
 				continue;
 
 			local->int_scan_req->channels[n_ch] = channels[i];
 			n_ch++;
 		}
 
-		if (WARN_ON_ONCE(n_ch == 0))
-			goto unlock;
+		if (n_ch == 0)
+			return -EINVAL;
 
 		local->int_scan_req->n_channels = n_ch;
 	}
@@ -1237,9 +1241,7 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
 	memcpy(local->int_scan_req->ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
 	local->int_scan_req->ssids[0].ssid_len = ssid_len;
 
-	ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req);
- unlock:
-	return ret;
+	return __ieee80211_start_scan(sdata, sdata->local->int_scan_req);
 }
 
 void ieee80211_scan_cancel(struct ieee80211_local *local)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 060/877] wifi: mac80211: dont warn when an IBSS has no channel to scan
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (58 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 059/877] wifi: mac80211: use vif radio mask to limit ibss scan frequencies Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 061/877] wifi: mac80211: dont offload TC setup on AP_VLAN interfaces Greg Kroah-Hartman
                   ` (824 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+1634c5399e29d8b66789,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit a7491b7efbd9136b120a12ed72af9c12121dd134 ]

ieee80211_request_ibss_scan() warns when regulatory leaves no
allowed channel, but that can happen as the regdomain can change
while IBSS is operating, and it can continue to operate briefly
during the 60s grace period until it's shut down.

Just remove the warning in this case.

Assisted-by: LLM
Fixes: 34bcf7150241 ("mac80211: fix ibss scanning")
Reported-by: syzbot+1634c5399e29d8b66789@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1634c5399e29d8b66789
Link: https://patch.msgid.link/20260904165722.fe380c27fef4.I0e8bee2e12a40d240851a4bc724d47753af46159@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/scan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 07ce9cd35dab2..19e374fa00795 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -1214,7 +1214,7 @@ int ieee80211_request_ibss_scan(struct ieee80211_sub_if_data *sdata,
 			}
 		}
 
-		if (WARN_ON_ONCE(n_ch == 0))
+		if (n_ch == 0)
 			return -EINVAL;
 
 		local->int_scan_req->n_channels = n_ch;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 061/877] wifi: mac80211: dont offload TC setup on AP_VLAN interfaces
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (59 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 060/877] wifi: mac80211: dont warn when an IBSS has no channel to scan Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 062/877] wifi: mac80211: suppress chanctx warning for debugfs reset Greg Kroah-Hartman
                   ` (823 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+f1ba58d6b55abd13239e,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit 362bd5bce29ed0f6fd3d39a7065567777d70606e ]

AP_VLAN interfaces are purely virtual, so don't try to offload
TC setup to drivers. We can't really use the AP interface either
since we may not know it all the time, and it could technically
even change.

Just reject the TC offload so things get done in software.

Assisted-by: LLM
Fixes: 61587f1556fe ("wifi: mac80211: add support for letting drivers register tc offload support")
Reported-by: syzbot+f1ba58d6b55abd13239e@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=f1ba58d6b55abd13239e
Link: https://patch.msgid.link/20260904165722.726cc076cecb.Iccfd88b13635425e850ce031376eb60a4ce5f4f8@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/iface.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 7a79b40d23b36..98bc924d74fa6 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -873,6 +873,9 @@ static int ieee80211_netdev_setup_tc(struct net_device *dev,
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	struct ieee80211_local *local = sdata->local;
 
+	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+		return -EOPNOTSUPP;
+
 	return drv_net_setup_tc(local, sdata, dev, type, type_data);
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 062/877] wifi: mac80211: suppress chanctx warning for debugfs reset
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (60 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 061/877] wifi: mac80211: dont offload TC setup on AP_VLAN interfaces Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 063/877] wifi: mac80211: abort chanswitch when leaving a mesh Greg Kroah-Hartman
                   ` (822 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+56a1a45a9a2c04d425ff,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit bf29d085e0eba92388518719d044f4702a8c6644 ]

Before suspend all the channel contexts should removed, so the
warning makes sense and should be there, but during reset the
same code is called without first removing. Limit the check to
the real suspend case.

Assisted-by: LLM
Fixes: 12e7f517029d ("mac80211: cleanup generic suspend/resume procedures")
Reported-by: syzbot+56a1a45a9a2c04d425ff@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=56a1a45a9a2c04d425ff
Link: https://patch.msgid.link/20260904165722.fe46395e310b.Ic4aaa95bd9d0ceb6a3cd7d84c425afee7d7d3dd7@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/cfg.c         | 2 +-
 net/mac80211/debugfs.c     | 2 +-
 net/mac80211/ieee80211_i.h | 2 +-
 net/mac80211/pm.c          | 8 +++++---
 4 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index f6c5de994898c..73d7183c1ce59 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2844,7 +2844,7 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
 static int ieee80211_suspend(struct wiphy *wiphy,
 			     struct cfg80211_wowlan *wowlan)
 {
-	return __ieee80211_suspend(wiphy_priv(wiphy), wowlan);
+	return __ieee80211_suspend(wiphy_priv(wiphy), wowlan, false);
 }
 
 static int ieee80211_resume(struct wiphy *wiphy)
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index e9b3b2c7b6faa..28b1355cc062f 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -418,7 +418,7 @@ static ssize_t reset_write(struct file *file, const char __user *user_buf,
 
 	rtnl_lock();
 	wiphy_lock(local->hw.wiphy);
-	__ieee80211_suspend(&local->hw, NULL);
+	__ieee80211_suspend(&local->hw, NULL, true);
 	ret = __ieee80211_resume(&local->hw);
 	wiphy_unlock(local->hw.wiphy);
 
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 3b00b3f9f17dd..24edf2d4eb4f5 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -2287,7 +2287,7 @@ int ieee80211_reconfig(struct ieee80211_local *local);
 void ieee80211_stop_device(struct ieee80211_local *local, bool suspend);
 
 int __ieee80211_suspend(struct ieee80211_hw *hw,
-			struct cfg80211_wowlan *wowlan);
+			struct cfg80211_wowlan *wowlan, bool reset);
 
 static inline int __ieee80211_resume(struct ieee80211_hw *hw)
 {
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 7be52345f218c..56c222bdd4905 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -18,7 +18,8 @@ static void ieee80211_sched_scan_cancel(struct ieee80211_local *local)
 	cfg80211_sched_scan_stopped_locked(local->hw.wiphy, 0);
 }
 
-int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
+int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan,
+			bool reset)
 {
 	struct ieee80211_local *local = hw_to_local(hw);
 	struct ieee80211_sub_if_data *sdata;
@@ -166,9 +167,10 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
 
 	/*
 	 * We disconnected on all interfaces before suspend, all channel
-	 * contexts should be released.
+	 * contexts should be released, but on 'reset' debugfs that's
+	 * not true so don't check there.
 	 */
-	WARN_ON(!list_empty(&local->chanctx_list));
+	WARN_ON(!reset && !list_empty(&local->chanctx_list));
 
 	/* stop hardware - this must stop RX */
 	ieee80211_stop_device(local, true);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 063/877] wifi: mac80211: abort chanswitch when leaving a mesh
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (61 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 062/877] wifi: mac80211: suppress chanctx warning for debugfs reset Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 064/877] wifi: mac80211: reset state when starting AP fails Greg Kroah-Hartman
                   ` (821 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+81cd9dc1596563141d19,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit ac7472a24bd433b81c06582835dd1d5547c10da9 ]

The code in ieee80211_stop_mesh() leaves CSA active, but leaving
the mesh released the channel context, so the CSA finalize work
crashes:

  Oops: general protection fault, probably for non-canonical address
        0xdffffc0000000003
  KASAN: null-ptr-deref in range [0x0000000000000018-0x000000000000001f]
  RIP: 0010:ieee80211_put_srates_elem+0x42/0x640 net/mac80211/util.c:3272
  Call Trace:
   ieee80211_mesh_build_beacon+0xa83/0x1b50 net/mac80211/mesh.c:1093
   ieee80211_mesh_rebuild_beacon+0xc7/0x170 net/mac80211/mesh.c:1147
   ieee80211_mesh_finish_csa+0x131/0x210 net/mac80211/mesh.c:1542
   ieee80211_set_after_csa_beacon net/mac80211/cfg.c:4085 [inline]
   __ieee80211_csa_finalize net/mac80211/cfg.c:4133 [inline]
   ieee80211_csa_finalize+0x633/0x1150 net/mac80211/cfg.c:4155
   cfg80211_wiphy_work+0x2ab/0x450 net/wireless/core.c:438

Abort the channel switch properly.

Assisted-by: LLM
Fixes: b8456a14e9d2 ("{nl,cfg,mac}80211: implement mesh channel switch userspace API")
Reported-by: syzbot+81cd9dc1596563141d19@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=81cd9dc1596563141d19
Link: https://patch.msgid.link/20260904165722.d0b87eee08aa.I80550d6127e0bb26efb49a5fbe95be1aef1cd0cb@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/mesh.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 253f4b0642842..57cf3f90f7fbe 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1225,6 +1225,10 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
 
 	netif_carrier_off(sdata->dev);
 
+	/* abort any running channel switch */
+	sdata->vif.bss_conf.csa_active = false;
+	ieee80211_vif_unblock_queues_csa(sdata);
+
 	/* flush STAs and mpaths on this iface */
 	sta_info_flush(sdata, -1);
 	ieee80211_free_keys(sdata, true);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 064/877] wifi: mac80211: reset state when starting AP fails
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (62 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 063/877] wifi: mac80211: abort chanswitch when leaving a mesh Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 065/877] wifi: mac80211: unlist vifs when their netdev is unregistered Greg Kroah-Hartman
                   ` (820 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+ca7a2759caaa6cd4e3db,
	syzbot+c4686c3eb8b64032618f, Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit 3f28551d0241254a75626d868041c6340285088b ]

ieee80211_start_ap() can set enable_beacon (and beacon_int) and fail
later, leaving it set forever. Scanning can then attempt to restore
beaconing on such an interface, leading to:

  Oops: divide error: 0000 [#1] SMP KASAN NOPTI
  RIP: 0010:mac80211_hwsim_link_info_changed+0xca7/0xf00
  Call Trace:
   drv_link_info_changed+0x413/0x860 net/mac80211/driver-ops.c:495
   ieee80211_link_info_change_notify+0x24b/0x3c0 net/mac80211/main.c:427
   ieee80211_offchannel_return+0x381/0x580 net/mac80211/offchannel.c:160
   __ieee80211_scan_completed+0x993/0xe30 net/mac80211/scan.c:519
   ieee80211_scan_work+0x472/0x2010 net/mac80211/scan.c:1193
   cfg80211_wiphy_work+0x2b7/0x550 net/wireless/core.c:538

in hwsim. Also, cfg80211 then allows changing the interface type,
and the off-channel path getgs confused about beaconing as well,
leading to another warning:

  WARNING: net/mac80211/driver-ops.c:468 at drv_link_info_changed+0x583/0x880
   ieee80211_link_info_change_notify+0x24b/0x3c0 net/mac80211/main.c:427
   ieee80211_offchannel_stop_vifs+0x328/0x5c0 net/mac80211/offchannel.c:122
   ieee80211_start_sw_scan net/mac80211/scan.c:583 [inline]
   __ieee80211_start_scan+0xfb6/0x1af0 net/mac80211/scan.c:882

Reset the state on failures to always have it correct.

Assisted-by: LLM
Fixes: d6a83228823f ("mac80211: track enable_beacon explicitly")
Reported-by: syzbot+ca7a2759caaa6cd4e3db@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=ca7a2759caaa6cd4e3db
Reported-by: syzbot+c4686c3eb8b64032618f@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=c4686c3eb8b64032618f
Link: https://patch.msgid.link/20260904165722.9629429a5221.I7f599412bfe12a09d41ea4901be9ad165d07d133@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/cfg.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 73d7183c1ce59..71310d708dbc4 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1514,6 +1514,9 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
 	return 0;
 
 error:
+	link_conf->enable_beacon = false;
+	link_conf->beacon_int = prev_beacon_int;
+	sdata->vif.cfg.ssid_len = 0;
 	ieee80211_link_release_channel(link);
 
 	return err;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 065/877] wifi: mac80211: unlist vifs when their netdev is unregistered
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (63 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 064/877] wifi: mac80211: reset state when starting AP fails Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 066/877] wifi: mac80211_hwsim: dont hand frames to mac80211 while stopping Greg Kroah-Hartman
                   ` (819 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit eee2efd82867b623982ac51925b5a1812a74c50d ]

mac80211 only removes vifs from the local->interfaces list when
an interface is removed via ieee80211_if_remove(), before it
unregisters the netdev. However, it's possible for a netdev to
be unregistered without going through that: When the netns that
holds the wiphy is destroyed, the wiphy is supposed to move to
the init_ns, but that can run into allocation failures.

Then, mac80211 has an interface listed that doesn't exist, and
will eventually hit

  BUG: failure at net/wireless/core.h:141/wiphy_to_rdev()!
  ...
  _cfg80211_unregister_wdev+0x24/0x36a [cfg80211]
  cfg80211_unregister_wdev+0x15/0x1d [cfg80211]
  ieee80211_remove_interfaces+0x1ff/0x257 [mac80211]
  ieee80211_unregister_hw+0x73/0x1d1 [mac80211]
  mac80211_hwsim_del_radio+0x114/0x166 [mac80211_hwsim]

Remove the interface from the list in ->ndo_uninit if it's still
around to avoid this.

Assisted-by: LLM
Fixes: 463d018323851 ("cfg80211: make aware of net namespaces")
Link: https://patch.msgid.link/20260904170220.038ad73e6c04.I990abca78483e058746b6f42b4796717c3028164@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/iface.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 98bc924d74fa6..ac0a7374d721a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -862,9 +862,33 @@ static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata)
 	ieee80211_link_stop(&sdata->deflink);
 }
 
+/*
+ * The netdev can be unregistered without mac80211 doing it, e.g. by the netdev
+ * core when cfg80211 couldn't move it out of a network namespace that's being
+ * destroyed. Drop it from the interface list either way.
+ */
+static void ieee80211_unlist_sdata(struct ieee80211_sub_if_data *sdata)
+{
+	struct ieee80211_local *local = sdata->local;
+	struct ieee80211_sub_if_data *iter;
+
+	ASSERT_RTNL();
+
+	list_for_each_entry(iter, &local->interfaces, list) {
+		if (iter != sdata)
+			continue;
+		guard(mutex)(&local->iflist_mtx);
+		list_del_rcu(&sdata->list);
+		return;
+	}
+}
+
 static void ieee80211_uninit(struct net_device *dev)
 {
-	ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev));
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+	ieee80211_unlist_sdata(sdata);
+	ieee80211_teardown_sdata(sdata);
 }
 
 static int ieee80211_netdev_setup_tc(struct net_device *dev,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 066/877] wifi: mac80211_hwsim: dont hand frames to mac80211 while stopping
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (64 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 065/877] wifi: mac80211: unlist vifs when their netdev is unregistered Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 067/877] wifi: cfg80211: skip regulatory for punctured subchannels Greg Kroah-Hartman
                   ` (818 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+b4aa2b672b18f1d4dc5f,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit 87840d4a3a21b1c19b867a80e16ba69dff284de2 ]

The code checks ->started for frames coming from wmediumd, but the
radio can be stopped after the check and before frame delivery,
causing mac80211 to hit the WARN_ON(!local->started).

Expand the mutex for this case and synchronise against it when the
radio is stopped to avoid being able to hit the warning with hwsim.

Drop the error print that would've complicated the error path, it
only triggers for allocation failures (already noisy) and malformed
frames anyway.

Assisted-by: LLM
Fixes: 7882513bacb1 ("mac80211_hwsim driver support userspace frame tx/rx")
Reported-by: syzbot+b4aa2b672b18f1d4dc5f@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=b4aa2b672b18f1d4dc5f
Link: https://patch.msgid.link/20260904170140.5f69a10d606b.I4a7921d00643f69e439c7a3b221d104f66a3dcdc@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/wireless/virtual/mac80211_hwsim.c | 39 ++++++++++++-------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
index 9410059e97f01..f1b96cd1198c5 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
@@ -2120,7 +2120,12 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw, bool suspend)
 	struct sk_buff *skb;
 	int i;
 
-	data->started = false;
+	/*
+	 * Serialise against wmediumd userspace, so no more frames
+	 * can be handed to mac80211 after this returns.
+	 */
+	scoped_guard(mutex, &data->mutex)
+		data->started = false;
 
 	for (i = 0; i < ARRAY_SIZE(data->link_data); i++)
 		hrtimer_cancel(&data->link_data[i].beacon_timer);
@@ -5851,12 +5856,12 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
 
 	if (frame_data_len < sizeof(struct ieee80211_hdr_3addr) ||
 	    frame_data_len > IEEE80211_MAX_DATA_LEN)
-		goto err;
+		goto out;
 
 	/* Allocate new skb here */
 	skb = alloc_skb(frame_data_len, GFP_KERNEL);
 	if (skb == NULL)
-		goto err;
+		goto out;
 
 	/* Copy the data */
 	skb_put_data(skb, frame_data, frame_data_len);
@@ -5881,10 +5886,17 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
 			goto out;
 	}
 
+	/*
+	 * Serialise against mac80211_hwsim_stop() - mac80211 doesn't allow
+	 * frames reported while the HW is down, hence the ->started check
+	 * must be under mutex.
+	 */
+	mutex_lock(&data2->mutex);
+
 	/* check if radio is configured properly */
 
 	if ((data2->idle && !data2->tmp_chan) || !data2->started)
-		goto out;
+		goto out_unlock;
 
 	/* A frame is received from user space */
 	memset(&rx_status, 0, sizeof(rx_status));
@@ -5900,22 +5912,18 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
 		iter_data.channel = ieee80211_get_channel(data2->hw->wiphy,
 							  rx_status.freq);
 		if (!iter_data.channel)
-			goto out;
+			goto out_unlock;
 		rx_status.band = iter_data.channel->band;
 
-		mutex_lock(&data2->mutex);
 		if (!hwsim_chans_compat(iter_data.channel, channel)) {
 			ieee80211_iterate_active_interfaces_atomic(
 				data2->hw, IEEE80211_IFACE_ITER_NORMAL,
 				mac80211_hwsim_tx_iter, &iter_data);
-			if (!iter_data.receive) {
-				mutex_unlock(&data2->mutex);
-				goto out;
-			}
+			if (!iter_data.receive)
+				goto out_unlock;
 		}
-		mutex_unlock(&data2->mutex);
 	} else if (!channel) {
-		goto out;
+		goto out_unlock;
 	} else {
 		rx_status.freq = channel->center_freq;
 		rx_status.band = channel->band;
@@ -5923,7 +5931,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
 
 	rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
 	if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates)
-		goto out;
+		goto out_unlock;
 	rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
 
 	hdr = (void *)skb->data;
@@ -5933,10 +5941,11 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
 		rx_status.boottime_ns = ktime_get_boottime_ns();
 
 	mac80211_hwsim_rx(data2, &rx_status, skb);
+	mutex_unlock(&data2->mutex);
 
 	return 0;
-err:
-	pr_debug("mac80211_hwsim: error occurred in %s\n", __func__);
+out_unlock:
+	mutex_unlock(&data2->mutex);
 out:
 	dev_kfree_skb(skb);
 	return -EINVAL;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 067/877] wifi: cfg80211: skip regulatory for punctured subchannels
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (65 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 066/877] wifi: mac80211_hwsim: dont hand frames to mac80211 while stopping Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 068/877] wifi: cfg80211: expose cfg80211_chandef_get_width() Greg Kroah-Hartman
                   ` (817 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Manaswini Paluri, Kavita Kavita,
	Johannes Berg, Sasha Levin

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

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

From: Kavita Kavita <quic_kkavita@quicinc.com>

[ Upstream commit 9add053591ed9d126b6f071236e33e762c439fa8 ]

The kernel performs several regulatory checks for AP mode in
nl80211/cfg80211. These checks include radar detection,
verification of whether the sub-channel is disabled, and
an examination to determine if the channel is a DFS channel
(both DFS usable and DFS available). These checks are
performed across a frequency range, examining each sub-channel.

However, these checks are also performed on subchannels that
have been punctured which should not be examined as they are
not in use.

This leads to the issue where the AP stops because one of
the 20 MHz sub-channels is disabled or radar detected on
the channel, even when the sub-channel is punctured.

To address this issue, add a condition check wherever
regulatory checks exist for AP mode in nl80211/cfg80211.
This check identifies punctured channels and, upon finding
them, skips the regulatory checks for those channels.

Co-developed-by: Manaswini Paluri <quic_mpaluri@quicinc.com>
Signed-off-by: Manaswini Paluri <quic_mpaluri@quicinc.com>
Signed-off-by: Kavita Kavita <quic_kkavita@quicinc.com>
Link: https://patch.msgid.link/20250109050409.25351-1-quic_kkavita@quicinc.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Stable-dep-of: e14bf37bb2b3 ("wifi: mac80211: don't allow injecting frames wider than the chanctx")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/wireless/chan.c | 370 +++++++++++++++-----------------------------
 1 file changed, 123 insertions(+), 247 deletions(-)

diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 515d40c09e788..b1a8d17baa62a 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -55,6 +55,56 @@ void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
 }
 EXPORT_SYMBOL(cfg80211_chandef_create);
 
+static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
+{
+	return nl80211_chan_width_to_mhz(c->width);
+}
+
+static u32 cfg80211_get_start_freq(const struct cfg80211_chan_def *chandef,
+				   u32 cf)
+{
+	u32 start_freq, center_freq, bandwidth;
+
+	center_freq = MHZ_TO_KHZ((cf == 1) ?
+			chandef->center_freq1 : chandef->center_freq2);
+	bandwidth = MHZ_TO_KHZ(cfg80211_chandef_get_width(chandef));
+
+	if (bandwidth <= MHZ_TO_KHZ(20))
+		start_freq = center_freq;
+	else
+		start_freq = center_freq - bandwidth / 2 + MHZ_TO_KHZ(10);
+
+	return start_freq;
+}
+
+static u32 cfg80211_get_end_freq(const struct cfg80211_chan_def *chandef,
+				 u32 cf)
+{
+	u32 end_freq, center_freq, bandwidth;
+
+	center_freq = MHZ_TO_KHZ((cf == 1) ?
+			chandef->center_freq1 : chandef->center_freq2);
+	bandwidth = MHZ_TO_KHZ(cfg80211_chandef_get_width(chandef));
+
+	if (bandwidth <= MHZ_TO_KHZ(20))
+		end_freq = center_freq;
+	else
+		end_freq = center_freq + bandwidth / 2 - MHZ_TO_KHZ(10);
+
+	return end_freq;
+}
+
+#define for_each_subchan(chandef, freq, cf)				\
+	for (u32 punctured = chandef->punctured,			\
+	     cf = 1, freq = cfg80211_get_start_freq(chandef, cf);	\
+	     freq <= cfg80211_get_end_freq(chandef, cf);		\
+	     freq += MHZ_TO_KHZ(20),					\
+	     ((cf == 1 && chandef->center_freq2 != 0 &&			\
+	       freq > cfg80211_get_end_freq(chandef, cf)) ?		\
+	      (cf++, freq = cfg80211_get_start_freq(chandef, cf),	\
+	       punctured = 0) : (punctured >>= 1)))			\
+		if (!(punctured & 1))
+
 struct cfg80211_per_bw_puncturing_values {
 	u8 len;
 	const u16 *valid_values;
@@ -258,11 +308,6 @@ int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width)
 }
 EXPORT_SYMBOL(nl80211_chan_width_to_mhz);
 
-static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
-{
-	return nl80211_chan_width_to_mhz(c->width);
-}
-
 static bool cfg80211_valid_center_freq(u32 center,
 				       enum nl80211_chan_width width)
 {
@@ -582,29 +627,11 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
 }
 EXPORT_SYMBOL(cfg80211_chandef_compatible);
 
-static void cfg80211_set_chans_dfs_state(struct wiphy *wiphy, u32 center_freq,
-					 u32 bandwidth,
-					 enum nl80211_dfs_state dfs_state)
-{
-	struct ieee80211_channel *c;
-	u32 freq;
-
-	for (freq = center_freq - bandwidth/2 + 10;
-	     freq <= center_freq + bandwidth/2 - 10;
-	     freq += 20) {
-		c = ieee80211_get_channel(wiphy, freq);
-		if (!c || !(c->flags & IEEE80211_CHAN_RADAR))
-			continue;
-
-		c->dfs_state = dfs_state;
-		c->dfs_state_entered = jiffies;
-	}
-}
-
 void cfg80211_set_dfs_state(struct wiphy *wiphy,
 			    const struct cfg80211_chan_def *chandef,
 			    enum nl80211_dfs_state dfs_state)
 {
+	struct ieee80211_channel *c;
 	int width;
 
 	if (WARN_ON(!cfg80211_chandef_valid(chandef)))
@@ -614,41 +641,14 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy,
 	if (width < 0)
 		return;
 
-	cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq1,
-				     width, dfs_state);
-
-	if (!chandef->center_freq2)
-		return;
-	cfg80211_set_chans_dfs_state(wiphy, chandef->center_freq2,
-				     width, dfs_state);
-}
-
-static u32 cfg80211_get_start_freq(u32 center_freq,
-				   u32 bandwidth)
-{
-	u32 start_freq;
-
-	bandwidth = MHZ_TO_KHZ(bandwidth);
-	if (bandwidth <= MHZ_TO_KHZ(20))
-		start_freq = center_freq;
-	else
-		start_freq = center_freq - bandwidth / 2 + MHZ_TO_KHZ(10);
-
-	return start_freq;
-}
-
-static u32 cfg80211_get_end_freq(u32 center_freq,
-				 u32 bandwidth)
-{
-	u32 end_freq;
-
-	bandwidth = MHZ_TO_KHZ(bandwidth);
-	if (bandwidth <= MHZ_TO_KHZ(20))
-		end_freq = center_freq;
-	else
-		end_freq = center_freq + bandwidth / 2 - MHZ_TO_KHZ(10);
+	for_each_subchan(chandef, freq, cf) {
+		c = ieee80211_get_channel_khz(wiphy, freq);
+		if (!c || !(c->flags & IEEE80211_CHAN_RADAR))
+			continue;
 
-	return end_freq;
+		c->dfs_state = dfs_state;
+		c->dfs_state_entered = jiffies;
+	}
 }
 
 static bool
@@ -725,17 +725,12 @@ static bool cfg80211_dfs_permissive_chan(struct wiphy *wiphy,
 }
 
 static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy,
-					    u32 center_freq,
-					    u32 bandwidth,
-					    enum nl80211_iftype iftype)
+					   const struct cfg80211_chan_def *chandef,
+					   enum nl80211_iftype iftype)
 {
 	struct ieee80211_channel *c;
-	u32 freq, start_freq, end_freq;
-
-	start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
-	end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
 
-	for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
+	for_each_subchan(chandef, freq, cf) {
 		c = ieee80211_get_channel_khz(wiphy, freq);
 		if (!c)
 			return -EINVAL;
@@ -768,25 +763,9 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
 		if (width < 0)
 			return -EINVAL;
 
-		ret = cfg80211_get_chans_dfs_required(wiphy,
-					ieee80211_chandef_to_khz(chandef),
-					width, iftype);
-		if (ret < 0)
-			return ret;
-		else if (ret > 0)
-			return BIT(chandef->width);
-
-		if (!chandef->center_freq2)
-			return 0;
-
-		ret = cfg80211_get_chans_dfs_required(wiphy,
-					MHZ_TO_KHZ(chandef->center_freq2),
-					width, iftype);
-		if (ret < 0)
-			return ret;
-		else if (ret > 0)
-			return BIT(chandef->width);
+		ret = cfg80211_get_chans_dfs_required(wiphy, chandef, iftype);
 
+		return (ret > 0) ? BIT(chandef->width) : ret;
 		break;
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_OCB:
@@ -806,16 +785,18 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
 }
 EXPORT_SYMBOL(cfg80211_chandef_dfs_required);
 
-static int cfg80211_get_chans_dfs_usable(struct wiphy *wiphy,
-					 u32 center_freq,
-					 u32 bandwidth)
+bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
+				 const struct cfg80211_chan_def *chandef)
 {
 	struct ieee80211_channel *c;
-	u32 freq, start_freq, end_freq;
-	int count = 0;
+	int width, count = 0;
 
-	start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
-	end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
+	if (WARN_ON(!cfg80211_chandef_valid(chandef)))
+		return false;
+
+	width = cfg80211_chandef_get_width(chandef);
+	if (width < 0)
+		return false;
 
 	/*
 	 * Check entire range of channels for the bandwidth.
@@ -823,61 +804,24 @@ static int cfg80211_get_chans_dfs_usable(struct wiphy *wiphy,
 	 * DFS_AVAILABLE). Return number of usable channels
 	 * (require CAC). Allow DFS and non-DFS channel mix.
 	 */
-	for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
+	for_each_subchan(chandef, freq, cf) {
 		c = ieee80211_get_channel_khz(wiphy, freq);
 		if (!c)
-			return -EINVAL;
+			return false;
 
 		if (c->flags & IEEE80211_CHAN_DISABLED)
-			return -EINVAL;
+			return false;
 
 		if (c->flags & IEEE80211_CHAN_RADAR) {
 			if (c->dfs_state == NL80211_DFS_UNAVAILABLE)
-				return -EINVAL;
+				return false;
 
 			if (c->dfs_state == NL80211_DFS_USABLE)
 				count++;
 		}
 	}
 
-	return count;
-}
-
-bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
-				 const struct cfg80211_chan_def *chandef)
-{
-	int width;
-	int r1, r2 = 0;
-
-	if (WARN_ON(!cfg80211_chandef_valid(chandef)))
-		return false;
-
-	width = cfg80211_chandef_get_width(chandef);
-	if (width < 0)
-		return false;
-
-	r1 = cfg80211_get_chans_dfs_usable(wiphy,
-					   MHZ_TO_KHZ(chandef->center_freq1),
-					   width);
-
-	if (r1 < 0)
-		return false;
-
-	switch (chandef->width) {
-	case NL80211_CHAN_WIDTH_80P80:
-		WARN_ON(!chandef->center_freq2);
-		r2 = cfg80211_get_chans_dfs_usable(wiphy,
-					MHZ_TO_KHZ(chandef->center_freq2),
-					width);
-		if (r2 < 0)
-			return false;
-		break;
-	default:
-		WARN_ON(chandef->center_freq2);
-		break;
-	}
-
-	return (r1 + r2 > 0);
+	return count > 0;
 }
 EXPORT_SYMBOL(cfg80211_chandef_dfs_usable);
 
@@ -1051,26 +995,29 @@ bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy,
 	return false;
 }
 
-static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
-					     u32 center_freq,
-					     u32 bandwidth)
+static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
+				const struct cfg80211_chan_def *chandef)
 {
 	struct ieee80211_channel *c;
-	u32 freq, start_freq, end_freq;
+	int width;
 	bool dfs_offload;
 
+	if (WARN_ON(!cfg80211_chandef_valid(chandef)))
+		return false;
+
+	width = cfg80211_chandef_get_width(chandef);
+	if (width < 0)
+		return false;
+
 	dfs_offload = wiphy_ext_feature_isset(wiphy,
 					      NL80211_EXT_FEATURE_DFS_OFFLOAD);
 
-	start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
-	end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
-
 	/*
 	 * Check entire range of channels for the bandwidth.
 	 * If any channel in between is disabled or has not
 	 * had gone through CAC return false
 	 */
-	for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
+	for_each_subchan(chandef, freq, cf) {
 		c = ieee80211_get_channel_khz(wiphy, freq);
 		if (!c)
 			return false;
@@ -1087,124 +1034,54 @@ static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
 	return true;
 }
 
-static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
-				const struct cfg80211_chan_def *chandef)
+unsigned int
+cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
+			      const struct cfg80211_chan_def *chandef)
 {
+	struct ieee80211_channel *c;
 	int width;
-	int r;
+	unsigned int t1 = 0, t2 = 0;
 
 	if (WARN_ON(!cfg80211_chandef_valid(chandef)))
-		return false;
+		return 0;
 
 	width = cfg80211_chandef_get_width(chandef);
 	if (width < 0)
-		return false;
-
-	r = cfg80211_get_chans_dfs_available(wiphy,
-					     MHZ_TO_KHZ(chandef->center_freq1),
-					     width);
-
-	/* If any of channels unavailable for cf1 just return */
-	if (!r)
-		return r;
-
-	switch (chandef->width) {
-	case NL80211_CHAN_WIDTH_80P80:
-		WARN_ON(!chandef->center_freq2);
-		r = cfg80211_get_chans_dfs_available(wiphy,
-					MHZ_TO_KHZ(chandef->center_freq2),
-					width);
-		break;
-	default:
-		WARN_ON(chandef->center_freq2);
-		break;
-	}
-
-	return r;
-}
-
-static unsigned int cfg80211_get_chans_dfs_cac_time(struct wiphy *wiphy,
-						    u32 center_freq,
-						    u32 bandwidth)
-{
-	struct ieee80211_channel *c;
-	u32 start_freq, end_freq, freq;
-	unsigned int dfs_cac_ms = 0;
-
-	start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
-	end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
+		return 0;
 
-	for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
+	for_each_subchan(chandef, freq, cf) {
 		c = ieee80211_get_channel_khz(wiphy, freq);
-		if (!c)
-			return 0;
-
-		if (c->flags & IEEE80211_CHAN_DISABLED)
-			return 0;
+		if (!c || (c->flags & IEEE80211_CHAN_DISABLED)) {
+			if (cf == 1)
+				t1 = INT_MAX;
+			else
+				t2 = INT_MAX;
+			continue;
+		}
 
 		if (!(c->flags & IEEE80211_CHAN_RADAR))
 			continue;
 
-		if (c->dfs_cac_ms > dfs_cac_ms)
-			dfs_cac_ms = c->dfs_cac_ms;
-	}
-
-	return dfs_cac_ms;
-}
-
-unsigned int
-cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
-			      const struct cfg80211_chan_def *chandef)
-{
-	int width;
-	unsigned int t1 = 0, t2 = 0;
+		if (cf == 1 && c->dfs_cac_ms > t1)
+			t1 = c->dfs_cac_ms;
 
-	if (WARN_ON(!cfg80211_chandef_valid(chandef)))
-		return 0;
+		if (cf == 2 && c->dfs_cac_ms > t2)
+			t2 = c->dfs_cac_ms;
+	}
 
-	width = cfg80211_chandef_get_width(chandef);
-	if (width < 0)
+	if (t1 == INT_MAX && t2 == INT_MAX)
 		return 0;
 
-	t1 = cfg80211_get_chans_dfs_cac_time(wiphy,
-					     MHZ_TO_KHZ(chandef->center_freq1),
-					     width);
+	if (t1 == INT_MAX)
+		return t2;
 
-	if (!chandef->center_freq2)
+	if (t2 == INT_MAX)
 		return t1;
 
-	t2 = cfg80211_get_chans_dfs_cac_time(wiphy,
-					     MHZ_TO_KHZ(chandef->center_freq2),
-					     width);
-
 	return max(t1, t2);
 }
 EXPORT_SYMBOL(cfg80211_chandef_dfs_cac_time);
 
-static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
-					u32 center_freq, u32 bandwidth,
-					u32 prohibited_flags,
-					u32 permitting_flags)
-{
-	struct ieee80211_channel *c;
-	u32 freq, start_freq, end_freq;
-
-	start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
-	end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
-
-	for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
-		c = ieee80211_get_channel_khz(wiphy, freq);
-		if (!c)
-			return false;
-		if (c->flags & permitting_flags)
-			continue;
-		if (c->flags & prohibited_flags)
-			return false;
-	}
-
-	return true;
-}
-
 /* check if the operating channels are valid and supported */
 static bool cfg80211_edmg_usable(struct wiphy *wiphy, u8 edmg_channels,
 				 enum ieee80211_edmg_bw_config edmg_bw_config,
@@ -1270,6 +1147,7 @@ bool _cfg80211_chandef_usable(struct wiphy *wiphy,
 	bool ext_nss_cap, support_80_80 = false, support_320 = false;
 	const struct ieee80211_sband_iftype_data *iftd;
 	struct ieee80211_supported_band *sband;
+	struct ieee80211_channel *c;
 	int i;
 
 	if (WARN_ON(!cfg80211_chandef_valid(chandef)))
@@ -1420,19 +1298,17 @@ bool _cfg80211_chandef_usable(struct wiphy *wiphy,
 	if (width < 20)
 		prohibited_flags |= IEEE80211_CHAN_NO_OFDM;
 
+	for_each_subchan(chandef, freq, cf) {
+		c = ieee80211_get_channel_khz(wiphy, freq);
+		if (!c)
+			return false;
+		if (c->flags & permitting_flags)
+			continue;
+		if (c->flags & prohibited_flags)
+			return false;
+	}
 
-	if (!cfg80211_secondary_chans_ok(wiphy,
-					 ieee80211_chandef_to_khz(chandef),
-					 width, prohibited_flags,
-					 permitting_flags))
-		return false;
-
-	if (!chandef->center_freq2)
-		return true;
-	return cfg80211_secondary_chans_ok(wiphy,
-					   MHZ_TO_KHZ(chandef->center_freq2),
-					   width, prohibited_flags,
-					   permitting_flags);
+	return true;
 }
 
 bool cfg80211_chandef_usable(struct wiphy *wiphy,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 068/877] wifi: cfg80211: expose cfg80211_chandef_get_width()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (66 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 067/877] wifi: cfg80211: skip regulatory for punctured subchannels Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 069/877] wifi: mac80211: dont allow injecting frames wider than the chanctx Greg Kroah-Hartman
                   ` (816 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Miriam Rachel Korenblit,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit b5c1622762f0937a66b69b7f15466c28fe85dcf1 ]

This can be just a trivial inline, to simplify some code.
Expose it, and also use it in util.c where it wasn't
previously available.

Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250311122534.c5c3b4af9a74.Ib25cf60f634dc359961182113214e5cdc3504e9c@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Stable-dep-of: e14bf37bb2b3 ("wifi: mac80211: don't allow injecting frames wider than the chanctx")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/net/cfg80211.h | 11 +++++++++++
 net/wireless/chan.c    |  5 -----
 net/wireless/util.c    |  4 ++--
 3 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f3915118c15d7..ede91e4709ee5 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1008,6 +1008,17 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *chandef1,
  */
 int nl80211_chan_width_to_mhz(enum nl80211_chan_width chan_width);
 
+/**
+ * cfg80211_chandef_get_width - return chandef width in MHz
+ * @c: chandef to return bandwidth for
+ * Return: channel width in MHz for the given chandef; note that it returns
+ *	80 for 80+80 configurations
+ */
+static inline int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
+{
+	return nl80211_chan_width_to_mhz(c->width);
+}
+
 /**
  * cfg80211_chandef_valid - check if a channel definition is valid
  * @chandef: the channel definition to check
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index b1a8d17baa62a..6f4b4770bf50b 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -55,11 +55,6 @@ void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
 }
 EXPORT_SYMBOL(cfg80211_chandef_create);
 
-static int cfg80211_chandef_get_width(const struct cfg80211_chan_def *c)
-{
-	return nl80211_chan_width_to_mhz(c->width);
-}
-
 static u32 cfg80211_get_start_freq(const struct cfg80211_chan_def *chandef,
 				   u32 cf)
 {
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 8cc205b9f105c..66f95044adb2a 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -5,7 +5,7 @@
  * Copyright 2007-2009	Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
  * Copyright 2017	Intel Deutschland GmbH
- * Copyright (C) 2018-2023 Intel Corporation
+ * Copyright (C) 2018-2023, 2025 Intel Corporation
  */
 #include <linux/export.h>
 #include <linux/bitops.h>
@@ -2954,7 +2954,7 @@ bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio,
 	u32 freq, width;
 
 	freq = ieee80211_chandef_to_khz(chandef);
-	width = nl80211_chan_width_to_mhz(chandef->width);
+	width = cfg80211_chandef_get_width(chandef);
 	if (!ieee80211_radio_freq_range_valid(radio, freq, width))
 		return false;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 069/877] wifi: mac80211: dont allow injecting frames wider than the chanctx
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (67 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 068/877] wifi: cfg80211: expose cfg80211_chandef_get_width() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 070/877] wifi: mac80211: reset the AP_VLAN tailroom counter on ifdown Greg Kroah-Hartman
                   ` (815 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+435fdb053cf98bfa5778,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit e14bf37bb2b3853012ff160131d1c6233f7a9cc9 ]

Frames injected on a monitor interface can carry a radiotap
field requesting a bandwidth, which mac80211 passes down to
the driver regardless of the the actual operational bandwidth.

If the bandwidth requested is too wide, that triggers a warning
in hwsim:

  WARN_ON(hwsim_get_chanwidth(bw) > hwsim_get_chanwidth(confbw))

Drop such frames entirely instead since they cannot be sent.

Assisted-by: LLM
Fixes: 646e76bb5daf ("mac80211: parse VHT info in injected frames")
Reported-by: syzbot+435fdb053cf98bfa5778@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=435fdb053cf98bfa5778
Link: https://patch.msgid.link/20260908122838.201719-13-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/net/mac80211.h |  5 ++++-
 net/mac80211/iface.c   |  2 +-
 net/mac80211/tx.c      | 28 ++++++++++++++++++++++++++--
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 7d71a4149cdf9..41ae682015fc0 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -7228,11 +7228,14 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
  *
  * @skb: packet injected by userspace
  * @dev: the &struct device of this 802.11 device
+ * @chandef: the channel definition the frame will be transmitted on, or
+ *	%NULL to skip the bandwidth checks
  *
  * Return: %true if the radiotap header was parsed, %false otherwise
  */
 bool ieee80211_parse_tx_radiotap(struct sk_buff *skb,
-				 struct net_device *dev);
+				 struct net_device *dev,
+				 const struct cfg80211_chan_def *chandef);
 
 /**
  * struct ieee80211_noa_data - holds temporary data for tracking P2P NoA state
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index ac0a7374d721a..3726dded1959a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -929,7 +929,7 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev,
 	/* reset flags and info before parsing radiotap header */
 	memset(info, 0, sizeof(*info));
 
-	if (!ieee80211_parse_tx_radiotap(skb, dev))
+	if (!ieee80211_parse_tx_radiotap(skb, dev, NULL))
 		return 0; /* doesn't matter, frame will be dropped */
 
 	len_rthdr = ieee80211_get_radiotap_len(skb->data);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 9bc1a80e80570..e78e71cb92f7f 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2084,8 +2084,29 @@ static bool ieee80211_validate_radiotap_len(struct sk_buff *skb)
 	return true;
 }
 
+static bool ieee80211_rate_bw_usable(u16 rate_flags,
+				     const struct cfg80211_chan_def *chandef)
+{
+	int width;
+
+	if (!chandef)
+		return true;
+
+	if (rate_flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
+		width = 160;
+	else if (rate_flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
+		width = 80;
+	else if (rate_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+		width = 40;
+	else
+		return true;
+
+	return width <= cfg80211_chandef_get_width(chandef);
+}
+
 bool ieee80211_parse_tx_radiotap(struct sk_buff *skb,
-				 struct net_device *dev)
+				 struct net_device *dev,
+				 const struct cfg80211_chan_def *chandef)
 {
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_radiotap_iterator iterator;
@@ -2259,6 +2280,9 @@ bool ieee80211_parse_tx_radiotap(struct sk_buff *skb,
 		struct ieee80211_supported_band *sband =
 			local->hw.wiphy->bands[info->band];
 
+		if (!ieee80211_rate_bw_usable(rate_flags, chandef))
+			return false;
+
 		info->control.flags |= IEEE80211_TX_CTRL_RATE_INJECT;
 
 		for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
@@ -2448,7 +2472,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
 	 * selected chandef above to accurately set injection rates and
 	 * retransmissions.
 	 */
-	if (!ieee80211_parse_tx_radiotap(skb, dev))
+	if (!ieee80211_parse_tx_radiotap(skb, dev, chandef))
 		goto fail_rcu;
 
 	/* remove the injection radiotap header */
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 070/877] wifi: mac80211: reset the AP_VLAN tailroom counter on ifdown
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (68 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 069/877] wifi: mac80211: dont allow injecting frames wider than the chanctx Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 071/877] wifi: mac80211: require a peer station for TDLS setup confirm Greg Kroah-Hartman
                   ` (814 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+de3ee5362db09487ea37,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit 4504f3960dc4501c73be9f99eabda2e26e9db41e ]

On ifup, AP_VLAN interfaces get crypto_tx_tailroom_needed_cnt from
the AP interface, but it's never decremented again unless the AP is
also brought down. Thus, bringing the same AP_VLAN up again will
increment the counter again and eventually hit the sanity check:

  WARN_ON_ONCE(sdata->crypto_tx_tailroom_needed_cnt !=
               master->crypto_tx_tailroom_needed_cnt);

Reset it on ifdown to avoid that.

Assisted-by: LLM
Fixes: f9dca80b98ca ("mac80211: fix AP_VLAN crypto tailroom calculation")
Reported-by: syzbot+de3ee5362db09487ea37@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=de3ee5362db09487ea37
Link: https://patch.msgid.link/20260908122838.201719-14-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/iface.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 3726dded1959a..14a80583956c1 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -618,6 +618,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
 		RCU_INIT_POINTER(sdata->vif.bss_conf.chanctx_conf, NULL);
 		/* see comment in the default case below */
 		ieee80211_free_keys(sdata, true);
+		/* increased by AP value on ifup, so reset on ifdown */
+		sdata->crypto_tx_tailroom_needed_cnt = 0;
 		/* no need to tell driver */
 		break;
 	case NL80211_IFTYPE_MONITOR:
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 071/877] wifi: mac80211: require a peer station for TDLS setup confirm
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (69 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 070/877] wifi: mac80211: reset the AP_VLAN tailroom counter on ifdown Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 072/877] wifi: mac80211: dont allow link changes when iface is down Greg Kroah-Hartman
                   ` (813 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+e55106f8389651870be0,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit 038e1d126304fd25d507fd4e671232df57bd1799 ]

It's nonsense for the setup confirm to go to station that
doesn't even exist, and it hits a warning when building
the frame:

  WARN_ON_ONCE(!sta || !ap_sta)

Only accept WLAN_TDLS_SETUP_CONFIRM when the station is
already there as a TDLS station. Need to copy the call
to ieee80211_tdls_prep_mgmt_packet() since the existing
WLAN_TDLS_DISCOVERY_REQUEST already falls through to it.

Assisted-by: LLM
Fixes: 6f7eaa47e1de ("mac80211: add TDLS QoS param IE on setup-confirm")
Reported-by: syzbot+e55106f8389651870be0@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=e55106f8389651870be0
Link: https://patch.msgid.link/20260908122838.201719-15-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/tdls.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index 92ab7be3d4824..b4bedf0b2b552 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -1285,6 +1285,24 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
 						   peer_capability, initiator,
 						   extra_ies, extra_ies_len);
 		break;
+	case WLAN_TDLS_SETUP_CONFIRM: {
+		struct sta_info *sta;
+
+		sta = sta_info_get(sdata, peer);
+		if (!sta || !sta->sta.tdls) {
+			ret = -ENOLINK;
+			break;
+		}
+
+		ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer,
+						      link_id, action_code,
+						      dialog_token,
+						      status_code,
+						      peer_capability,
+						      initiator, extra_ies,
+						      extra_ies_len, 0, NULL);
+		break;
+	}
 	case WLAN_TDLS_DISCOVERY_REQUEST:
 		/*
 		 * Protect the discovery so we can hear the TDLS discovery
@@ -1293,7 +1311,6 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
 		 */
 		drv_mgd_protect_tdls_discover(sdata->local, sdata, link_id);
 		fallthrough;
-	case WLAN_TDLS_SETUP_CONFIRM:
 	case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
 		/* no special handling */
 		ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 072/877] wifi: mac80211: dont allow link changes when iface is down
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (70 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 071/877] wifi: mac80211: require a peer station for TDLS setup confirm Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 073/877] wifi: mac80211: dont RCU-dereference the mesh CSA settings we just set Greg Kroah-Hartman
                   ` (812 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+582469b3a9ef5f13606b,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit 370872d30349d81dec519e15ea2949fd63511cf7 ]

ieee80211_set_active_links() only checks that the interface is running in
the inner __ieee80211_set_active_links(), after drv_can_activate_links()
was already called, so using active_links on an interface that's down
triggers the check-sdata-in-driver warning.

Add the missing check in the debugfs file.

Assisted-by: LLM
Fixes: 3d9011029227 ("wifi: mac80211: implement link switching")
Reported-by: syzbot+582469b3a9ef5f13606b@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=582469b3a9ef5f13606b
Link: https://patch.msgid.link/20260908122838.201719-16-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/debugfs_netdev.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index d0b145888e139..bb5812925d82e 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -731,6 +731,9 @@ static ssize_t ieee80211_if_parse_active_links(struct ieee80211_sub_if_data *sda
 	if (kstrtou16(buf, 0, &active_links) || !active_links)
 		return -EINVAL;
 
+	if (!ieee80211_sdata_running(sdata))
+		return -ENETDOWN;
+
 	return ieee80211_set_active_links(&sdata->vif, active_links) ?: buflen;
 }
 IEEE80211_IF_FILE_RW(active_links);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 073/877] wifi: mac80211: dont RCU-dereference the mesh CSA settings we just set
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (71 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 072/877] wifi: mac80211: dont allow link changes when iface is down Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 074/877] wifi: mac80211: dont access the TSF of a down interface Greg Kroah-Hartman
                   ` (811 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+b59873f5699e941717ca,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit b481e64e4498e2c053d5954f546ee02338f6ab63 ]

In the error path of ieee80211_mesh_csa_beacon() the settings that were
just assigned are read back with rcu_dereference(), which lockdep then
complains about.

There's no need to read the pointer at all, tmp_csa_settings still is
the right value anyway.

Assisted-by: LLM
Fixes: b8456a14e9d2 ("{nl,cfg,mac}80211: implement mesh channel switch userspace API")
Reported-by: syzbot+b59873f5699e941717ca@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=b59873f5699e941717ca
Link: https://patch.msgid.link/20260908122838.201719-17-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/mesh.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 57cf3f90f7fbe..4c601b9cb3bb2 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1577,7 +1577,6 @@ int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata,
 
 	ret = ieee80211_mesh_rebuild_beacon(sdata);
 	if (ret) {
-		tmp_csa_settings = rcu_dereference(ifmsh->csa);
 		RCU_INIT_POINTER(ifmsh->csa, NULL);
 		kfree_rcu(tmp_csa_settings, rcu_head);
 		return ret;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 074/877] wifi: mac80211: dont access the TSF of a down interface
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (72 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 073/877] wifi: mac80211: dont RCU-dereference the mesh CSA settings we just set Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 075/877] wifi: mac80211: add HE 6 GHz capability in the scan elems len Greg Kroah-Hartman
                   ` (810 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+1c8c45017f784e646b47,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit 0b1de9feeb8651f7a3bb53ed7c9006e3b5298c01 ]

The tsf debugfs files call the driver even if the interface
isn't up, tgriggering check-sdata-in-driver warnings.

Reject the access in that case.

Assisted-by: LLM
Fixes: 37a41b4affa3 ("mac80211: add ieee80211_vif param to tsf functions")
Reported-by: syzbot+1c8c45017f784e646b47@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1c8c45017f784e646b47
Link: https://patch.msgid.link/20260908122838.201719-18-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/debugfs_netdev.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index bb5812925d82e..d3519bbc4285f 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -659,6 +659,9 @@ static ssize_t ieee80211_if_fmt_tsf(
 	struct ieee80211_local *local = sdata->local;
 	u64 tsf;
 
+	if (!ieee80211_sdata_running((struct ieee80211_sub_if_data *)sdata))
+		return -ENETDOWN;
+
 	tsf = drv_get_tsf(local, (struct ieee80211_sub_if_data *)sdata);
 
 	return scnprintf(buf, buflen, "0x%016llx\n", (unsigned long long) tsf);
@@ -672,6 +675,9 @@ static ssize_t ieee80211_if_parse_tsf(
 	int ret;
 	int tsf_is_delta = 0;
 
+	if (!ieee80211_sdata_running(sdata))
+		return -ENETDOWN;
+
 	if (strncmp(buf, "reset", 5) == 0) {
 		if (local->ops->reset_tsf) {
 			drv_reset_tsf(local, sdata);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 075/877] wifi: mac80211: add HE 6 GHz capability in the scan elems len
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (73 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 074/877] wifi: mac80211: dont access the TSF of a down interface Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 076/877] wifi: mac80211: mesh: reset the CSA state when leaving Greg Kroah-Hartman
                   ` (809 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+f961b9f94edbc266f1f8,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit cd54bf333f5631d3630bab0a832e9ae648f73515 ]

The HE 6 GHz Band Capability element is in the probe request for
every band if 6 GHz is supported, so add the size to scan_ies_len.

Otherwise, building probe request elements can fail, triggering the
WARN_ON in __ieee80211_start_scan().

Assisted-by: LLM
Fixes: 2ad2274c58ee ("mac80211: Add HE 6GHz capabilities element to probe request")
Reported-by: syzbot+f961b9f94edbc266f1f8@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=f961b9f94edbc266f1f8
Link: https://patch.msgid.link/20260908122838.201719-19-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/main.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 84cc2a21a9a59..a65d49e4402ad 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1424,6 +1424,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 			sizeof(struct ieee80211_he_mcs_nss_supp) +
 			IEEE80211_HE_PPE_THRES_MAX_LEN;
 
+		if (local->hw.wiphy->bands[NL80211_BAND_6GHZ])
+			local->scan_ies_len +=
+				3 + sizeof(struct ieee80211_he_6ghz_capa);
+
 		if (supp_eht)
 			local->scan_ies_len +=
 				3 + sizeof(struct ieee80211_eht_cap_elem) +
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 076/877] wifi: mac80211: mesh: reset the CSA state when leaving
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (74 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 075/877] wifi: mac80211: add HE 6 GHz capability in the scan elems len Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 077/877] wifi: mac80211: mesh: release the channel if start fails Greg Kroah-Hartman
                   ` (808 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+f5752cd6b94fe38be666,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit 860134b3af77970e006feab7e5decb8c84771c7f ]

ifmsh->csa is allocated in ieee80211_mesh_csa_beacon() and only freed
in ieee80211_mesh_finish_csa(), i.e. when the channel switch completes.
Leaving the mesh while a switch is still pending therefore leaks it.

Additionally, ifmsh->csa_role and ifmsh->chsw_ttl have their state leak
in this case, so things can get mixed up in addition to the memory
leak.

Refactor the reset and call it in ieee80211_stop_mesh() to fix it all.

Assisted-by: LLM
Reported-by: syzbot+f5752cd6b94fe38be666@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=f5752cd6b94fe38be666
Fixes: b8456a14e9d2 ("{nl,cfg,mac}80211: implement mesh channel switch userspace API")
Link: https://patch.msgid.link/20260908122838.201719-20-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/mesh.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 4c601b9cb3bb2..258c865921784 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1217,6 +1217,21 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
 	return 0;
 }
 
+static void ieee80211_mesh_reset_csa(struct ieee80211_sub_if_data *sdata)
+{
+	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+	struct mesh_csa_settings *csa;
+
+	/* Reset the TTL value and Initiator flag */
+	ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_NONE;
+	ifmsh->chsw_ttl = 0;
+
+	/* Remove the CSA and MCSP elements from the beacon */
+	csa = sdata_dereference(ifmsh->csa, sdata);
+	RCU_INIT_POINTER(ifmsh->csa, NULL);
+	kfree_rcu(csa, rcu_head);
+}
+
 void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
 {
 	struct ieee80211_local *local = sdata->local;
@@ -1227,6 +1242,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
 
 	/* abort any running channel switch */
 	sdata->vif.bss_conf.csa_active = false;
+	ieee80211_mesh_reset_csa(sdata);
 	ieee80211_vif_unblock_queues_csa(sdata);
 
 	/* flush STAs and mpaths on this iface */
@@ -1531,19 +1547,10 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
 
 int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata, u64 *changed)
 {
-	struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-	struct mesh_csa_settings *tmp_csa_settings;
-	int ret = 0;
+	int ret;
 
-	/* Reset the TTL value and Initiator flag */
-	ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_NONE;
-	ifmsh->chsw_ttl = 0;
+	ieee80211_mesh_reset_csa(sdata);
 
-	/* Remove the CSA and MCSP elements from the beacon */
-	tmp_csa_settings = sdata_dereference(ifmsh->csa, sdata);
-	RCU_INIT_POINTER(ifmsh->csa, NULL);
-	if (tmp_csa_settings)
-		kfree_rcu(tmp_csa_settings, rcu_head);
 	ret = ieee80211_mesh_rebuild_beacon(sdata);
 	if (ret)
 		return -EINVAL;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 077/877] wifi: mac80211: mesh: release the channel if start fails
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (75 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 076/877] wifi: mac80211: mesh: reset the CSA state when leaving Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 078/877] wifi: mac80211: set up the TX info early to fix failure paths Greg Kroah-Hartman
                   ` (807 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+63a84ea9c0f57d6133fa,
	Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit ae97fff6495a8764bc0ef281cfe5444f701e527f ]

ieee80211_join_mesh() acquires a channel context and then calls
ieee80211_start_mesh(), which can fail. In that case, the chanctx
isn't released then interface removal will attempt to unassign it
after it's removed from the driver, hitting:

  wlan0: Failed check-sdata-in-driver check, flags: 0x0
  WARNING: net/mac80211/driver-ops.c:366 at drv_unassign_vif_chanctx
   ieee80211_assign_link_chanctx
   __ieee80211_link_release_channel
   ieee80211_link_release_channel
   ieee80211_teardown_sdata
   unregister_netdevice_many_notify
   _cfg80211_unregister_wdev
   ieee80211_remove_interfaces
   ieee80211_unregister_hw
   mac80211_hwsim_del_radio
   hwsim_exit_net

Correctly release the channel on start failures.

Assisted-by: LLM
Reported-by: syzbot+63a84ea9c0f57d6133fa@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=63a84ea9c0f57d6133fa
Fixes: 2b5e19677592 ("mac80211: cache mesh beacon")
Link: https://patch.msgid.link/20260908122838.201719-21-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/cfg.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 71310d708dbc4..73f56e4143f66 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2691,7 +2691,11 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
 	if (err)
 		return err;
 
-	return ieee80211_start_mesh(sdata);
+	err = ieee80211_start_mesh(sdata);
+	if (err)
+		ieee80211_link_release_channel(&sdata->deflink);
+
+	return err;
 }
 
 static int ieee80211_leave_mesh(struct wiphy *wiphy, struct net_device *dev)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 078/877] wifi: mac80211: set up the TX info early to fix failure paths
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (76 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 077/877] wifi: mac80211: mesh: release the channel if start fails Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 079/877] mm: memblock: show all region flags in debugfs Greg Kroah-Hartman
                   ` (806 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Johannes Berg, Sasha Levin

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

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

From: Johannes Berg <johannes.berg@intel.com>

[ Upstream commit 50d3d79dc0743b616afb00d01a626c76758721f7 ]

The previous commit 2c51457d930f ("wifi: mac80211: free ack status
frame on TX header build failure") cleaned up the leak, but still
left the code a bit messy and the failed SKB didn't get reported
to userspace.

Fix this up by initialising skb->cb[] earlier, which allows using
ieee80211_free_txskb() and therefore reports it for the failure
in ieee80211_build_hdr(), and unifies the ieee80211_skb_resize()
failure path with it.

Assisted-by: LLM
Fixes: c3e7724b6bc2 ("mac80211: use ieee80211_free_txskb to fix possible skb leaks")
Link: https://patch.msgid.link/20260908122838.201719-22-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mac80211/tx.c | 38 ++++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e78e71cb92f7f..228c717ea314b 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2927,10 +2927,23 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
 	 */
 	skb = skb_share_check(skb, GFP_ATOMIC);
 	if (unlikely(!skb)) {
-		ret = -ENOMEM;
-		goto free;
+		/* skb_share_check() already freed the skb */
+		if (info_id)
+			ieee80211_remove_ack_skb(local, info_id);
+		return ERR_PTR(-ENOMEM);
 	}
 
+	/* set this up so failure paths can clean up ack skb */
+	info = IEEE80211_SKB_CB(skb);
+	memset(info, 0, sizeof(*info));
+
+	info->flags = info_flags;
+	if (info_id) {
+		info->status_data = info_id;
+		info->status_data_idr = 1;
+	}
+	info->band = band;
+
 	hdr.frame_control = fc;
 	hdr.duration_id = 0;
 	hdr.seq_ctrl = 0;
@@ -2969,10 +2982,8 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
 		head_need += local->tx_headroom;
 		head_need = max_t(int, 0, head_need);
 		if (ieee80211_skb_resize(sdata, skb, head_need, ENCRYPT_DATA)) {
-			ieee80211_free_txskb(&local->hw, skb);
-			skb = NULL;
 			ret = -ENOMEM;
-			goto free;
+			goto free_txskb;
 		}
 	}
 
@@ -2999,16 +3010,6 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
 
 	skb_reset_mac_header(skb);
 
-	info = IEEE80211_SKB_CB(skb);
-	memset(info, 0, sizeof(*info));
-
-	info->flags = info_flags;
-	if (info_id) {
-		info->status_data = info_id;
-		info->status_data_idr = 1;
-	}
-	info->band = band;
-
 	if (likely(!cookie)) {
 		ctrl_flags |= u32_encode_bits(link_id,
 					      IEEE80211_TX_CTRL_MLO_LINK);
@@ -3032,16 +3033,17 @@ static struct sk_buff *ieee80211_build_hdr(struct ieee80211_sub_if_data *sdata,
 					     pre_conf_link_id, link_id);
 #endif
 			ret = -EINVAL;
-			goto free;
+			goto free_txskb;
 		}
 	}
 
 	info->control.flags = ctrl_flags;
 
 	return skb;
+ free_txskb:
+	ieee80211_free_txskb(&local->hw, skb);
+	return ERR_PTR(ret);
  free:
-	if (info_id)
-		ieee80211_remove_ack_skb(local, info_id);
 	kfree_skb(skb);
 	return ERR_PTR(ret);
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 079/877] mm: memblock: show all region flags in debugfs
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (77 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 078/877] wifi: mac80211: set up the TX info early to fix failure paths Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 080/877] scsi: qla2xxx: Fix the ql2xfc2target parameter description Greg Kroah-Hartman
                   ` (805 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Meijing Zhao,
	Mike Rapoport (Microsoft), Sasha Levin

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

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

From: Meijing Zhao <zhaomeijing@lixiang.com>

[ Upstream commit e2d5b01f878d76bd1142e512a0b979a1d3cd0abf ]

Commit 493f349e38d0 ("memblock: Add flags and nid info in memblock
debugfs") made memblock_debug_show() stop after finding the first set
flag. A memblock region can carry multiple flags, so the remaining flags
are hidden from debugfs.

Walk all bits in the region flags and print every set flag separated by
"|". Keep walking beyond flagname[] so that a set flag without a known
name is reported as UNKNOWN rather than silently ignored.

Fixes: 493f349e38d0 ("memblock: Add flags and nid info in memblock debugfs")
Signed-off-by: Meijing Zhao <zhaomeijing@lixiang.com>
Link: https://patch.msgid.link/20260902075944.3742866-1-zhaomeijing100@gmail.com
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 mm/memblock.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/mm/memblock.c b/mm/memblock.c
index 3d7b0114442c4..00ef6bea6fe8c 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -2416,14 +2416,18 @@ static int memblock_debug_show(struct seq_file *m, void *private)
 		else
 			seq_printf(m, "%4c ", 'x');
 		if (reg->flags) {
-			for (j = 0; j < count; j++) {
-				if (reg->flags & (1U << j)) {
-					seq_printf(m, "%s\n", flagname[j]);
-					break;
-				}
+			unsigned int flags = reg->flags;
+			bool first = true;
+
+			for (j = 0; flags; j++, flags >>= 1) {
+				if (!(flags & 1))
+					continue;
+				if (!first)
+					seq_putc(m, '|');
+				seq_puts(m, j < count ? flagname[j] : "UNKNOWN");
+				first = false;
 			}
-			if (j == count)
-				seq_printf(m, "%s\n", "UNKNOWN");
+			seq_putc(m, '\n');
 		} else {
 			seq_printf(m, "%s\n", "NONE");
 		}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 080/877] scsi: qla2xxx: Fix the ql2xfc2target parameter description
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (78 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 079/877] mm: memblock: show all region flags in debugfs Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 081/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor reuse order Greg Kroah-Hartman
                   ` (804 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Karl Mehltretter,
	Martin K. Petersen (Oracle), Sasha Levin

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

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

From: Karl Mehltretter <kmehltretter@gmail.com>

[ Upstream commit 779f202a92ef10a426efc07d0f4267918cb07ca3 ]

The module parameter is ql2xfc2target, but its MODULE_PARM_DESC() names
qla2xfc2target, so modinfo describes a parameter that does not exist and
shows no description for the real one.

Use the parameter name in the description.

Fixes: 877b03795fcf ("scsi: qla2xxx: Add option to disable FC2 Target support")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://patch.msgid.link/20260906171009.2560-1-kmehltretter@gmail.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/scsi/qla2xxx/qla_os.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 7a78cff128cfa..e2c0c99a5b052 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -363,7 +363,7 @@ MODULE_PARM_DESC(ql2xnvme_queues,
 
 int ql2xfc2target = 1;
 module_param(ql2xfc2target, int, 0444);
-MODULE_PARM_DESC(qla2xfc2target,
+MODULE_PARM_DESC(ql2xfc2target,
 		  "Enables FC2 Target support. "
 		  "0 - FC2 Target support is disabled. "
 		  "1 - FC2 Target support is enabled (default).");
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 081/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor reuse order
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (79 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 080/877] scsi: qla2xxx: Fix the ql2xfc2target parameter description Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 082/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor chain after cyclic DMA Greg Kroah-Hartman
                   ` (803 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Alex Bereza, Frank Li, Suraj Gupta,
	Vinod Koul, Sasha Levin

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

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

From: Alex Bereza <alex@bereza.email>

[ Upstream commit cee9c863ee68cb27d66745eb03f60e357f4f8ad2 ]

xilinx_dma_alloc_chan_resources() builds a static ring of hardware
buffer descriptors once and the driver uses this ring throughout the
lifetime of a channel. This requires the allocation order of hardware
buffer descriptors from chan->free_seg_list to stay in sync with the
hardware buffer descriptor ring built at channel allocation time by
returning oldest descriptors to chan->free_seg_list first.

When chan->pending_list is not empty e.g. during
xilinx_dma_terminate_all() the chan->free_seg_list and the order of the
static hardware buffer descriptor ring get out of sync. Descriptors age
in this order: pending -> active -> done. So freeing pending_list first
returns the newest buffer descriptors to the chan->free_seg_list first
and thus breaks the order required by the static hardware buffer
descriptor ring. Then when the channel is reused, after a wrap around of
the free_seg_list the DMA will find a hardware buffer descriptor with a
length field that is still zeroed and stop with something like this:

  xilinx-vdma 86000000.dma: Channel 000000003a21d7b8 has errors 10, cdr 6de4c000 tdr 6de4c000

After this no more descriptors are completed and a consumer potentially
blocks and waits forever. The only way to get out of this error state is
to rebuild the static hardware buffer descriptor ring and the
free_seg_list by releasing and re-acquiring the channel.

Fix the order in which hardware buffer descriptors are returned to
free_seg_list to ensure the mentioned requirement holds.

Fixes: 23059408b6a3 ("dmaengine: xilinx_dma: Fix race condition in the driver for multiple descriptor scenario")
Signed-off-by: Alex Bereza <alex@bereza.email>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Suraj Gupta <suraj.gupta2@amd.com>
Link: https://patch.msgid.link/20260817-fix-hw-buf-desc-reuse-v1-1-d79827a844c7@bereza.email
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/dma/xilinx/xilinx_dma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index bea55dc99673b..29ff6c8082fb1 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -917,9 +917,9 @@ static void xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan)
 
 	spin_lock_irqsave(&chan->lock, flags);
 
-	xilinx_dma_free_desc_list(chan, &chan->pending_list);
 	xilinx_dma_free_desc_list(chan, &chan->done_list);
 	xilinx_dma_free_desc_list(chan, &chan->active_list);
+	xilinx_dma_free_desc_list(chan, &chan->pending_list);
 
 	spin_unlock_irqrestore(&chan->lock, flags);
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 082/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor chain after cyclic DMA
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (80 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 081/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor reuse order Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 083/877] RDMA/efa: Keep admin queues alive while IRQ is registered Greg Kroah-Hartman
                   ` (802 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Alex Bereza, Frank Li, Suraj Gupta,
	Vinod Koul, Sasha Levin

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

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

From: Alex Bereza <alex@bereza.email>

[ Upstream commit 7ed1e3070c9b4bbd67d5519e14711038dd53ab13 ]

Using the DMA in cyclic mode modifies the hardware buffer descriptor
chain in xilinx_dma_prep_dma_cyclic so that the last descriptor used by
the cyclic transfer points back to the first descriptor, but it never
restores the original descriptor ring. This breaks using non-cyclic mode
after cyclic mode with an error like:

  xilinx-vdma 86000000.dma: Channel 00000000354d5c8d has errors 100, cdr 6de40000 tdr 6de40400

The only way to get out of this error state is to rebuild the hardware
buffer descriptor ring by releasing and re-acquiring the channel.

Fix using non-cyclic mode after cyclic mode by always restoring the
original buffer descriptor ring in the same manner as it is set up by
xilinx_dma_alloc_chan_resources().

Fixes: 23059408b6a3 ("dmaengine: xilinx_dma: Fix race condition in the driver for multiple descriptor scenario")
Signed-off-by: Alex Bereza <alex@bereza.email>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Suraj Gupta <suraj.gupta2@amd.com>
Link: https://patch.msgid.link/20260817-fix-hw-buf-desc-after-cyclic-mode-v1-1-1fe47e701d6c@bereza.email
Link: https://patch.msgid.link/20260818-fix-hw-buf-desc-after-cyclic-mode-v2-1-530ff44c6a81@bereza.email
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/dma/xilinx/xilinx_dma.c | 24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 29ff6c8082fb1..4a89ad8c90a34 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -753,15 +753,25 @@ xilinx_aximcdma_alloc_tx_segment(struct xilinx_dma_chan *chan)
 	return segment;
 }
 
-static void xilinx_dma_clean_hw_desc(struct xilinx_axidma_desc_hw *hw)
+static void xilinx_dma_clean_hw_desc(struct xilinx_dma_chan *chan,
+				     struct xilinx_axidma_tx_segment *segment)
 {
-	u32 next_desc = hw->next_desc;
-	u32 next_desc_msb = hw->next_desc_msb;
+	dma_addr_t next;
+	u32 i;
 
-	memset(hw, 0, sizeof(struct xilinx_axidma_desc_hw));
+	/*
+	 * Restore the buffer descriptor's next descriptor pointer to the value
+	 * set up in xilinx_dma_alloc_chan_resources(). Otherwise using the DMA
+	 * in cyclic mode leaves the next descriptor pointer altered and
+	 * prevents subsequent non-cyclic transfers.
+	 */
+	i = segment - chan->seg_v;
+	next = chan->seg_p +
+	       sizeof(*chan->seg_v) * ((i + 1) % XILINX_DMA_NUM_DESCS);
 
-	hw->next_desc = next_desc;
-	hw->next_desc_msb = next_desc_msb;
+	memset(&segment->hw, 0, sizeof(segment->hw));
+	segment->hw.next_desc = lower_32_bits(next);
+	segment->hw.next_desc_msb = upper_32_bits(next);
 }
 
 static void xilinx_mcdma_clean_hw_desc(struct xilinx_aximcdma_desc_hw *hw)
@@ -783,7 +793,7 @@ static void xilinx_mcdma_clean_hw_desc(struct xilinx_aximcdma_desc_hw *hw)
 static void xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
 				struct xilinx_axidma_tx_segment *segment)
 {
-	xilinx_dma_clean_hw_desc(&segment->hw);
+	xilinx_dma_clean_hw_desc(chan, segment);
 
 	list_add_tail(&segment->node, &chan->free_seg_list);
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 083/877] RDMA/efa: Keep admin queues alive while IRQ is registered
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (81 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 082/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor chain after cyclic DMA Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 084/877] RDMA/efa: Keep EQ resources " Greg Kroah-Hartman
                   ` (801 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Michael Margolin, Leon Romanovsky,
	Sasha Levin

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

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

From: Leon Romanovsky <leonro@nvidia.com>

[ Upstream commit e08aca85c02ff290f785f07acae758f0daf5f49e ]

The management IRQ handler accesses both the admin completion queue and the
async event queue. The driver registered the IRQ before constructing these
queues and destroyed them before freeing the IRQ, so the handler's lifetime
was not contained by the resources it accesses.

Initialize the queues with interrupts masked, request the IRQ, and then
switch to interrupt mode. On removal, reset the device and free the IRQ
before destroying the queues. Also reset the device before destroying the
queues if IRQ registration fails, because the device already has their DMA
addresses.

Fixes: b7f5e880f377 ("RDMA/efa: Add the efa module")
Link: https://patch.msgid.link/20260907-use-after-free-of-admin-queue-struct-v1-1-dd9d9267fbf4@nvidia.com
Reviewed-by: Michael Margolin <mrgolin@amazon.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/hw/efa/efa_com.c  |  4 +---
 drivers/infiniband/hw/efa/efa_main.c | 15 +++++++++------
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/infiniband/hw/efa/efa_com.c b/drivers/infiniband/hw/efa/efa_com.c
index bafd210dd43e8..d6fb2edc96891 100644
--- a/drivers/infiniband/hw/efa/efa_com.c
+++ b/drivers/infiniband/hw/efa/efa_com.c
@@ -743,7 +743,7 @@ int efa_com_admin_init(struct efa_com_dev *edev,
 
 	aq->dmadev = edev->dmadev;
 	aq->efa_dev = edev->efa_dev;
-	set_bit(EFA_AQ_STATE_POLLING_BIT, &aq->state);
+	efa_com_set_admin_polling_mode(edev, true);
 
 	sema_init(&aq->avail_cmds, aq->depth);
 
@@ -761,8 +761,6 @@ int efa_com_admin_init(struct efa_com_dev *edev,
 	if (err)
 		goto err_destroy_sq;
 
-	efa_com_set_admin_polling_mode(edev, false);
-
 	err = efa_com_admin_init_aenq(edev, aenq_handlers);
 	if (err)
 		goto err_destroy_cq;
diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c
index 45a4564c670c0..83323a7ad7120 100644
--- a/drivers/infiniband/hw/efa/efa_main.c
+++ b/drivers/infiniband/hw/efa/efa_main.c
@@ -615,18 +615,21 @@ static struct efa_dev *efa_probe_device(struct pci_dev *pdev)
 	edev->aq.msix_vector_idx = dev->admin_msix_vector_idx;
 	edev->aenq.msix_vector_idx = dev->admin_msix_vector_idx;
 
-	err = efa_set_mgmnt_irq(dev);
+	err = efa_com_admin_init(edev, &aenq_handlers);
 	if (err)
 		goto err_disable_msix;
 
-	err = efa_com_admin_init(edev, &aenq_handlers);
+	err = efa_set_mgmnt_irq(dev);
 	if (err)
-		goto err_free_mgmnt_irq;
+		goto err_destroy_admin;
+
+	efa_com_set_admin_polling_mode(edev, false);
 
 	return dev;
 
-err_free_mgmnt_irq:
-	efa_free_irq(dev, &dev->admin_irq);
+err_destroy_admin:
+	efa_com_dev_reset(edev, EFA_REGS_RESET_INIT_ERR);
+	efa_com_admin_destroy(edev);
 err_disable_msix:
 	efa_disable_msix(dev);
 err_reg_read_destroy:
@@ -650,8 +653,8 @@ static void efa_remove_device(struct pci_dev *pdev,
 
 	edev = &dev->edev;
 	efa_com_dev_reset(edev, reset_reason);
-	efa_com_admin_destroy(edev);
 	efa_free_irq(dev, &dev->admin_irq);
+	efa_com_admin_destroy(edev);
 	efa_disable_msix(dev);
 	efa_com_mmio_reg_read_destroy(edev);
 	devm_iounmap(&pdev->dev, edev->reg_bar);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 084/877] RDMA/efa: Keep EQ resources alive while IRQ is registered
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (82 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 083/877] RDMA/efa: Keep admin queues alive while IRQ is registered Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 085/877] RDMA/siw: Bound fragmented header copies by the remaining length Greg Kroah-Hartman
                   ` (800 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Michael Margolin, Leon Romanovsky,
	Sasha Levin

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

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

From: Leon Romanovsky <leonro@nvidia.com>

[ Upstream commit e22a3627b7151754f07f90ea3d1ab6e85f5d93f4 ]

The completion IRQ handler accesses the EQ state and DMA buffer. Its IRQ was
registered before that state was initialized, while teardown released the
buffer before free_irq() synchronized the handler.

Initialize the EQ without arming it, register the IRQ, and then arm it.
Reverse the resource order during teardown by freeing the IRQ before
destroying the EQ.

Fixes: 2a152512a155 ("RDMA/efa: CQ notifications")
Link: https://patch.msgid.link/20260907-use-after-free-of-admin-queue-struct-v1-2-dd9d9267fbf4@nvidia.com
Reviewed-by: Michael Margolin <mrgolin@amazon.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/hw/efa/efa_com.c  |  3 +--
 drivers/infiniband/hw/efa/efa_com.h  |  1 +
 drivers/infiniband/hw/efa/efa_main.c | 18 ++++++++++--------
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/infiniband/hw/efa/efa_com.c b/drivers/infiniband/hw/efa/efa_com.c
index d6fb2edc96891..00e339abc2c13 100644
--- a/drivers/infiniband/hw/efa/efa_com.c
+++ b/drivers/infiniband/hw/efa/efa_com.c
@@ -1149,7 +1149,7 @@ static void efa_com_destroy_eq(struct efa_com_dev *edev,
 				      err);
 }
 
-static void efa_com_arm_eq(struct efa_com_dev *edev, struct efa_com_eq *eeq)
+void efa_com_arm_eq(struct efa_com_dev *edev, struct efa_com_eq *eeq)
 {
 	u32 val = 0;
 
@@ -1238,7 +1238,6 @@ int efa_com_eq_init(struct efa_com_dev *edev, struct efa_com_eq *eeq,
 	eeq->phase = 1;
 	eeq->depth = params.depth;
 	eeq->cb = cb;
-	efa_com_arm_eq(edev, eeq);
 
 	return 0;
 
diff --git a/drivers/infiniband/hw/efa/efa_com.h b/drivers/infiniband/hw/efa/efa_com.h
index 77282234ce686..29a9d087db5d9 100644
--- a/drivers/infiniband/hw/efa/efa_com.h
+++ b/drivers/infiniband/hw/efa/efa_com.h
@@ -157,6 +157,7 @@ int efa_com_admin_init(struct efa_com_dev *edev,
 void efa_com_admin_destroy(struct efa_com_dev *edev);
 int efa_com_eq_init(struct efa_com_dev *edev, struct efa_com_eq *eeq,
 		    efa_eqe_handler cb, u16 depth, u8 msix_vec);
+void efa_com_arm_eq(struct efa_com_dev *edev, struct efa_com_eq *eeq);
 void efa_com_eq_destroy(struct efa_com_dev *edev, struct efa_com_eq *eeq);
 int efa_com_dev_reset(struct efa_com_dev *edev,
 		      enum efa_regs_reset_reason_types reset_reason);
diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c
index 83323a7ad7120..30cefd0bb4f56 100644
--- a/drivers/infiniband/hw/efa/efa_main.c
+++ b/drivers/infiniband/hw/efa/efa_main.c
@@ -301,28 +301,30 @@ static void efa_set_host_info(struct efa_dev *dev)
 
 static void efa_destroy_eq(struct efa_dev *dev, struct efa_eq *eq)
 {
-	efa_com_eq_destroy(&dev->edev, &eq->eeq);
 	efa_free_irq(dev, &eq->irq);
+	efa_com_eq_destroy(&dev->edev, &eq->eeq);
 }
 
 static int efa_create_eq(struct efa_dev *dev, struct efa_eq *eq, u8 msix_vec)
 {
 	int err;
 
-	efa_setup_comp_irq(dev, eq, msix_vec);
-	err = efa_request_irq(dev, &eq->irq);
+	err = efa_com_eq_init(&dev->edev, &eq->eeq, efa_process_eqe,
+			      dev->dev_attr.max_eq_depth, msix_vec);
 	if (err)
 		return err;
 
-	err = efa_com_eq_init(&dev->edev, &eq->eeq, efa_process_eqe,
-			      dev->dev_attr.max_eq_depth, msix_vec);
+	efa_setup_comp_irq(dev, eq, msix_vec);
+	err = efa_request_irq(dev, &eq->irq);
 	if (err)
-		goto err_free_comp_irq;
+		goto err_destroy_eq;
+
+	efa_com_arm_eq(&dev->edev, &eq->eeq);
 
 	return 0;
 
-err_free_comp_irq:
-	efa_free_irq(dev, &eq->irq);
+err_destroy_eq:
+	efa_com_eq_destroy(&dev->edev, &eq->eeq);
 	return err;
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 085/877] RDMA/siw: Bound fragmented header copies by the remaining length
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (83 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 084/877] RDMA/efa: Keep EQ resources " Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 086/877] netfilter: nft_nat: fully initialise new_addr in netmap setup Greg Kroah-Hartman
                   ` (799 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jérémy Jean,
	Bernard Metzler, Leon Romanovsky, Sasha Levin

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

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

From: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>

[ Upstream commit 9ff797e516dbc1ecb73701ec4c24055712d44411 ]

siw_get_hdr() can receive an extended DDP/RDMAP header across more than
one TCP callback. The first callback may receive most of the header,
while the next one still limits the copy to hdrlen - MIN_DDP_HDR instead
of the number of missing bytes. This makes the destination move past the
end of the header and overwrite the receive state, including
fpdu_part_rcvd. A later callback can then use a negative fpdu_part_rcvd
value as a copy offset, which creates an OOB write.

Use the number of header bytes already received when calculating the
next copy length.

Fixes: 754209850df8 ("RDMA/siw: Always consume all skbuf data in sk_data_ready() upcall.")
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Link: https://patch.msgid.link/20260908085520.1746329-1-Jeremy.Jean@oss.cyber.gouv.fr
Assisted-by: Codex:gpt-6
Acked-by: Bernard Metzler <bernard.metzler@linux.dev>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/infiniband/sw/siw/siw_qp_rx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/infiniband/sw/siw/siw_qp_rx.c b/drivers/infiniband/sw/siw/siw_qp_rx.c
index ad281da44cb49..4db245748af0b 100644
--- a/drivers/infiniband/sw/siw/siw_qp_rx.c
+++ b/drivers/infiniband/sw/siw/siw_qp_rx.c
@@ -1079,7 +1079,7 @@ static int siw_get_hdr(struct siw_rx_stream *srx)
 	if (iwarp_pktinfo[opcode].hdr_len > sizeof(struct iwarp_ctrl_tagged)) {
 		int hdrlen = iwarp_pktinfo[opcode].hdr_len;
 
-		bytes = min_t(int, hdrlen - MIN_DDP_HDR, srx->skb_new);
+		bytes = min_t(int, hdrlen - srx->fpdu_part_rcvd, srx->skb_new);
 
 		skb_copy_bits(skb, srx->skb_offset,
 			      (char *)c_hdr + srx->fpdu_part_rcvd, bytes);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 086/877] netfilter: nft_nat: fully initialise new_addr in netmap setup
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (84 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 085/877] RDMA/siw: Bound fragmented header copies by the remaining length Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 087/877] netfilter: flowtable: hold reference on ct until flow is released Greg Kroah-Hartman
                   ` (798 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Theodor Arsenij Larionov Trichkine,
	Pablo Neira Ayuso, Sasha Levin

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

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

From: Theodor Arsenij Larionov Trichkine <theodorlarionov@gmail.com>

[ Upstream commit d313499df66159b4b7971d760d16729598ab7e5a ]

nft_nat_setup_netmap() builds the mapped address in an on-stack
union nf_inet_addr. For an IPv4 mapping it writes only the 4-byte .ip
member and the loop runs a single 32-bit iteration, but it then copies
the whole 16-byte union into range->min_addr and range->max_addr, so the
upper 12 bytes reach nf_nat_setup_info() uninitialised.

KMSAN reports an uninit-value in nf_nat_setup_info() reached from
nft_nat_eval(). The IPv6 path fills all 16 bytes and is not affected.

Zero-initialise new_addr.

Fixes: 3ff7ddb1353d ("netfilter: nft_nat: add netmap support")
Signed-off-by: Theodor Arsenij Larionov Trichkine <theodorlarionov@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/netfilter/nft_nat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
index e32cd9fbc7c2e..cdbd800cac969 100644
--- a/net/netfilter/nft_nat.c
+++ b/net/netfilter/nft_nat.c
@@ -64,8 +64,8 @@ static void nft_nat_setup_netmap(struct nf_nat_range2 *range,
 				 const struct nft_pktinfo *pkt,
 				 const struct nft_nat *priv)
 {
+	union nf_inet_addr new_addr = {};
 	struct sk_buff *skb = pkt->skb;
-	union nf_inet_addr new_addr;
 	__be32 netmask;
 	int i, len = 0;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 087/877] netfilter: flowtable: hold reference on ct until flow is released
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (85 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 086/877] netfilter: nft_nat: fully initialise new_addr in netmap setup Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 088/877] perf/arm-cmn: Fix wp_dev_sel2 setting for multi-DTM configurations Greg Kroah-Hartman
                   ` (797 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Pablo Neira Ayuso, Sasha Levin

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

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

From: Pablo Neira Ayuso <pablo@netfilter.org>

[ Upstream commit e75a9fa1d44bcbd66ea02e8781bcca6ea4076e0d ]

nf_ct_put() releases the ct->ext area inmediately, the rcu typesafe
semantics also allow to refer to the wrong conntrack from the flowtable
datapath. Hold reference on ct until flow is released after rcu grace
period.

Add rcu_barrier() on module exit path, to ensure pending flow entries
are release before module goes away.

Fixes: 0ff90b6c2034 ("netfilter: nf_flow_offload: fix use-after-free and a resource leak")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/netfilter/nf_flow_table_core.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c
index b9e3ac950894f..b00f1c68a8e76 100644
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -205,6 +205,14 @@ static void flow_offload_route_release(struct flow_offload *flow)
 	nft_flow_dst_release(flow, FLOW_OFFLOAD_DIR_REPLY);
 }
 
+static void flow_offload_free_rcu(struct rcu_head *rcu_head)
+{
+	struct flow_offload *flow = container_of(rcu_head, struct flow_offload, rcu_head);
+
+	nf_ct_put(flow->ct);
+	kfree(flow);
+}
+
 void flow_offload_free(struct flow_offload *flow)
 {
 	switch (flow->type) {
@@ -214,8 +222,7 @@ void flow_offload_free(struct flow_offload *flow)
 	default:
 		break;
 	}
-	nf_ct_put(flow->ct);
-	kfree_rcu(flow, rcu_head);
+	call_rcu(&flow->rcu_head, flow_offload_free_rcu);
 }
 EXPORT_SYMBOL_GPL(flow_offload_free);
 
@@ -686,6 +693,7 @@ static int __init nf_flow_table_module_init(void)
 
 static void __exit nf_flow_table_module_exit(void)
 {
+	rcu_barrier();
 	nf_flow_table_offload_exit();
 	unregister_pernet_subsys(&nf_flow_table_net_ops);
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 088/877] perf/arm-cmn: Fix wp_dev_sel2 setting for multi-DTM configurations
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (86 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 087/877] netfilter: flowtable: hold reference on ct until flow is released Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 089/877] arm64: hibernate: clone only the linear map that exists at runtime Greg Kroah-Hartman
                   ` (796 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Shouping Wang, Robin Murphy,
	Will Deacon, Sasha Levin

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

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

From: Shouping Wang <allen.wang@hj-micro.com>

[ Upstream commit 49daa3d668b69a5454b5aba0078848a479f79f1c ]

When MXP_MULTIPLE_DTM_EN is TRUE, each DTM will monitor at most
two device ports. In this case, {wp_dev_sel2, wp_dev_sel} will
only use values 2'b00 and 2'b01 per DTM.

Previously the setting allowed values beyond the supported range
per DTM, which could cause each DTM to select invalid ports when
MXP_MULTIPLE_DTM_EN is TRUE.

Fix this by only setting CMN_DTM_WPn_CONFIG_WP_DEV_SEL2 when
!multi_dtm.

Fixes: 60d1504070c2 ("perf/arm-cmn: Support new IP features")
Signed-off-by: Shouping Wang <allen.wang@hj-micro.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/perf/arm-cmn.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c
index 892bc6b5875a7..3a4541c51863b 100644
--- a/drivers/perf/arm-cmn.c
+++ b/drivers/perf/arm-cmn.c
@@ -1395,13 +1395,14 @@ static void arm_cmn_claim_wp_idx(struct arm_cmn_dtm *dtm,
 
 static u32 arm_cmn_wp_config(struct perf_event *event, int wp_idx)
 {
+	struct arm_cmn *cmn = to_cmn(event->pmu);
 	u32 config;
 	u32 dev = CMN_EVENT_WP_DEV_SEL(event);
 	u32 chn = CMN_EVENT_WP_CHN_SEL(event);
 	u32 grp = CMN_EVENT_WP_GRP(event);
 	u32 exc = CMN_EVENT_WP_EXCLUSIVE(event);
 	u32 combine = CMN_EVENT_WP_COMBINE(event);
-	bool is_cmn600 = to_cmn(event->pmu)->part == PART_CMN600;
+	bool is_cmn600 = cmn->part == PART_CMN600;
 
 	/* CMN-600 supports only primary and secondary matching groups */
 	if (is_cmn600)
@@ -1409,8 +1410,11 @@ static u32 arm_cmn_wp_config(struct perf_event *event, int wp_idx)
 
 	config = FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_DEV_SEL, dev) |
 		 FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_CHN_SEL, chn) |
-		 FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_GRP, grp) |
-		 FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_DEV_SEL2, dev >> 1);
+		 FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_GRP, grp);
+
+	if (!cmn->multi_dtm)
+		config |= FIELD_PREP(CMN_DTM_WPn_CONFIG_WP_DEV_SEL2, dev >> 1);
+
 	if (exc)
 		config |= is_cmn600 ? CMN600_WPn_CONFIG_WP_EXCLUSIVE :
 				      CMN_DTM_WPn_CONFIG_WP_EXCLUSIVE;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 089/877] arm64: hibernate: clone only the linear map that exists at runtime
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (87 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 088/877] perf/arm-cmn: Fix wp_dev_sel2 setting for multi-DTM configurations Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 090/877] drm: Fix drm_pending_vblank_event leak in error path for out_fence_ptr Greg Kroah-Hartman
                   ` (795 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Breno Leitao, Ard Biesheuvel,
	Will Deacon, Sasha Levin

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

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

From: Breno Leitao <leitao@debian.org>

[ Upstream commit e4a6f57d22e079e23fafac51057fad534160b269 ]

This is similar to commit 1537e55728ec2 ("arm64: trans_pgd: clone only
the linear map that exists at runtime"), but in a different place.

swsusp_arch_resume() clones the kernel linear map with
trans_pgd_create_copy(..., PAGE_OFFSET, PAGE_END). PAGE_OFFSET comes
from the compile-time VA_BITS, so a CONFIG_ARM64_VA_BITS_52 kernel
booting on hardware without LPA2 -- vabits_actual is 48 and the fifth
level is folded -- hands the walk a 3.9PB window while its linear map
only spans the top 128TB.

On a VA_BITS_52 4k kernel with CONFIG_KASAN_GENERIC in a 4GB VM, I see:

  swapper/0: page allocation failure: order:0, mode:0x920(GFP_ATOMIC|__GFP_ZERO)
   hibernate_page_alloc+0x10/0x1c
   swsusp_arch_resume+0x70/0x320
   hibernation_restore+0xa4/0x138
   software_resume+0x15c/0x270
  PM: hibernation: Failed to load image, recovering.
  PM: hibernation: resume failed (-12)

Fix it by copying the linear map that is the actual one, not the
compiled one.

Fixes: a6bbf5d4d9d1 ("arm64: mm: Add definitions to support 5 levels of paging")
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/arm64/kernel/hibernate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
index 44d31b019efd5..b883f6d833b6b 100644
--- a/arch/arm64/kernel/hibernate.c
+++ b/arch/arm64/kernel/hibernate.c
@@ -417,8 +417,8 @@ int __nocfi swsusp_arch_resume(void)
 	 * Create a second copy of just the linear map, and use this when
 	 * restoring.
 	 */
-	rc = trans_pgd_create_copy(&trans_info, &tmp_pg_dir, PAGE_OFFSET,
-				   PAGE_END);
+	rc = trans_pgd_create_copy(&trans_info, &tmp_pg_dir,
+				   _PAGE_OFFSET(vabits_actual), PAGE_END);
 	if (rc)
 		return rc;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 090/877] drm: Fix drm_pending_vblank_event leak in error path for out_fence_ptr
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (88 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 089/877] arm64: hibernate: clone only the linear map that exists at runtime Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 091/877] keys: fix lost wakeup when reaping a dead key type Greg Kroah-Hartman
                   ` (794 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, sashiko-bot,
	Thadeu Lima de Souza Cascardo, Melissa Wen, Sasha Levin

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

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

From: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>

[ Upstream commit 9eb1a393c89a79c4210230d23e7d88d239c61d7b ]

When an out_fence_ptr is provided but DRM_MODE_PAGE_FLIP_EVENT is not
set, a drm_pending_vblank_event will be allocated. If later, there is an
allocation failure or another failure at setup_out_fence(), that event
will not have base.fence set and it will not be released at
complete_signaling().

Release the event and set crtc_state->event to NULL just like in the
DRM_MODE_PAGE_FLIP_EVENT case when there is a failure at
drm_event_reserve_init(). That is, prepare_signaling() releases the
event and there is nothing to be done at complete_signaling(). Use
drm_event_cancel_free() as that will also undo drm_event_reserve_init()
in case it has been called.

Reported-by: sashiko-bot@kernel.org
Closes: https://sashiko.dev/#/patchset/20260727-drm_crtc_atomic_commit_leak-v1-1-23d9948a9d7c@igalia.com?part=1
Fixes: 92c715fca907 ("drm/atomic: Fix double free in drm_atomic_state_default_clear")
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
Reviewed-by: Melissa Wen <mwen@igalia.com>
Signed-off-by: Melissa Wen <mwen@igalia.com>
Link: https://patch.msgid.link/20260826-drm_pending_vblank_event_leak-v4-1-f8de8b996b9d@igalia.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/drm_atomic_uapi.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index fc20b039bed40..02255296cc576 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -1225,10 +1225,12 @@ static int prepare_signaling(struct drm_device *dev,
 			struct dma_fence *fence;
 			struct drm_out_fence_state *f;
 
+			ret = -ENOMEM;
+
 			f = krealloc(*fence_state, sizeof(**fence_state) *
 				     (*num_fences + 1), GFP_KERNEL);
 			if (!f)
-				return -ENOMEM;
+				goto err_free_event;
 
 			memset(&f[*num_fences], 0, sizeof(*f));
 
@@ -1237,12 +1239,12 @@ static int prepare_signaling(struct drm_device *dev,
 
 			fence = drm_crtc_create_fence(crtc);
 			if (!fence)
-				return -ENOMEM;
+				goto err_free_event;
 
 			ret = setup_out_fence(&f[(*num_fences)++], fence);
 			if (ret) {
 				dma_fence_put(fence);
-				return ret;
+				goto err_free_event;
 			}
 
 			crtc_state->event->base.fence = fence;
@@ -1298,6 +1300,11 @@ static int prepare_signaling(struct drm_device *dev,
 	}
 
 	return 0;
+
+err_free_event:
+	drm_event_cancel_free(dev, &crtc_state->event->base);
+	crtc_state->event = NULL;
+	return ret;
 }
 
 static void complete_signaling(struct drm_device *dev,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 091/877] keys: fix lost wakeup when reaping a dead key type
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (89 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 090/877] drm: Fix drm_pending_vblank_event leak in error path for out_fence_ptr Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 092/877] neighbour: Use rtnl_register_many() Greg Kroah-Hartman
                   ` (793 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Jarkko Sakkinen,
	Sasha Levin

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

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

From: Karl Mehltretter <kmehltretter@gmail.com>

[ Upstream commit 2725ab3f5ad1c5f375c7c9fee4af02a9b138f701 ]

clear_bit() is atomic with respect to the word it modifies, but it is
an unordered operation: it implies no memory barrier on either side
(Documentation/atomic_bitops.txt).

key_garbage_collector() clears KEY_GC_REAPING_KEYTYPE with clear_bit()
and calls wake_up_bit() after reaping a dead key type. wake_up_bit()
uses a lockless waitqueue check and requires a full barrier after the
clear.

The existing smp_mb() is before clear_bit(), so nothing orders the clear
against that check. The GC can see an empty waitqueue while
unregister_key_type() still sees the bit set. The final wakeup is then
lost, leaving module unload stuck in wait_on_bit().

Use clear_and_wake_up_bit(). Its clear_bit_unlock() has RELEASE
semantics, so the completed GC work stays ordered before the clear, and
its smp_mb__after_atomic() orders the clear before the waitqueue check.

Fixes: 0c061b5707ab ("KEYS: Correctly destroy key payloads when their keytype is removed")
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://lore.kernel.org/r/20260821025327.61488-1-kmehltretter@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 security/keys/gc.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/security/keys/gc.c b/security/keys/gc.c
index f27223ea4578f..cf71b26c0c008 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -318,9 +318,7 @@ static void key_garbage_collector(struct work_struct *work)
 
 	if (unlikely(gc_state & KEY_GC_REAPING_DEAD_3)) {
 		kdebug("dead wake");
-		smp_mb();
-		clear_bit(KEY_GC_REAPING_KEYTYPE, &key_gc_flags);
-		wake_up_bit(&key_gc_flags, KEY_GC_REAPING_KEYTYPE);
+		clear_and_wake_up_bit(KEY_GC_REAPING_KEYTYPE, &key_gc_flags);
 	}
 
 	if (gc_state & KEY_GC_REAP_AGAIN)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 092/877] neighbour: Use rtnl_register_many().
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (90 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 091/877] keys: fix lost wakeup when reaping a dead key type Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-10-01 19:19   ` Harshit Mogalapalli
  2026-09-30 15:16 ` [PATCH 6.12 093/877] neighbour: Make neigh_valid_get_req() return ndmsg Greg Kroah-Hartman
                   ` (792 subsequent siblings)
  884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Eric Dumazet,
	Jakub Kicinski, Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@amazon.com>

[ Upstream commit d0d14aef50a6184426c5a05b9815fb2697d6d42c ]

We will remove rtnl_register() in favour of rtnl_register_many().

When it succeeds, rtnl_register_many() guarantees all rtnetlink types
in the passed array are supported, and there is no chance that a part
of message types is not supported.

Let's use rtnl_register_many() instead.

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20241014201828.91221-4-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/neighbour.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index bf07438d6dfa5..1dd9f85b74997 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -3898,17 +3898,18 @@ EXPORT_SYMBOL(neigh_sysctl_unregister);
 
 #endif	/* CONFIG_SYSCTL */
 
+static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
+	{.msgtype = RTM_NEWNEIGH, .doit = neigh_add},
+	{.msgtype = RTM_DELNEIGH, .doit = neigh_delete},
+	{.msgtype = RTM_GETNEIGH, .doit = neigh_get, .dumpit = neigh_dump_info,
+	 .flags = RTNL_FLAG_DUMP_UNLOCKED},
+	{.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info},
+	{.msgtype = RTM_SETNEIGHTBL, .doit = neightbl_set},
+};
+
 static int __init neigh_init(void)
 {
-	rtnl_register(PF_UNSPEC, RTM_NEWNEIGH, neigh_add, NULL, 0);
-	rtnl_register(PF_UNSPEC, RTM_DELNEIGH, neigh_delete, NULL, 0);
-	rtnl_register(PF_UNSPEC, RTM_GETNEIGH, neigh_get, neigh_dump_info,
-		      RTNL_FLAG_DUMP_UNLOCKED);
-
-	rtnl_register(PF_UNSPEC, RTM_GETNEIGHTBL, NULL, neightbl_dump_info,
-		      0);
-	rtnl_register(PF_UNSPEC, RTM_SETNEIGHTBL, neightbl_set, NULL, 0);
-
+	rtnl_register_many(neigh_rtnl_msg_handlers);
 	return 0;
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 093/877] neighbour: Make neigh_valid_get_req() return ndmsg.
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (91 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 092/877] neighbour: Use rtnl_register_many() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 094/877] neighbour: Move two validations from neigh_get() to neigh_valid_get_req() Greg Kroah-Hartman
                   ` (791 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Jakub Kicinski,
	Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit caf0a753a8eb7ca2b035e199b71a3dabb853a18a ]

neigh_get() passes 4 local variable pointers to neigh_valid_get_req().

If it returns a pointer of struct ndmsg, we do not need to pass two
of them.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250716221221.442239-2-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/neighbour.c | 43 +++++++++++++++++++------------------------
 1 file changed, 19 insertions(+), 24 deletions(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 1dd9f85b74997..fe921f8cc81c1 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2911,10 +2911,9 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 	return err;
 }
 
-static int neigh_valid_get_req(const struct nlmsghdr *nlh,
-			       struct neigh_table **tbl,
-			       void **dst, int *dev_idx, u8 *ndm_flags,
-			       struct netlink_ext_ack *extack)
+static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
+					 struct neigh_table **tbl, void **dst,
+					 struct netlink_ext_ack *extack)
 {
 	struct nlattr *tb[NDA_MAX + 1];
 	struct ndmsg *ndm;
@@ -2922,32 +2921,30 @@ static int neigh_valid_get_req(const struct nlmsghdr *nlh,
 
 	if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ndm))) {
 		NL_SET_ERR_MSG(extack, "Invalid header for neighbor get request");
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 	}
 
 	ndm = nlmsg_data(nlh);
 	if (ndm->ndm_pad1  || ndm->ndm_pad2  || ndm->ndm_state ||
 	    ndm->ndm_type) {
 		NL_SET_ERR_MSG(extack, "Invalid values in header for neighbor get request");
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 	}
 
 	if (ndm->ndm_flags & ~NTF_PROXY) {
 		NL_SET_ERR_MSG(extack, "Invalid flags in header for neighbor get request");
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 	}
 
 	err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct ndmsg), tb,
 					    NDA_MAX, nda_policy, extack);
 	if (err < 0)
-		return err;
+		return ERR_PTR(err);
 
-	*ndm_flags = ndm->ndm_flags;
-	*dev_idx = ndm->ndm_ifindex;
 	*tbl = neigh_find_table(ndm->ndm_family);
-	if (*tbl == NULL) {
+	if (!*tbl) {
 		NL_SET_ERR_MSG(extack, "Unsupported family in header for neighbor get request");
-		return -EAFNOSUPPORT;
+		return ERR_PTR(-EAFNOSUPPORT);
 	}
 
 	for (i = 0; i <= NDA_MAX; ++i) {
@@ -2958,17 +2955,17 @@ static int neigh_valid_get_req(const struct nlmsghdr *nlh,
 		case NDA_DST:
 			if (nla_len(tb[i]) != (int)(*tbl)->key_len) {
 				NL_SET_ERR_MSG(extack, "Invalid network address in neighbor get request");
-				return -EINVAL;
+				return ERR_PTR(-EINVAL);
 			}
 			*dst = nla_data(tb[i]);
 			break;
 		default:
 			NL_SET_ERR_MSG(extack, "Unsupported attribute in neighbor get request");
-			return -EINVAL;
+			return ERR_PTR(-EINVAL);
 		}
 	}
 
-	return 0;
+	return ndm;
 }
 
 static inline size_t neigh_nlmsg_size(void)
@@ -3039,18 +3036,16 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 	struct net_device *dev = NULL;
 	struct neigh_table *tbl = NULL;
 	struct neighbour *neigh;
+	struct ndmsg *ndm;
 	void *dst = NULL;
-	u8 ndm_flags = 0;
-	int dev_idx = 0;
 	int err;
 
-	err = neigh_valid_get_req(nlh, &tbl, &dst, &dev_idx, &ndm_flags,
-				  extack);
-	if (err < 0)
-		return err;
+	ndm = neigh_valid_get_req(nlh, &tbl, &dst, extack);
+	if (IS_ERR(ndm))
+		return PTR_ERR(ndm);
 
-	if (dev_idx) {
-		dev = __dev_get_by_index(net, dev_idx);
+	if (ndm->ndm_ifindex) {
+		dev = __dev_get_by_index(net, ndm->ndm_ifindex);
 		if (!dev) {
 			NL_SET_ERR_MSG(extack, "Unknown device ifindex");
 			return -ENODEV;
@@ -3062,7 +3057,7 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 		return -EINVAL;
 	}
 
-	if (ndm_flags & NTF_PROXY) {
+	if (ndm->ndm_flags & NTF_PROXY) {
 		struct pneigh_entry *pn;
 
 		pn = pneigh_lookup(tbl, net, dst, dev, 0);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 094/877] neighbour: Move two validations from neigh_get() to neigh_valid_get_req().
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (92 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 093/877] neighbour: Make neigh_valid_get_req() return ndmsg Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 095/877] neighbour: Allocate skb in neigh_get() Greg Kroah-Hartman
                   ` (790 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Jakub Kicinski,
	Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit f5046fbc1b6d8c5168d47a617f368f9d4a025e34 ]

We will remove RTNL for neigh_get() and run it under RCU instead.

neigh_get() returns -EINVAL in the following cases:

  * NDA_DST is not specified
  * Both ndm->ndm_ifindex and NTF_PROXY are not specified

These validations do not require RCU.

Let's move them to neigh_valid_get_req().

While at it, the extack string for the first case is replaced with
NL_SET_ERR_ATTR_MISS().

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250716221221.442239-3-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/neighbour.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index fe921f8cc81c1..ecfa1cc2f85f2 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2936,6 +2936,11 @@ static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
 		return ERR_PTR(-EINVAL);
 	}
 
+	if (!(ndm->ndm_flags & NTF_PROXY) && !ndm->ndm_ifindex) {
+		NL_SET_ERR_MSG(extack, "No device specified");
+		return ERR_PTR(-EINVAL);
+	}
+
 	err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct ndmsg), tb,
 					    NDA_MAX, nda_policy, extack);
 	if (err < 0)
@@ -2948,11 +2953,13 @@ static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
 	}
 
 	for (i = 0; i <= NDA_MAX; ++i) {
-		if (!tb[i])
-			continue;
-
 		switch (i) {
 		case NDA_DST:
+			if (!tb[i]) {
+				NL_SET_ERR_ATTR_MISS(extack, NULL, NDA_DST);
+				return ERR_PTR(-EINVAL);
+			}
+
 			if (nla_len(tb[i]) != (int)(*tbl)->key_len) {
 				NL_SET_ERR_MSG(extack, "Invalid network address in neighbor get request");
 				return ERR_PTR(-EINVAL);
@@ -2960,6 +2967,9 @@ static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
 			*dst = nla_data(tb[i]);
 			break;
 		default:
+			if (!tb[i])
+				continue;
+
 			NL_SET_ERR_MSG(extack, "Unsupported attribute in neighbor get request");
 			return ERR_PTR(-EINVAL);
 		}
@@ -3052,11 +3062,6 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 		}
 	}
 
-	if (!dst) {
-		NL_SET_ERR_MSG(extack, "Network address not specified");
-		return -EINVAL;
-	}
-
 	if (ndm->ndm_flags & NTF_PROXY) {
 		struct pneigh_entry *pn;
 
@@ -3069,11 +3074,6 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 					nlh->nlmsg_seq, tbl);
 	}
 
-	if (!dev) {
-		NL_SET_ERR_MSG(extack, "No device specified");
-		return -EINVAL;
-	}
-
 	neigh = neigh_lookup(tbl, dst, dev);
 	if (!neigh) {
 		NL_SET_ERR_MSG(extack, "Neighbour entry not found");
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 095/877] neighbour: Allocate skb in neigh_get().
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (93 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 094/877] neighbour: Move two validations from neigh_get() to neigh_valid_get_req() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 096/877] neighbour: Move neigh_find_table() to neigh_get() Greg Kroah-Hartman
                   ` (789 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Jakub Kicinski,
	Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit 3dfe0b57dcda070d9f1ed2bfb3a9bf0ec8632e08 ]

We will remove RTNL for neigh_get() and run it under RCU instead.

neigh_get_reply() and pneigh_get_reply() allocate skb with GFP_KERNEL.

Let's move the allocation before __dev_get_by_index() in neigh_get().

Now, neigh_get_reply() and pneigh_get_reply() are inlined and
rtnl_unicast() is factorised.

We will convert pneigh_lookup() to __pneigh_lookup() later.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250716221221.442239-4-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/neighbour.c | 88 ++++++++++++++++----------------------------
 1 file changed, 32 insertions(+), 56 deletions(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index ecfa1cc2f85f2..b57d5810fa0d8 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2989,27 +2989,6 @@ static inline size_t neigh_nlmsg_size(void)
 	       + nla_total_size(1); /* NDA_PROTOCOL */
 }
 
-static int neigh_get_reply(struct net *net, struct neighbour *neigh,
-			   u32 pid, u32 seq)
-{
-	struct sk_buff *skb;
-	int err = 0;
-
-	skb = nlmsg_new(neigh_nlmsg_size(), GFP_KERNEL);
-	if (!skb)
-		return -ENOBUFS;
-
-	err = neigh_fill_info(skb, neigh, pid, seq, RTM_NEWNEIGH, 0);
-	if (err) {
-		kfree_skb(skb);
-		goto errout;
-	}
-
-	err = rtnl_unicast(skb, net, pid);
-errout:
-	return err;
-}
-
 static inline size_t pneigh_nlmsg_size(void)
 {
 	return NLMSG_ALIGN(sizeof(struct ndmsg))
@@ -3018,34 +2997,16 @@ static inline size_t pneigh_nlmsg_size(void)
 	       + nla_total_size(1); /* NDA_PROTOCOL */
 }
 
-static int pneigh_get_reply(struct net *net, struct pneigh_entry *neigh,
-			    u32 pid, u32 seq, struct neigh_table *tbl)
-{
-	struct sk_buff *skb;
-	int err = 0;
-
-	skb = nlmsg_new(pneigh_nlmsg_size(), GFP_KERNEL);
-	if (!skb)
-		return -ENOBUFS;
-
-	err = pneigh_fill_info(skb, neigh, pid, seq, RTM_NEWNEIGH, 0, tbl);
-	if (err) {
-		kfree_skb(skb);
-		goto errout;
-	}
-
-	err = rtnl_unicast(skb, net, pid);
-errout:
-	return err;
-}
-
 static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 		     struct netlink_ext_ack *extack)
 {
 	struct net *net = sock_net(in_skb->sk);
+	u32 pid = NETLINK_CB(in_skb).portid;
 	struct net_device *dev = NULL;
 	struct neigh_table *tbl = NULL;
+	u32 seq = nlh->nlmsg_seq;
 	struct neighbour *neigh;
+	struct sk_buff *skb;
 	struct ndmsg *ndm;
 	void *dst = NULL;
 	int err;
@@ -3054,11 +3015,19 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 	if (IS_ERR(ndm))
 		return PTR_ERR(ndm);
 
+	if (ndm->ndm_flags & NTF_PROXY)
+		skb = nlmsg_new(neigh_nlmsg_size(), GFP_KERNEL);
+	else
+		skb = nlmsg_new(pneigh_nlmsg_size(), GFP_KERNEL);
+	if (!skb)
+		return -ENOBUFS;
+
 	if (ndm->ndm_ifindex) {
 		dev = __dev_get_by_index(net, ndm->ndm_ifindex);
 		if (!dev) {
 			NL_SET_ERR_MSG(extack, "Unknown device ifindex");
-			return -ENODEV;
+			err = -ENODEV;
+			goto err_free_skb;
 		}
 	}
 
@@ -3068,23 +3037,30 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 		pn = pneigh_lookup(tbl, net, dst, dev, 0);
 		if (!pn) {
 			NL_SET_ERR_MSG(extack, "Proxy neighbour entry not found");
-			return -ENOENT;
+			err = -ENOENT;
+			goto err_free_skb;
 		}
-		return pneigh_get_reply(net, pn, NETLINK_CB(in_skb).portid,
-					nlh->nlmsg_seq, tbl);
-	}
-
-	neigh = neigh_lookup(tbl, dst, dev);
-	if (!neigh) {
-		NL_SET_ERR_MSG(extack, "Neighbour entry not found");
-		return -ENOENT;
-	}
 
-	err = neigh_get_reply(net, neigh, NETLINK_CB(in_skb).portid,
-			      nlh->nlmsg_seq);
+		err = pneigh_fill_info(skb, pn, pid, seq, RTM_NEWNEIGH, 0, tbl);
+		if (err)
+			goto err_free_skb;
+	} else {
+		neigh = neigh_lookup(tbl, dst, dev);
+		if (!neigh) {
+			NL_SET_ERR_MSG(extack, "Neighbour entry not found");
+			err = -ENOENT;
+			goto err_free_skb;
+		}
 
-	neigh_release(neigh);
+		err = neigh_fill_info(skb, neigh, pid, seq, RTM_NEWNEIGH, 0);
+		neigh_release(neigh);
+		if (err)
+			goto err_free_skb;
+	}
 
+	return rtnl_unicast(skb, net, pid);
+err_free_skb:
+	kfree_skb(skb);
 	return err;
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 096/877] neighbour: Move neigh_find_table() to neigh_get().
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (94 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 095/877] neighbour: Allocate skb in neigh_get() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 097/877] neighbour: Convert RTM_GETNEIGH to RCU Greg Kroah-Hartman
                   ` (788 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Jakub Kicinski,
	Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit 0e5ac19c78654abbf43dc4ffdae290c8cb81c59c ]

neigh_valid_get_req() calls neigh_find_table() to fetch neigh_tables[].

neigh_find_table() uses rcu_dereference_rtnl(), but RTNL actually does
not protect it at all; neigh_table_clear() can be called without RTNL
and only waits for RCU readers by synchronize_rcu().

Fortunately, there is no bug because IPv4 is built-in, IPv6 cannot be
unloaded, and DECNET was removed.

To fetch neigh_tables[] by rcu_dereference() later, let's move
neigh_find_table() from neigh_valid_get_req() to neigh_get().

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250716221221.442239-5-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/neighbour.c | 37 ++++++++++++++++++++-----------------
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index b57d5810fa0d8..0dc0ba5cf7443 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2912,10 +2912,9 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 }
 
 static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
-					 struct neigh_table **tbl, void **dst,
+					 struct nlattr **tb,
 					 struct netlink_ext_ack *extack)
 {
-	struct nlattr *tb[NDA_MAX + 1];
 	struct ndmsg *ndm;
 	int err, i;
 
@@ -2946,12 +2945,6 @@ static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
 	if (err < 0)
 		return ERR_PTR(err);
 
-	*tbl = neigh_find_table(ndm->ndm_family);
-	if (!*tbl) {
-		NL_SET_ERR_MSG(extack, "Unsupported family in header for neighbor get request");
-		return ERR_PTR(-EAFNOSUPPORT);
-	}
-
 	for (i = 0; i <= NDA_MAX; ++i) {
 		switch (i) {
 		case NDA_DST:
@@ -2959,12 +2952,6 @@ static struct ndmsg *neigh_valid_get_req(const struct nlmsghdr *nlh,
 				NL_SET_ERR_ATTR_MISS(extack, NULL, NDA_DST);
 				return ERR_PTR(-EINVAL);
 			}
-
-			if (nla_len(tb[i]) != (int)(*tbl)->key_len) {
-				NL_SET_ERR_MSG(extack, "Invalid network address in neighbor get request");
-				return ERR_PTR(-EINVAL);
-			}
-			*dst = nla_data(tb[i]);
 			break;
 		default:
 			if (!tb[i])
@@ -3002,16 +2989,17 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 {
 	struct net *net = sock_net(in_skb->sk);
 	u32 pid = NETLINK_CB(in_skb).portid;
+	struct nlattr *tb[NDA_MAX + 1];
 	struct net_device *dev = NULL;
-	struct neigh_table *tbl = NULL;
 	u32 seq = nlh->nlmsg_seq;
+	struct neigh_table *tbl;
 	struct neighbour *neigh;
 	struct sk_buff *skb;
 	struct ndmsg *ndm;
-	void *dst = NULL;
+	void *dst;
 	int err;
 
-	ndm = neigh_valid_get_req(nlh, &tbl, &dst, extack);
+	ndm = neigh_valid_get_req(nlh, tb, extack);
 	if (IS_ERR(ndm))
 		return PTR_ERR(ndm);
 
@@ -3022,6 +3010,21 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 	if (!skb)
 		return -ENOBUFS;
 
+	tbl = neigh_find_table(ndm->ndm_family);
+	if (!tbl) {
+		NL_SET_ERR_MSG(extack, "Unsupported family in header for neighbor get request");
+		err = -EAFNOSUPPORT;
+		goto err_free_skb;
+	}
+
+	if (nla_len(tb[NDA_DST]) != (int)tbl->key_len) {
+		NL_SET_ERR_MSG(extack, "Invalid network address in neighbor get request");
+		err = -EINVAL;
+		goto err_free_skb;
+	}
+
+	dst = nla_data(tb[NDA_DST]);
+
 	if (ndm->ndm_ifindex) {
 		dev = __dev_get_by_index(net, ndm->ndm_ifindex);
 		if (!dev) {
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 097/877] neighbour: Convert RTM_GETNEIGH to RCU.
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (95 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 096/877] neighbour: Move neigh_find_table() to neigh_get() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL " Greg Kroah-Hartman
                   ` (787 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Jakub Kicinski,
	Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit ed6e380d2d419a3e8ca73de7b4c7ccb522835f1e ]

Only __dev_get_by_index() is the RTNL dependant in neigh_get().

Let's replace it with dev_get_by_index_rcu() and convert RTM_GETNEIGH
to RCU.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250716221221.442239-10-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/neighbour.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 0dc0ba5cf7443..50a18ae55409e 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -3010,27 +3010,29 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 	if (!skb)
 		return -ENOBUFS;
 
+	rcu_read_lock();
+
 	tbl = neigh_find_table(ndm->ndm_family);
 	if (!tbl) {
 		NL_SET_ERR_MSG(extack, "Unsupported family in header for neighbor get request");
 		err = -EAFNOSUPPORT;
-		goto err_free_skb;
+		goto err_unlock;
 	}
 
 	if (nla_len(tb[NDA_DST]) != (int)tbl->key_len) {
 		NL_SET_ERR_MSG(extack, "Invalid network address in neighbor get request");
 		err = -EINVAL;
-		goto err_free_skb;
+		goto err_unlock;
 	}
 
 	dst = nla_data(tb[NDA_DST]);
 
 	if (ndm->ndm_ifindex) {
-		dev = __dev_get_by_index(net, ndm->ndm_ifindex);
+		dev = dev_get_by_index_rcu(net, ndm->ndm_ifindex);
 		if (!dev) {
 			NL_SET_ERR_MSG(extack, "Unknown device ifindex");
 			err = -ENODEV;
-			goto err_free_skb;
+			goto err_unlock;
 		}
 	}
 
@@ -3041,28 +3043,31 @@ static int neigh_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 		if (!pn) {
 			NL_SET_ERR_MSG(extack, "Proxy neighbour entry not found");
 			err = -ENOENT;
-			goto err_free_skb;
+			goto err_unlock;
 		}
 
 		err = pneigh_fill_info(skb, pn, pid, seq, RTM_NEWNEIGH, 0, tbl);
 		if (err)
-			goto err_free_skb;
+			goto err_unlock;
 	} else {
 		neigh = neigh_lookup(tbl, dst, dev);
 		if (!neigh) {
 			NL_SET_ERR_MSG(extack, "Neighbour entry not found");
 			err = -ENOENT;
-			goto err_free_skb;
+			goto err_unlock;
 		}
 
 		err = neigh_fill_info(skb, neigh, pid, seq, RTM_NEWNEIGH, 0);
 		neigh_release(neigh);
 		if (err)
-			goto err_free_skb;
+			goto err_unlock;
 	}
 
+	rcu_read_unlock();
+
 	return rtnl_unicast(skb, net, pid);
-err_free_skb:
+err_unlock:
+	rcu_read_unlock();
 	kfree_skb(skb);
 	return err;
 }
@@ -3876,7 +3881,7 @@ static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
 	{.msgtype = RTM_NEWNEIGH, .doit = neigh_add},
 	{.msgtype = RTM_DELNEIGH, .doit = neigh_delete},
 	{.msgtype = RTM_GETNEIGH, .doit = neigh_get, .dumpit = neigh_dump_info,
-	 .flags = RTNL_FLAG_DUMP_UNLOCKED},
+	 .flags = RTNL_FLAG_DOIT_UNLOCKED | RTNL_FLAG_DUMP_UNLOCKED},
 	{.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info},
 	{.msgtype = RTM_SETNEIGHTBL, .doit = neightbl_set},
 };
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL to RCU.
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (96 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 097/877] neighbour: Convert RTM_GETNEIGH to RCU Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-10-01 19:34   ` Harshit Mogalapalli
  2026-09-30 15:16 ` [PATCH 6.12 099/877] neighbour: Add missing RCU annotation for neightbl_dump_info() Greg Kroah-Hartman
                   ` (786 subsequent siblings)
  884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Eric Dumazet,
	Jakub Kicinski, Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit 4ae34be500649ec452ac1fc2748958683ad9b55d ]

neightbl_dump_info() calls these functions for each neigh_tables[]
entry:

  1. neightbl_fill_info() for tbl->parms
  2. neightbl_fill_param_info() for tbl->parms_list (except tbl->parms)

Both functions rely on the table lock (read_lock_bh(&tbl->lock))
and RTNL is not needed.

Let's fetch the table under RCU and convert RTM_GETNEIGHTBL to RCU.

Note that the first entry of tbl->parms_list is tbl->parms.list and
embedded in neigh_table, so list_next_entry() is safe.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20251022054004.2514876-4-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/neighbour.c | 23 +++++++++--------------
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 50a18ae55409e..d38c309e7fa61 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2131,7 +2131,7 @@ static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)
 		return -ENOBUFS;
 
 	if ((parms->dev &&
-	     nla_put_u32(skb, NDTPA_IFINDEX, parms->dev->ifindex)) ||
+	     nla_put_u32(skb, NDTPA_IFINDEX, READ_ONCE(parms->dev->ifindex))) ||
 	    nla_put_u32(skb, NDTPA_REFCNT, refcount_read(&parms->refcnt)) ||
 	    nla_put_u32(skb, NDTPA_QUEUE_LENBYTES,
 			NEIGH_VAR(parms, QUEUE_LEN_BYTES)) ||
@@ -2183,8 +2183,6 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
 		return -EMSGSIZE;
 
 	ndtmsg = nlmsg_data(nlh);
-
-	read_lock_bh(&tbl->lock);
 	ndtmsg->ndtm_family = tbl->family;
 	ndtmsg->ndtm_pad1   = 0;
 	ndtmsg->ndtm_pad2   = 0;
@@ -2210,11 +2208,9 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
 			.ndtc_proxy_qlen	= READ_ONCE(tbl->proxy_queue.qlen),
 		};
 
-		rcu_read_lock();
 		nht = rcu_dereference(tbl->nht);
 		ndc.ndtc_hash_rnd = nht->hash_rnd[0];
 		ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1);
-		rcu_read_unlock();
 
 		if (nla_put(skb, NDTA_CONFIG, sizeof(ndc), &ndc))
 			goto nla_put_failure;
@@ -2252,12 +2248,10 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
 	if (neightbl_fill_parms(skb, &tbl->parms) < 0)
 		goto nla_put_failure;
 
-	read_unlock_bh(&tbl->lock);
 	nlmsg_end(skb, nlh);
 	return 0;
 
 nla_put_failure:
-	read_unlock_bh(&tbl->lock);
 	nlmsg_cancel(skb, nlh);
 	return -EMSGSIZE;
 }
@@ -2276,8 +2270,6 @@ static int neightbl_fill_param_info(struct sk_buff *skb,
 		return -EMSGSIZE;
 
 	ndtmsg = nlmsg_data(nlh);
-
-	read_lock_bh(&tbl->lock);
 	ndtmsg->ndtm_family = tbl->family;
 	ndtmsg->ndtm_pad1   = 0;
 	ndtmsg->ndtm_pad2   = 0;
@@ -2286,11 +2278,9 @@ static int neightbl_fill_param_info(struct sk_buff *skb,
 	    neightbl_fill_parms(skb, parms) < 0)
 		goto errout;
 
-	read_unlock_bh(&tbl->lock);
 	nlmsg_end(skb, nlh);
 	return 0;
 errout:
-	read_unlock_bh(&tbl->lock);
 	nlmsg_cancel(skb, nlh);
 	return -EMSGSIZE;
 }
@@ -2531,10 +2521,12 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 
 	family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family;
 
+	rcu_read_lock();
+
 	for (tidx = 0; tidx < NEIGH_NR_TABLES; tidx++) {
 		struct neigh_parms *p;
 
-		tbl = rcu_dereference_rtnl(neigh_tables[tidx]);
+		tbl = rcu_dereference(neigh_tables[tidx]);
 		if (!tbl)
 			continue;
 
@@ -2548,7 +2540,7 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 
 		nidx = 0;
 		p = list_next_entry(&tbl->parms, list);
-		list_for_each_entry_from(p, &tbl->parms_list, list) {
+		list_for_each_entry_from_rcu(p, &tbl->parms_list, list) {
 			if (!net_eq(neigh_parms_net(p), net))
 				continue;
 
@@ -2568,6 +2560,8 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 		neigh_skip = 0;
 	}
 out:
+	rcu_read_unlock();
+
 	cb->args[0] = tidx;
 	cb->args[1] = nidx;
 
@@ -3882,7 +3876,8 @@ static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
 	{.msgtype = RTM_DELNEIGH, .doit = neigh_delete},
 	{.msgtype = RTM_GETNEIGH, .doit = neigh_get, .dumpit = neigh_dump_info,
 	 .flags = RTNL_FLAG_DOIT_UNLOCKED | RTNL_FLAG_DUMP_UNLOCKED},
-	{.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info},
+	{.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info,
+	 .flags = RTNL_FLAG_DUMP_UNLOCKED},
 	{.msgtype = RTM_SETNEIGHTBL, .doit = neightbl_set},
 };
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 099/877] neighbour: Add missing RCU annotation for neightbl_dump_info().
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (97 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL " Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 100/877] neighbour: Skip default parms when resumed in neightbl_dump_info() Greg Kroah-Hartman
                   ` (785 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Ido Schimmel,
	Jakub Kicinski, Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit 764dcebb033764633700a036c7351a7c6350eec6 ]

neightbl_dump_info() fetches the first non-default neigh_parms
with list_next_entry(&tbl->parms, ...) and iterates through the
list with list_for_each_entry_from_rcu().

However, list_next_entry() does not use RCU helper.

Let's use list_for_each_entry_rcu() and skip the default parms.

Fixes: 4ae34be50064 ("neighbour: Convert RTM_GETNEIGHTBL to RCU.")
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260909233143.2401847-2-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/neighbour.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index d38c309e7fa61..c9d848085dad3 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2539,11 +2539,14 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 			break;
 
 		nidx = 0;
-		p = list_next_entry(&tbl->parms, list);
-		list_for_each_entry_from_rcu(p, &tbl->parms_list, list) {
+
+		list_for_each_entry_rcu(p, &tbl->parms_list, list) {
 			if (!net_eq(neigh_parms_net(p), net))
 				continue;
 
+			if (!p->dev)
+				continue;
+
 			if (nidx < neigh_skip)
 				goto next;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 100/877] neighbour: Skip default parms when resumed in neightbl_dump_info().
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (98 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 099/877] neighbour: Add missing RCU annotation for neightbl_dump_info() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 101/877] ALSA: bcd2000: Fix race between rawmidi and disconnect Greg Kroah-Hartman
                   ` (784 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Ido Schimmel,
	Jakub Kicinski, Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit 979aabdad8dd03394467ee484a1a70f3d40b19ba ]

neightbl_dump_info() calls neightbl_fill_info() in each loop
to render the default parms.

If there are many devices and neightbl_fill_param_info() failed,
neightbl_fill_info() is called again when the dump resumes:

  # ynl --family rt-neigh --dump getneightbl --output-json |
    jq '.[] | {name: .name, ifindex: .parms.ifindex}'
  ...
  {
    "name": "ndisc_cache",
    "ifindex": null
  }
  ...
  {
    "name": "ndisc_cache",
    "ifindex": 6
  }
  {
    "name": "ndisc_cache",
    "ifindex": null
  }
  {
    "name": "ndisc_cache",
    "ifindex": 5
  }

Let's skip neightbl_fill_info() if it is already called in
neightbl_dump_info().

Note that we cannot use !neigh_skip instead of !default_skip
because default_skip == 1 && neigh_skip == 0 could be true
if the first neightbl_fill_param_info() fails.

Also, nidx must be cleared at the end of each table loop;
otherwise, if neightbl_fill_info() for a subsequent table
fails, the leftover nidx from the previous table would be
saved in cb->args[1], resulting in erroneously skipping parms
of the subsequent table in the next dump.

Fixes: c7fb64db001f ("[NETLINK]: Neighbour table configuration and statistics via rtnetlink")
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260909233143.2401847-5-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/neighbour.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index c9d848085dad3..99822878262c7 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2507,9 +2507,10 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	const struct nlmsghdr *nlh = cb->nlh;
 	struct net *net = sock_net(skb->sk);
+	int default_skip = cb->args[2];
+	int neigh_skip = cb->args[1];
 	int family, tidx, nidx = 0;
 	int tbl_skip = cb->args[0];
-	int neigh_skip = cb->args[1];
 	struct neigh_table *tbl;
 
 	if (cb->strict_check) {
@@ -2533,12 +2534,13 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 		if (tidx < tbl_skip || (family && tbl->family != family))
 			continue;
 
-		if (neightbl_fill_info(skb, tbl, NETLINK_CB(cb->skb).portid,
+		if (!default_skip &&
+		    neightbl_fill_info(skb, tbl, NETLINK_CB(cb->skb).portid,
 				       nlh->nlmsg_seq, RTM_NEWNEIGHTBL,
 				       NLM_F_MULTI) < 0)
 			break;
 
-		nidx = 0;
+		default_skip = 1;
 
 		list_for_each_entry_rcu(p, &tbl->parms_list, list) {
 			if (!net_eq(neigh_parms_net(p), net))
@@ -2561,12 +2563,15 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
 		}
 
 		neigh_skip = 0;
+		nidx = 0;
+		default_skip = 0;
 	}
 out:
 	rcu_read_unlock();
 
 	cb->args[0] = tidx;
 	cb->args[1] = nidx;
+	cb->args[2] = default_skip;
 
 	return skb->len;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 101/877] ALSA: bcd2000: Fix race between rawmidi and disconnect
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (99 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 100/877] neighbour: Skip default parms when resumed in neightbl_dump_info() Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 102/877] phy: mediatek: phy-mtk-hdmi-mt8195: Fix PLL calc divisor overflow Greg Kroah-Hartman
                   ` (783 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Takashi Iwai, Sasha Levin

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

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

From: Takashi Iwai <tiwai@suse.de>

[ Upstream commit 221253723dc58bb901c3f27a7659823e63fc598c ]

Although we tried to fix the potential UAF issues at USB disconnect on
bcd2000 driver, there is still an overlooked case -- namely, when a
rawmidi trigger callback has been already running at USB disconnect
handling, the in-flight function (e.g. bcd2000_midi_send()) could
still access the URB, because the previous URB NULL-check & clearance
was considered only for the URB complete callbacks, but not about the
parallel rawmidi operations.

For addressing the race, this patch introduced a new spinlock that
covers each rawmidi operation as well as the rawmidi handling in the
complete callback.  The URB is cleared with the lock, so it guarantees
that the pending rawmidi task already finished or a NULL check is
effective.

Fixes: 459d3a64766f ("ALSA: bcd2000: clear the URB pointers on disconnect")
Link: https://patch.msgid.link/20260910155227.996210-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/usb/bcd2000/bcd2000.c | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c
index c7e7149c6dabd..dce6d1f611f94 100644
--- a/sound/usb/bcd2000/bcd2000.c
+++ b/sound/usb/bcd2000/bcd2000.c
@@ -43,6 +43,7 @@ struct bcd2000 {
 	struct usb_interface *intf;
 	int card_index;
 
+	spinlock_t midi_lock;
 	int midi_out_active;
 	struct snd_rawmidi *rmidi;
 	struct snd_rawmidi_substream *midi_receive_substream;
@@ -90,6 +91,8 @@ static void bcd2000_midi_input_trigger(struct snd_rawmidi_substream *substream,
 						int up)
 {
 	struct bcd2000 *bcd2k = substream->rmidi->private_data;
+
+	guard(spinlock_irqsave)(&bcd2k->midi_lock);
 	bcd2k->midi_receive_substream = up ? substream : NULL;
 }
 
@@ -195,6 +198,8 @@ static void bcd2000_midi_output_trigger(struct snd_rawmidi_substream *substream,
 {
 	struct bcd2000 *bcd2k = substream->rmidi->private_data;
 
+	guard(spinlock_irqsave)(&bcd2k->midi_lock);
+
 	if (up) {
 		bcd2k->midi_out_substream = substream;
 		/* check if there is data userspace wants to send */
@@ -219,6 +224,7 @@ static void bcd2000_output_complete(struct urb *urb)
 		return;
 
 	/* check if there is more data userspace wants to send */
+	guard(spinlock_irqsave)(&bcd2k->midi_lock);
 	bcd2000_midi_send(bcd2k);
 }
 
@@ -234,6 +240,8 @@ static void bcd2000_input_complete(struct urb *urb)
 	if (!bcd2k || urb->status == -ESHUTDOWN)
 		return;
 
+	guard(spinlock_irqsave)(&bcd2k->midi_lock);
+
 	if (urb->actual_length > 0)
 		bcd2000_midi_handle_input(bcd2k, urb->transfer_buffer,
 					urb->actual_length);
@@ -348,16 +356,26 @@ static int bcd2000_init_midi(struct bcd2000 *bcd2k)
 	return 0;
 }
 
+static void bcd2000_midi_free(struct bcd2000 *bcd2k,
+			      struct urb **urb_p)
+{
+	struct urb *urb = *urb_p;
+
+	if (!urb)
+		return;
+
+	usb_poison_urb(urb);
+	scoped_guard(spinlock_irq, &bcd2k->midi_lock)
+		*urb_p = NULL;
+
+	usb_free_urb(urb);
+}
+
 static void bcd2000_free_usb_related_resources(struct bcd2000 *bcd2k,
 						struct usb_interface *interface)
 {
-	usb_poison_urb(bcd2k->midi_out_urb);
-	usb_poison_urb(bcd2k->midi_in_urb);
-
-	usb_free_urb(bcd2k->midi_out_urb);
-	usb_free_urb(bcd2k->midi_in_urb);
-	bcd2k->midi_out_urb = NULL;
-	bcd2k->midi_in_urb = NULL;
+	bcd2000_midi_free(bcd2k, &bcd2k->midi_out_urb);
+	bcd2000_midi_free(bcd2k, &bcd2k->midi_in_urb);
 
 	if (bcd2k->intf) {
 		usb_set_intfdata(bcd2k->intf, NULL);
@@ -397,6 +415,7 @@ static int bcd2000_probe(struct usb_interface *interface,
 	bcd2k->card = card;
 	bcd2k->card_index = card_index;
 	bcd2k->intf = interface;
+	spin_lock_init(&bcd2k->midi_lock);
 
 	snd_card_set_dev(card, &interface->dev);
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 102/877] phy: mediatek: phy-mtk-hdmi-mt8195: Fix PLL calc divisor overflow
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (100 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 101/877] ALSA: bcd2000: Fix race between rawmidi and disconnect Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 103/877] phy: mediatek: phy-mtk-hdmi-mt8195: Fix TMDS clk bit ratio setting Greg Kroah-Hartman
                   ` (782 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Manivannan Sadhasivam,
	AngeloGioacchino Del Regno, Vinod Koul, Sasha Levin

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

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

From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

[ Upstream commit de7f29a1fe1dc2864d8a47f8c39d508442cae167 ]

When trying to calculate a PLL rate for target display resolutions
above 2560x1440, 24bpp, 30Hz, the pixel clock value will be more
than 32-bits long but the division to finally calculate the digital
clock divider is being done with div_u64(), which expects a 32bit
unsigned divisor.

Fix the overflow by using div64_u64() instead.

Fixes: 9d9ff3d2a4a5 ("phy: mediatek: hdmi: mt8195: fix wrong pll calculus")
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://patch.msgid.link/20260911074015.9994-2-angelogioacchino.delregno@collabora.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
index bbfe11d6a69d7..80600b2b6b38d 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
@@ -288,7 +288,7 @@ static int mtk_hdmi_pll_calc(struct mtk_hdmi_phy *hdmi_phy, struct clk_hw *hw,
 	posdiv2 = 1;
 
 	/* Digital clk divider, max /32 */
-	digital_div = div_u64(ns_hdmipll_ck, posdiv1 * posdiv2 * pixel_clk);
+	digital_div = div64_u64(ns_hdmipll_ck, posdiv1 * posdiv2 * pixel_clk);
 	if (!(digital_div <= 32 && digital_div >= 1))
 		return -EINVAL;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 103/877] phy: mediatek: phy-mtk-hdmi-mt8195: Fix TMDS clk bit ratio setting
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (101 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 102/877] phy: mediatek: phy-mtk-hdmi-mt8195: Fix PLL calc divisor overflow Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 104/877] ALSA: pcm: set timer->private_data before registering the PCM timer Greg Kroah-Hartman
                   ` (781 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Manivannan Sadhasivam,
	AngeloGioacchino Del Regno, Vinod Koul, Sasha Levin

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

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

From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

[ Upstream commit 486a70ef848264dcf9a57f0bb0452848db9537de ]

The comment in the mtk_phy_tmds_clk_ratio() function clearly and
correctly explains that the TMDS ratio has to be 1/10 for data
rates under 3.4Gbps, and 1/40 over that.

Unfortunately though, the TXC_DIV register setting was wrong, as
in value 3 means to divide by 8 and, in order to achieve the in
spec 1/40 (tmds) data rate, this has to divide by 4 instead!

Add definitions for the TXC_DIV register values clearly explaining
the meanings (DIV2, DIV4, DIV8), and program the correct, DIV 4,
value to the register in mtk_phy_tmds_clk_ratio().

This fixes out of spec clocking and, with this change, SoCs using
the MT8195 class HDMI PHYs can now successfully be configured to
output 3840x2160@60Hz over HDMI.

Fixes: 45810d486bb4 ("phy: mediatek: add support for phy-mtk-hdmi-mt8195")
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://patch.msgid.link/20260911074015.9994-3-angelogioacchino.delregno@collabora.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 2 +-
 drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
index 80600b2b6b38d..9f2c4db843479 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c
@@ -34,7 +34,7 @@ mtk_phy_tmds_clk_ratio(struct mtk_hdmi_phy *hdmi_phy, bool enable)
 	 * clock bit ratio 1:40, under 3.4Gbps, clock bit ratio 1:10
 	 */
 	if (enable)
-		mtk_phy_update_field(regs + HDMI20_CLK_CFG, REG_TXC_DIV, 3);
+		mtk_phy_update_field(regs + HDMI20_CLK_CFG, REG_TXC_DIV, VAL_TXC_DIV4);
 	else
 		mtk_phy_clear_bits(regs + HDMI20_CLK_CFG, REG_TXC_DIV);
 }
diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h
index 22a68dc9550ca..8e118a10ffbf2 100644
--- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h
+++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.h
@@ -17,6 +17,9 @@
 
 #define HDMI20_CLK_CFG 0x70
 #define REG_TXC_DIV GENMASK(31, 30)
+#define VAL_TXC_DIV2 1
+#define VAL_TXC_DIV4 2
+#define VAL_TXC_DIV8 3
 
 #define HDMI_1_CFG_0 0x00
 #define RG_HDMITX21_DRV_IBIAS_CLK GENMASK(10, 5)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 104/877] ALSA: pcm: set timer->private_data before registering the PCM timer
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (102 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 103/877] phy: mediatek: phy-mtk-hdmi-mt8195: Fix TMDS clk bit ratio setting Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 105/877] ASoC: Rename snd_soc_dai_link_ch_map.ch_mask to cpu_ch_mask Greg Kroah-Hartman
                   ` (780 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+19da64013c46df87f971,
	Nguyen Ngoc Thang, Takashi Iwai, Sasha Levin

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

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

From: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>

[ Upstream commit 1e713f9bb2ac583521f06b0eb4e22440b1e3d078 ]

snd_pcm_timer_init() calls snd_device_register() to link the new
struct snd_timer into the global timer list while it still carries
hw.c_resolution = snd_pcm_timer_resolution (and hw.start/hw.stop),
and only afterwards sets timer->private_data = substream.

Once the timer is on the list under register_mutex, a concurrent
reader can already reach it through the same mutex and invoke these
callbacks. /proc/asound/timers does this via c_resolution(), and
snd_timer_open()+snd_timer_start() reach start()/stop() the same way.
All three dereference timer->private_data, which for this brief
window is NULL, giving a NULL-pointer dereference:

  substream = timer->private_data;
  return substream->runtime ? ...   // substream is NULL

Move the private_data/private_free assignment before
snd_device_register() so the timer is never visible on the list
without its private_data set. On the snd_device_register() failure
path, private_free() (snd_pcm_timer_free()) can now run, but it only
does substream->timer = NULL, which is already NULL at that point
since substream->timer is set to the new timer just once, after a
successful registration -- so the failure path stays safe.

Reported-by: syzbot+19da64013c46df87f971@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=19da64013c46df87f971
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
Link: https://patch.msgid.link/20260913134446.114724-1-ngocthang2710.1999@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/core/pcm_timer.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/sound/core/pcm_timer.c b/sound/core/pcm_timer.c
index ab0e5bd70f8fa..18bedd66435dc 100644
--- a/sound/core/pcm_timer.c
+++ b/sound/core/pcm_timer.c
@@ -111,12 +111,15 @@ void snd_pcm_timer_init(struct snd_pcm_substream *substream)
 			snd_pcm_direction_name(substream->stream),
 			tid.card, tid.device, tid.subdevice);
 	timer->hw = snd_pcm_timer;
+	/* Set before registering: a concurrent reader can invoke our hw
+	 * callbacks as soon as the timer is on the global list.
+	 */
+	timer->private_data = substream;
+	timer->private_free = snd_pcm_timer_free;
 	if (snd_device_register(timer->card, timer) < 0) {
 		snd_device_free(timer->card, timer);
 		return;
 	}
-	timer->private_data = substream;
-	timer->private_free = snd_pcm_timer_free;
 	substream->timer = timer;
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 105/877] ASoC: Rename snd_soc_dai_link_ch_map.ch_mask to cpu_ch_mask
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (103 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 104/877] ALSA: pcm: set timer->private_data before registering the PCM timer Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 106/877] ASoC: Add codec_ch_mask to snd_soc_dai_link_ch_map Greg Kroah-Hartman
                   ` (779 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Richard Fitzgerald, Mark Brown,
	Sasha Levin

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

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

From: Richard Fitzgerald <rf@opensource.cirrus.com>

[ Upstream commit 4d855d747521505b54457c96bc73577bf74b2374 ]

Rename the ch_mask member of snd_soc_dai_link_ch_map to cpu_ch_mask,
as that is what it is used for.

The CPU and codec channel masks are not necessarily the same, and are
quite likely different. SoundWire and I2S/TDM both support assigning
different sample slots to each codec, so for example channel 0 on each
codec could map to different channels at the CPU. So it's quite normal
that the channel mask at the CPU end is different for each codec, but
the codec channel masks are the same for each codec.

Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20260910114500.1586637-2-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 6b382bdfe26a ("ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/sound/soc.h                 | 2 +-
 sound/soc/sdw_utils/soc_sdw_utils.c | 2 +-
 sound/soc/soc-pcm.c                 | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index cd467f8babdb6..87e50c8cdda31 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -717,7 +717,7 @@ struct snd_soc_dai_link_component {
 struct snd_soc_dai_link_ch_map {
 	unsigned int cpu;
 	unsigned int codec;
-	unsigned int ch_mask;
+	unsigned int cpu_ch_mask;
 };
 
 struct snd_soc_dai_link {
diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index e6ac5c0fd3bec..70a7abede618f 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -795,7 +795,7 @@ int asoc_sdw_hw_params(struct snd_pcm_substream *substream,
 	 * ASoC will set the corresponding channel numbers for each cpu dai.
 	 */
 	for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
-		ch_maps->ch_mask = ch_mask << (i * step);
+		ch_maps->cpu_ch_mask = ch_mask << (i * step);
 
 	return 0;
 }
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 628322790c878..440acec700a56 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1180,7 +1180,7 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
 		 */
 		for_each_rtd_ch_maps(rtd, j, ch_maps)
 			if (ch_maps->cpu == i)
-				ch_mask |= ch_maps->ch_mask;
+				ch_mask |= ch_maps->cpu_ch_mask;
 
 		/* fixup cpu channel number */
 		if (ch_mask)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 106/877] ASoC: Add codec_ch_mask to snd_soc_dai_link_ch_map
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (104 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 105/877] ASoC: Rename snd_soc_dai_link_ch_map.ch_mask to cpu_ch_mask Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:16 ` [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params Greg Kroah-Hartman
                   ` (778 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Richard Fitzgerald, Mark Brown,
	Sasha Levin

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

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

From: Richard Fitzgerald <rf@opensource.cirrus.com>

[ Upstream commit 88b14c0d0bab5c0f3e7c641f274e3c70210c0e36 ]

Add a codec_ch_mask member to snd_soc_dai_link_ch_map.

The CPU and codec channel masks are not necessarily the same, and are
quite likely different. SoundWire and I2S/TDM both support assigning
different sample slots to each codec, so for example channel 0 on each
codec could map to different channels at the CPU.

It is also possible for one TX channel to map to multiple RX channels.
So it isn't _always_ safe to assume that the total number of set bits
in the CPU ch_mask is the same as the total number of enabled channels
on the codec.

For example consider this mapping on a capture stream:

CPU0 CODEC0 cpu_ch_mask = 0x03
CPU1 CODEC0 cpu_ch_mask = 0x03

This could be either four TX channels on the codec split across two
receiving CPUs, or two TX channels on the codec duplicated to two CPUs.

Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20260910114500.1586637-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 6b382bdfe26a ("ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/sound/soc.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 87e50c8cdda31..a5f8e83e6ced4 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -718,6 +718,7 @@ struct snd_soc_dai_link_ch_map {
 	unsigned int cpu;
 	unsigned int codec;
 	unsigned int cpu_ch_mask;
+	unsigned int codec_ch_mask;
 };
 
 struct snd_soc_dai_link {
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (105 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 106/877] ASoC: Add codec_ch_mask to snd_soc_dai_link_ch_map Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-10-01 20:39   ` Harshit Mogalapalli
  2026-09-30 15:16 ` [PATCH 6.12 108/877] Input: trackpoint - fix the inertia attribute name in the ABI document Greg Kroah-Hartman
                   ` (777 subsequent siblings)
  884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Richard Fitzgerald, Mark Brown,
	Sasha Levin

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

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

From: Richard Fitzgerald <rf@opensource.cirrus.com>

[ Upstream commit 6b382bdfe26a2232091bf743e454e6794295783e ]

In __soc_pcm_hw_params() if there is a snd_soc_dai_link_ch_map with
non-zero codec_ch_mask, use that channel mask to restrict which channels
are enabled on the codec. But only if there isn't a TDM mask.

It is possible that a snd_soc_dai_link_ch_map could include the same codec
multiple times on different CPUs so the for_each_rtd_ch_maps() loop
accumulates the channel masks for all entries of that codec.

If a TDM mask was also set, it takes priority and is used instead of any
possible snd_soc_dai_link_ch_map entries. (They cannot be ANDed together
because the bit positions are indicating different things: TDM is a bit
for each TDM slot, codec_ch_mask is a bit for each codec channel.)

This fixes a problem of incorrect TX channels enabled on the codec when
multiple codecs are aggregated on a single capture link. For example:

- Two CPUs with six 4-channel codecs.
- The machine driver chooses to assign one channel from each codec to
  one channel on the CPU
- But the codec hw_params() would be passed a channel count of 6, which
  (a) is more channels than the codec has and (b) allows enabling channels
  that should not be driving the audio bus.

Fixes: ac950278b087 ("ASoC: add N cpus to M codecs dai link support")
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20260910114500.1586637-4-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/soc/soc-pcm.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 440acec700a56..d52771a4a723b 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1122,7 +1122,9 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
 		goto out;
 
 	for_each_rtd_codec_dais(rtd, i, codec_dai) {
-		unsigned int tdm_mask = snd_soc_dai_tdm_mask_get(codec_dai, substream->stream);
+		unsigned int ch_mask = snd_soc_dai_tdm_mask_get(codec_dai, substream->stream);
+		struct snd_soc_dai_link_ch_map *ch_maps;
+		int j;
 
 		/*
 		 * Skip CODECs which don't support the current stream type,
@@ -1144,9 +1146,15 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
 		/* copy params for each codec */
 		tmp_params = *params;
 
-		/* fixup params based on TDM slot masks */
-		if (tdm_mask)
-			soc_pcm_codec_params_fixup(&tmp_params, tdm_mask);
+		/* fixup params based on TDM or ch_map masks */
+		if (!ch_mask) {
+			for_each_rtd_ch_maps(rtd, j, ch_maps)
+				if (ch_maps->codec == i)
+					ch_mask |= ch_maps->codec_ch_mask;
+		}
+
+		if (ch_mask)
+			soc_pcm_codec_params_fixup(&tmp_params, ch_mask);
 
 		ret = snd_soc_dai_hw_params(codec_dai, substream,
 					    &tmp_params);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 108/877] Input: trackpoint - fix the inertia attribute name in the ABI document
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (106 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params Greg Kroah-Hartman
@ 2026-09-30 15:16 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 109/877] gpio: virtuser: skip free_irq when no IRQ is installed Greg Kroah-Hartman
                   ` (776 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:16 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Dmitry Torokhov,
	Sasha Levin

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

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

From: Karl Mehltretter <kmehltretter@gmail.com>

[ Upstream commit 45b0037899704caf9078be2be4de69361ca7d933 ]

The attribute is created as "inertia" (TRACKPOINT_INT_ATTR(inertia, ...)
in drivers/input/mouse/trackpoint.c); the ABI file spells the path
"intertia". The description below it already says inertia.

Fix the spelling.

Fixes: aebb47d4e7a9 ("Input: trackpoint: document sysfs interface")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://patch.msgid.link/20260905102038.42882-1-kmehltretter@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 Documentation/ABI/testing/sysfs-devices-platform-trackpoint | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-devices-platform-trackpoint b/Documentation/ABI/testing/sysfs-devices-platform-trackpoint
index df11901a6b3df..7954434b0434a 100644
--- a/Documentation/ABI/testing/sysfs-devices-platform-trackpoint
+++ b/Documentation/ABI/testing/sysfs-devices-platform-trackpoint
@@ -5,7 +5,7 @@ Contact:	linux-input@vger.kernel.org
 Description:
 		(RW) Trackpoint sensitivity.
 
-What:		/sys/devices/platform/i8042/.../intertia
+What:		/sys/devices/platform/i8042/.../inertia
 Date:		Aug, 2005
 KernelVersion:	2.6.14
 Contact:	linux-input@vger.kernel.org
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 109/877] gpio: virtuser: skip free_irq when no IRQ is installed
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (107 preceding siblings ...)
  2026-09-30 15:16 ` [PATCH 6.12 108/877] Input: trackpoint - fix the inertia attribute name in the ABI document Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 110/877] ALSA: 6fire: Clean ups with guard() Greg Kroah-Hartman
                   ` (775 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Linus Walleij,
	Bartosz Golaszewski, Sasha Levin

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

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

From: Runyu Xiao <runyu.xiao@seu.edu.cn>

[ Upstream commit 50fd0ada8d37587223001600933270b59cb30e19 ]

Disabling interrupt monitoring uses atomic_xchg() to clear the stored IRQ.
When monitoring is already disabled, atomic_xchg() returns 0. It must not
be passed to free_irq().

The bug is reproducible on an x86_64 QEMU guest with
CONFIG_GPIO_VIRTUSER=y and CONFIG_GPIO_SIM=y. Configure a live
gpio-virtuser device through configfs. Its input lookup must refer to a
live gpio-sim bank, such as key gpio-sim-test with offset 0. The
consumer's dev_name attribute is shown as <dev> below; then run:

    echo 0 > /sys/kernel/debug/gpio-virtuser/<dev>/gpiod:input:0/interrupts

On an unpatched kernel, this reaches gpio_virtuser_interrupts_set() with
ld->irq still at its initial value 0, and free_irq() reports:

    Trying to free already-free IRQ 0

The same reproducer completes without the warning on the patched kernel.

Fixes: 91581c4b3f29 ("gpio: virtuser: new virtual testing driver for the GPIO API")
Assisted-by: LLM
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260914051537.15320-1-runyu.xiao@seu.edu.cn
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpio/gpio-virtuser.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpio/gpio-virtuser.c b/drivers/gpio/gpio-virtuser.c
index ff1977b269914..5de9cee51fd08 100644
--- a/drivers/gpio/gpio-virtuser.c
+++ b/drivers/gpio/gpio-virtuser.c
@@ -698,7 +698,8 @@ static int gpio_virtuser_interrupts_set(void *data, u64 val)
 		atomic_set(&ld->irq, irq);
 	} else {
 		irq = atomic_xchg(&ld->irq, 0);
-		free_irq(irq, ld);
+		if (irq)
+			free_irq(irq, ld);
 	}
 
 	return 0;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 110/877] ALSA: 6fire: Clean ups with guard()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (108 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 109/877] gpio: virtuser: skip free_irq when no IRQ is installed Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 111/877] ALSA: usb: 6fire: Avoid embedded URBs Greg Kroah-Hartman
                   ` (774 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Takashi Iwai, Sasha Levin

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

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

From: Takashi Iwai <tiwai@suse.de>

[ Upstream commit 6ff0d95774f0c728f96b8f78367318e95e09ee64 ]

Simple code cleanups with the guard() for spinlock and mutex.
No functional changes.

Link: https://patch.msgid.link/20250811082231.31498-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Stable-dep-of: 1589afe2d099 ("ALSA: 6fire: fix OOB write from device-reported iso length")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/usb/6fire/chip.c | 40 ++++++++++----------
 sound/usb/6fire/midi.c | 21 +++--------
 sound/usb/6fire/pcm.c  | 83 ++++++++++++++++++------------------------
 3 files changed, 59 insertions(+), 85 deletions(-)

diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
index e5916c6b75aea..30b240e06a8c8 100644
--- a/sound/usb/6fire/chip.c
+++ b/sound/usb/6fire/chip.c
@@ -83,24 +83,22 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
 	struct snd_card *card = NULL;
 
 	/* look if we already serve this card and return if so */
-	mutex_lock(&register_mutex);
-	for (i = 0; i < SNDRV_CARDS; i++) {
-		if (devices[i] == device) {
-			if (chips[i])
-				chips[i]->intf_count++;
-			usb_set_intfdata(intf, chips[i]);
-			mutex_unlock(&register_mutex);
-			return 0;
-		} else if (!devices[i] && regidx < 0)
-			regidx = i;
-	}
-	if (regidx < 0) {
-		mutex_unlock(&register_mutex);
-		dev_err(&intf->dev, "too many cards registered.\n");
-		return -ENODEV;
+	scoped_guard(mutex, &register_mutex) {
+		for (i = 0; i < SNDRV_CARDS; i++) {
+			if (devices[i] == device) {
+				if (chips[i])
+					chips[i]->intf_count++;
+				usb_set_intfdata(intf, chips[i]);
+				return 0;
+			} else if (!devices[i] && regidx < 0)
+				regidx = i;
+		}
+		if (regidx < 0) {
+			dev_err(&intf->dev, "too many cards registered.\n");
+			return -ENODEV;
+		}
+		devices[regidx] = device;
 	}
-	devices[regidx] = device;
-	mutex_unlock(&register_mutex);
 
 	/* check, if firmware is present on device, upload it if not */
 	ret = usb6fire_fw_init(intf);
@@ -175,10 +173,10 @@ static void usb6fire_chip_disconnect(struct usb_interface *intf)
 	if (chip) { /* if !chip, fw upload has been performed */
 		chip->intf_count--;
 		if (!chip->intf_count) {
-			mutex_lock(&register_mutex);
-			devices[chip->regidx] = NULL;
-			chips[chip->regidx] = NULL;
-			mutex_unlock(&register_mutex);
+			scoped_guard(mutex, &register_mutex) {
+				devices[chip->regidx] = NULL;
+				chips[chip->regidx] = NULL;
+			}
 
 			/*
 			 * Save card pointer before teardown.
diff --git a/sound/usb/6fire/midi.c b/sound/usb/6fire/midi.c
index de2691d58de6e..6c6bccc0c410d 100644
--- a/sound/usb/6fire/midi.c
+++ b/sound/usb/6fire/midi.c
@@ -23,9 +23,8 @@ static void usb6fire_midi_out_handler(struct urb *urb)
 {
 	struct midi_runtime *rt = urb->context;
 	int ret;
-	unsigned long flags;
 
-	spin_lock_irqsave(&rt->out_lock, flags);
+	guard(spinlock_irqsave)(&rt->out_lock);
 
 	if (rt->out) {
 		ret = snd_rawmidi_transmit(rt->out, rt->out_buffer + 4,
@@ -43,18 +42,14 @@ static void usb6fire_midi_out_handler(struct urb *urb)
 		} else /* no more data to transmit */
 			rt->out = NULL;
 	}
-	spin_unlock_irqrestore(&rt->out_lock, flags);
 }
 
 static void usb6fire_midi_in_received(
 		struct midi_runtime *rt, u8 *data, int length)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&rt->in_lock, flags);
+	guard(spinlock_irqsave)(&rt->in_lock);
 	if (rt->in)
 		snd_rawmidi_receive(rt->in, data, length);
-	spin_unlock_irqrestore(&rt->in_lock, flags);
 }
 
 static int usb6fire_midi_out_open(struct snd_rawmidi_substream *alsa_sub)
@@ -73,14 +68,11 @@ static void usb6fire_midi_out_trigger(
 	struct midi_runtime *rt = alsa_sub->rmidi->private_data;
 	struct urb *urb = &rt->out_urb;
 	__s8 ret;
-	unsigned long flags;
 
-	spin_lock_irqsave(&rt->out_lock, flags);
+	guard(spinlock_irqsave)(&rt->out_lock);
 	if (up) { /* start transfer */
-		if (rt->out) { /* we are already transmitting so just return */
-			spin_unlock_irqrestore(&rt->out_lock, flags);
+		if (rt->out) /* we are already transmitting so just return */
 			return;
-		}
 
 		ret = snd_rawmidi_transmit(alsa_sub, rt->out_buffer + 4,
 				MIDI_BUFSIZE - 4);
@@ -99,7 +91,6 @@ static void usb6fire_midi_out_trigger(
 		}
 	} else if (rt->out == alsa_sub)
 		rt->out = NULL;
-	spin_unlock_irqrestore(&rt->out_lock, flags);
 }
 
 static void usb6fire_midi_out_drain(struct snd_rawmidi_substream *alsa_sub)
@@ -125,14 +116,12 @@ static void usb6fire_midi_in_trigger(
 		struct snd_rawmidi_substream *alsa_sub, int up)
 {
 	struct midi_runtime *rt = alsa_sub->rmidi->private_data;
-	unsigned long flags;
 
-	spin_lock_irqsave(&rt->in_lock, flags);
+	guard(spinlock_irqsave)(&rt->in_lock);
 	if (up)
 		rt->in = alsa_sub;
 	else
 		rt->in = NULL;
-	spin_unlock_irqrestore(&rt->in_lock, flags);
 }
 
 static const struct snd_rawmidi_ops out_ops = {
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index 32c39d8bd2e55..14d23e3103989 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -289,7 +289,7 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
 	struct pcm_urb *out_urb = in_urb->peer;
 	struct pcm_runtime *rt = in_urb->chip->pcm;
 	struct pcm_substream *sub;
-	unsigned long flags;
+	bool period_elapsed;
 	int total_length = 0;
 	int frame_count;
 	int frame;
@@ -313,17 +313,18 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
 
 	/* receive our capture data */
 	sub = &rt->capture;
-	spin_lock_irqsave(&sub->lock, flags);
-	if (sub->active) {
-		usb6fire_pcm_capture(sub, in_urb);
-		if (sub->period_off >= sub->instance->runtime->period_size) {
-			sub->period_off %= sub->instance->runtime->period_size;
-			spin_unlock_irqrestore(&sub->lock, flags);
-			snd_pcm_period_elapsed(sub->instance);
-		} else
-			spin_unlock_irqrestore(&sub->lock, flags);
-	} else
-		spin_unlock_irqrestore(&sub->lock, flags);
+	period_elapsed = false;
+	scoped_guard(spinlock_irqsave, &sub->lock) {
+		if (sub->active) {
+			usb6fire_pcm_capture(sub, in_urb);
+			if (sub->period_off >= sub->instance->runtime->period_size) {
+				sub->period_off %= sub->instance->runtime->period_size;
+				period_elapsed = true;
+			}
+		}
+	}
+	if (period_elapsed)
+		snd_pcm_period_elapsed(sub->instance);
 
 	/* setup out urb structure */
 	for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
@@ -338,17 +339,18 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
 
 	/* now send our playback data (if a free out urb was found) */
 	sub = &rt->playback;
-	spin_lock_irqsave(&sub->lock, flags);
-	if (sub->active) {
-		usb6fire_pcm_playback(sub, out_urb);
-		if (sub->period_off >= sub->instance->runtime->period_size) {
-			sub->period_off %= sub->instance->runtime->period_size;
-			spin_unlock_irqrestore(&sub->lock, flags);
-			snd_pcm_period_elapsed(sub->instance);
-		} else
-			spin_unlock_irqrestore(&sub->lock, flags);
-	} else
-		spin_unlock_irqrestore(&sub->lock, flags);
+	period_elapsed = false;
+	scoped_guard(spinlock_irqsave, &sub->lock) {
+		if (sub->active) {
+			usb6fire_pcm_playback(sub, out_urb);
+			if (sub->period_off >= sub->instance->runtime->period_size) {
+				sub->period_off %= sub->instance->runtime->period_size;
+				period_elapsed = true;
+			}
+		}
+	}
+	if (period_elapsed)
+		snd_pcm_period_elapsed(sub->instance);
 
 	/* setup the 4th byte of each sample (0x40 for analog channels) */
 	dest = out_urb->buffer;
@@ -392,7 +394,7 @@ static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub)
 	if (rt->panic)
 		return -EPIPE;
 
-	mutex_lock(&rt->stream_mutex);
+	guard(mutex)(&rt->stream_mutex);
 	alsa_rt->hw = pcm_hw;
 
 	if (alsa_sub->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -408,14 +410,12 @@ static int usb6fire_pcm_open(struct snd_pcm_substream *alsa_sub)
 	}
 
 	if (!sub) {
-		mutex_unlock(&rt->stream_mutex);
 		dev_err(&rt->chip->dev->dev, "invalid stream type.\n");
 		return -EINVAL;
 	}
 
 	sub->instance = alsa_sub;
 	sub->active = false;
-	mutex_unlock(&rt->stream_mutex);
 	return 0;
 }
 
@@ -423,18 +423,17 @@ static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
 {
 	struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
 	struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
-	unsigned long flags;
 
 	if (rt->panic)
 		return 0;
 
-	mutex_lock(&rt->stream_mutex);
+	guard(mutex)(&rt->stream_mutex);
 	if (sub) {
 		/* deactivate substream */
-		spin_lock_irqsave(&sub->lock, flags);
-		sub->instance = NULL;
-		sub->active = false;
-		spin_unlock_irqrestore(&sub->lock, flags);
+		scoped_guard(spinlock_irqsave, &sub->lock) {
+			sub->instance = NULL;
+			sub->active = false;
+		}
 
 		/* all substreams closed? if so, stop streaming */
 		if (!rt->playback.instance && !rt->capture.instance) {
@@ -442,7 +441,6 @@ static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub)
 			rt->rate = ARRAY_SIZE(rates);
 		}
 	}
-	mutex_unlock(&rt->stream_mutex);
 	return 0;
 }
 
@@ -458,7 +456,7 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
 	if (!sub)
 		return -ENODEV;
 
-	mutex_lock(&rt->stream_mutex);
+	guard(mutex)(&rt->stream_mutex);
 	sub->dma_off = 0;
 	sub->period_off = 0;
 
@@ -467,7 +465,6 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
 			if (alsa_rt->rate == rates[rt->rate])
 				break;
 		if (rt->rate == ARRAY_SIZE(rates)) {
-			mutex_unlock(&rt->stream_mutex);
 			dev_err(&rt->chip->dev->dev,
 				"invalid rate %d in prepare.\n",
 				alsa_rt->rate);
@@ -475,19 +472,15 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub)
 		}
 
 		ret = usb6fire_pcm_set_rate(rt);
-		if (ret) {
-			mutex_unlock(&rt->stream_mutex);
+		if (ret)
 			return ret;
-		}
 		ret = usb6fire_pcm_stream_start(rt);
 		if (ret) {
-			mutex_unlock(&rt->stream_mutex);
 			dev_err(&rt->chip->dev->dev,
 				"could not start pcm stream.\n");
 			return ret;
 		}
 	}
-	mutex_unlock(&rt->stream_mutex);
 	return 0;
 }
 
@@ -495,26 +488,22 @@ static int usb6fire_pcm_trigger(struct snd_pcm_substream *alsa_sub, int cmd)
 {
 	struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
 	struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
-	unsigned long flags;
 
 	if (rt->panic)
 		return -EPIPE;
 	if (!sub)
 		return -ENODEV;
 
+	guard(spinlock_irqsave)(&sub->lock);
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		spin_lock_irqsave(&sub->lock, flags);
 		sub->active = true;
-		spin_unlock_irqrestore(&sub->lock, flags);
 		return 0;
 
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-		spin_lock_irqsave(&sub->lock, flags);
 		sub->active = false;
-		spin_unlock_irqrestore(&sub->lock, flags);
 		return 0;
 
 	default:
@@ -527,15 +516,13 @@ static snd_pcm_uframes_t usb6fire_pcm_pointer(
 {
 	struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub);
 	struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub);
-	unsigned long flags;
 	snd_pcm_uframes_t ret;
 
 	if (rt->panic || !sub)
 		return SNDRV_PCM_POS_XRUN;
 
-	spin_lock_irqsave(&sub->lock, flags);
+	guard(spinlock_irqsave)(&sub->lock);
 	ret = sub->dma_off;
-	spin_unlock_irqrestore(&sub->lock, flags);
 	return ret;
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 111/877] ALSA: usb: 6fire: Avoid embedded URBs
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (109 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 110/877] ALSA: 6fire: Clean ups with guard() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 112/877] ALSA: 6fire: fix OOB write from device-reported iso length Greg Kroah-Hartman
                   ` (773 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Takashi Iwai, Sasha Levin

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

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

From: Takashi Iwai <tiwai@suse.de>

[ Upstream commit 9fe49dbc023e82dfaee7b245997d820d01742a9a ]

The USB 6fire driver uses URBs embedded in different structs for PCM,
MIDI and communication, and this is basically a buggy implementation
nowadays; since a URB is managed with a refcount, this may lead to a
UAF when the URB is released asynchronously.

For addressing the problem, this patch converts those embedded URBs to
ones that are properly allocated via usb_alloc_urb().  The
pcm_urb.packets[] is gone, as it's allocated by usb_alloc_urb(), hence
it's found in urb.iso_frame_desc[] instead.

The conversions are rather straightforward; each embedded struct urb
is changed to a pointer, and its callers are updated accordingly.
The resource for those structs are released in the common destructor
functions (usb6fire_comm_free(), etc), which are called at both the
init error path and the disconnect.

No functional changes, only compile-tested.

Link: https://lore.kernel.org/20260903130757.0668310a.michal.pecio@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260903160458.1938392-4-tiwai@suse.de
Stable-dep-of: 1589afe2d099 ("ALSA: 6fire: fix OOB write from device-reported iso length")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/usb/6fire/comm.c |  42 +++++++++-----
 sound/usb/6fire/comm.h |   2 +-
 sound/usb/6fire/midi.c |  43 +++++++++-----
 sound/usb/6fire/midi.h |   2 +-
 sound/usb/6fire/pcm.c  | 128 ++++++++++++++++++++++++-----------------
 sound/usb/6fire/pcm.h  |   5 +-
 6 files changed, 136 insertions(+), 86 deletions(-)

diff --git a/sound/usb/6fire/comm.c b/sound/usb/6fire/comm.c
index bcfb34db37d95..cfaaad9d24028 100644
--- a/sound/usb/6fire/comm.c
+++ b/sound/usb/6fire/comm.c
@@ -21,7 +21,6 @@ enum {
 static void usb6fire_comm_init_urb(struct comm_runtime *rt, struct urb *urb,
 		u8 *buffer, void *context, void(*handler)(struct urb *urb))
 {
-	usb_init_urb(urb);
 	urb->transfer_buffer = buffer;
 	urb->pipe = usb_sndintpipe(rt->chip->dev, COMM_EP);
 	urb->complete = handler;
@@ -142,6 +141,19 @@ static int usb6fire_comm_write16(struct comm_runtime *rt, u8 request,
 	return ret;
 }
 
+static void usb6fire_comm_free(struct comm_runtime *rt)
+{
+	if (!rt)
+		return;
+
+	if (rt->chip)
+		rt->chip->comm = NULL;
+
+	usb_free_urb(rt->receiver);
+	kfree(rt->receiver_buffer);
+	kfree(rt);
+}
+
 int usb6fire_comm_init(struct sfire_chip *chip)
 {
 	struct comm_runtime *rt = kzalloc(sizeof(struct comm_runtime),
@@ -154,14 +166,18 @@ int usb6fire_comm_init(struct sfire_chip *chip)
 
 	rt->receiver_buffer = kzalloc(COMM_RECEIVER_BUFSIZE, GFP_KERNEL);
 	if (!rt->receiver_buffer) {
-		kfree(rt);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto error;
 	}
 
-	urb = &rt->receiver;
+	urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!urb) {
+		ret = -ENOMEM;
+		goto error;
+	}
+	rt->receiver = urb;
 	rt->serial = 1;
 	rt->chip = chip;
-	usb_init_urb(urb);
 	rt->init_urb = usb6fire_comm_init_urb;
 	rt->write8 = usb6fire_comm_write8;
 	rt->write16 = usb6fire_comm_write16;
@@ -176,13 +192,15 @@ int usb6fire_comm_init(struct sfire_chip *chip)
 	urb->interval = 1;
 	ret = usb_submit_urb(urb, GFP_KERNEL);
 	if (ret < 0) {
-		kfree(rt->receiver_buffer);
-		kfree(rt);
 		dev_err(&chip->dev->dev, "cannot create comm data receiver.");
-		return ret;
+		goto error;
 	}
 	chip->comm = rt;
 	return 0;
+
+ error:
+	usb6fire_comm_free(rt);
+	return ret;
 }
 
 void usb6fire_comm_abort(struct sfire_chip *chip)
@@ -190,14 +208,10 @@ void usb6fire_comm_abort(struct sfire_chip *chip)
 	struct comm_runtime *rt = chip->comm;
 
 	if (rt)
-		usb_poison_urb(&rt->receiver);
+		usb_poison_urb(rt->receiver);
 }
 
 void usb6fire_comm_destroy(struct sfire_chip *chip)
 {
-	struct comm_runtime *rt = chip->comm;
-
-	kfree(rt->receiver_buffer);
-	kfree(rt);
-	chip->comm = NULL;
+	usb6fire_comm_free(chip->comm);
 }
diff --git a/sound/usb/6fire/comm.h b/sound/usb/6fire/comm.h
index 2447d7ecf1798..89976f510f6c2 100644
--- a/sound/usb/6fire/comm.h
+++ b/sound/usb/6fire/comm.h
@@ -19,7 +19,7 @@ enum /* settings for comm */
 struct comm_runtime {
 	struct sfire_chip *chip;
 
-	struct urb receiver;
+	struct urb *receiver;
 	u8 *receiver_buffer;
 
 	u8 serial; /* urb serial */
diff --git a/sound/usb/6fire/midi.c b/sound/usb/6fire/midi.c
index 6c6bccc0c410d..9a1dd5b6557c7 100644
--- a/sound/usb/6fire/midi.c
+++ b/sound/usb/6fire/midi.c
@@ -66,7 +66,7 @@ static void usb6fire_midi_out_trigger(
 		struct snd_rawmidi_substream *alsa_sub, int up)
 {
 	struct midi_runtime *rt = alsa_sub->rmidi->private_data;
-	struct urb *urb = &rt->out_urb;
+	struct urb *urb = rt->out_urb;
 	__s8 ret;
 
 	guard(spinlock_irqsave)(&rt->out_lock);
@@ -137,6 +137,19 @@ static const struct snd_rawmidi_ops in_ops = {
 	.trigger = usb6fire_midi_in_trigger
 };
 
+static void usb6fire_midi_free(struct midi_runtime *rt)
+{
+	if (!rt)
+		return;
+
+	if (rt->chip)
+		rt->chip->midi = NULL;
+
+	usb_free_urb(rt->out_urb);
+	kfree(rt->out_buffer);
+	kfree(rt);
+}
+
 int usb6fire_midi_init(struct sfire_chip *chip)
 {
 	int ret;
@@ -149,8 +162,14 @@ int usb6fire_midi_init(struct sfire_chip *chip)
 
 	rt->out_buffer = kzalloc(MIDI_BUFSIZE, GFP_KERNEL);
 	if (!rt->out_buffer) {
-		kfree(rt);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	rt->out_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!rt->out_urb) {
+		ret = -ENOMEM;
+		goto error;
 	}
 
 	rt->chip = chip;
@@ -161,15 +180,13 @@ int usb6fire_midi_init(struct sfire_chip *chip)
 	spin_lock_init(&rt->in_lock);
 	spin_lock_init(&rt->out_lock);
 
-	comm_rt->init_urb(comm_rt, &rt->out_urb, rt->out_buffer, rt,
+	comm_rt->init_urb(comm_rt, rt->out_urb, rt->out_buffer, rt,
 			usb6fire_midi_out_handler);
 
 	ret = snd_rawmidi_new(chip->card, "6FireUSB", 0, 1, 1, &rt->instance);
 	if (ret < 0) {
-		kfree(rt->out_buffer);
-		kfree(rt);
 		dev_err(&chip->dev->dev, "unable to create midi.\n");
-		return ret;
+		goto error;
 	}
 	rt->instance->private_data = rt;
 	strcpy(rt->instance->name, "DMX6FireUSB MIDI");
@@ -183,6 +200,10 @@ int usb6fire_midi_init(struct sfire_chip *chip)
 
 	chip->midi = rt;
 	return 0;
+
+ error:
+	usb6fire_midi_free(rt);
+	return ret;
 }
 
 void usb6fire_midi_abort(struct sfire_chip *chip)
@@ -190,14 +211,10 @@ void usb6fire_midi_abort(struct sfire_chip *chip)
 	struct midi_runtime *rt = chip->midi;
 
 	if (rt)
-		usb_poison_urb(&rt->out_urb);
+		usb_poison_urb(rt->out_urb);
 }
 
 void usb6fire_midi_destroy(struct sfire_chip *chip)
 {
-	struct midi_runtime *rt = chip->midi;
-
-	kfree(rt->out_buffer);
-	kfree(rt);
-	chip->midi = NULL;
+	usb6fire_midi_free(chip->midi);
 }
diff --git a/sound/usb/6fire/midi.h b/sound/usb/6fire/midi.h
index 47640c845903b..8716ab8a863ae 100644
--- a/sound/usb/6fire/midi.h
+++ b/sound/usb/6fire/midi.h
@@ -22,7 +22,7 @@ struct midi_runtime {
 	spinlock_t in_lock;
 	spinlock_t out_lock;
 	struct snd_rawmidi_substream *out;
-	struct urb out_urb;
+	struct urb *out_urb;
 	u8 out_serial; /* serial number of out packet */
 	u8 *out_buffer;
 	int buffer_offset;
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index 14d23e3103989..9e8f4371e89ff 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -138,8 +138,8 @@ static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt)
 		rt->stream_state = STREAM_STOPPING;
 
 		for (i = 0; i < PCM_N_URBS; i++) {
-			usb_kill_urb(&rt->in_urbs[i].instance);
-			usb_kill_urb(&rt->out_urbs[i].instance);
+			usb_kill_urb(rt->in_urbs[i].instance);
+			usb_kill_urb(rt->out_urbs[i].instance);
 		}
 		ctrl_rt->usb_streaming = false;
 		ctrl_rt->update_streaming(ctrl_rt);
@@ -161,13 +161,13 @@ static int usb6fire_pcm_stream_start(struct pcm_runtime *rt)
 		rt->stream_state = STREAM_STARTING;
 		for (i = 0; i < PCM_N_URBS; i++) {
 			for (k = 0; k < PCM_N_PACKETS_PER_URB; k++) {
-				packet = &rt->in_urbs[i].packets[k];
+				packet = &rt->in_urbs[i].instance->iso_frame_desc[k];
 				packet->offset = k * rt->in_packet_size;
 				packet->length = rt->in_packet_size;
 				packet->actual_length = 0;
 				packet->status = 0;
 			}
-			ret = usb_submit_urb(&rt->in_urbs[i].instance,
+			ret = usb_submit_urb(rt->in_urbs[i].instance,
 					GFP_ATOMIC);
 			if (ret) {
 				usb6fire_pcm_stream_stop(rt);
@@ -197,6 +197,7 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
 	unsigned int total_length = 0;
 	struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
 	struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
+	struct usb_iso_packet_descriptor *isoc;
 	u32 *src = NULL;
 	u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off
 			* (alsa_rt->frame_bits >> 3));
@@ -207,8 +208,9 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
 	for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
 		/* at least 4 header bytes for valid packet.
 		 * after that: 32 bits per sample for analog channels */
-		if (urb->packets[i].actual_length > 4)
-			frame_count = (urb->packets[i].actual_length - 4)
+		isoc = &urb->instance->iso_frame_desc[i];
+		if (isoc->actual_length > 4)
+			frame_count = (isoc->actual_length - 4)
 					/ (rt->in_n_analog << 2);
 		else
 			frame_count = 0;
@@ -220,7 +222,7 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb)
 		else
 			return;
 		src++; /* skip leading 4 bytes of every packet */
-		total_length += urb->packets[i].length;
+		total_length += isoc->length;
 		for (frame = 0; frame < frame_count; frame++) {
 			memcpy(dest, src, bytes_per_frame);
 			dest += alsa_rt->channels;
@@ -244,6 +246,7 @@ static void usb6fire_pcm_playback(struct pcm_substream *sub,
 	int frame_count;
 	struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance);
 	struct snd_pcm_runtime *alsa_rt = sub->instance->runtime;
+	struct usb_iso_packet_descriptor *isoc;
 	u32 *src = (u32 *) (alsa_rt->dma_area + sub->dma_off
 			* (alsa_rt->frame_bits >> 3));
 	u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size
@@ -263,8 +266,9 @@ static void usb6fire_pcm_playback(struct pcm_substream *sub,
 	for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
 		/* at least 4 header bytes for valid packet.
 		 * after that: 32 bits per sample for analog channels */
-		if (urb->packets[i].length > 4)
-			frame_count = (urb->packets[i].length - 4)
+		isoc = &urb->instance->iso_frame_desc[i];
+		if (isoc->length > 4)
+			frame_count = (isoc->length - 4)
 					/ (rt->out_n_analog << 2);
 		else
 			frame_count = 0;
@@ -289,6 +293,7 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
 	struct pcm_urb *out_urb = in_urb->peer;
 	struct pcm_runtime *rt = in_urb->chip->pcm;
 	struct pcm_substream *sub;
+	struct usb_iso_packet_descriptor *isoc_out, *isoc_in;
 	bool period_elapsed;
 	int total_length = 0;
 	int frame_count;
@@ -299,11 +304,13 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
 
 	if (usb_urb->status || rt->panic || rt->stream_state == STREAM_STOPPING)
 		return;
-	for (i = 0; i < PCM_N_PACKETS_PER_URB; i++)
-		if (in_urb->packets[i].status) {
+	for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
+		isoc_in = &in_urb->instance->iso_frame_desc[i];
+		if (isoc_in->status) {
 			rt->panic = true;
 			return;
 		}
+	}
 
 	if (rt->stream_state == STREAM_DISABLED) {
 		dev_err(&rt->chip->dev->dev,
@@ -328,12 +335,13 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
 
 	/* setup out urb structure */
 	for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
-		out_urb->packets[i].offset = total_length;
-		out_urb->packets[i].length = (in_urb->packets[i].actual_length
-				- 4) / (rt->in_n_analog << 2)
+		isoc_out = &out_urb->instance->iso_frame_desc[i];
+		isoc_in = &in_urb->instance->iso_frame_desc[i];
+		isoc_out->offset = total_length;
+		isoc_out->length = (isoc_in->actual_length - 4) / (rt->in_n_analog << 2)
 				* (rt->out_n_analog << 2) + 4;
-		out_urb->packets[i].status = 0;
-		total_length += out_urb->packets[i].length;
+		isoc_out->status = 0;
+		total_length += isoc_out->length;
 	}
 	memset(out_urb->buffer, 0, total_length);
 
@@ -354,9 +362,10 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
 
 	/* setup the 4th byte of each sample (0x40 for analog channels) */
 	dest = out_urb->buffer;
-	for (i = 0; i < PCM_N_PACKETS_PER_URB; i++)
-		if (out_urb->packets[i].length >= 4) {
-			frame_count = (out_urb->packets[i].length - 4)
+	for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
+		isoc_out = &out_urb->instance->iso_frame_desc[i];
+		if (isoc_out->length >= 4) {
+			frame_count = (isoc_out->length - 4)
 					/ (rt->out_n_analog << 2);
 			*(dest++) = 0xaa;
 			*(dest++) = 0xaa;
@@ -370,8 +379,10 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
 					*(dest++) = 0x40;
 				}
 		}
-	usb_submit_urb(&out_urb->instance, GFP_ATOMIC);
-	usb_submit_urb(&in_urb->instance, GFP_ATOMIC);
+	}
+
+	usb_submit_urb(out_urb->instance, GFP_ATOMIC);
+	usb_submit_urb(in_urb->instance, GFP_ATOMIC);
 }
 
 static void usb6fire_pcm_out_urb_handler(struct urb *usb_urb)
@@ -534,22 +545,25 @@ static const struct snd_pcm_ops pcm_ops = {
 	.pointer = usb6fire_pcm_pointer,
 };
 
-static void usb6fire_pcm_init_urb(struct pcm_urb *urb,
-				  struct sfire_chip *chip, bool in, int ep,
-				  void (*handler)(struct urb *))
+static int usb6fire_pcm_init_urb(struct pcm_urb *urb,
+				 struct sfire_chip *chip, bool in, int ep,
+				 void (*handler)(struct urb *))
 {
 	urb->chip = chip;
-	usb_init_urb(&urb->instance);
-	urb->instance.transfer_buffer = urb->buffer;
-	urb->instance.transfer_buffer_length =
+	urb->instance = usb_alloc_urb(PCM_N_PACKETS_PER_URB, GFP_KERNEL);
+	if (!urb->instance)
+		return -ENOMEM;
+	urb->instance->transfer_buffer = urb->buffer;
+	urb->instance->transfer_buffer_length =
 			PCM_N_PACKETS_PER_URB * PCM_MAX_PACKET_SIZE;
-	urb->instance.dev = chip->dev;
-	urb->instance.pipe = in ? usb_rcvisocpipe(chip->dev, ep)
+	urb->instance->dev = chip->dev;
+	urb->instance->pipe = in ? usb_rcvisocpipe(chip->dev, ep)
 			: usb_sndisocpipe(chip->dev, ep);
-	urb->instance.interval = 1;
-	urb->instance.complete = handler;
-	urb->instance.context = urb;
-	urb->instance.number_of_packets = PCM_N_PACKETS_PER_URB;
+	urb->instance->interval = 1;
+	urb->instance->complete = handler;
+	urb->instance->context = urb;
+	urb->instance->number_of_packets = PCM_N_PACKETS_PER_URB;
+	return 0;
 }
 
 static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt)
@@ -571,14 +585,23 @@ static int usb6fire_pcm_buffers_init(struct pcm_runtime *rt)
 	return 0;
 }
 
-static void usb6fire_pcm_buffers_destroy(struct pcm_runtime *rt)
+static void usb6fire_pcm_free(struct pcm_runtime *rt)
 {
 	int i;
 
+	if (!rt)
+		return;
+
+	if (rt->chip)
+		rt->chip->pcm = NULL;
+
 	for (i = 0; i < PCM_N_URBS; i++) {
+		usb_free_urb(rt->out_urbs[i].instance);
 		kfree(rt->out_urbs[i].buffer);
+		usb_free_urb(rt->in_urbs[i].instance);
 		kfree(rt->in_urbs[i].buffer);
 	}
+	kfree(rt);
 }
 
 int usb6fire_pcm_init(struct sfire_chip *chip)
@@ -593,11 +616,8 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
 		return -ENOMEM;
 
 	ret = usb6fire_pcm_buffers_init(rt);
-	if (ret) {
-		usb6fire_pcm_buffers_destroy(rt);
-		kfree(rt);
-		return ret;
-	}
+	if (ret)
+		goto error;
 
 	rt->chip = chip;
 	rt->stream_state = STREAM_DISABLED;
@@ -609,10 +629,14 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
 	spin_lock_init(&rt->capture.lock);
 
 	for (i = 0; i < PCM_N_URBS; i++) {
-		usb6fire_pcm_init_urb(&rt->in_urbs[i], chip, true, IN_EP,
-				usb6fire_pcm_in_urb_handler);
-		usb6fire_pcm_init_urb(&rt->out_urbs[i], chip, false, OUT_EP,
-				usb6fire_pcm_out_urb_handler);
+		ret = usb6fire_pcm_init_urb(&rt->in_urbs[i], chip, true, IN_EP,
+					    usb6fire_pcm_in_urb_handler);
+		if (ret < 0)
+			goto error;
+		ret = usb6fire_pcm_init_urb(&rt->out_urbs[i], chip, false, OUT_EP,
+					    usb6fire_pcm_out_urb_handler);
+		if (ret < 0)
+			goto error;
 
 		rt->in_urbs[i].peer = &rt->out_urbs[i];
 		rt->out_urbs[i].peer = &rt->in_urbs[i];
@@ -620,10 +644,8 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
 
 	ret = snd_pcm_new(chip->card, "DMX6FireUSB", 0, 1, 1, &pcm);
 	if (ret < 0) {
-		usb6fire_pcm_buffers_destroy(rt);
-		kfree(rt);
 		dev_err(&chip->dev->dev, "cannot create pcm instance.\n");
-		return ret;
+		goto error;
 	}
 
 	pcm->private_data = rt;
@@ -636,6 +658,10 @@ int usb6fire_pcm_init(struct sfire_chip *chip)
 
 	chip->pcm = rt;
 	return 0;
+
+ error:
+	usb6fire_pcm_free(rt);
+	return ret;
 }
 
 void usb6fire_pcm_abort(struct sfire_chip *chip)
@@ -653,8 +679,8 @@ void usb6fire_pcm_abort(struct sfire_chip *chip)
 			snd_pcm_stop_xrun(rt->capture.instance);
 
 		for (i = 0; i < PCM_N_URBS; i++) {
-			usb_poison_urb(&rt->in_urbs[i].instance);
-			usb_poison_urb(&rt->out_urbs[i].instance);
+			usb_poison_urb(rt->in_urbs[i].instance);
+			usb_poison_urb(rt->out_urbs[i].instance);
 		}
 
 	}
@@ -662,9 +688,5 @@ void usb6fire_pcm_abort(struct sfire_chip *chip)
 
 void usb6fire_pcm_destroy(struct sfire_chip *chip)
 {
-	struct pcm_runtime *rt = chip->pcm;
-
-	usb6fire_pcm_buffers_destroy(rt);
-	kfree(rt);
-	chip->pcm = NULL;
+	usb6fire_pcm_free(chip->pcm);
 }
diff --git a/sound/usb/6fire/pcm.h b/sound/usb/6fire/pcm.h
index 5a092dfd69f5a..b586fe220fd11 100644
--- a/sound/usb/6fire/pcm.h
+++ b/sound/usb/6fire/pcm.h
@@ -24,10 +24,7 @@ enum /* settings for pcm */
 struct pcm_urb {
 	struct sfire_chip *chip;
 
-	/* BEGIN DO NOT SEPARATE */
-	struct urb instance;
-	struct usb_iso_packet_descriptor packets[PCM_N_PACKETS_PER_URB];
-	/* END DO NOT SEPARATE */
+	struct urb *instance;
 	u8 *buffer;
 
 	struct pcm_urb *peer;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 112/877] ALSA: 6fire: fix OOB write from device-reported iso length
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (110 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 111/877] ALSA: usb: 6fire: Avoid embedded URBs Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 113/877] wifi: virt_wifi: dont transfer operstate before register Greg Kroah-Hartman
                   ` (772 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, co+855929c2df672879, Xiang Mei,
	Takashi Iwai, Sasha Levin

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

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

From: Xiang Mei <xmei5@asu.edu>

[ Upstream commit 1589afe2d099d3e817873bc474676968d7080410 ]

usb6fire_pcm_in_urb_handler() sizes each outgoing isochronous packet as
(actual_length - 4) / (in_n_analog << 2) * (out_n_analog << 2) + 4, where
actual_length is the unsigned length the device reported for the matching
IN packet.  A packet completed with status 0 and actual_length < 4 wraps
the subtraction to 0x7fffffec; a zero-length isochronous packet is legal
on the bus, and the preceding loop rejects only non-zero status.  The sum
reaches memset() on out_urb->buffer, a 4832-byte object from
kcalloc(PCM_MAX_PACKET_SIZE, PCM_N_PACKETS_PER_URB).

Even without the wrap the result is out of bounds: at 88.2/96 kHz the
4-in/6-out scaling turns a full 420-byte IN packet into 628, so eight
packets span 5024 bytes of that buffer.  usb_submit_urb() rejects an
over-long descriptor only after the memset() and the
usb6fire_pcm_playback() copy of user PCM data have run.

Guard the subtraction as the sibling usb6fire_pcm_capture() already does,
and limit the frame count to what fits in rt->out_packet_size, the OUT
endpoint's wMaxPacketSize.  This bounds total_length by the buffer size
while keeping each packet length aligned to a whole output frame.

  BUG: KASAN: out-of-bounds in usb6fire_pcm_in_urb_handler (sound/usb/6fire/pcm.c:338)
  Write of size 18446744073709551456 at addr ffff88802a3d0000 by task vhci_rx/5018
  Call Trace:
   dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120)
   print_report (mm/kasan/report.c:378 mm/kasan/report.c:482)
   kasan_report (mm/kasan/report.c:595)
   kasan_check_range (mm/kasan/generic.c:186 mm/kasan/generic.c:200)
   __asan_memset (mm/kasan/shadow.c:84)
   usb6fire_pcm_in_urb_handler (sound/usb/6fire/pcm.c:338)
   __usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1657)
   usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1741)
   vhci_rx_loop (drivers/usb/usbip/vhci_rx.c:107 drivers/usb/usbip/vhci_rx.c:242)
   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)

  Allocated by task 10:
   __kmalloc_cache_noprof (mm/slub.c:5563)
   usb6fire_pcm_init (sound/usb/6fire/pcm.c:560 sound/usb/6fire/pcm.c:595)
   usb6fire_chip_probe (sound/usb/6fire/chip.c:133)
   usb_probe_interface (drivers/usb/core/driver.c:399)

  The buggy address belongs to the object at ffff88802a3d0000
   which belongs to the cache kmalloc-8k of size 8192
  The buggy address is located 0 bytes inside of
   4832-byte region [ffff88802a3d0000, ffff88802a3d12e0)
  Kernel panic - not syncing: Fatal exception in interrupt

Fixes: c6d43ba816d1 ("ALSA: usb/6fire - Driver for TerraTec DMX 6Fire USB")
Reported-by: co+855929c2df672879@bugs.sh
Closes: https://lore.kernel.org/all/gisnub8aWGLbyZLcDCSc7zWsHonMWGcyRgt5%40bugs.sh/
Assisted-by: LLM
Signed-off-by: Xiang Mei <xmei5@asu.edu>
Link: https://patch.msgid.link/20260914074324.3590843-1-xmei5@asu.edu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/usb/6fire/pcm.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c
index 9e8f4371e89ff..5f6a63f79990b 100644
--- a/sound/usb/6fire/pcm.c
+++ b/sound/usb/6fire/pcm.c
@@ -335,11 +335,19 @@ static void usb6fire_pcm_in_urb_handler(struct urb *usb_urb)
 
 	/* setup out urb structure */
 	for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) {
+		unsigned int frames = 0;
+
 		isoc_out = &out_urb->instance->iso_frame_desc[i];
 		isoc_in = &in_urb->instance->iso_frame_desc[i];
+		if (isoc_in->actual_length > 4)
+			frames = (isoc_in->actual_length - 4)
+					/ (rt->in_n_analog << 2);
+		frames = min_t(unsigned int, frames,
+				       (rt->out_packet_size - 4)
+				       / (rt->out_n_analog << 2));
+
 		isoc_out->offset = total_length;
-		isoc_out->length = (isoc_in->actual_length - 4) / (rt->in_n_analog << 2)
-				* (rt->out_n_analog << 2) + 4;
+		isoc_out->length = frames * (rt->out_n_analog << 2) + 4;
 		isoc_out->status = 0;
 		total_length += isoc_out->length;
 	}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 113/877] wifi: virt_wifi: dont transfer operstate before register
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (111 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 112/877] ALSA: 6fire: fix OOB write from device-reported iso length Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 114/877] drm/vc4: Use managed KMS polling to fix UAF on unbind Greg Kroah-Hartman
                   ` (771 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Luxing Yin, Zihan Xi,
	Johannes Berg, Sasha Levin

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

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

From: Zihan Xi <zihanx@nebusec.ai>

[ Upstream commit e5c8d7acd31b27057ea42cd405d0b3ece097bc89 ]

virt_wifi_newlink() calls netif_stacked_transfer_operstate() before
register_netdevice(). If the lower device is dormant, that queues the
new netdev on lweventlist while it is still uninitialized. If
registration fails after that, for example because of an invalid name
such as "bad/name", free_netdev() immediately frees the object. A
later linkwatch_fire_event() then use-after-frees the list entry.

Move the transfer to after netdev_upper_dev_link(), as macvlan and
ipvlan already do.

Fixes: c7cdba31ed8b ("mac80211-next: rtnetlink wifi simulation device")
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Link: https://patch.msgid.link/f5a832fb0ab228ce6e2b5a91fba4ca8b79198a2f.1788948455.git.zihanx@nebusec.ai
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/wireless/virtual/virt_wifi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/virtual/virt_wifi.c b/drivers/net/wireless/virtual/virt_wifi.c
index 056d375e3f41f..4d36c15c1118e 100644
--- a/drivers/net/wireless/virtual/virt_wifi.c
+++ b/drivers/net/wireless/virtual/virt_wifi.c
@@ -554,7 +554,6 @@ static int virt_wifi_newlink(struct net *src_net, struct net_device *dev,
 	}
 
 	eth_hw_addr_inherit(dev, priv->lowerdev);
-	netif_stacked_transfer_operstate(priv->lowerdev, dev);
 
 	dev->ieee80211_ptr = kzalloc(sizeof(*dev->ieee80211_ptr), GFP_KERNEL);
 
@@ -580,6 +579,8 @@ static int virt_wifi_newlink(struct net *src_net, struct net_device *dev,
 		goto unregister_netdev;
 	}
 
+	netif_stacked_transfer_operstate(priv->lowerdev, dev);
+
 	dev->priv_destructor = virt_wifi_net_device_destructor;
 	priv->being_deleted = false;
 	priv->is_connected = false;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 114/877] drm/vc4: Use managed KMS polling to fix UAF on unbind
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (112 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 113/877] wifi: virt_wifi: dont transfer operstate before register Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 115/877] ALSA: hda: trace PCM open only after assigning a stream Greg Kroah-Hartman
                   ` (770 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Maíra Canal,
	Sasha Levin

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

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

From: Karl Mehltretter <kmehltretter@gmail.com>

[ Upstream commit 073a30d75f309812ed61af134f24ffef4107b13a ]

vc4_kms_load() calls drm_kms_helper_poll_init() but the driver provides
no matching drm_kms_helper_poll_fini(). The output poll work stays
scheduled after unbind and runs on the freed drm_device:

  # modprobe vc4; rmmod vc4; sleep 10
  BUG: KASAN: slab-use-after-free in delayed_work_timer_fn
  BUG: KASAN: slab-use-after-free in drm_client_dev_hotplug [drm]
  Workqueue: events output_poll_execute [drm_kms_helper]
  Allocated by task 171: __devm_drm_dev_alloc
  Freed by task 262 (rmmod): drm_dev_put / component_del

Use drmm_kms_helper_poll_init() so polling is finalized with the device,
as other drivers do.

Fixes: c8b75bca92cb ("drm/vc4: Add KMS support for Raspberry Pi.")
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://patch.msgid.link/20260822143110.68594-1-kmehltretter@gmail.com
Reviewed-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/vc4/vc4_kms.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index bddfcad109501..c5e28ff3931a7 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -1084,7 +1084,7 @@ int vc4_kms_load(struct drm_device *dev)
 
 	drm_mode_config_reset(dev);
 
-	drm_kms_helper_poll_init(dev);
+	drmm_kms_helper_poll_init(dev);
 
 	return 0;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 115/877] ALSA: hda: trace PCM open only after assigning a stream
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (113 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 114/877] drm/vc4: Use managed KMS polling to fix UAF on unbind Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 116/877] wifi: ath11k: cleanup arsta in ath11k_mac_peer_cleanup_all() Greg Kroah-Hartman
                   ` (769 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Slavin Liu, Takashi Iwai,
	Sasha Levin

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

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

From: Slavin Liu <bolin.liu@seu.edu.cn>

[ Upstream commit c9e6e5f38bf75276605f1952b22285f5f3abcaff ]

Stream assignment can fail when hardware streams are exhausted.
Move the tracepoint after the NULL check because its payload accesses
the assigned stream tag.

Detected by static analysis and reviewed with AI-assisted source auditing.

Fixes: 184865085b88 ("ALSA: hda - rename hda_intel_trace.h to hda_controller_trace.h")
Assisted-by: LLM
Signed-off-by: Slavin Liu <bolin.liu@seu.edu.cn>
Link: https://patch.msgid.link/20260913125154.109944-1-bolin.liu@seu.edu.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/pci/hda/hda_controller.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index bd13ea0c9352e..7c0574eb54c61 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -593,11 +593,11 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
 	snd_hda_codec_pcm_get(apcm->info);
 	mutex_lock(&chip->open_mutex);
 	azx_dev = azx_assign_device(chip, substream);
-	trace_azx_pcm_open(chip, azx_dev);
 	if (azx_dev == NULL) {
 		err = -EBUSY;
 		goto unlock;
 	}
+	trace_azx_pcm_open(chip, azx_dev);
 	runtime->private_data = azx_dev;
 
 	runtime->hw = azx_pcm_hw;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 116/877] wifi: ath11k: cleanup arsta in ath11k_mac_peer_cleanup_all()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (114 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 115/877] ALSA: hda: trace PCM open only after assigning a stream Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 117/877] btrfs: tree-checker: print dev extent offset in error message Greg Kroah-Hartman
                   ` (768 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nicolas Escande,
	Rameshkumar Sundaram, Baochen Qiang, Jeff Johnson, Sasha Levin

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

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

From: Nicolas Escande <nico.escande@gmail.com>

[ Upstream commit 820b8cff81c796ba20573e04722ab62500713f97 ]

When mac80211 removes a sta, it calls .sta_state() which in turn calls
ath11k_mac_station_remove(). In that function we clean up both peers &
arsta related resources.

But when the firmware crashes, ath11k calls ieee80211_restart_hw(), which
assumes that all driver related resources are cleaned up beforehand. This
cleanup is supposedly done by ath11k_mac_peer_cleanup_all() but does not
in fact free arsta->rx_stats / tx_stats.

Extract the arsta cleanup from ath11k_mac_station_remove() into a
new ath11k_mac_station_cleanup() and call it from both there and
ath11k_mac_peer_cleanup_all().

This should handle kmemleaks reports like:
	unreferenced object 0xffffff801ae66400 (size 1024):
	  comm "hostapd", pid 1306, jiffies 4295011565
	  hex dump (first 32 bytes):
	    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
	    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
	  backtrace (crc d61c08ec):
	    kmemleak_alloc+0x3c/0x50
	    __kmalloc_cache_noprof+0x2b0/0x3e0
	    ath11k_mac_op_sta_state+0x1dc/0xb10
	    drv_sta_state+0xac/0x6f8
	    sta_info_insert_rcu+0x314/0x5e0
	    sta_info_insert+0x14/0x38
	    ieee80211_add_station+0x10c/0x1a0
	    nl80211_new_station+0x3e8/0x680
	    genl_family_rcv_msg_doit+0xc0/0x120
	    genl_rcv_msg+0x1b4/0x258
	    netlink_rcv_skb+0x4c/0x108
	    genl_rcv+0x38/0x60
	    netlink_unicast+0x190/0x278
	    netlink_sendmsg+0x15c/0x370
	    ____sys_sendmsg+0x120/0x290
	    ___sys_sendmsg+0x70/0xa0

Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.9.0.1-01977-QCAHKSWPL_SILICONZ-1

Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices")
Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Link: https://patch.msgid.link/20260731145830.769811-1-nico.escande@gmail.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/wireless/ath/ath11k/mac.c | 25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
index c4856480fffe7..53bc1b90bab3c 100644
--- a/drivers/net/wireless/ath/ath11k/mac.c
+++ b/drivers/net/wireless/ath/ath11k/mac.c
@@ -873,6 +873,22 @@ static int ath11k_mac_set_kickout(struct ath11k_vif *arvif)
 	return 0;
 }
 
+static void ath11k_mac_station_cleanup(struct ieee80211_sta *sta)
+{
+	struct ath11k_sta *arsta;
+
+	if (!sta)
+		return;
+
+	arsta = ath11k_sta_to_arsta(sta);
+
+	kfree(arsta->tx_stats);
+	arsta->tx_stats = NULL;
+
+	kfree(arsta->rx_stats);
+	arsta->rx_stats = NULL;
+}
+
 void ath11k_mac_peer_cleanup_all(struct ath11k *ar)
 {
 	struct ath11k_peer *peer, *tmp;
@@ -885,6 +901,7 @@ void ath11k_mac_peer_cleanup_all(struct ath11k *ar)
 	list_for_each_entry_safe(peer, tmp, &ab->peers, list) {
 		ath11k_peer_rx_tid_cleanup(ar, peer);
 		ath11k_peer_rhash_delete(ab, peer);
+		ath11k_mac_station_cleanup(peer->sta);
 		list_del(&peer->list);
 		kfree(peer);
 	}
@@ -9759,7 +9776,6 @@ static int ath11k_mac_station_remove(struct ath11k *ar,
 {
 	struct ath11k_base *ab = ar->ab;
 	struct ath11k_vif *arvif = ath11k_vif_to_arvif(vif);
-	struct ath11k_sta *arsta = ath11k_sta_to_arsta(sta);
 	int ret;
 
 	if (ab->hw_params.vdev_start_delay &&
@@ -9783,12 +9799,7 @@ static int ath11k_mac_station_remove(struct ath11k *ar,
 			   sta->addr, arvif->vdev_id);
 
 	ath11k_mac_dec_num_stations(arvif, sta);
-
-	kfree(arsta->tx_stats);
-	arsta->tx_stats = NULL;
-
-	kfree(arsta->rx_stats);
-	arsta->rx_stats = NULL;
+	ath11k_mac_station_cleanup(sta);
 
 	return ret;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 117/877] btrfs: tree-checker: print dev extent offset in error message
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (115 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 116/877] wifi: ath11k: cleanup arsta in ath11k_mac_peer_cleanup_all() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 118/877] drm/msm/dsi: round the byte clock rate after reparenting to the PHY PLL Greg Kroah-Hartman
                   ` (767 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Filipe Manana,
	David Sterba, Sasha Levin

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

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

From: Filipe Manana <fdmanana@suse.com>

[ Upstream commit a1167d9420474ab9ed9efca99d86aeb6217c0265 ]

If a dev extent's offset is not sector size aligned, the error message is
printing the dev extent's objectid instead of the offset. This is a copy
paste error, as before this check we check the objectid field.

Fixes: 008e2512dc56 ("btrfs: tree-checker: add dev extent item checks")
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/btrfs/tree-checker.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c
index 92a2df6dd3a4e..6b68d87cbf446 100644
--- a/fs/btrfs/tree-checker.c
+++ b/fs/btrfs/tree-checker.c
@@ -1914,7 +1914,7 @@ static int check_dev_extent_item(const struct extent_buffer *leaf,
 				 sectorsize))) {
 		generic_err(leaf, slot,
 			    "invalid dev extent chunk offset, has %llu not aligned to %u",
-			    btrfs_dev_extent_chunk_objectid(leaf, de),
+			    btrfs_dev_extent_chunk_offset(leaf, de),
 			    sectorsize);
 		return -EUCLEAN;
 	}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 118/877] drm/msm/dsi: round the byte clock rate after reparenting to the PHY PLL
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (116 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 117/877] btrfs: tree-checker: print dev extent offset in error message Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 119/877] seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation Greg Kroah-Hartman
                   ` (766 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Abel Vesa, Krzysztof Kozlowski,
	Dmitry Baryshkov, Konrad Dybcio, Sasha Levin

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

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

From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>

[ Upstream commit 2028280686f4fa78e2f1f6dede4b6c1fd782b9e3 ]

DSI 6G v2.9 hosts (SM8650, SM8750, Kaanapali, etc.) reparent the byte and
pixel RCGs to the DSI PHY PLL at runtime from
dsi_link_clk_set_rate_6g_v2_9(), after the PHY has been enabled. However
dsi_calc_clk_rate_6g() runs earlier, in order to compute the bit clock
request for the PHY. At that point the byte RCG still has its reset
parent (XO), so clk_round_rate() returns a bogus rate, which then ends up
in the PHY bit clock request and the PLL gets programmed to a wrong
frequency, breaking the panel.

Move the rounding to dsi_link_clk_set_rate_6g(), which is called after
the RCGs have been reparented to the PLL. Storing the rounded rate at
this point still makes later link_clk_set_rate() calls no-ops in the
CCF. Derive the byte interface clock rate from the rounded byte clock
rate, otherwise it would keep requesting the idealized rate and
retrigger the PLL on every transfer.

Reported-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reported-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Fixes: 6cd33b6f4155 ("drm/msm/dsi: round 6G byte clock rate to the PLL-achievable value")
Assisted-by: LLM
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Tested-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> # SM6115P J606F
Tested-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Reviewed-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/750496/
Link: https://lore.kernel.org/r/20260903-fix-eliza-dsi-v1-1-3474a6c9f2e0@oss.qualcomm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 36 ++++++++++++++++--------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 77173183509f1..cd605c75cef8e 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -120,7 +120,7 @@ struct msm_dsi_host {
 	struct clk *byte_intf_clk;
 
 	unsigned long byte_clk_rate;
-	unsigned long byte_intf_clk_rate;
+	bool byte_intf_clk_div_2;
 	unsigned long pixel_clk_rate;
 	unsigned long esc_clk_rate;
 
@@ -350,8 +350,20 @@ int msm_dsi_runtime_resume(struct device *dev)
 
 int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
 {
+	unsigned long byte_intf_clk_rate;
+	long rounded_byte_clk_rate;
 	int ret;
 
+	rounded_byte_clk_rate = clk_round_rate(msm_host->byte_clk,
+					       msm_host->byte_clk_rate);
+	if (rounded_byte_clk_rate < 0) {
+		pr_err("%s: failed to round byte clock rate, %ld\n",
+		       __func__, rounded_byte_clk_rate);
+		return rounded_byte_clk_rate;
+	}
+
+	msm_host->byte_clk_rate = rounded_byte_clk_rate;
+
 	DBG("Set clk rates: pclk=%lu, byteclk=%lu",
 	    msm_host->pixel_clk_rate, msm_host->byte_clk_rate);
 
@@ -369,7 +381,11 @@ int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)
 	}
 
 	if (msm_host->byte_intf_clk) {
-		ret = clk_set_rate(msm_host->byte_intf_clk, msm_host->byte_intf_clk_rate);
+		byte_intf_clk_rate = msm_host->byte_clk_rate;
+		if (msm_host->byte_intf_clk_div_2)
+			byte_intf_clk_rate /= 2;
+
+		ret = clk_set_rate(msm_host->byte_intf_clk, byte_intf_clk_rate);
 		if (ret) {
 			pr_err("%s: Failed to set rate byte intf clk, %d\n",
 			       __func__, ret);
@@ -619,24 +635,12 @@ static void dsi_calc_pclk(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
 
 int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
 {
-	long rounded_byte_clk_rate;
-
 	if (!msm_host->mode) {
 		pr_err("%s: mode not set\n", __func__);
 		return -EINVAL;
 	}
 
 	dsi_calc_pclk(msm_host, is_bonded_dsi);
-
-	rounded_byte_clk_rate = clk_round_rate(msm_host->byte_clk,
-					       msm_host->byte_clk_rate);
-	if (rounded_byte_clk_rate < 0) {
-		pr_err("%s: failed to round byte clock rate, %ld\n",
-		       __func__, rounded_byte_clk_rate);
-		return rounded_byte_clk_rate;
-	}
-
-	msm_host->byte_clk_rate = rounded_byte_clk_rate;
 	msm_host->esc_clk_rate = clk_get_rate(msm_host->esc_clk);
 	return 0;
 }
@@ -2419,9 +2423,7 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host,
 		goto unlock_ret;
 	}
 
-	msm_host->byte_intf_clk_rate = msm_host->byte_clk_rate;
-	if (phy_shared_timings->byte_intf_clk_div_2)
-		msm_host->byte_intf_clk_rate /= 2;
+	msm_host->byte_intf_clk_div_2 = phy_shared_timings->byte_intf_clk_div_2;
 
 	msm_dsi_sfpb_config(msm_host, true);
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 119/877] seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (117 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 118/877] drm/msm/dsi: round the byte clock rate after reparenting to the PHY PLL Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 120/877] ipv4: icmp: reject RTN_UNREACHABLE input routes in icmp_route_lookup Greg Kroah-Hartman
                   ` (765 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Andrea Mayer, David Ahern,
	Hangbin Liu, Jakub Kicinski, Sasha Levin

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

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

From: Andrea Mayer <andrea.mayer@uniroma2.it>

[ Upstream commit 7616242a2b37883f7322aaa1d2bd6cd0fed28315 ]

When an SRv6 packet arrives on an interface enslaved to a VRF,
vrf_ip6_rcv() sets IP6SKB_L3SLAVE in IP6CB, but decap_and_validate()
has never set IPSKB_L3SLAVE in IPCB. The bit stayed clear in the
common case, and with CONFIG_IPV6_MIP6 the leftover frag_max_size of
a reassembled outer packet could even set it, with no VRF involved.
Commit 44930446dde4 ("ipv6: seg6: clear IPv4 control block on IPIP
decapsulation") then made the unreliable bit reliably clear.

The effect of the missing flag is visible with End.DX4 when a
delivery to a local address of the node reaches the socket lookup.
For example, a UDP socket bound to the enslaved ingress interface
does not receive any of the decapsulated packets, while an unbound
socket outside the VRF does.
This contradicts Documentation/networking/vrf.rst: by default the
scope of an unbound UDP or TCP socket is limited to the default VRF.

Set IPSKB_L3SLAVE for IPv4 in decap_and_validate(), which already does
the same for IPv6. The socket lookup then matches the decapsulated
packet like any other packet received on that enslaved interface. Such
a packet matches an unbound UDP or TCP socket only when
udp_l3mdev_accept or tcp_l3mdev_accept is set.

Fixes: 891ef8dd2a8d ("ipv6: sr: implement additional seg6local actions")
Signed-off-by: Andrea Mayer <andrea.mayer@uniroma2.it>
Reviewed-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260913194421.31-1-andrea.mayer@uniroma2.it
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv6/seg6_local.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
index 10f29bb8e608f..191b99b073b06 100644
--- a/net/ipv6/seg6_local.c
+++ b/net/ipv6/seg6_local.c
@@ -257,10 +257,13 @@ static bool decap_and_validate(struct sk_buff *skb, int proto)
 		return false;
 
 	if (proto == IPPROTO_IPIP) {
+		bool l3slave = ipv6_l3mdev_skb(IP6CB(skb)->flags);
 		int iif = IP6CB(skb)->iif;
 
 		memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
 		IPCB(skb)->iif = iif;
+		if (l3slave)
+			IPCB(skb)->flags |= IPSKB_L3SLAVE;
 	} else if (proto == IPPROTO_IPV6) {
 		bool l3slave = ipv6_l3mdev_skb(IP6CB(skb)->flags);
 		int iif = IP6CB(skb)->iif;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 120/877] ipv4: icmp: reject RTN_UNREACHABLE input routes in icmp_route_lookup
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (118 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 119/877] seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 121/877] net: fddi: skfp: fix NULL deref when setting the MAC address while down Greg Kroah-Hartman
                   ` (764 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Jiayuan Chen,
	Dong Chenchen, Paolo Abeni, Sasha Levin

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

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

From: Dong Chenchen <dongchenchen2@huawei.com>

[ Upstream commit 2998147b59c9df0a51477c7a6b3d1f0ba3127dd4 ]

When the forward output route cannot be used in icmp_route_lookup(),
it enters the "reverse path" and calls ip_route_input() on fl4_dec.daddr,
the original packet's source address.

ip_route_input() only returns an error for truly invalid packets. For
unreachable addresses it will succeed and return an input route whose
dst.output is set to ip_rt_bug(). The existing check only rejects
RTN_LOCAL routes, so the RTN_UNREACHABLE route types can still be returned
and later used for output, syzkaller triggering a WARN_ON_ONCE()
in ip_rt_bug() as bellow:

 ------------[ cut here ]------------
 WARNING: net/ipv4/route.c:1273 at ip_rt_bug+0x14/0x20
 RIP: 0010:ip_rt_bug+0x14/0x20
 Call Trace:
  ip_push_pending_frames+0xfa/0x100
  __icmp_send+0x905/0xf10
  ip_options_compile+0xc0/0xd0
  ip_rcv_finish_core+0x321/0xae0
  ip_rcv+0x1de/0x260
  __netif_receive_skb_one_core+0x11a/0x130
  netif_receive_skb+0x7b/0x260
  tun_get_user+0x11bf/0x1c10
 ------------[ cut here ]------------

Reject input route that is RTN_UNREACHABLE to fix it. The net warning
is only printed for RTN_LOCAL, as RTN_UNREACHABLE is not the result of
a race condition.

Fixes: 8b7817f3a959 ("[IPSEC]: Add ICMP host relookup support")
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com>
Link: https://patch.msgid.link/20260910140042.1880242-1-dongchenchen2@huawei.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv4/icmp.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 7e391c2bc5bc0..3b0475f658105 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -573,16 +573,19 @@ static struct rtable *icmp_route_lookup(struct net *net, struct flowi4 *fl4,
 		skb_dstref_restore(skb_in, orefdst);
 
 		/*
-		 * At this point, fl4_dec.daddr should NOT be local (we
-		 * checked fl4_dec.saddr above). However, a race condition
-		 * may occur if the address is added to the interface
-		 * concurrently. In that case, ip_route_input() returns a
-		 * LOCAL route with dst.output=ip_rt_bug, which must not
-		 * be used for output.
+		 * fl4_dec.daddr is not expected to be local here, but it can be
+		 * added to an interface concurrently, in which case
+		 * ip_route_input() returns a LOCAL route. It can also fail to
+		 * build a forwarding route towards fl4_dec.daddr, for example,
+		 * when forwarding is disabled, and return an UNREACHABLE route.
+		 * Both cases will result in a route with dst.output=ip_rt_bug,
+		 * which must not be used for output.
 		 */
-		if (!err && rt2 && rt2->rt_type == RTN_LOCAL) {
+		if (!err && rt2 && rt2->rt_type == RTN_LOCAL)
 			net_warn_ratelimited("detected local route for %pI4 during ICMP sending, src %pI4\n",
 					     &fl4_dec.daddr, &fl4_dec.saddr);
+		if (!err && rt2 &&
+		    (rt2->rt_type == RTN_LOCAL || rt2->rt_type == RTN_UNREACHABLE)) {
 			dst_release(&rt2->dst);
 			err = -EINVAL;
 		}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 121/877] net: fddi: skfp: fix NULL deref when setting the MAC address while down
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (119 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 120/877] ipv4: icmp: reject RTN_UNREACHABLE input routes in icmp_route_lookup Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 122/877] wifi: brcmfmac: fix lost 802.1x TX completion wakeup Greg Kroah-Hartman
                   ` (763 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Hohyun Sim, Paolo Abeni, Sasha Levin

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

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

From: Hohyun Sim <tlaghgus0425@korea.ac.kr>

[ Upstream commit 7c8810c2e69c3d9ca6df870b40ae9218e50b4fb1 ]

skfp_ctl_set_mac_address() calls ResetAdapter() unconditionally, without
checking netif_running(). ResetAdapter() first calls card_stop(), which
sets smc->hw.hw_state to STOPPED, and then mac_drv_clear_tx_queue(),
which walks the two transmit queues:

	for (i = QUEUE_S; i <= QUEUE_A0; i++) {
		queue = smc->hw.fp.tx[i] ;
		...
		t = queue->tx_curr_get ;

smc->hw.fp.tx[] is only populated by init_tx(), which is reached from
skfp_open() through init_smt() -> init_fddi_driver() -> init_fplus() ->
init_mac() -> init_tx(). The private area is allocated and zeroed by
alloc_fddidev(), so on an interface that has never been brought up both
queue pointers are still NULL. The hw_state test at the top of
mac_drv_clear_tx_queue() does not catch this, because card_stop() has
just set STOPPED; the function proceeds into the loop and dereferences
NULL. ResetAdapter() does call init_smt() itself, but only after the
queues have been cleared.

Setting the MAC address on a down interface therefore oopses:

  ip link set dev fddi0 address 02:00:00:00:00:01

  BUG: KASAN: null-ptr-deref in mac_drv_clear_tx_queue+0x68/0x2c0 [skfp]
  Read of size 8 at addr 0000000000000010 by task ip/302
  Call Trace:
   <TASK>
   mac_drv_clear_tx_queue+0x68/0x2c0 [skfp 6c01d4bab63c36978bd0a7d7e90837adb44cc37b]
   ResetAdapter+0x29/0x100 [skfp 6c01d4bab63c36978bd0a7d7e90837adb44cc37b]
   skfp_ctl_set_mac_address+0x57/0x80 [skfp 6c01d4bab63c36978bd0a7d7e90837adb44cc37b]
   netif_set_mac_address+0x1e4/0x2c0
   do_setlink+0x684/0x2680
   </TASK>

Address 0x10 is the offset of tx_curr_get, the third pointer in
struct s_smt_tx_queue, on 64-bit. mac_drv_clear_rx_queue(), which
ResetAdapter() calls immediately afterwards, dereferences
smc->hw.fp.rx[QUEUE_R1] in the same way behind the same ineffective
hw_state test; the transmit queue merely crashes first. Both are
covered by the guard below.

Skip the adapter reset when the interface is down. dev_addr_set() is
left unconditional, so the new address is still recorded in
dev->dev_addr. Nothing is lost by not resetting the adapter here:
skfp_open() deliberately re-reads the factory address on every open,

	read_address(smc, NULL);
	eth_hw_addr_set(dev, smc->hw.fddi_canon_addr.a);

and the comment above it states this is done to discard exactly such an
address override across a close/open cycle. An address set while the
interface is down could not have survived the following open even
before this change, so the guard removes no working behaviour. Guarding
the hardware side of ndo_set_mac_address() with netif_running() is
established practice; skge_set_mac_address() has done so since commit
2eb3e621c4e0 ("skge: set mac address bonding fix").

Guarding the reset as a whole, rather than NULL-checking the queues, is
also what the rest of the driver expects. After a previous open/close
the queue pointers are stale but non-NULL, so there is no crash, yet
ResetAdapter() goes on to call smt_online() and STI_FBI() ("Enable
Board Interrupts") while skfp_close() has already called free_irq() -
the adapter would be brought back online with no handler installed. The
only other ResetAdapter() caller is skfp_interrupt(), which by
construction runs only while the device is open.

Found by automated driver testing against an emulated SysKonnect FDDI
adapter under a KASAN-enabled 7.0.0 kernel. Triggering it requires
CAP_NET_ADMIN.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Assisted-by: LLM KASAN
Signed-off-by: Hohyun Sim <tlaghgus0425@korea.ac.kr>
Link: https://patch.msgid.link/20260910063743.110747-1-tlaghgus0425@korea.ac.kr
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/fddi/skfp/skfddi.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/fddi/skfp/skfddi.c b/drivers/net/fddi/skfp/skfddi.c
index a273362c9e703..feea7baa48168 100644
--- a/drivers/net/fddi/skfp/skfddi.c
+++ b/drivers/net/fddi/skfp/skfddi.c
@@ -928,7 +928,8 @@ static int skfp_ctl_set_mac_address(struct net_device *dev, void *addr)
 
 	dev_addr_set(dev, p_sockaddr->sa_data);
 	spin_lock_irqsave(&bp->DriverLock, Flags);
-	ResetAdapter(smc);
+	if (netif_running(dev))
+		ResetAdapter(smc);
 	spin_unlock_irqrestore(&bp->DriverLock, Flags);
 
 	return 0;		/* always return zero */
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 122/877] wifi: brcmfmac: fix lost 802.1x TX completion wakeup
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (120 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 121/877] net: fddi: skfp: fix NULL deref when setting the MAC address while down Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 123/877] net: bridge: mst: move switchdev call outside rcu Greg Kroah-Hartman
                   ` (762 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Arend van Spriel,
	Johannes Berg, Sasha Levin

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

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

From: Karl Mehltretter <kmehltretter@gmail.com>

[ Upstream commit 621d90169cef6c8da5b6134db5c0c4e23cdd09ce ]

brcmf_txfinalize() decrements pend_8021x_cnt before a lockless
waitqueue_active() check. atomic_dec() does not order the decrement
against the check.

The waiter can therefore observe a nonzero count while the waker observes
an empty queue, losing the final wakeup and delaying key installation
until the 950 ms timeout.

Add smp_mb__after_atomic() to order the decrement before the queue
check. wait_event_timeout() provides the matching barrier. LKMM confirms
that this forbids the lost-wakeup outcome.

Fixes: 21fff75d2fb6 ("brcmfmac: use wait_event_timeout for 8021x pending count")
Assisted-by: Claude:claude-fable-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260811082702.44521-1-kmehltretter@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index 58eaf08a147b6..f99accc34a36e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -550,6 +550,8 @@ void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success)
 
 	if (type == ETH_P_PAE) {
 		atomic_dec(&ifp->pend_8021x_cnt);
+		/* Order the decrement before waitqueue_active() */
+		smp_mb__after_atomic();
 		if (waitqueue_active(&ifp->pend_8021x_wait))
 			wake_up(&ifp->pend_8021x_wait);
 	}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 123/877] net: bridge: mst: move switchdev call outside rcu
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (121 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 122/877] wifi: brcmfmac: fix lost 802.1x TX completion wakeup Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 124/877] tcp: Dont call skb_clone_and_charge_r() for close()d listener in tcp_v6_do_rcv() Greg Kroah-Hartman
                   ` (761 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nikolay Aleksandrov, Ido Schimmel,
	Paolo Abeni, Sasha Levin

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

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

From: Nikolay Aleksandrov <razor@blackwall.org>

[ Upstream commit 18a6fe05fb6e18de29fa90d388bb34044114b3d8 ]

This is a follow-up of one of sashiko's pre-existing bug reports.
br_mst_set_state() calls switchdev_port_attr_set() for nonzero MSTIs
while holding rcu_read_lock() which invokes the blocking switchdev
notifier chain and may sleep. Nonzero MSTI changes come from netlink
with rtnl held. Move the switchdev call before entering the rcu section and
assert that rtnl is held.

The call cannot be deferred because netlink needs its error and extack.
Also DSA reads the old bridge MST state during the callback and checks it.
A deferred callback will be late and will see the updated state.

Fixes: 3a7c1661ae13 ("net: bridge: mst: fix vlan use-after-free")
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260911105021.1385934-1-razor@blackwall.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/bridge/br_mst.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/net/bridge/br_mst.c b/net/bridge/br_mst.c
index 43a300ae6bfaf..1654efd3045b0 100644
--- a/net/bridge/br_mst.c
+++ b/net/bridge/br_mst.c
@@ -107,21 +107,24 @@ int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state,
 	struct net_bridge_vlan *v;
 	int err = 0;
 
-	rcu_read_lock();
-	vg = nbp_vlan_group_rcu(p);
-	if (!vg)
-		goto out;
-
 	/* MSTI 0 (CST) state changes are notified via the regular
-	 * SWITCHDEV_ATTR_ID_PORT_STP_STATE.
+	 * SWITCHDEV_ATTR_ID_PORT_STP_STATE. All other MSTIs are handled via
+	 * netlink with RTNL held
 	 */
 	if (msti) {
+		ASSERT_RTNL();
+
 		err = switchdev_port_attr_set(p->dev, &attr, extack);
 		if (err && err != -EOPNOTSUPP)
 			goto out;
+		err = 0;
 	}
 
-	err = 0;
+	rcu_read_lock();
+	vg = nbp_vlan_group_rcu(p);
+	if (!vg)
+		goto out_rcu_unlock;
+
 	list_for_each_entry_rcu(v, &vg->vlan_list, vlist) {
 		if (v->brvlan->msti != msti)
 			continue;
@@ -129,8 +132,9 @@ int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state,
 		br_mst_vlan_set_state(vg, v, state);
 	}
 
-out:
+out_rcu_unlock:
 	rcu_read_unlock();
+out:
 	return err;
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 124/877] tcp: Dont call skb_clone_and_charge_r() for close()d listener in tcp_v6_do_rcv().
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (122 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 123/877] net: bridge: mst: move switchdev call outside rcu Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 125/877] tcp: do not let tcp_rmem be set below 4096 Greg Kroah-Hartman
                   ` (760 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Taras Madan, Kuniyuki Iwashima,
	Xuanqiang Luo, Eric Dumazet, Paolo Abeni, Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit 8e759cd1f6444a946bd1fd2b2b29eea582eea1d5 ]

tcp_v6_do_rcv() no longer calls skb_clone_and_charge_r() for
TCP_LISTEN since commit 073d89808c06 ("net: fix data-races around
sk->sk_forward_alloc").

However, there is still a small race window between tcp_v6_rcv()
and tcp_v6_do_rcv(), where concurrent close() changes TCP_LISTEN
to TCP_CLOSE, causing skb_clone_and_charge_r() to be called
locklessly and resulting in the splat below. [0]

Let's avoid calling skb_clone_and_charge_r() for TCP_CLOSE as well.

This is fine for non-listeners because tcp_rcv_state_process()
drops skb for TCP_CLOSE and opt_skb was freed immediately anyway.

[0]:
sk->sk_forward_alloc
WARNING: net/ipv4/af_inet.c:162 at inet_sock_destruct+0x64d/0x810 net/ipv4/af_inet.c:162, CPU#1: ksoftirqd/1/28
Modules linked in:
CPU: 1 UID: 0 PID: 28 Comm: ksoftirqd/1 Not tainted 7.2.0 #17 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
RIP: 0010:inet_sock_destruct+0x64d/0x810 net/ipv4/af_inet.c:162
Code: 3d 49 ff e9 06 fd ff ff e8 d0 5b 83 f8 90 0f 0b 90 e9 35 fe ff ff e8 c2 5b 83 f8 90 0f 0b 90 e9 c5 fe ff ff e8 b4 5b 83 f8 90 <0f> 0b 90 e9 04 ff ff ff e8 a6 5b 83 f8 90 0f 0b 90 e9 65 fe ff ff
RSP: 0018:ffffc90000677bb8 EFLAGS: 00010246
RAX: 0000000000000000 RBX: ffff8880117bde80 RCX: ffffffff8957eb41
RDX: ffff88801dad5d00 RSI: ffffffff8957ec3c RDI: 0000000000000005
RBP: 00000000fffff000 R08: ffffffff8957eb41 R09: 00000000fffff000
R10: 0000000000000005 R11: 0000000000000000 R12: dffffc0000000000
R13: ffff8880117bdf10 R14: ffffffff81c08eb7 R15: 0000000000000003
FS:  0000000000000000(0000) GS:ffff8880d7ae5000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f93a1021138 CR3: 00000000207a9000 CR4: 0000000000350ef0
Call Trace:
 <TASK>
 __sk_destruct+0x82/0xae0 net/core/sock.c:2356
 rcu_do_batch kernel/rcu/tree.c:2645 [inline]
 rcu_core+0x59c/0x1100 kernel/rcu/tree.c:2897
 handle_softirqs+0x1e4/0x9b0 kernel/softirq.c:622
 run_ksoftirqd kernel/softirq.c:1076 [inline]
 run_ksoftirqd+0x38/0x60 kernel/softirq.c:1068
 smpboot_thread_fn+0x458/0xc80 kernel/smpboot.c:160
 kthread+0x396/0x4a0 kernel/kthread.c:436
 ret_from_fork+0x8e0/0xe40 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
 </TASK>

Fixes: e994b2f0fb92 ("tcp: do not lock listener to process SYN packets")
Reported-by: Taras Madan <tarasmadan@google.com>
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260914011420.115556-1-kuniyu@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv6/tcp_ipv6.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 533943a7127dc..e5f632b683c5d 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1605,7 +1605,8 @@ int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
 	   by tcp. Feel free to propose better solution.
 					       --ANK (980728)
 	 */
-	if (np->rxopt.all && sk->sk_state != TCP_LISTEN)
+	if (np->rxopt.all &&
+	    !((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)))
 		opt_skb = skb_clone_and_charge_r(skb, sk);
 
 	if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 125/877] tcp: do not let tcp_rmem be set below 4096
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (123 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 124/877] tcp: Dont call skb_clone_and_charge_r() for close()d listener in tcp_v6_do_rcv() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 126/877] ksmbd: return buffer overflow for partial filesystem info Greg Kroah-Hartman
                   ` (759 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Simon Horman,
	Paolo Abeni, Sasha Levin

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

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

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit 83a945a529d6e002dd7339c532288a931f463dba ]

We can hit a division by zero crash in tcp_rcvbuf_grow()
and tcp_rcv_space_adjust():

divide error: 0000 [#1] PREEMPT SMP
RIP: 0010:tcp_rcvbuf_grow+0x187/0x450 net/ipv4/tcp_input.c:939
...
grow = div_u64(((u64)rcvwin << 1) * (newval - oldval), oldval);

The division uses oldval = tp->rcvq_space.space as divisor.
When tp->rcvq_space.space is zero, this leads to a divide-by-zero
exception.

tp->rcvq_space.space is initialized in tcp_init_buffer_space():
    tp->rcvq_space.space = min3(tp->rcv_ssthresh, tp->rcv_wnd,
                                (u32)TCP_INIT_CWND * tp->advmss);

If tcp_rmem[1] is configured to very small values (such as 1),
sk->sk_rcvbuf is initialized to 1. Then tcp_full_space(sk), which
computes (sk->sk_rcvbuf * scaling_ratio) >> 8, truncates to 0.
This sets tp->window_clamp = 0, tp->rcv_ssthresh = 0, and
tp->rcvq_space.space = 0. Later, when data arrives and DRS is invoked,
tcp_rcvbuf_grow() divides by oldval == 0.

Back in 2015, commit b1cb59cf2efe ("net: sysctl_net_core: check SNDBUF
and RCVBUF for min length") ensured that net.core.rmem_default and
net.core.rmem_max cannot be set below SOCK_MIN_RCVBUF. Similarly,
SO_RCVBUF setsockopt enforces max_t(int, val * 2, SOCK_MIN_RCVBUF).

However, net.ipv4.tcp_rmem still had .extra1 = SYSCTL_ONE, allowing
arbitrarily small values.

Because SOCK_MIN_RCVBUF depends on sizeof(struct sk_buff) and cacheline
alignment, its value varies across architectures and configuration options.
Using a fixed constant of 4096 ensures a predictable, architecture-
independent lower bound that is safely above SOCK_MIN_RCVBUF everywhere
and matches the documented 4K default.

Fix this by setting tcp_rmem.extra1 to 4096 and updating the documentation.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260912144848.3448026-1-edumazet@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 Documentation/networking/ip-sysctl.rst | 2 ++
 net/ipv4/sysctl_net_ipv4.c             | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst
index dcbb6f6caf6de..eb2c136be63da 100644
--- a/Documentation/networking/ip-sysctl.rst
+++ b/Documentation/networking/ip-sysctl.rst
@@ -735,6 +735,8 @@ tcp_rmem - vector of 3 INTEGERs: min, default, max
 	case this value is ignored.
 	Default: between 131072 and 6MB, depending on RAM size.
 
+	Each of the three values cannot be set below 4096.
+
 tcp_sack - BOOLEAN
 	Enable select acknowledgments (SACKS).
 
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 63625a5038af4..00d3be968a53d 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -46,6 +46,8 @@ static unsigned int udp_child_hash_entries_max = UDP_HTABLE_SIZE_MAX;
 static int tcp_plb_max_rounds = 31;
 static int tcp_plb_max_cong_thresh = 256;
 
+static int tcp_min_rcvbuf = 4096;
+
 /* obsolete */
 static int sysctl_tcp_low_latency __read_mostly;
 
@@ -1405,7 +1407,7 @@ static struct ctl_table ipv4_net_table[] = {
 		.maxlen		= sizeof(init_net.ipv4.sysctl_tcp_rmem),
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_minmax,
-		.extra1		= SYSCTL_ONE,
+		.extra1		= &tcp_min_rcvbuf,
 	},
 	{
 		.procname	= "tcp_comp_sack_delay_ns",
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 126/877] ksmbd: return buffer overflow for partial filesystem info
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (124 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 125/877] tcp: do not let tcp_rmem be set below 4096 Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 127/877] ksmbd: fix partial file information responses Greg Kroah-Hartman
                   ` (758 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Sasha Levin

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

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

From: Namjae Jeon <linkinjeon@kernel.org>

[ Upstream commit 0ecd35fac4b4f2828490689b46039744d201dcb0 ]

The query-info buffer check returns STATUS_INFO_LENGTH_MISMATCH for
every output buffer smaller than the complete response. Variable-length
filesystem information instead requires STATUS_BUFFER_OVERFLOW when the
fixed portion fits but the complete data does not.

Pass the fixed size for each filesystem information class to the buffer
checker. Keep INFO_LENGTH_MISMATCH for buffers below that size, and
return BUFFER_OVERFLOW with a response truncated to the requested length
for larger partial buffers.

This fixes smb2.getinfo.qfs_buffercheck.

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Stable-dep-of: 9fa26285ae70 ("ksmbd: keep compound responses on query info errors")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/smb/server/smb2pdu.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 37d8db4bbbaec..b12dad36bb574 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -4648,21 +4648,30 @@ int smb2_query_dir(struct ksmbd_work *work)
 /**
  * buffer_check_err() - helper function to check buffer errors
  * @reqOutputBufferLength:	max buffer length expected in command response
+ * @fixed_len:			minimum fixed response length
  * @rsp:		query info response buffer contains output buffer length
  * @rsp_org:		base response buffer pointer in case of chained response
  *
  * Return:	0 on success, otherwise error
  */
 static int buffer_check_err(int reqOutputBufferLength,
+			    unsigned int fixed_len,
 			    struct smb2_query_info_rsp *rsp,
 			    void *rsp_org)
 {
-	if (reqOutputBufferLength < le32_to_cpu(rsp->OutputBufferLength)) {
+	unsigned int output_len = le32_to_cpu(rsp->OutputBufferLength);
+
+	if (reqOutputBufferLength < fixed_len) {
 		pr_err("Invalid Buffer Size Requested\n");
 		rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH;
 		*(__be32 *)rsp_org = cpu_to_be32(sizeof(struct smb2_hdr));
 		return -EINVAL;
 	}
+
+	if (reqOutputBufferLength < output_len) {
+		rsp->hdr.Status = STATUS_BUFFER_OVERFLOW;
+		rsp->OutputBufferLength = cpu_to_le32(reqOutputBufferLength);
+	}
 	return 0;
 }
 
@@ -4725,11 +4734,13 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
 	case FILE_STANDARD_INFORMATION:
 		get_standard_info_pipe(rsp, rsp_org);
 		rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
+				      le32_to_cpu(rsp->OutputBufferLength),
 				      rsp, rsp_org);
 		break;
 	case FILE_INTERNAL_INFORMATION:
 		get_internal_info_pipe(rsp, id, rsp_org);
 		rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
+				      le32_to_cpu(rsp->OutputBufferLength),
 				      rsp, rsp_org);
 		break;
 	default:
@@ -5523,6 +5534,7 @@ static int smb2_get_info_file(struct ksmbd_work *work,
 	}
 	if (!rc)
 		rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
+				      le32_to_cpu(rsp->OutputBufferLength),
 				      rsp, work->response_buf);
 	ksmbd_fd_put(work, fp);
 
@@ -5544,6 +5556,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
 	struct kstatfs stfs;
 	struct path path;
 	int rc = 0, len;
+	unsigned int fixed_len = 0;
 
 	if (!share->path)
 		return -EIO;
@@ -5578,6 +5591,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
 			info->DeviceCharacteristics |=
 				cpu_to_le32(FILE_READ_ONLY_DEVICE);
 		rsp->OutputBufferLength = cpu_to_le32(8);
+		fixed_len = 8;
 		break;
 	}
 	case FS_ATTRIBUTE_INFORMATION:
@@ -5606,6 +5620,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
 		info->FileSystemNameLen = cpu_to_le32(len);
 		sz = sizeof(struct filesystem_attribute_info) + len;
 		rsp->OutputBufferLength = cpu_to_le32(sz);
+		fixed_len = 16;
 		break;
 	}
 	case FS_VOLUME_INFORMATION:
@@ -5632,6 +5647,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
 		info->Reserved = 0;
 		sz = sizeof(struct filesystem_vol_info) + len;
 		rsp->OutputBufferLength = cpu_to_le32(sz);
+		fixed_len = 24;
 		break;
 	}
 	case FS_SIZE_INFORMATION:
@@ -5644,6 +5660,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
 		info->SectorsPerAllocationUnit = cpu_to_le32(1);
 		info->BytesPerSector = cpu_to_le32(stfs.f_bsize);
 		rsp->OutputBufferLength = cpu_to_le32(24);
+		fixed_len = 24;
 		break;
 	}
 	case FS_FULL_SIZE_INFORMATION:
@@ -5659,6 +5676,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
 		info->SectorsPerAllocationUnit = cpu_to_le32(1);
 		info->BytesPerSector = cpu_to_le32(stfs.f_bsize);
 		rsp->OutputBufferLength = cpu_to_le32(32);
+		fixed_len = 32;
 		break;
 	}
 	case FS_OBJECT_ID_INFORMATION:
@@ -5679,6 +5697,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
 		info->extended_info.rel_date = 0;
 		memcpy(info->extended_info.version_string, "1.1.0", strlen("1.1.0"));
 		rsp->OutputBufferLength = cpu_to_le32(64);
+		fixed_len = 64;
 		break;
 	}
 	case FS_SECTOR_SIZE_INFORMATION:
@@ -5700,6 +5719,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
 		info->ByteOffsetForSectorAlignment = 0;
 		info->ByteOffsetForPartitionAlignment = 0;
 		rsp->OutputBufferLength = cpu_to_le32(28);
+		fixed_len = 28;
 		break;
 	}
 	case FS_CONTROL_INFORMATION:
@@ -5720,6 +5740,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
 		info->DefaultQuotaLimit = cpu_to_le64(SMB2_NO_FID);
 		info->Padding = 0;
 		rsp->OutputBufferLength = cpu_to_le32(48);
+		fixed_len = 48;
 		break;
 	}
 	case FS_POSIX_INFORMATION:
@@ -5740,6 +5761,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
 			info->TotalFileNodes = cpu_to_le64(stfs.f_files);
 			info->FreeFileNodes = cpu_to_le64(stfs.f_ffree);
 			rsp->OutputBufferLength = cpu_to_le32(56);
+			fixed_len = 56;
 		}
 		break;
 	}
@@ -5748,6 +5770,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
 		return -EOPNOTSUPP;
 	}
 	rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
+			      fixed_len,
 			      rsp, work->response_buf);
 	path_put(&path);
 
@@ -5862,6 +5885,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
 iov_pin:
 	rsp->OutputBufferLength = cpu_to_le32(secdesclen);
 	rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
+			      le32_to_cpu(rsp->OutputBufferLength),
 			      rsp, work->response_buf);
 	if (rc)
 		goto err_out;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 127/877] ksmbd: fix partial file information responses
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (125 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 126/877] ksmbd: return buffer overflow for partial filesystem info Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 128/877] ksmbd: keep compound responses on query info errors Greg Kroah-Hartman
                   ` (757 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Sasha Levin

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

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

From: Namjae Jeon <linkinjeon@kernel.org>

[ Upstream commit 6b8b79226bc3e0ac3fdd4e91836241af712e8cd1 ]

Variable-length file information handlers use the client output length
while constructing the response. FILE_ALL_INFORMATION can consequently
return -EINVAL before the common buffer check, while stream information
can stop building the complete result too early.

Build the complete response within the available server response buffer
and apply the client output length only when selecting the final status
and transmitted length. Use the protocol-defined fixed sizes for all,
alternate-name, and stream information to distinguish
STATUS_INFO_LENGTH_MISMATCH from STATUS_BUFFER_OVERFLOW.

This fixes smb2.getinfo.qfile_buffercheck.

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Stable-dep-of: 9fa26285ae70 ("ksmbd: keep compound responses on query info errors")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/smb/server/smb2pdu.c | 31 ++++++++++++++++++++-----------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index b12dad36bb574..af3178031c1ee 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -5019,7 +5019,6 @@ static int get_file_all_info(struct ksmbd_work *work,
 	char *filename;
 	u64 time;
 	int ret, buf_free_len, filename_len;
-	struct smb2_query_info_req *req = ksmbd_req_buf_next(work);
 
 	if (!(fp->daccess & FILE_READ_ATTRIBUTES_LE)) {
 		ksmbd_debug(SMB, "no right to read the attributes : 0x%x\n",
@@ -5032,10 +5031,9 @@ static int get_file_all_info(struct ksmbd_work *work,
 		return PTR_ERR(filename);
 
 	filename_len = strlen(filename);
-	buf_free_len = smb2_calc_max_out_buf_len(work,
+	buf_free_len = smb2_resp_buf_len(work,
 			offsetof(struct smb2_query_info_rsp, Buffer) +
-			offsetof(struct smb2_file_all_info, FileName),
-			le32_to_cpu(req->OutputBufferLength));
+			offsetof(struct smb2_file_all_info, FileName));
 	if (buf_free_len < (filename_len + 1) * 2) {
 		kfree(filename);
 		return -EINVAL;
@@ -5120,7 +5118,6 @@ static int get_file_stream_info(struct ksmbd_work *work,
 	ssize_t xattr_list_len;
 	int nbytes = 0, streamlen, stream_name_len, next, idx = 0;
 	int buf_free_len;
-	struct smb2_query_info_req *req = ksmbd_req_buf_next(work);
 	int ret;
 
 	ret = vfs_getattr(&fp->filp->f_path, &stat, STATX_BASIC_STATS,
@@ -5130,10 +5127,8 @@ static int get_file_stream_info(struct ksmbd_work *work,
 
 	file_info = (struct smb2_file_stream_info *)rsp->Buffer;
 
-	buf_free_len =
-		smb2_calc_max_out_buf_len(work,
-				offsetof(struct smb2_query_info_rsp, Buffer),
-				le32_to_cpu(req->OutputBufferLength));
+	buf_free_len = smb2_resp_buf_len(work,
+			offsetof(struct smb2_query_info_rsp, Buffer));
 	if (buf_free_len < 0)
 		goto out;
 
@@ -5429,6 +5424,7 @@ static int smb2_get_info_file(struct ksmbd_work *work,
 	struct ksmbd_file *fp;
 	int fileinfoclass = 0;
 	int rc = 0;
+	unsigned int fixed_len;
 	unsigned int id = KSMBD_NO_FID, pid = KSMBD_NO_FID;
 
 	if (test_share_config_flag(work->tcon->share_conf,
@@ -5532,10 +5528,23 @@ static int smb2_get_info_file(struct ksmbd_work *work,
 			    fileinfoclass);
 		rc = -EOPNOTSUPP;
 	}
-	if (!rc)
+	if (!rc) {
+		fixed_len = le32_to_cpu(rsp->OutputBufferLength);
+		switch (fileinfoclass) {
+		case FILE_ALL_INFORMATION:
+			fixed_len = FILE_ALL_INFORMATION_SIZE;
+			break;
+		case FILE_ALTERNATE_NAME_INFORMATION:
+			fixed_len = FILE_ALTERNATE_NAME_INFORMATION_SIZE;
+			break;
+		case FILE_STREAM_INFORMATION:
+			fixed_len = FILE_STREAM_INFORMATION_SIZE;
+			break;
+		}
 		rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
-				      le32_to_cpu(rsp->OutputBufferLength),
+				      fixed_len,
 				      rsp, work->response_buf);
+	}
 	ksmbd_fd_put(work, fp);
 
 iov_pin_out:
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 128/877] ksmbd: keep compound responses on query info errors
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (126 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 127/877] ksmbd: fix partial file information responses Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 129/877] dmaengine: mmp_pdma: fix wrong sg length in mmp_pdma_prep_slave_sg() Greg Kroah-Hartman
                   ` (756 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mobin Aydinfar, ChenXiaoSong,
	Namjae Jeon, Sasha Levin

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

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

From: Namjae Jeon <linkinjeon@kernel.org>

[ Upstream commit 9fa26285ae70ac2d3d1b47459a6b4463ab053e1c ]

Do not reset the RFC1002 length of the complete response when a query
info buffer is too small. The current command will add its error response
through ksmbd_iov_pin_rsp(), while resetting the base length can truncate
earlier responses in a compound request.

This lets ksmbd return the earlier responses and the query-info error
response together. Remove the now-unused rsp_org parameter from the pipe
query-info helpers.

Fixes: e2b76ab8b5c9 ("ksmbd: add support for read compound")
Reported-by: Mobin Aydinfar <mobin@mobintestserver.ir>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/smb/server/smb2pdu.c | 31 ++++++++++++-------------------
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index af3178031c1ee..283160908218e 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -4650,21 +4650,18 @@ int smb2_query_dir(struct ksmbd_work *work)
  * @reqOutputBufferLength:	max buffer length expected in command response
  * @fixed_len:			minimum fixed response length
  * @rsp:		query info response buffer contains output buffer length
- * @rsp_org:		base response buffer pointer in case of chained response
  *
  * Return:	0 on success, otherwise error
  */
 static int buffer_check_err(int reqOutputBufferLength,
 			    unsigned int fixed_len,
-			    struct smb2_query_info_rsp *rsp,
-			    void *rsp_org)
+			    struct smb2_query_info_rsp *rsp)
 {
 	unsigned int output_len = le32_to_cpu(rsp->OutputBufferLength);
 
 	if (reqOutputBufferLength < fixed_len) {
 		pr_err("Invalid Buffer Size Requested\n");
 		rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH;
-		*(__be32 *)rsp_org = cpu_to_be32(sizeof(struct smb2_hdr));
 		return -EINVAL;
 	}
 
@@ -4675,8 +4672,7 @@ static int buffer_check_err(int reqOutputBufferLength,
 	return 0;
 }
 
-static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp,
-				   void *rsp_org)
+static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp)
 {
 	struct smb2_file_standard_info *sinfo;
 
@@ -4691,8 +4687,7 @@ static void get_standard_info_pipe(struct smb2_query_info_rsp *rsp,
 		cpu_to_le32(sizeof(struct smb2_file_standard_info));
 }
 
-static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, u64 num,
-				   void *rsp_org)
+static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, u64 num)
 {
 	struct smb2_file_internal_info *file_info;
 
@@ -4706,8 +4701,7 @@ static void get_internal_info_pipe(struct smb2_query_info_rsp *rsp, u64 num,
 
 static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
 				   struct smb2_query_info_req *req,
-				   struct smb2_query_info_rsp *rsp,
-				   void *rsp_org)
+				   struct smb2_query_info_rsp *rsp)
 {
 	u64 id;
 	int rc;
@@ -4732,16 +4726,16 @@ static int smb2_get_info_file_pipe(struct ksmbd_session *sess,
 
 	switch (req->FileInfoClass) {
 	case FILE_STANDARD_INFORMATION:
-		get_standard_info_pipe(rsp, rsp_org);
+		get_standard_info_pipe(rsp);
 		rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
 				      le32_to_cpu(rsp->OutputBufferLength),
-				      rsp, rsp_org);
+				      rsp);
 		break;
 	case FILE_INTERNAL_INFORMATION:
-		get_internal_info_pipe(rsp, id, rsp_org);
+		get_internal_info_pipe(rsp, id);
 		rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
 				      le32_to_cpu(rsp->OutputBufferLength),
-				      rsp, rsp_org);
+				      rsp);
 		break;
 	default:
 		ksmbd_debug(SMB, "smb2_info_file_pipe for %u not supported\n",
@@ -5430,8 +5424,7 @@ static int smb2_get_info_file(struct ksmbd_work *work,
 	if (test_share_config_flag(work->tcon->share_conf,
 				   KSMBD_SHARE_FLAG_PIPE)) {
 		/* smb2 info file called for pipe */
-		rc = smb2_get_info_file_pipe(work->sess, req, rsp,
-					       work->response_buf);
+		rc = smb2_get_info_file_pipe(work->sess, req, rsp);
 		goto iov_pin_out;
 	}
 
@@ -5543,7 +5536,7 @@ static int smb2_get_info_file(struct ksmbd_work *work,
 		}
 		rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
 				      fixed_len,
-				      rsp, work->response_buf);
+				      rsp);
 	}
 	ksmbd_fd_put(work, fp);
 
@@ -5780,7 +5773,7 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
 	}
 	rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
 			      fixed_len,
-			      rsp, work->response_buf);
+			      rsp);
 	path_put(&path);
 
 	if (!rc)
@@ -5895,7 +5888,7 @@ static int smb2_get_info_sec(struct ksmbd_work *work,
 	rsp->OutputBufferLength = cpu_to_le32(secdesclen);
 	rc = buffer_check_err(le32_to_cpu(req->OutputBufferLength),
 			      le32_to_cpu(rsp->OutputBufferLength),
-			      rsp, work->response_buf);
+			      rsp);
 	if (rc)
 		goto err_out;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 129/877] dmaengine: mmp_pdma: fix wrong sg length in mmp_pdma_prep_slave_sg()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (127 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 128/877] ksmbd: keep compound responses on query info errors Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 130/877] Bluetooth: hci_core: Print number of packets in conn->data_q Greg Kroah-Hartman
                   ` (755 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Baineng Shou, Frank Li, Vinod Koul,
	Sasha Levin

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

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

From: Baineng Shou <shoubaineng@gmail.com>

[ Upstream commit 075bc7b1d3dde5ed43fbaabbc1a69f09b7fc3a47 ]

In mmp_pdma_prep_slave_sg(), for_each_sg() iterates the scatterlist
putting each entry into 'sg', but the entry length is read from 'sgl'
(the list head) instead of 'sg' (the current entry):

    for_each_sg(sgl, sg, sg_len, i) {
        addr = sg_dma_address(sg);
        avail = sg_dma_len(sgl);   /* should be 'sg' */

Consequently 'avail' is always the length of the first entry. For
multi-sg lists this causes out-of-bounds reads when a later entry is
shorter than the first, and silent data loss when it is longer.
Single-sg or uniformly-sized lists happen to mask the issue.

Fixes: c8acd6aa6bed3 ("dmaengine: mmp-pdma support")
Signed-off-by: Baineng Shou <shoubaineng@gmail.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260910021652.1296640-1-shoubaineng@gmail.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/dma/mmp_pdma.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c
index 852e6714d9f28..59227fbed9045 100644
--- a/drivers/dma/mmp_pdma.c
+++ b/drivers/dma/mmp_pdma.c
@@ -541,7 +541,7 @@ mmp_pdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl,
 
 	for_each_sg(sgl, sg, sg_len, i) {
 		addr = sg_dma_address(sg);
-		avail = sg_dma_len(sgl);
+		avail = sg_dma_len(sg);
 
 		do {
 			len = min_t(size_t, avail, PDMA_MAX_DESC_BYTES);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 130/877] Bluetooth: hci_core: Print number of packets in conn->data_q
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (128 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 129/877] dmaengine: mmp_pdma: fix wrong sg length in mmp_pdma_prep_slave_sg() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 131/877] Bluetooth: hci_core: Fix queuing tx_work after workqueue is drained Greg Kroah-Hartman
                   ` (754 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Luiz Augusto von Dentz, Sasha Levin

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

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

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

[ Upstream commit 3c34d6428740e47b29ae3afd85d6f9eb656a3ea3 ]

This attempts to print the number of packets pending to be transmitted
in the conn->data_q.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Stable-dep-of: 6610c6fe4b89 ("Bluetooth: hci_core: Fix queuing tx_work after workqueue is drained")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/bluetooth/hci_core.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index f68238406ad2e..24f2119c7abfa 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3273,6 +3273,8 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
 
 		spin_unlock_bh(&queue->lock);
 	}
+
+	bt_dev_dbg(hdev, "chan %p queued %d", chan, skb_queue_len(queue));
 }
 
 void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
@@ -3304,6 +3306,10 @@ void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
 	hci_skb_pkt_type(skb) = HCI_SCODATA_PKT;
 
 	skb_queue_tail(&conn->data_q, skb);
+
+	bt_dev_dbg(hdev, "hcon %p queued %d", conn,
+		   skb_queue_len(&conn->data_q));
+
 	queue_work(hdev->workqueue, &hdev->tx_work);
 }
 
@@ -3363,6 +3369,8 @@ static void hci_queue_iso(struct hci_conn *conn, struct sk_buff_head *queue,
 			__skb_queue_tail(queue, skb);
 		} while (list);
 	}
+
+	bt_dev_dbg(hdev, "hcon %p queued %d", conn, skb_queue_len(queue));
 }
 
 void hci_send_iso(struct hci_conn *conn, struct sk_buff *skb)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 131/877] Bluetooth: hci_core: Fix queuing tx_work after workqueue is drained
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (129 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 130/877] Bluetooth: hci_core: Print number of packets in conn->data_q Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 132/877] Bluetooth: coredump: Quiesce dump work on unregister Greg Kroah-Hartman
                   ` (753 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+b6919040d9958e2fc1ae,
	ThangNN99, Luiz Augusto von Dentz, Sasha Levin

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

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

From: ThangNN99 <ngocthang2710.1999@gmail.com>

[ Upstream commit 6610c6fe4b8936c232048e6049bf77c70a6f759c ]

hci_send_acl(), hci_send_sco() and hci_send_iso() queue hdev->tx_work
unconditionally. They can run from the L2CAP/SCO/ISO socket send path
while hci_dev_close_sync() is draining hdev->workqueue (HCIDEVDOWN
racing with a socket write). Since that queue_work() is not chained
work from the tx_work worker itself, __queue_work() sees the queue
marked __WQ_DRAINING, warns "cannot queue %ps on wq %s", and drops
the work:

  WARNING: CPU: 1 PID: 5985 at kernel/workqueue.c:2352 __queue_work
  Call Trace:
   queue_work_on
   l2cap_chan_send
   l2cap_sock_sendmsg
   ...

hci_dev_close_sync() already sets HCI_CMD_DRAIN_WORKQUEUE before
draining, but only hci_cmd_work() and handle_cmd_cnt_and_timer()
check it before queuing. Route the tx_work producers through the
same guard via a shared hci_sched_tx() helper.

Fixes: 525daaea459f ("Bluetooth: hci_sync: Set HCI_CMD_DRAIN_WORKQUEUE during device close")
Reported-by: syzbot+b6919040d9958e2fc1ae@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=b6919040d9958e2fc1ae
Signed-off-by: ThangNN99 <ngocthang2710.1999@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/bluetooth/hci_core.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 24f2119c7abfa..85aecd4c5b9b2 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3277,6 +3277,17 @@ static void hci_queue_acl(struct hci_chan *chan, struct sk_buff_head *queue,
 	bt_dev_dbg(hdev, "chan %p queued %d", chan, skb_queue_len(queue));
 }
 
+/* Queue hdev->tx_work, unless hdev->workqueue is being drained by
+ * hci_dev_close_sync(), which would otherwise WARN and drop the work.
+ */
+static void hci_sched_tx(struct hci_dev *hdev)
+{
+	rcu_read_lock();
+	if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
+		queue_work(hdev->workqueue, &hdev->tx_work);
+	rcu_read_unlock();
+}
+
 void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
 {
 	struct hci_dev *hdev = chan->conn->hdev;
@@ -3285,7 +3296,7 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags)
 
 	hci_queue_acl(chan, &chan->data_q, skb, flags);
 
-	queue_work(hdev->workqueue, &hdev->tx_work);
+	hci_sched_tx(hdev);
 }
 
 /* Send SCO data */
@@ -3310,7 +3321,7 @@ void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb)
 	bt_dev_dbg(hdev, "hcon %p queued %d", conn,
 		   skb_queue_len(&conn->data_q));
 
-	queue_work(hdev->workqueue, &hdev->tx_work);
+	hci_sched_tx(hdev);
 }
 
 /* Send ISO data */
@@ -3381,7 +3392,7 @@ void hci_send_iso(struct hci_conn *conn, struct sk_buff *skb)
 
 	hci_queue_iso(conn, &conn->data_q, skb);
 
-	queue_work(hdev->workqueue, &hdev->tx_work);
+	hci_sched_tx(hdev);
 }
 
 /* ---- HCI TX task (outgoing data) ---- */
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 132/877] Bluetooth: coredump: Quiesce dump work on unregister
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (130 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 131/877] Bluetooth: hci_core: Fix queuing tx_work after workqueue is drained Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 133/877] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready() Greg Kroah-Hartman
                   ` (752 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+b170dbf55520ebf5969a,
	Aby Sam Ross, Tristan Madani, Xiang Mei, Weiming Shi,
	Luiz Augusto von Dentz, Sasha Levin

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

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

From: Weiming Shi <bestswngs@gmail.com>

[ Upstream commit d236517c264e41dc09833c708ef23bccb7a91219 ]

hci_devcd_handle_pkt_init() arms dump_timeout and coredump producers
queue dump_rx without holding an hdev reference. Unregister leaves both
works live, so disconnecting during an active dump lets them access hdev
after hci_release_dev() frees it.

Shut down coredump processing during unregister. Close the producer gate
under dump_q.lock before disabling both works, then free the active buffer
and queued packets under hci_dev_lock. Serializing the gate with enqueue
prevents controller-specific workers from adding packets after the final
purge.

Fixes: 9695ef876fd1 ("Bluetooth: Add support for hci devcoredump")
Reported-by: syzbot+b170dbf55520ebf5969a@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=b170dbf55520ebf5969a
Reported-by: Aby Sam Ross <abysamross@gmail.com>
Link: https://lore.kernel.org/r/20260322210849.68743-1-abysamross@gmail.com
Suggested-by: Aby Sam Ross <abysamross@gmail.com>
Reported-by: Tristan Madani <tristan@talencesecurity.com>
Link: https://lore.kernel.org/r/20260814231248.3096377-1-tristmd@gmail.com
Reported-by: Xiang Mei <xmei5@asu.edu>
Assisted-by: OpenAI Codex:gpt-5
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Reported-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/net/bluetooth/coredump.h |  2 +
 net/bluetooth/coredump.c         | 65 +++++++++++++++++++++-----------
 net/bluetooth/hci_core.c         |  1 +
 3 files changed, 47 insertions(+), 21 deletions(-)

diff --git a/include/net/bluetooth/coredump.h b/include/net/bluetooth/coredump.h
index 72f51b587a046..00c12c7ac042f 100644
--- a/include/net/bluetooth/coredump.h
+++ b/include/net/bluetooth/coredump.h
@@ -61,6 +61,7 @@ struct hci_devcoredump {
 #ifdef CONFIG_DEV_COREDUMP
 
 void hci_devcd_reset(struct hci_dev *hdev);
+void hci_devcd_shutdown(struct hci_dev *hdev);
 void hci_devcd_rx(struct work_struct *work);
 void hci_devcd_timeout(struct work_struct *work);
 
@@ -75,6 +76,7 @@ int hci_devcd_abort(struct hci_dev *hdev);
 #else
 
 static inline void hci_devcd_reset(struct hci_dev *hdev) {}
+static inline void hci_devcd_shutdown(struct hci_dev *hdev) {}
 static inline void hci_devcd_rx(struct work_struct *work) {}
 static inline void hci_devcd_timeout(struct work_struct *work) {}
 
diff --git a/net/bluetooth/coredump.c b/net/bluetooth/coredump.c
index c18df3a086075..517a61234ef43 100644
--- a/net/bluetooth/coredump.c
+++ b/net/bluetooth/coredump.c
@@ -105,6 +105,22 @@ static void hci_devcd_free(struct hci_dev *hdev)
 	hci_devcd_reset(hdev);
 }
 
+void hci_devcd_shutdown(struct hci_dev *hdev)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&hdev->dump.dump_q.lock, flags);
+	hdev->dump.supported = false;
+	spin_unlock_irqrestore(&hdev->dump.dump_q.lock, flags);
+
+	disable_work_sync(&hdev->dump.dump_rx);
+	disable_delayed_work_sync(&hdev->dump.dump_timeout);
+
+	hci_dev_lock(hdev);
+	hci_devcd_free(hdev);
+	hci_dev_unlock(hdev);
+}
+
 /* Call with hci_dev_lock only. */
 static int hci_devcd_alloc(struct hci_dev *hdev, u32 size)
 {
@@ -426,7 +442,29 @@ EXPORT_SYMBOL(hci_devcd_register);
 
 static inline bool hci_devcd_enabled(struct hci_dev *hdev)
 {
-	return hdev->dump.supported;
+	return READ_ONCE(hdev->dump.supported);
+}
+
+static int hci_devcd_queue(struct hci_dev *hdev, struct sk_buff *skb)
+{
+	unsigned long flags;
+	int err = 0;
+
+	spin_lock_irqsave(&hdev->dump.dump_q.lock, flags);
+	if (!hdev->dump.supported)
+		err = -EOPNOTSUPP;
+	else
+		__skb_queue_tail(&hdev->dump.dump_q, skb);
+	spin_unlock_irqrestore(&hdev->dump.dump_q.lock, flags);
+
+	if (err) {
+		kfree_skb(skb);
+		return err;
+	}
+
+	queue_work(hdev->workqueue, &hdev->dump.dump_rx);
+
+	return 0;
 }
 
 int hci_devcd_init(struct hci_dev *hdev, u32 dump_size)
@@ -443,10 +481,7 @@ int hci_devcd_init(struct hci_dev *hdev, u32 dump_size)
 	hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_INIT;
 	put_unaligned_le32(dump_size, skb_put(skb, 4));
 
-	skb_queue_tail(&hdev->dump.dump_q, skb);
-	queue_work(hdev->workqueue, &hdev->dump.dump_rx);
-
-	return 0;
+	return hci_devcd_queue(hdev, skb);
 }
 EXPORT_SYMBOL(hci_devcd_init);
 
@@ -462,10 +497,7 @@ int hci_devcd_append(struct hci_dev *hdev, struct sk_buff *skb)
 
 	hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_SKB;
 
-	skb_queue_tail(&hdev->dump.dump_q, skb);
-	queue_work(hdev->workqueue, &hdev->dump.dump_rx);
-
-	return 0;
+	return hci_devcd_queue(hdev, skb);
 }
 EXPORT_SYMBOL(hci_devcd_append);
 
@@ -487,10 +519,7 @@ int hci_devcd_append_pattern(struct hci_dev *hdev, u8 pattern, u32 len)
 	hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_PATTERN;
 	skb_put_data(skb, &p, sizeof(p));
 
-	skb_queue_tail(&hdev->dump.dump_q, skb);
-	queue_work(hdev->workqueue, &hdev->dump.dump_rx);
-
-	return 0;
+	return hci_devcd_queue(hdev, skb);
 }
 EXPORT_SYMBOL(hci_devcd_append_pattern);
 
@@ -507,10 +536,7 @@ int hci_devcd_complete(struct hci_dev *hdev)
 
 	hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_COMPLETE;
 
-	skb_queue_tail(&hdev->dump.dump_q, skb);
-	queue_work(hdev->workqueue, &hdev->dump.dump_rx);
-
-	return 0;
+	return hci_devcd_queue(hdev, skb);
 }
 EXPORT_SYMBOL(hci_devcd_complete);
 
@@ -527,9 +553,6 @@ int hci_devcd_abort(struct hci_dev *hdev)
 
 	hci_dmp_cb(skb)->pkt_type = HCI_DEVCOREDUMP_PKT_ABORT;
 
-	skb_queue_tail(&hdev->dump.dump_q, skb);
-	queue_work(hdev->workqueue, &hdev->dump.dump_rx);
-
-	return 0;
+	return hci_devcd_queue(hdev, skb);
 }
 EXPORT_SYMBOL(hci_devcd_abort);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 85aecd4c5b9b2..a85c77ed4a13e 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2731,6 +2731,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
 	disable_work_sync(&hdev->error_reset);
 	disable_delayed_work_sync(&hdev->cmd_timer);
 	disable_delayed_work_sync(&hdev->ncmd_timer);
+	hci_devcd_shutdown(hdev);
 
 	hci_cmd_sync_clear(hdev);
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 133/877] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (131 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 132/877] Bluetooth: coredump: Quiesce dump work on unregister Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 134/877] Bluetooth: ISO: set BT_LISTEN before requesting a BIG sync Greg Kroah-Hartman
                   ` (751 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Luiz Augusto von Dentz, Sasha Levin

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

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

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

[ Upstream commit ca18ee413a7cb6f09885778039225e58bae0d607 ]

iso_get_sock() returns the parent socket with a reference held, which is
dropped by sock_put() once the child socket has been set up. The error
path taken when iso_sock_alloc() fails only calls release_sock() and
returns, leaking the reference and thus the parent socket itself.

Drop the reference on that path as well.

Fixes: fa224d0c094a ("Bluetooth: ISO: Reassociate a socket with an active BIS")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/bluetooth/iso.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index 6e1fac4b1cf63..8cdfe3b6e1235 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -2013,6 +2013,7 @@ static void iso_conn_ready(struct iso_conn *conn)
 				    BTPROTO_ISO, GFP_ATOMIC, 0);
 		if (!sk) {
 			release_sock(parent);
+			sock_put(parent);
 			return;
 		}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 134/877] Bluetooth: ISO: set BT_LISTEN before requesting a BIG sync
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (132 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 133/877] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 135/877] Bluetooth: btmtk: fix wrong status for short WMT FUNC_CTRL events Greg Kroah-Hartman
                   ` (750 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Luiz Augusto von Dentz, Sasha Levin

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

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

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

[ Upstream commit 296e7f3c5071cc02dc22e1566e759179fa1792ae ]

A BIS connection is matched to its parent socket by looking for a
socket in BT_LISTEN state with the same BIG handle:

  iso_conn_ready()
    if (test_bit(HCI_CONN_BIG_SYNC, &hcon->flags))
            parent = iso_get_sock(hdev, &hcon->src, &hcon->dst,
                                  BT_LISTEN, iso_match_big_hcon, hcon);

The socket was only moved to BT_LISTEN after iso_conn_big_sync()
returned, while the LE BIG Create Sync command has already been queued
by then. If the BIG sync is established before the state is updated,
which is easy to hit with an emulated controller as the command may
complete in a few hundred microseconds, no parent is found and the BIS
connections are never notified to the listening socket.

The user space is then left waiting for connections that never arrive,
e.g. bluetoothd never completes a MediaTransport1.Acquire of a
Broadcast Sink transport.

Move the socket to BT_LISTEN before requesting the BIG sync, so the
state is visible by the time the command is queued, and restore the
previous state if the request could not be started. Since the socket is
briefly visible as a listening socket, child sockets may have been
queued in the meantime, so drain the accept queue before restoring the
state: the cleanup paths of BT_CONNECT2/BT_CONNECTED don't do it and the
children would be left with a dangling parent pointer.

Fixes: fbdc4bc47268 ("Bluetooth: ISO: Use defer setup to separate PA sync and BIG sync")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/bluetooth/iso.c | 52 +++++++++++++++++++++++++++++++++++----------
 1 file changed, 41 insertions(+), 11 deletions(-)

diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c
index 8cdfe3b6e1235..3cf4ef291bf54 100644
--- a/net/bluetooth/iso.c
+++ b/net/bluetooth/iso.c
@@ -738,19 +738,24 @@ static void iso_sock_destruct(struct sock *sk)
 	skb_queue_purge(&sk->sk_write_queue);
 }
 
-static void iso_sock_cleanup_listen(struct sock *parent)
+/* Close not yet accepted channels */
+static void iso_sock_flush_accept_q(struct sock *parent)
 {
 	struct sock *sk;
 
-	BT_DBG("parent %p", parent);
-
-	/* Close not yet accepted channels */
 	while ((sk = bt_accept_dequeue(parent, NULL))) {
 		iso_sock_close(sk);
 		iso_sock_kill(sk);
 		/* Drop the reference handed back by bt_accept_dequeue(). */
 		sock_put(sk);
 	}
+}
+
+static void iso_sock_cleanup_listen(struct sock *parent)
+{
+	BT_DBG("parent %p", parent);
+
+	iso_sock_flush_accept_q(parent);
 
 	/* If listening socket has a hcon, properly disconnect it */
 	if (iso_pi(parent)->conn && iso_pi(parent)->conn->hcon) {
@@ -1524,6 +1529,13 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
 		switch (sk->sk_state) {
 		case BT_CONNECT2:
 			if (test_bit(BT_SK_PA_SYNC, &pi->flags)) {
+				/* Move to BT_LISTEN before requesting the BIG
+				 * sync: the BIS connections are matched to a
+				 * parent socket in BT_LISTEN state, and they
+				 * may be notified before the request returns.
+				 */
+				sk->sk_state = BT_LISTEN;
+
 				release_sock(sk);
 				err = iso_conn_big_sync(sk);
 				lock_sock(sk);
@@ -1532,12 +1544,20 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
 				 * connection may have been torn down
 				 * meanwhile and iso_chan_del() may have
 				 * already moved the socket to BT_CLOSED.
-				 * Only move on to BT_LISTEN if the BIG sync
-				 * was actually started and nothing else has
-				 * changed the state.
+				 * Only move back if the BIG sync could not be
+				 * started and nothing else has changed the
+				 * state.
 				 */
-				if (!err && sk->sk_state == BT_CONNECT2)
-					sk->sk_state = BT_LISTEN;
+				if (err && sk->sk_state == BT_LISTEN) {
+					/* Discard any child socket that may
+					 * have been queued while the socket
+					 * was in BT_LISTEN, as the cleanup of
+					 * BT_CONNECT2 doesn't drain the
+					 * accept queue.
+					 */
+					iso_sock_flush_accept_q(sk);
+					sk->sk_state = BT_CONNECT2;
+				}
 			} else {
 				iso_conn_defer_accept(pi->conn->hcon);
 				sk->sk_state = BT_CONFIG;
@@ -1547,12 +1567,22 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg,
 			break;
 		case BT_CONNECTED:
 			if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) {
+				/* As above, the BIS connections may be
+				 * notified before the request returns.
+				 */
+				sk->sk_state = BT_LISTEN;
+
 				release_sock(sk);
 				err = iso_conn_big_sync(sk);
 				lock_sock(sk);
 
-				if (!err && sk->sk_state == BT_CONNECTED)
-					sk->sk_state = BT_LISTEN;
+				if (err && sk->sk_state == BT_LISTEN) {
+					/* As above, don't leave any child
+					 * socket behind in the accept queue.
+					 */
+					iso_sock_flush_accept_q(sk);
+					sk->sk_state = BT_CONNECTED;
+				}
 				early_ret = true;
 			}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 135/877] Bluetooth: btmtk: fix wrong status for short WMT FUNC_CTRL events
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (133 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 134/877] Bluetooth: ISO: set BT_LISTEN before requesting a BIG sync Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 136/877] Bluetooth: btmtksdio: Fix PM runtime reference leak in shutdown Greg Kroah-Hartman
                   ` (749 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Chris Lu, Luiz Augusto von Dentz,
	Sasha Levin

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

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

From: Chris Lu <chris.lu@mediatek.com>

[ Upstream commit 78b6abd6c7a7591aacdae657f813214dae4fcd3b ]

A too-short BTMTK_WMT_FUNC_CTRL event (WMT header only, no trailing
2-byte status word) is always treated as BTMTK_WMT_ON_UNDONE. This
short form is how firmware acks a plain enable/disable request, and
the actual result is carried in the header's own flag byte (0 =
success), not a separate status word. Decode it from there instead of
assuming failure.

Verified setup on MT7920, MT7921, MT7922 and MT7925: no regression.

Fixes: e3ac0d9f1a20 ("Bluetooth: btmtk: accept too short WMT FUNC_CTRL events")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Chris Lu <chris.lu@mediatek.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/bluetooth/btmtk.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index eb42b694da7f2..33e0e3eb65159 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -709,7 +709,12 @@ static int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,
 	case BTMTK_WMT_FUNC_CTRL:
 		if (!skb_pull_data(data->evt_skb,
 				   sizeof(wmt_evt_funcc->status))) {
-			status = BTMTK_WMT_ON_UNDONE;
+			/* A plain enable/disable request is acked with just
+			 * the WMT header and no trailing status word; the
+			 * result is carried in the header's own flag byte.
+			 */
+			status = wmt_evt->whdr.flag ? BTMTK_WMT_ON_UNDONE :
+						       BTMTK_WMT_ON_DONE;
 			break;
 		}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 136/877] Bluetooth: btmtksdio: Fix PM runtime reference leak in shutdown
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (134 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 135/877] Bluetooth: btmtk: fix wrong status for short WMT FUNC_CTRL events Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 137/877] Bluetooth: btintel_pcie: fix off-by-one bounds check in RX submit Greg Kroah-Hartman
                   ` (748 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih,
	Luiz Augusto von Dentz, Sasha Levin

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

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

From: Tzung-Bi Shih <tzungbi@kernel.org>

[ Upstream commit 7b60ee5f46f2ee329de661f7c68b6818d8136220 ]

In btmtksdio_shutdown(), pm_runtime_get_sync() is called at the
beginning of the function.  However, if sending the WMT function
control command fails later, the driver returns early.

It bypasses the corresponding pm_runtime_put_noidle() and
pm_runtime_disable() calls, leaking the PM usage counter and leaving PM
runtime enabled indefinitely.

Fall through to execute the PM runtime cleanup block even if WMT errors.

Fixes: 7f3c563c575e ("Bluetooth: btmtksdio: Add runtime PM support to SDIO based Bluetooth")
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/bluetooth/btmtksdio.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c
index 0e8fb01981432..575bac139715b 100644
--- a/drivers/bluetooth/btmtksdio.c
+++ b/drivers/bluetooth/btmtksdio.c
@@ -1245,10 +1245,8 @@ static int btmtksdio_shutdown(struct hci_dev *hdev)
 	wmt_params.status = NULL;
 
 	err = mtk_hci_wmt_sync(hdev, &wmt_params);
-	if (err < 0) {
+	if (err < 0)
 		bt_dev_err(hdev, "Failed to send wmt func ctrl (%d)", err);
-		return err;
-	}
 
 ignore_wmt_cmd:
 	pm_runtime_put_noidle(bdev->dev);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 137/877] Bluetooth: btintel_pcie: fix off-by-one bounds check in RX submit
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (135 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 136/877] Bluetooth: btmtksdio: Fix PM runtime reference leak in shutdown Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 138/877] Bluetooth: RFCOMM: avoid socket lock inversion in listener cleanup Greg Kroah-Hartman
                   ` (747 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sai Teja Aluvala,
	Luiz Augusto von Dentz, Sasha Levin

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

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

From: Sai Teja Aluvala <aluvala.sai.teja@intel.com>

[ Upstream commit 2ea5a87a5a7ae58cb2662b8a7d06f209383e1765 ]

btintel_pcie_submit_rx() used frbd_index > rxq->count to guard the
FRBD array access, allowing frbd_index == rxq->count to pass through
and index one element past the end of the array. Change the check to
>= rxq->count so every out-of-range index is rejected.

This issue was reported by Claude Mythos.

Fixes: c2b636b3f788 (Bluetooth: btintel_pcie: Add support for PCIe transport)
Signed-off-by: Sai Teja Aluvala <aluvala.sai.teja@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/bluetooth/btintel_pcie.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index 8ebdfd9744ca0..bc87ebc46f4db 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -210,7 +210,7 @@ static int btintel_pcie_submit_rx(struct btintel_pcie_data *data)
 
 	frbd_index = data->ia.tr_hia[BTINTEL_PCIE_RXQ_NUM];
 
-	if (frbd_index > rxq->count)
+	if (frbd_index >= rxq->count)
 		return -ERANGE;
 
 	/* Prepare for RX submit. It updates the FRBD with the address of DMA
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 138/877] Bluetooth: RFCOMM: avoid socket lock inversion in listener cleanup
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (136 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 137/877] Bluetooth: btintel_pcie: fix off-by-one bounds check in RX submit Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 139/877] pppoatm: ensure a writable skb header and linear data Greg Kroah-Hartman
                   ` (746 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+0cece8fa7d83523f47a3,
	Juan Perdomo, Luiz Augusto von Dentz, Sasha Levin

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

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

From: Juan Perdomo <jcperdomo100@gmail.com>

[ Upstream commit 801fb950cae7048eb7d83b18857d1ca37b8cd5a4 ]

rfcomm_sock_cleanup_listen() closes unaccepted child sockets through
rfcomm_sock_close(), which takes the child socket lock before
rfcomm_dlc_close() acquires rfcomm_mutex. The RFCOMM worker takes these
locks in reverse order while handling connections and DLC state changes,
so lockdep reports a possible deadlock.

Close dequeued children without taking their socket lock. The accept queue
owns a reference to each child, and bt_accept_dequeue() locks the child
while unlinking it and clearing its parent pointer.

Dropping the child lock makes it important to prevent a concurrent
rfcomm_connect_ind() from enqueueing a new child after cleanup observes an
empty queue. Set a listening socket to BT_CLOSED while its lock is still
held, before dropping the lock and draining the queue. The state check in
rfcomm_connect_ind() then rejects new children once cleanup starts.

Reported-by: syzbot+0cece8fa7d83523f47a3@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=0cece8fa7d83523f47a3
Fixes: b7ce436a5d79 ("Bluetooth: switch to lock_sock in RFCOMM")
Signed-off-by: Juan Perdomo <jcperdomo100@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/bluetooth/rfcomm/sock.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 2286efef62f5b..037a7fcab3023 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -243,9 +243,7 @@ static void __rfcomm_sock_close(struct sock *sk)
  */
 static void rfcomm_sock_close(struct sock *sk)
 {
-	lock_sock(sk);
 	__rfcomm_sock_close(sk);
-	release_sock(sk);
 }
 
 static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
@@ -902,6 +900,7 @@ static int rfcomm_sock_compat_ioctl(struct socket *sock, unsigned int cmd, unsig
 static int rfcomm_sock_shutdown(struct socket *sock, int how)
 {
 	struct sock *sk = sock->sk;
+	bool cleanup_listen = false;
 	int err = 0;
 
 	BT_DBG("sock %p, sk %p", sock, sk);
@@ -912,9 +911,17 @@ static int rfcomm_sock_shutdown(struct socket *sock, int how)
 	lock_sock(sk);
 	if (!sk->sk_shutdown) {
 		sk->sk_shutdown = SHUTDOWN_MASK;
+		if (sk->sk_state == BT_LISTEN) {
+			/* Block new children before cleaning up without sk lock. */
+			sk->sk_state = BT_CLOSED;
+			cleanup_listen = true;
+		}
 
 		release_sock(sk);
-		__rfcomm_sock_close(sk);
+		if (cleanup_listen)
+			rfcomm_sock_cleanup_listen(sk);
+		else
+			__rfcomm_sock_close(sk);
 		lock_sock(sk);
 
 		if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime &&
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 139/877] pppoatm: ensure a writable skb header and linear data
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (137 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 138/877] Bluetooth: RFCOMM: avoid socket lock inversion in listener cleanup Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 140/877] drop_monitor: synchronize tracepoint unregistration on error path Greg Kroah-Hartman
                   ` (745 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Simon Horman,
	Jakub Kicinski, Sasha Levin

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

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

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit ecc7253683a3c55caa868ce0ee530fcb0044bd3c ]

In pppoatm_send(), LLC encapsulation checks whether there is sufficient
headroom for the 4-byte LLC header, but does not ensure that the skb header
is writable.

Normal transmit packets passing through ppp_start_xmit() have their header
unshared via skb_cow_head(). However, packets can also reach pppoatm_send()
via PPP channel bridging (PPPIOCBRIDGECHAN) without going through
ppp_start_xmit().

Use skb_cow_head() to ensure both sufficient headroom and a writable
header before pushing the LLC header.

While at it:
- Call pskb_may_pull(skb, 1) before inspecting skb->data[0] to prevent
  out-of-bounds reads on zero-length or non-linear frames (e.g. from
  bridging).
- Defer SC_COMP_PROT protocol compression until after pppoatm_may_send()
  succeeds. This eliminates the temporary skb allocation on admission failure
  and completely removes the fragile "undo" heuristic at the nospace label,
  avoiding any risk of reading uninitialized headroom or performing an
  unbalanced skb_push().

Fixes: 4cf476ced45d ("ppp: add PPPIOCBRIDGECHAN and PPPIOCUNBRIDGECHAN ioctls")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260912233048.3977192-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/atm/pppoatm.c | 42 +++++++++++++++++-------------------------
 1 file changed, 17 insertions(+), 25 deletions(-)

diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c
index 3e4f17d335feb..b668a30b67a8d 100644
--- a/net/atm/pppoatm.c
+++ b/net/atm/pppoatm.c
@@ -292,10 +292,13 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
 	struct atm_vcc *vcc;
 	int ret;
 
+	if (!pskb_may_pull(skb, 1)) {
+		kfree_skb(skb);
+		return DROP_PACKET;
+	}
+
 	ATM_SKB(skb)->vcc = pvcc->atmvcc;
 	pr_debug("(skb=0x%p, vcc=0x%p)\n", skb, pvcc->atmvcc);
-	if (skb->data[0] == '\0' && (pvcc->flags & SC_COMP_PROT))
-		(void) skb_pull(skb, 1);
 
 	vcc = ATM_SKB(skb)->vcc;
 	bh_lock_sock(sk_atm(vcc));
@@ -318,23 +321,13 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
 
 	switch (pvcc->encaps) {		/* LLC encapsulation needed */
 	case e_llc:
-		if (skb_headroom(skb) < LLC_LEN) {
-			struct sk_buff *n;
-			n = skb_realloc_headroom(skb, LLC_LEN);
-			if (n != NULL &&
-			    !pppoatm_may_send(pvcc, n->truesize)) {
-				kfree_skb(n);
-				goto nospace;
-			}
-			consume_skb(skb);
-			skb = n;
-			if (skb == NULL) {
-				bh_unlock_sock(sk_atm(vcc));
-				return DROP_PACKET;
-			}
-		} else if (!pppoatm_may_send(pvcc, skb->truesize))
+		if (skb_cow_head(skb, LLC_LEN)) {
+			bh_unlock_sock(sk_atm(vcc));
+			kfree_skb(skb);
+			return DROP_PACKET;
+		}
+		if (!pppoatm_may_send(pvcc, skb->truesize))
 			goto nospace;
-		memcpy(skb_push(skb, LLC_LEN), pppllc, LLC_LEN);
 		break;
 	case e_vc:
 		if (!pppoatm_may_send(pvcc, skb->truesize))
@@ -347,6 +340,12 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
 		return 1;
 	}
 
+	if (skb->data[0] == '\0' && (pvcc->flags & SC_COMP_PROT))
+		skb_pull(skb, 1);
+
+	if (pvcc->encaps == e_llc)
+		memcpy(skb_push(skb, LLC_LEN), pppllc, LLC_LEN);
+
 	atm_account_tx(vcc, skb);
 	pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n",
 		 skb, ATM_SKB(skb)->vcc, ATM_SKB(skb)->vcc->dev);
@@ -356,13 +355,6 @@ static int pppoatm_send(struct ppp_channel *chan, struct sk_buff *skb)
 	return ret;
 nospace:
 	bh_unlock_sock(sk_atm(vcc));
-	/*
-	 * We don't have space to send this SKB now, but we might have
-	 * already applied SC_COMP_PROT compression, so may need to undo
-	 */
-	if ((pvcc->flags & SC_COMP_PROT) && skb_headroom(skb) > 0 &&
-	    skb->data[-1] == '\0')
-		(void) skb_push(skb, 1);
 	return 0;
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 140/877] drop_monitor: synchronize tracepoint unregistration on error path
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (138 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 139/877] pppoatm: ensure a writable skb header and linear data Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 141/877] drop_monitor: fix out-of-bounds write in reset_per_cpu_data() Greg Kroah-Hartman
                   ` (744 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Hangbin Liu,
	Jakub Kicinski, Sasha Levin

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

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

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit 6a038ef2b57922b6d9ca98ddac0df0681849b704 ]

If register_trace_napi_poll() fails in net_dm_trace_on_set(),
unregister_trace_kfree_skb() is called to roll back the kfree_skb
tracepoint registration.

However, tracepoint_synchronize_unregister() is omitted before calling
cancel_work_sync() and module_put(). An in-flight probe executing
concurrently on another CPU could call schedule_work() after
cancel_work_sync() has already returned, leaving a pending work item
scheduled after the module reference is dropped. If the module is then
unloaded, executing the work item triggers a kernel panic.

Add tracepoint_synchronize_unregister() after unregister_trace_kfree_skb()
in the error path, matching net_dm_trace_off_set() and
net_dm_hw_probe_unregister().

Fixes: 7c747838a558 ("drop_monitor: Split tracing enable / disable to different functions")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260910204612.3762015-2-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/drop_monitor.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 308e0fa8f723f..a9c604ef2c826 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -1174,6 +1174,7 @@ static int net_dm_trace_on_set(struct netlink_ext_ack *extack)
 
 err_unregister_trace:
 	unregister_trace_kfree_skb(ops->kfree_skb_probe, NULL);
+	tracepoint_synchronize_unregister();
 err_module_put:
 	for_each_possible_cpu(cpu) {
 		struct per_cpu_dm_data *data = &per_cpu(dm_cpu_data, cpu);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 141/877] drop_monitor: fix out-of-bounds write in reset_per_cpu_data()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (139 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 140/877] drop_monitor: synchronize tracepoint unregistration on error path Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 142/877] net: stmmac: do not overwrite phc_index when no PTP clock is registered Greg Kroah-Hartman
                   ` (743 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Hangbin Liu,
	Jakub Kicinski, Sasha Levin

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

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

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit 439f392084f8f7f59ab9d47a9579185accefe1d8 ]

In reset_per_cpu_data(), al is computed as:

    al = sizeof(struct net_dm_alert_msg);
    al += dm_hit_limit * sizeof(struct net_dm_drop_point);
    al += sizeof(struct nlattr);

    skb = genlmsg_new(al, GFP_KERNEL);
    ...
    nla = nla_reserve(skb, NLA_UNSPEC, sizeof(struct net_dm_alert_msg));
    ...
    msg = nla_data(nla);
    memset(msg, 0, al);

Because al includes sizeof(struct nlattr) (the 4-byte attribute header),
genlmsg_new() allocates al bytes of tailroom starting at nla.
However, msg points to nla_data(nla), which is located
sizeof(struct nlattr) bytes past nla. Calling memset(msg, 0, al)
therefore writes al bytes starting from msg, exceeding the allocated
buffer by sizeof(struct nlattr) (4 bytes) and corrupting
skb_shared_info.

Fix this by letting al represent only the payload length, allocating
the skb with genlmsg_new(nla_total_size(al), GFP_KERNEL), and zeroing
al bytes from msg.

Fixes: 683703a26e46 ("drop_monitor: Update netlink protocol to include netlink attribute header in alert message")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260910204612.3762015-5-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/drop_monitor.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index a9c604ef2c826..1ba281bef21e3 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -141,9 +141,8 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data)
 
 	al = sizeof(struct net_dm_alert_msg);
 	al += dm_hit_limit * sizeof(struct net_dm_drop_point);
-	al += sizeof(struct nlattr);
 
-	skb = genlmsg_new(al, GFP_KERNEL);
+	skb = genlmsg_new(nla_total_size(al), GFP_KERNEL);
 
 	if (!skb)
 		goto err;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 142/877] net: stmmac: do not overwrite phc_index when no PTP clock is registered
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (140 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 141/877] drop_monitor: fix out-of-bounds write in reset_per_cpu_data() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 143/877] KVM: PPC: Book3S HV: fix use-after-free in kvmhv_emulate_tlbie_all_lpid() Greg Kroah-Hartman
                   ` (742 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Maxime Chevallier, Rahul Rameshbabu,
	Lorenzo Bianconi, Gal Pressman, Jakub Kicinski, Sasha Levin

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

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

From: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>

[ Upstream commit f0ef4b1eaed000a304726a43091588e8426ba08a ]

stmmac_get_ts_info() reports phc_index as 0 when hardware timestamping
is supported but no PTP clock has been registered yet (e.g. while the
interface is down). Zero is a valid PHC index and would make userspace
resolve the wrong clock; the absence of a clock should be reported as
-1.

The ethtool core already initializes phc_index to -1 before invoking
the get_ts_info callback (ethtool_init_tsinfo()), so just drop the
erroneous assignment.

Fixes: 9364fa7fcf12 ("net: stmmac: Remove setting of RX software timestamp")
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Reviewed-by: Gal Pressman <gal@nvidia.com>
Link: https://patch.msgid.link/20260914-stmmac-fix-phc_index-v2-1-bf3d90373fe4@oss.qualcomm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index 2a37592a62810..ca8712a573ea0 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -1206,8 +1206,6 @@ static int stmmac_get_ts_info(struct net_device *dev,
 
 		if (priv->ptp_clock)
 			info->phc_index = ptp_clock_index(priv->ptp_clock);
-		else
-			info->phc_index = 0;
 
 		info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 143/877] KVM: PPC: Book3S HV: fix use-after-free in kvmhv_emulate_tlbie_all_lpid()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (141 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 142/877] net: stmmac: do not overwrite phc_index when no PTP clock is registered Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 144/877] KVM: PPC: Book3S HV: fix secure device page leak on uv_page_in() failure Greg Kroah-Hartman
                   ` (741 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ritesh Harjani (IBM),
	R Nageswara Sastry, Amit Machhiwal, Gautam Menghani,
	Madhavan Srinivasan, Sasha Levin

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

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

From: Amit Machhiwal <amachhiw@linux.ibm.com>

[ Upstream commit 51938dfa8a51a4f85328413fca9b6e21f9d2d088 ]

kvmhv_emulate_tlbie_all_lpid() iterates the nested-guest IDR and drops
mmu_lock before calling kvmhv_emulate_tlbie_lpid(), but does not hold a
reference on the kvm_nested_guest pointer obtained from the IDR.  A
concurrent vCPU issuing a single-LPID tlbie (is=2, ric=2) can race
through kvmhv_flush_nested() -> kvmhv_remove_nested() -> idr_remove /
--refcnt -> kvmhv_release_nested() -> kfree(gp) in that window, leaving
the iterating vCPU with a dangling pointer.  The subsequent
mutex_lock(&gp->tlb_lock) and accesses to gp->shadow_pgtable,
gp->shadow_lpid and gp->l1_host all touch freed memory.  The free path
is fully L1-controlled.

Fix this by incrementing gp->refcnt inside the loop before dropping
mmu_lock, mirroring what kvmhv_get_nested() does, and releasing the
reference with kvmhv_put_nested() after the per-guest work completes.
This is the same get/put discipline already used at every other
call site that drops mmu_lock while holding a nested-guest pointer.

Fixes: e3b6b4661527 ("KVM: PPC: Book3S HV: Implement H_TLB_INVALIDATE hcall")
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>
Signed-off-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Signed-off-by: Gautam Menghani <gautam@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/powerpc/kvm/book3s_hv_nested.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c
index 125440a606ee3..a4dd8d983ec76 100644
--- a/arch/powerpc/kvm/book3s_hv_nested.c
+++ b/arch/powerpc/kvm/book3s_hv_nested.c
@@ -1202,8 +1202,10 @@ static void kvmhv_emulate_tlbie_all_lpid(struct kvm_vcpu *vcpu, int ric)
 
 	spin_lock(&kvm->mmu_lock);
 	idr_for_each_entry(&kvm->arch.kvm_nested_guest_idr, gp, lpid) {
+		++gp->refcnt;
 		spin_unlock(&kvm->mmu_lock);
 		kvmhv_emulate_tlbie_lpid(vcpu, gp, ric);
+		kvmhv_put_nested(gp);
 		spin_lock(&kvm->mmu_lock);
 	}
 	spin_unlock(&kvm->mmu_lock);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 144/877] KVM: PPC: Book3S HV: fix secure device page leak on uv_page_in() failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (142 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 143/877] KVM: PPC: Book3S HV: fix use-after-free in kvmhv_emulate_tlbie_all_lpid() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 145/877] powerpc/iommu: Fix the overflow validation in iommu_tce_check_ioba Greg Kroah-Hartman
                   ` (740 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ritesh Harjani (IBM),
	R Nageswara Sastry, Amit Machhiwal, Gautam Menghani,
	Madhavan Srinivasan, Sasha Levin

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

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

From: Amit Machhiwal <amachhiw@linux.ibm.com>

[ Upstream commit 0a416ee20bcccddf91ca5b63696a23b9d11d73aa ]

In kvmppc_svm_page_in(), if uv_page_in() fails after
kvmppc_uvmem_get_page() has succeeded, the secure device page is never
released.  kvmppc_uvmem_get_page() sets a bit in kvmppc_uvmem_bitmap,
allocates a kvmppc_uvmem_page_pvt struct, marks the GFN as
KVMPPC_GFN_UVMEM_PFN, and calls zone_device_page_init() which sets
refcount=1 and locks the page.  The subsequent goto out_finalize skips
the *mig.dst assignment, so migrate_vma_finalize() is a no-op for the
page, and none of those resources are ever reclaimed.

Each occurrence permanently consumes one entry from the firmware-bounded
secure memory pool (kvmppc_uvmem_bitmap), leaks pvt, and leaves the GFN
marked as secure — making it unusable for the lifetime of the VM.

The twin __kvmppc_svm_page_out() already handles the analogous uv_page_out()
failure correctly with unlock_page(dpage); __free_page(dpage).  Apply
the same pattern here: unlock_page() followed by put_page(), which
chains through free_zone_device_folio() into kvmppc_uvmem_folio_free()
to clear the bitmap bit, free pvt, and reset the GFN state.

Reachable whenever uv_page_in() returns an error (e.g. UV pool
exhaustion) on any POWER9/10 + Ultravisor/PEF system.

Fixes: ca9f4942670c ("KVM: PPC: Book3S HV: Support for running secure guests")
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>
Signed-off-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Signed-off-by: Gautam Menghani <gautam@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/powerpc/kvm/book3s_hv_uvmem.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c b/arch/powerpc/kvm/book3s_hv_uvmem.c
index 92f33115144b2..7ea0c58622274 100644
--- a/arch/powerpc/kvm/book3s_hv_uvmem.c
+++ b/arch/powerpc/kvm/book3s_hv_uvmem.c
@@ -779,8 +779,11 @@ static int kvmppc_svm_page_in(struct vm_area_struct *vma,
 		if (spage) {
 			ret = uv_page_in(kvm->arch.lpid, pfn << page_shift,
 					gpa, 0, page_shift);
-			if (ret)
+			if (ret) {
+				unlock_page(dpage);
+				put_page(dpage);
 				goto out_finalize;
+			}
 		}
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 145/877] powerpc/iommu: Fix the overflow validation in iommu_tce_check_ioba
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (143 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 144/877] KVM: PPC: Book3S HV: fix secure device page leak on uv_page_in() failure Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 146/877] ASoC: ux500: Parenthesize MSP_{RX,TX}_CLKPOL_BIT() arguments Greg Kroah-Hartman
                   ` (739 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ritesh Harjani (IBM),
	R Nageswara Sastry, Shivaprasad G Bhat, Gautam Menghani,
	Madhavan Srinivasan, Sasha Levin

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

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

From: Shivaprasad G Bhat <sbhat@linux.ibm.com>

[ Upstream commit 0b271f7d7f5ed45bc498a03ce0aa9cfd8402fc71 ]

The commit b1af23d836f8 ("KVM: PPC: iommu: Unify TCE checking") unified
IOBA parameter checking across KVM and VFIO into iommu_tce_check_ioba().
While doing so, the passed in argument npages is ignored and constant
value '1' is used leaving out a possible overflow as the callers can
legitimately be using npages > 1 for H_STUFF_TCE or H_PUT_TCE_INDIRECT
cases.

Fix this by accounting for 'npages', checking for arithmetic overflow,
and verifying that the entire requested range (ioba - offset + npages)
does not exceed the table capacity 'size'.

Fixes: b1af23d836f8 ("KVM: PPC: iommu: Unify TCE checking")
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>
Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Signed-off-by: Gautam Menghani <gautam@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/powerpc/kernel/iommu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 0ebae6e4c19dd..50c180cd1fa31 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -1074,7 +1074,7 @@ int iommu_tce_check_ioba(unsigned long page_shift,
 	if (ioba < offset)
 		return -EINVAL;
 
-	if ((ioba + 1) > (offset + size))
+	if ((ioba + npages < ioba) || (ioba - offset + npages > size))
 		return -EINVAL;
 
 	return 0;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 146/877] ASoC: ux500: Parenthesize MSP_{RX,TX}_CLKPOL_BIT() arguments
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (144 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 145/877] powerpc/iommu: Fix the overflow validation in iommu_tce_check_ioba Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 147/877] ASoC: hdmi-codec: Report a change when the channel status moves Greg Kroah-Hartman
                   ` (738 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, kernel test robot, Sasha Levin,
	Linus Walleij, Mark Brown

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

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

[ Upstream commit 11fc0048a6930f4fca44fe3bd16a0023e78846a2 ]

arm allmodconfig fails to build with gcc:

  In file included from sound/soc/ux500/ux500_msp_i2s.c:20:
  sound/soc/ux500/ux500_msp_i2s.h:151:38: error: suggest parentheses
  around arithmetic in operand of '^' [-Werror=parentheses]
  sound/soc/ux500/ux500_msp_i2s.c:204:21: note: in expansion of macro
  'MSP_TX_CLKPOL_BIT'
  cc1: all warnings being treated as errors

The macros never parenthesized their argument:

  #define MSP_TX_CLKPOL_BIT(n)  ((n & TCKPOL_MASK) << TCKPOL_SHIFT)

That went unnoticed while every caller passed a plain variable, but
configure_protocol() now passes an XOR expression, which binds as
"a ^ (b & MASK)" rather than "(a ^ b) & MASK", and gcc rightly
complains.

No functional change: tx_clk_pol and rx_clk_pol only ever hold
MSP_FALLING_EDGE (0) or MSP_RISING_EDGE (1), and bclk_inverted is a
bool, so masking before or after the XOR gives the same 0/1 result.
Parenthesize the argument anyway - it fixes the build and stops the
macros from silently mis-evaluating a future composite argument.

Fixes: 9ccbacf5a012 ("ASoC: ux500: Validate MSP DAI configuration")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202609051547.G9SJp8UQ-lkp@intel.com/
Assisted-by: LLM
Signed-off-by: Sasha Levin <sashal@kernel.org>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260913173132.1172003-1-sashal@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/soc/ux500/ux500_msp_i2s.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h
index 2bf2699bdc49f..c66ef455e1380 100644
--- a/sound/soc/ux500/ux500_msp_i2s.h
+++ b/sound/soc/ux500/ux500_msp_i2s.h
@@ -147,8 +147,8 @@ enum msp_direction {
 #define RCKPOL_MASK		BIT(0)
 #define TCKPOL_MASK		BIT(0)
 #define SPICKM_MASK		(BIT(1) | BIT(0))
-#define MSP_RX_CLKPOL_BIT(n)     ((n & RCKPOL_MASK) << RCKPOL_SHIFT)
-#define MSP_TX_CLKPOL_BIT(n)     ((n & TCKPOL_MASK) << TCKPOL_SHIFT)
+#define MSP_RX_CLKPOL_BIT(n)     (((n) & RCKPOL_MASK) << RCKPOL_SHIFT)
+#define MSP_TX_CLKPOL_BIT(n)     (((n) & TCKPOL_MASK) << TCKPOL_SHIFT)
 
 #define P1ELEN_SHIFT		0
 #define P1FLEN_SHIFT		3
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 147/877] ASoC: hdmi-codec: Report a change when the channel status moves
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (145 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 146/877] ASoC: ux500: Parenthesize MSP_{RX,TX}_CLKPOL_BIT() arguments Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 148/877] net: netsec: fix device_node reference leak on phy_np Greg Kroah-Hartman
                   ` (737 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, HyeongJun An, Mark Brown,
	Sasha Levin

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

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

From: HyeongJun An <sammiee5311@gmail.com>

[ Upstream commit c17ae8c26eac16ad244daef44044d714f68a2ddc ]

The put() callback of "IEC958 Playback Default" stores all 24 channel
status bytes and then returns 0. The core notifies userspace only on a
positive return, so a write that changes what the get() callback hands
back is never announced, and a mixer holding the control open keeps
showing the old value.

Compare the stored bytes and return 1 when they move, the way
snd_hda_spdif_default_put() does.

The same shape is in img-spdif-out and uniperif_player.

No board with this codec was to hand. The change is a comparison of
driver state with no hardware behaviour in it, and mixer-test counts the
missing notification as event_missing.

Fixes: 7a8e1d44211e ("ASoC: hdmi-codec: Add iec958 controls")
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Assisted-by: Claude:claude-opus-5
Link: https://patch.msgid.link/20260915092515.2638542-1-sammiee5311@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/soc/codecs/hdmi-codec.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c
index d9df29a26f4f2..0ffc649c6ad21 100644
--- a/sound/soc/codecs/hdmi-codec.c
+++ b/sound/soc/codecs/hdmi-codec.c
@@ -423,10 +423,14 @@ static int hdmi_codec_iec958_default_put(struct snd_kcontrol *kcontrol,
 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 	struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
 
+	if (!memcmp(hcp->iec_status, ucontrol->value.iec958.status,
+		    sizeof(hcp->iec_status)))
+		return 0;
+
 	memcpy(hcp->iec_status, ucontrol->value.iec958.status,
 	       sizeof(hcp->iec_status));
 
-	return 0;
+	return 1;
 }
 
 static int hdmi_codec_iec958_mask_get(struct snd_kcontrol *kcontrol,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 148/877] net: netsec: fix device_node reference leak on phy_np
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (146 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 147/877] ASoC: hdmi-codec: Report a change when the channel status moves Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 149/877] net: lock the socket in sock_gettstamp() Greg Kroah-Hartman
                   ` (736 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yige Jiang, Simon Horman,
	Jakub Kicinski, Sasha Levin

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

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

From: Yige Jiang <yigejiang86@gmail.com>

[ Upstream commit 5ae916fabca141b79b32e2e57f3c915c0f1e1b2e ]

netsec_of_probe() takes a reference on the PHY device_node with
of_parse_phandle() and stores it in priv->phy_np, but the driver never
drops it.  One device_node reference is leaked per probe, on the success
path as well as on every error path reached after netsec_of_probe().

Neither consumer takes ownership.  of_mdio_parse_addr() is a static
inline taking a const struct device_node * that only reads the "reg"
property.  of_phy_connect() borrows as well: of_phy_get_and_connect() in
drivers/net/mdio/of_mdio.c brackets its own call with of_node_get() at
:364 and of_node_put() at :373, which would be a double put if
of_phy_connect() consumed the reference.

The node is still in use at netsec_netdev_open() time, where it is
passed to of_phy_connect(), so it has device lifetime.  Release it at
the probe error label, which every failure path after the acquire
funnels through, and in netsec_remove().  Both releases precede
free_netdev(), since priv is netdev_priv(ndev).  The ACPI probe path
leaves priv->phy_np NULL and of_node_put(NULL) is a no-op.

There is no end-user visible symptom on currently supported platforms:
a device_node is only freed once OF_DYNAMIC is enabled and the node has
been detached, so on a static device tree the imbalance is inert.  It is
observable as a refcount that grows across bind/unbind cycles, and would
matter under device tree overlays.

Found by static analysis of reference acquire/release pairing rather
than from a runtime report.  No reproducer was produced and the change
has not been runtime tested; it is compile-tested only (arm64,
CONFIG_SNI_NETSEC=m via COMPILE_TEST).

Fixes: 533dd11a12f6 ("net: socionext: Add Synquacer NetSec driver")
Signed-off-by: Yige Jiang <yigejiang86@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260913064102.37452-1-yigejiang86@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/socionext/netsec.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c
index 5ab8b81b84e6f..e96e22dd30808 100644
--- a/drivers/net/ethernet/socionext/netsec.c
+++ b/drivers/net/ethernet/socionext/netsec.c
@@ -2146,6 +2146,7 @@ static int netsec_probe(struct platform_device *pdev)
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 free_ndev:
+	of_node_put(priv->phy_np);
 	free_netdev(ndev);
 	dev_err(&pdev->dev, "init failed\n");
 
@@ -2163,6 +2164,7 @@ static void netsec_remove(struct platform_device *pdev)
 	netif_napi_del(&priv->napi);
 
 	pm_runtime_disable(&pdev->dev);
+	of_node_put(priv->phy_np);
 	free_netdev(priv->ndev);
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 149/877] net: lock the socket in sock_gettstamp()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (147 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 148/877] net: netsec: fix device_node reference leak on phy_np Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 150/877] net: ethernet: cortina: Ack RX overrun interrupt correctly Greg Kroah-Hartman
                   ` (735 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jungwoo Lee, Wongi Lee, Eric Dumazet,
	Simon Horman, Jakub Kicinski, Sasha Levin

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

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

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit 9ed55f3dbef4f4adfe65eb03b0c35c53229a8490 ]

sk->sk_flags must only be changed while holding the socket lock,
because sock_set_flag() and sock_reset_flag() use non atomic
operations (__set_bit() and __clear_bit()).

sock_gettstamp() is one of the last places where a bit of sk->sk_flags
is changed from a syscall without owning the socket lock, through
sock_enable_timestamp(sk, SOCK_TIMESTAMP).

sk_set_memalloc() and sk_clear_memalloc() also change sk->sk_flags
without the socket lock, but their callers (nbd, iscsi_tcp, nvme-tcp,
sunrpc, wireguard) need a careful audit, this will be addressed in a
separate patch.

Jungwoo Lee and Wongi Lee reported an UDP socket use-after-free
caused by this bug: a SIOCGSTAMPNS_NEW ioctl racing with bind()
can cancel the SOCK_RCU_FREE bit that udp_lib_get_port() just set,
because both threads perform a read-modify-write on the same word.

  CPU 0 (bind)                        CPU 1 (SIOCGSTAMPNS_NEW)
  --------------------------------    ----------------------------
  read sk_flags = F                   read sk_flags = F
  compute F | BIT(SOCK_RCU_FREE)      compute F | BIT(SOCK_TIMESTAMP)
  store F | BIT(SOCK_RCU_FREE)
  sk_add_node_rcu(sk, ...)
                                      store F | BIT(SOCK_TIMESTAMP)

After the lost update, SOCK_RCU_FREE is clear while the socket is
visible to lockless UDP receive lookups. sk_destruct() then frees
the socket immediately instead of waiting for a RCU grace period,
while the receive path still holds a reference-less pointer to it:

 BUG: KASAN: slab-use-after-free in ipv4_pktinfo_prepare+0x30/0x410
 Read of size 8 at addr ffff888008806610 by task exploit/207
 CPU: 0 UID: 1000 PID: 207 Comm: exploit Not tainted 6.12.95+ #1
  ipv4_pktinfo_prepare+0x30/0x410
  udp_queue_rcv_one_skb+0x51c/0x1180
  udp_unicast_rcv_skb+0x109/0x350
  ip_protocol_deliver_rcu+0x14b/0x310
  ip_local_deliver_finish+0x29d/0x390
  ip_local_deliver+0x24d/0x2a0

Only grab the socket lock when SOCK_TIMESTAMP has to be set,
to keep the common case lockless.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Jungwoo Lee <jwlee2217@gmail.com>
Reported-by: Wongi Lee <qw3rtyp0@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260915043055.3441600-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/sock.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/net/core/sock.c b/net/core/sock.c
index e8b03cf3a428c..08b3569ac7a18 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3724,7 +3724,14 @@ int sock_gettstamp(struct socket *sock, void __user *userstamp,
 	struct sock *sk = sock->sk;
 	struct timespec64 ts;
 
-	sock_enable_timestamp(sk, SOCK_TIMESTAMP);
+	/* sk->sk_flags must only be changed under the socket lock,
+	 * because sock_set_flag() uses non atomic operations.
+	 */
+	if (!sock_flag(sk, SOCK_TIMESTAMP)) {
+		lock_sock(sk);
+		sock_enable_timestamp(sk, SOCK_TIMESTAMP);
+		release_sock(sk);
+	}
 	ts = ktime_to_timespec64(sock_read_timestamp(sk));
 	if (ts.tv_sec == -1)
 		return -ENOENT;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 150/877] net: ethernet: cortina: Ack RX overrun interrupt correctly
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (148 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 149/877] net: lock the socket in sock_gettstamp() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 151/877] net: stmmac: propagate FPE preemption-class mapping errors Greg Kroah-Hartman
                   ` (734 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Linus Walleij, Jakub Kicinski,
	Sasha Levin

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

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

From: Linus Walleij <linusw@kernel.org>

[ Upstream commit 1dd85662fee6e2ac580b1c4f9a0c0a7ae6e31f0e ]

The RX overrun interrupt is reported in interrupt status register 4, but
gmac_irq() acknowledges it using the RX descriptor error bit from status
register 0. For GMAC0 this writes the GMAC1 overrun bit, while for GMAC1
the shift leaves no bit in the 32-bit register.

Acknowledge the same per-port RX overrun bit that was detected.

Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet")
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260914-b4-gemini-ethernet-fixes-2-v2-1-5ab39a047b90@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/cortina/gemini.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 96fd27545b29b..1b81798914acc 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -1798,7 +1798,7 @@ static irqreturn_t gmac_irq(int irq, void *data)
 
 	if (val & (GMAC0_RX_OVERRUN_INT_BIT << (netdev->dev_id * 8))) {
 		spin_lock(&geth->irq_lock);
-		writel(GMAC0_RXDERR_INT_BIT << (netdev->dev_id * 8),
+		writel(GMAC0_RX_OVERRUN_INT_BIT << (netdev->dev_id * 8),
 		       geth->base + GLOBAL_INTERRUPT_STATUS_4_REG);
 		u64_stats_update_begin(&port->ir_stats_syncp);
 		++port->stats.rx_fifo_errors;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 151/877] net: stmmac: propagate FPE preemption-class mapping errors
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (149 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 150/877] net: ethernet: cortina: Ack RX overrun interrupt correctly Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 152/877] net: macb: fix ordering around PTP timestamp read Greg Kroah-Hartman
                   ` (733 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Lorenzo Bianconi, Jakub Kicinski,
	Sasha Levin

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

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

From: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>

[ Upstream commit 90e4b849dfa6fc8e6c050bcfe1b331b69c015d28 ]

stmmac_fpe_map_preemption_class() dispatches through the
stmmac_do_void_callback() helper, which forces the callback's return
value to 0 whenever the op pointer is populated. As a result the
-EINVAL returned by dwmac5_fpe_map_preemption_class() (e.g. when a
preemptible TC owns more than one TXQ under SP scheduling) is silently
swallowed by every caller.

Switch the dispatch macro to stmmac_do_callback() so the callback's real
result is propagated, and honour it in the taprio and mqprio qdisc
offload.

Note that the taprio "if (ret)" check in tc_taprio_configure() used to
be dead code and now becomes live: a preemptible TC spanning more than
one TXQ under SP scheduling cannot be programmed in hardware, so a
taprio or mqprio configuration that previously returned success while
leaving the preemption-class register unprogrammed now fails with
-EINVAL. For taprio, the failure also runs the disable path, tearing
down the schedule that was just installed; this is the intended
behaviour.

Fixes: 195e4f409a40 ("net: stmmac: support fp parameter of tc-mqprio")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Link: https://patch.msgid.link/20260911-stmmac-tc_setup_dwmac510_mqprio-error-path-v3-1-a76b1e2547c1@oss.qualcomm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/stmicro/stmmac/hwif.h    |  2 +-
 .../net/ethernet/stmicro/stmmac/stmmac_tc.c   | 19 +++++++++----------
 2 files changed, 10 insertions(+), 11 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index d5a9f01ecac53..31d7f9375d747 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -541,7 +541,7 @@ struct stmmac_ops {
 #define stmmac_fpe_set_add_frag_size(__priv, __args...) \
 	stmmac_do_void_callback(__priv, mac, fpe_set_add_frag_size, __args)
 #define stmmac_fpe_map_preemption_class(__priv, __args...) \
-	stmmac_do_void_callback(__priv, mac, fpe_map_preemption_class, __args)
+	stmmac_do_callback(__priv, mac, fpe_map_preemption_class, __args)
 
 /* PTP and HW Timer helpers */
 struct stmmac_hwtimestamp {
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
index 49f133dec810d..65085f9c9290e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
@@ -970,7 +970,7 @@ static int tc_taprio_configure(struct stmmac_priv *priv,
 	struct netlink_ext_ack *extack = qopt->mqprio.extack;
 	struct timespec64 time, current_time, qopt_time;
 	ktime_t current_time_ns;
-	int i, ret = 0;
+	int err, i, ret = 0;
 	u64 ctr;
 
 	if (qopt->base_time < 0)
@@ -1119,9 +1119,9 @@ static int tc_taprio_configure(struct stmmac_priv *priv,
 		mutex_unlock(&priv->est_lock);
 	}
 
-	stmmac_fpe_map_preemption_class(priv, priv->dev, extack, 0);
+	err = stmmac_fpe_map_preemption_class(priv, priv->dev, extack, 0);
 
-	return ret;
+	return qopt->cmd == TAPRIO_CMD_DESTROY ? err : ret;
 }
 
 static void tc_taprio_stats(struct stmmac_priv *priv,
@@ -1234,14 +1234,15 @@ static int tc_query_caps(struct stmmac_priv *priv,
 	}
 }
 
-static void stmmac_reset_tc_mqprio(struct net_device *ndev,
-				   struct netlink_ext_ack *extack)
+static int stmmac_reset_tc_mqprio(struct net_device *ndev,
+				  struct netlink_ext_ack *extack)
 {
 	struct stmmac_priv *priv = netdev_priv(ndev);
 
 	netdev_reset_tc(ndev);
 	netif_set_real_num_tx_queues(ndev, priv->plat->tx_queues_to_use);
-	stmmac_fpe_map_preemption_class(priv, ndev, extack, 0);
+
+	return stmmac_fpe_map_preemption_class(priv, ndev, extack, 0);
 }
 
 static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,
@@ -1254,10 +1255,8 @@ static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,
 	u32 num_tc = qopt->num_tc;
 	int err;
 
-	if (!num_tc) {
-		stmmac_reset_tc_mqprio(ndev, extack);
-		return 0;
-	}
+	if (!num_tc)
+		return stmmac_reset_tc_mqprio(ndev, extack);
 
 	err = netdev_set_num_tc(ndev, num_tc);
 	if (err)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 152/877] net: macb: fix ordering around PTP timestamp read
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (150 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 151/877] net: stmmac: propagate FPE preemption-class mapping errors Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 153/877] net: mvpp2: prevent buffer overflow in page_pool allocation Greg Kroah-Hartman
                   ` (732 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Théo Lebrun,
	James Clark, Paolo Abeni, Sasha Levin

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

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

From: James Clark <jjc@jclark.com>

[ Upstream commit 9ca4ba24259183ce15665be86b2956cd896c4687 ]

PTP_SYS_OFFSET_EXTENDED returns system timestamps that do not correctly
bracket the PHC register read on MACB/GEM. On a Raspberry Pi 5, the
returned interval can be as short as 37 ns, while an ordered register
read takes approximately 1 us. This biases the midpoint used by phc2sys,
causing CLOCK_REALTIME to run approximately 0.5 us ahead when synchronized
to the PHC.

gem_tsu_get_time() reads the nanoseconds register using the driver's
relaxed MMIO accessor. On weakly ordered systems, the subsequent system
timestamp can be taken before the register read completes. The internal
smp_rmb() in the pre-timestamp path also does not guarantee ordering
against the subsequent MMIO read.

Add rmb() before and after the bracketed nanoseconds read in both the
normal and seconds rollover paths so the system timestamps bracket the
PHC read. Adding the post-read barrier increases the minimum interval on
the same Raspberry Pi 5 to approximately 1 us.

Fixes: e51bb5c2784c ("net: macb: ptp: Switch to gettimex64() interface")
Tested-by: Nicolai Buchwitz <nb@tipi-net.de> # Raspberry Pi CM5, min bracket 37 ns -> 981 ns
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Reviewed-by: Théo Lebrun <theo.lebrun@bootlin.com>
Assisted-by: LLM
Signed-off-by: James Clark <jjc@jclark.com>
Link: https://patch.msgid.link/20260915045823.76100-1-jjc@jclark.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/cadence/macb_ptp.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c
index f2b09100f710e..004c0b3b9181c 100644
--- a/drivers/net/ethernet/cadence/macb_ptp.c
+++ b/drivers/net/ethernet/cadence/macb_ptp.c
@@ -48,7 +48,12 @@ static int gem_tsu_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts,
 
 	spin_lock_irqsave(&bp->tsu_clk_lock, flags);
 	ptp_read_system_prets(sts);
+	/* explicit barriers are needed because gem_readl() is relaxed */
+	if (sts)
+		rmb();
 	first = gem_readl(bp, TN);
+	if (sts)
+		rmb();
 	ptp_read_system_postts(sts);
 	secl = gem_readl(bp, TSL);
 	sech = gem_readl(bp, TSH);
@@ -60,7 +65,11 @@ static int gem_tsu_get_time(struct ptp_clock_info *ptp, struct timespec64 *ts,
 		 * (assume all done within 1s)
 		 */
 		ptp_read_system_prets(sts);
+		if (sts)
+			rmb();
 		ts->tv_nsec = gem_readl(bp, TN);
+		if (sts)
+			rmb();
 		ptp_read_system_postts(sts);
 		secl = gem_readl(bp, TSL);
 		sech = gem_readl(bp, TSH);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 153/877] net: mvpp2: prevent buffer overflow in page_pool allocation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (151 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 152/877] net: macb: fix ordering around PTP timestamp read Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 154/877] net: skbuff: do not leave stale header offsets after pskb_carve() Greg Kroah-Hartman
                   ` (731 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Dmitriy Okunev, Paolo Abeni,
	Sasha Levin

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

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

From: Dmitriy Okunev <dokunevdmitriy@gmail.com>

[ Upstream commit 14cb1e7702e5cb3c58888f6aed498381a73927d2 ]

The per‑processor buffering scheme is supported only if the
number of pools (nrxqs * 2) does not exceed MVPP2_BM_MAX_POOLS (8).
This is already checked in mvpp2_probe() during the initial
activation of percpu_pools.

However, mvpp2_change_mtu() may later call
mvpp2_bm_switch_buffers(priv, true) without this check, which can
lead to an out-of-bounds access in the priv->page_pool array in
mvpp2_bm_init(). The array is sized to hold MVPP2_PORT_MAX_RXQ
entries, and mvpp2_get_nrxqs() may return exactly that value. The
per-CPU scheme then doubles it to nrxqs * 2, exceeding the array
bounds.

Check that the hardware version is MVPP22 or newer and that the
number of pools (nrxqs * 2) does not exceed MVPP2_BM_MAX_POOLS
before switching to per-CPU mode.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 7d04b0b13b11 ("mvpp2: percpu buffers")
Signed-off-by: Dmitriy Okunev <dokunevdmitriy@gmail.com>
Link: https://patch.msgid.link/20260914091557.71769-1-dokunevdmitriy@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
index 325a3a657249d..8096b46b654fd 100644
--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
@@ -5099,7 +5099,8 @@ static int mvpp2_change_mtu(struct net_device *dev, int mtu)
 			netdev_warn(dev, "mtu %d too high, switching to shared buffers", mtu);
 			mvpp2_bm_switch_buffers(priv, false);
 		}
-	} else {
+	} else if (priv->hw_version >= MVPP22 &&
+		   mvpp2_get_nrxqs(priv) * 2 <= MVPP2_BM_MAX_POOLS) {
 		bool jumbo = false;
 		int i;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 154/877] net: skbuff: do not leave stale header offsets after pskb_carve()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (152 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 153/877] net: mvpp2: prevent buffer overflow in page_pool allocation Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 155/877] drm/amdgpu: check ras and obj before dereference Greg Kroah-Hartman
                   ` (730 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+586af68eb819833c2d91,
	Xuanqiang Luo, Allison Henderson, rds-devel, Eric Dumazet,
	Xuanqiang Luo, Paolo Abeni, Sasha Levin

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

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

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit a5117e1eccac6ee3bd4aed7cacf8ebcb6b3eb309 ]

pskb_carve_inside_header() and pskb_carve_inside_nonlinear() remove
the first bytes of a packet and reallocate skb->head.

All the headers that were present before the operation are gone,
but both functions call skb_headers_offset_update(skb, 0), which
is a no-op : skb->mac_header, skb->network_header,
skb->transport_header and skb->csum_start keep their old values and
now describe bytes which are no longer there.

Both helpers size the new head from the old skb_end_offset(), so the
stale offsets still land inside the new allocation. They point past
skb_tail_pointer() though, to bytes that were never initialized.

pskb_carve_inside_nonlinear() is the worst case, because it leaves a
zombie skb with an empty linear part (skb->data ==
skb_tail_pointer(skb), skb_headlen(skb) == 0), while
skb_mac_header_was_set() is still true and skb->mac_header is way
ahead of skb->data.

The only user of pskb_extract() is rds_tcp_data_recv(), and the
carved skb is queued on tinc->ti_skb_list. When the RDS incoming
message is released, rds_tcp_inc_free() calls skb_queue_purge(),
which frees the skbs with SKB_DROP_REASON_QUEUE_PURGE. This is
visible from drop_monitor, which then tries to pull back to the
(bogus) mac header :

skbuff: __skb_pull(len=234)
skb len=6968 data_len=6968 headroom=0 headlen=0 tailroom=0
end-tail=384 mac=(234,14) mac_len=14 net=(248,40) trans=288
shinfo(txflags=0 nr_frags=1 gso(size=1428 type=16 segs=5))
csum(0x100120 start=288 offset=16 ip_summed=3 complete_sw=0 valid=1 level=0)
hash(0x7b446c6c sw=0 l4=1) proto=0x86dd pkttype=0 iif=60
kernel BUG at ./include/linux/skbuff.h:2847!

Add skb_carve_reset_headers() to mark the mac and transport headers
as not set, reset the network header, clear skb->mac_len, and drop
a now meaningless CHECKSUM_PARTIAL (csum_start no longer describes
anything).

Invalidate the inner offsets as well. Unlike mac_header and
transport_header they have no "unset" sentinel, so a leftover
non-zero value still looks like a real header. Zero
skb->inner_mac_header, skb->inner_network_header,
skb->inner_transport_header, skb->inner_protocol and
skb->encapsulation, so that all the header state is invalidated in
one place.

v2: fixed an inaccurate changelog. The stale offsets stay inside the
    new skb->head, which is never smaller than the old one, they
    simply point past skb_tail_pointer() to bytes that are gone.
    Thanks to Xuanqiang Luo for insisting on this.
    Also invalidate the inner header state, as suggested by the
    netdev AI review :
    https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260911114922.621937-1-edumazet%40google.com

Fixes: 6fa01ccd8830 ("skbuff: Add pskb_extract() helper function")
Reported-by: syzbot+586af68eb819833c2d91@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6aa3e9d3.f2639fcc.29487d.0028.GAE@google.com/
Cc: Xuanqiang Luo <xuanqiang.luo@linux.dev>
Cc: Allison Henderson <achender@kernel.org>
Cc: rds-devel@oss.oracle.com
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Link: https://patch.msgid.link/20260915130423.3956471-1-edumazet@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/skbuff.c | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 449c84fa73539..1e4f7b8e952cc 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -6696,6 +6696,34 @@ struct sk_buff *alloc_skb_with_frags(unsigned long header_len,
 }
 EXPORT_SYMBOL(alloc_skb_with_frags);
 
+/* pskb_carve_inside_header() and pskb_carve_inside_nonlinear()
+ * remove the first bytes of a packet and reallocate skb->head.
+ *
+ * Whatever headers were present before the operation are gone,
+ * we must not leave stale offsets, otherwise users of this skb
+ * (skb_dump(), drop_monitor, taps, ...) would read or pull garbage.
+ */
+static void skb_carve_reset_headers(struct sk_buff *skb)
+{
+	skb_unset_mac_header(skb);
+	skb_unset_transport_header(skb);
+	skb_reset_network_header(skb);
+	skb->mac_len = 0;
+
+	/* Inner offsets have no "unset" marker, zero them so that
+	 * skb_inner_network_header_was_set() becomes false and no
+	 * consumer mistakes them for a real (and long gone) header.
+	 */
+	skb->inner_mac_header = 0;
+	skb->inner_network_header = 0;
+	skb->inner_transport_header = 0;
+	skb->inner_protocol = 0;
+	skb->encapsulation = 0;
+
+	if (skb->ip_summed == CHECKSUM_PARTIAL)
+		skb->ip_summed = CHECKSUM_NONE;
+}
+
 /* carve out the first off bytes from skb when off < headlen */
 static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
 				    const int headlen, gfp_t gfp_mask)
@@ -6751,7 +6779,7 @@ static int pskb_carve_inside_header(struct sk_buff *skb, const u32 off,
 	skb->head_frag = 0;
 	skb_set_end_offset(skb, size);
 	skb_set_tail_pointer(skb, skb_headlen(skb));
-	skb_headers_offset_update(skb, 0);
+	skb_carve_reset_headers(skb);
 	skb->cloned = 0;
 	skb->hdr_len = 0;
 	skb->nohdr = 0;
@@ -6892,7 +6920,7 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off,
 	skb->data = data;
 	skb_set_end_offset(skb, size);
 	skb_reset_tail_pointer(skb);
-	skb_headers_offset_update(skb, 0);
+	skb_carve_reset_headers(skb);
 	skb->cloned   = 0;
 	skb->hdr_len  = 0;
 	skb->nohdr    = 0;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 155/877] drm/amdgpu: check ras and obj before dereference
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (153 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 154/877] net: skbuff: do not leave stale header offsets after pskb_carve() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 156/877] btrfs: abort transaction on failure to update inode for hole punching and reflinking Greg Kroah-Hartman
                   ` (729 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Tao Zhou, Dmitriy Chumachenko,
	Alex Deucher, Sasha Levin

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

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

From: Dmitriy Chumachenko <Dmitry.Chumachenko@cyberprotect.ru>

[ Upstream commit 723d4dc628d764b19cf9efca14b82cca5ff020c9 ]

nbio_v7_9_handle_ras_controller_intr_no_bifring() dereferences ras and obj
without checking either for NULL. Both amdgpu_ras_get_context() and
amdgpu_ras_find_obj() can return NULL, e.g. during the window between
adev->nbio.ras being set (early in amdgpu_ras_init(), by design, to
enable the fatal-error interrupt as soon as possible) and the PCIE_BIF
ras object actually being created in RAS late_init. Any interrupt in that
window crashes in hard-IRQ context.

This is analogous to commit d190b459b2a4 ("drm/amdgpu: the warning
dereferencing obj for nbio_v7_4"), which fixed the same issue in the
nbio_v7_4 handler.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 7692e1ee2446 ("drm/amdgpu: add RAS fatal error handler for NBIO v7.9")
Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
Signed-off-by: Dmitriy Chumachenko <Dmitry.Chumachenko@cyberprotect.ru>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit c7071767a50a32ed727cf800ac84372429e3b4b3)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c b/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c
index 8e401f8b2a054..2b3a1b9f8efc0 100644
--- a/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c
+++ b/drivers/gpu/drm/amd/amdgpu/nbio_v7_9.c
@@ -518,7 +518,7 @@ static void nbio_v7_9_handle_ras_controller_intr_no_bifring(struct amdgpu_device
 						RAS_CNTLR_INTERRUPT_CLEAR, 1);
 		WREG32_SOC15(NBIO, 0, regBIF_BX0_BIF_DOORBELL_INT_CNTL, bif_doorbell_intr_cntl);
 
-		if (!ras->disable_ras_err_cnt_harvest) {
+		if (ras && !ras->disable_ras_err_cnt_harvest && obj) {
 			/*
 			 * clear error status after ras_controller_intr
 			 * according to hw team and count ue number
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 156/877] btrfs: abort transaction on failure to update inode for hole punching and reflinking
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (154 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 155/877] drm/amdgpu: check ras and obj before dereference Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 157/877] x86/fred: Reconstruct the #GP context for rejected INT instructions Greg Kroah-Hartman
                   ` (728 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Filipe Manana,
	David Sterba, Sasha Levin

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

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

From: Filipe Manana <fdmanana@suse.com>

[ Upstream commit 97fcd34aa9fd73cefe3120ac9a82ca9d7763922f ]

If we fail to update the inode we error out without aborting the
transaction, which can result in a persistent inconsistency if after
the failure the transaction is committed, as we have dropped file
extent items from a range and either punched a hole or insert a new file
extent item for that range (for reflinks).

So add the missing transaction abort.

Fixes: 2aaa66558172 ("Btrfs: add hole punching")
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/btrfs/file.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 9c3b5ecb0b01e..5627e2f7dd64a 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -2545,8 +2545,10 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode,
 					      inode_set_ctime_current(&inode->vfs_inode));
 
 		ret = btrfs_update_inode(trans, inode);
-		if (ret)
+		if (unlikely(ret)) {
+			btrfs_abort_transaction(trans, ret);
 			break;
+		}
 
 		btrfs_end_transaction(trans);
 		btrfs_btree_balance_dirty(fs_info);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 157/877] x86/fred: Reconstruct the #GP context for rejected INT instructions
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (155 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 156/877] btrfs: abort transaction on failure to update inode for hole punching and reflinking Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 158/877] mm/huge_memory: use folios memcg inside __folio_split() Greg Kroah-Hartman
                   ` (727 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Paul Gofman, Matthew Schwartz,
	Peter Zijlstra (Intel), H. Peter Anvin, Sasha Levin

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

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

From: Matthew Schwartz <matthew.schwartz@linux.dev>

[ Upstream commit 93f53499d0b945e8ae447f497faf743d60069f61 ]

FRED event delivery does not use the IDT, so the gate DPL check that
rejects a user INT n falls to software (Intel FRED specification [1],
section 8.3). fred_intx() rejects the same vectors as IDT delivery, but
reports a zero error code and the IP after the INT. This breaks the
signal ABI. Wine uses the error code to recognize INT 0x2d, so the
changed context turns a handled breakpoint into an access violation in
Elden Ring.

Rewind IP using the instruction length in the augmented SS and
synthesize the IDT selector error code, (vector << 3) | 2. Set RF in the
saved flags, as the CPU does for a #GP fault. Section 5.2.1 defines the
saved vector, instruction length and RF state. The supplied length
handles prefixes without reading user memory. Limit the changes to
already-rejected software interrupts, preserving the accepted INT3, INT4
and enabled INT80 paths and hardware exceptions. With IA32 emulation
disabled, INT 0x80 now reports the same #GP as the DPL 0 gate IDT
installs there. The rewound IP also stops fixup_iopl_exception() from
inspecting the byte after the INT.

Also clear the software event flag. Section 6.2.3 specifies that ERETU
with this flag and TF set traps before executing any user instruction. A
tracer that suppresses SIGSEGV and resumes with TF set expects the next
instruction to run first, as after IRET. The sigreturn path clears the
same flag for this reason in prevent_single_step_upon_eretu().

[1] Intel Flexible Return and Event Delivery (FRED) Specification,
revision 9.0 (346446-009US), sections 5.2.1, 6.2.3 and 8.3.

Fixes: 14619d912b65 ("x86/fred: FRED entry/exit and dispatch code")
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/15745
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/16132
Reported-by: Paul Gofman <pgofman@codeweavers.com>
Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: H. Peter Anvin <hpa@zytor.com>
Link: https://cdrdv2.intel.com/v1/dl/getContent/678938 # [1]
Link: https://patch.msgid.link/20260917230907.2080792-2-matthew.schwartz@linux.dev
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/x86/entry/entry_fred.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/x86/entry/entry_fred.c b/arch/x86/entry/entry_fred.c
index 9f50f0c1c00f5..c43c750fa26dc 100644
--- a/arch/x86/entry/entry_fred.c
+++ b/arch/x86/entry/entry_fred.c
@@ -10,6 +10,7 @@
 #include <asm/desc.h>
 #include <asm/fred.h>
 #include <asm/idtentry.h>
+#include <asm/processor-flags.h>
 #include <asm/syscall.h>
 #include <asm/trapnr.h>
 #include <asm/traps.h>
@@ -71,7 +72,15 @@ static noinstr void fred_intx(struct pt_regs *regs)
 #endif
 
 	default:
-		return exc_general_protection(regs, 0);
+		/*
+		 * Reconstruct the #GP fault state that IDT delivery would produce.
+		 * Clear the software event flag so ERETU with TF set does not trap
+		 * before the resumed instruction. See prevent_single_step_upon_eretu().
+		 */
+		regs->ip -= regs->fred_ss.insnlen;
+		regs->flags |= X86_EFLAGS_RF;
+		regs->fred_ss.swevent = 0;
+		return exc_general_protection(regs, (regs->fred_ss.vector << 3) | 2);
 	}
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 158/877] mm/huge_memory: use folios memcg inside __folio_split()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (156 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 157/877] x86/fred: Reconstruct the #GP context for rejected INT instructions Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 159/877] wifi: rtw88: TX QOS Null data the same way as Null data Greg Kroah-Hartman
                   ` (726 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Zi Yan, Johannes Weiner, Baolin Wang,
	Lorenzo Stoakes (ARM), Barry Song, David Hildenbrand, Dev Jain,
	Lance Yang, Liam R. Howlett, Matthew Wilcox (Oracle),
	Ryan Roberts, William Kucharski, Andrew Morton, Sasha Levin

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

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

From: Zi Yan <ziy@nvidia.com>

commit c299a2285d9d8bda4da024455de65e3d00de6f17 upstream.

Patch series "Honor XA_FLAGS_ACCOUNT in xas_split_alloc() and charge to
folio's memcg", v3.

__GFP_ACCOUNT is needed for xarray node allocation accounting when
XA_FLAGS_ACCOUNT is set. Commit 7b785645e8f13 ("mm: fix page cache
convergence regression") fixed a workingset regression with it.
xas_split_alloc() does not have it and needs to be fixed.

In addition, based on Sashiko's review[1] and Johannes' confirmation[2], to
charge the right memcg, folio's memcg needs to be active during folio
split. Add that before adding __GFP_ACCOUNT.

There is no workingset convergence regression related to missing
__GFP_ACCOUNT in xas_split_alloc() and the impact to userspace should be
minor.

This patch (of 2):

During a pagecache folio split, an xarray node allocation can happen and
needs to charge at folio's memcg instead of folio split invoker's memcg,
because for example folio split can happen during reclaim and reclaim's
active memcg might not be folio's memcg.  Switch to folio's memcg at the
beginning and switch back afterwards.

Link: https://lore.kernel.org/20260804-add-gfp_account-to-xas_split_alloc-v3-0-38cb3ff325c5@nvidia.com
Link: https://lore.kernel.org/20260804-add-gfp_account-to-xas_split_alloc-v3-1-38cb3ff325c5@nvidia.com
Link: https://sashiko.dev/#/patchset/20260727-add-gfp_account-to-xas_split_alloc-v1-1-9fae6bf64838%40nvidia.com?part=1 [1]
Link: https://lore.kernel.org/all/amtcBZ-_QVRgCd6b@cmpxchg.org/ [2]
Fixes: 6b24ca4a1a8d ("mm: Use multi-index entries in the page cache")
Signed-off-by: Zi Yan <ziy@nvidia.com>
Suggested-by: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: Barry Song <baohua@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: William Kucharski <william.kucharski@oracle.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
(cherry picked from commit c299a2285d9d8bda4da024455de65e3d00de6f17)
Signed-off-by: Zi Yan <ziy@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 mm/huge_memory.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 6fc4e1fb88ae6..1a76a21724d40 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -3420,6 +3420,7 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,
 	/* reset xarray order to new order after split */
 	XA_STATE_ORDER(xas, &folio->mapping->i_pages, folio->index, new_order);
 	bool is_anon = folio_test_anon(folio);
+	struct mem_cgroup *memcg, *old_memcg;
 	struct address_space *mapping = NULL;
 	struct anon_vma *anon_vma = NULL;
 	int order = folio_order(folio);
@@ -3483,6 +3484,13 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,
 	if (folio_test_writeback(folio))
 		return -EBUSY;
 
+	/*
+	 * switch to folio's memcg as xarray node allocation can happen and
+	 * needs to charge to it.
+	 */
+	memcg = folio_memcg(folio);
+	old_memcg = set_active_memcg(memcg);
+
 	if (is_anon) {
 		/*
 		 * The caller does not necessarily hold an mmap_lock that would
@@ -3629,6 +3637,8 @@ int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,
 	if (mapping)
 		i_mmap_unlock_read(mapping);
 out:
+	/* restore to caller's old_memcg */
+	set_active_memcg(old_memcg);
 	xas_destroy(&xas);
 	if (order == HPAGE_PMD_ORDER)
 		count_vm_event(!ret ? THP_SPLIT_PAGE : THP_SPLIT_PAGE_FAILED);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 159/877] wifi: rtw88: TX QOS Null data the same way as Null data
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (157 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 158/877] mm/huge_memory: use folios memcg inside __folio_split() Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 160/877] wifi: rtw88: Fix the random "error beacon valid" messages for USB Greg Kroah-Hartman
                   ` (725 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bitterblue Smith, Ping-Ke Shih,
	Sasha Levin

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

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

From: Bitterblue Smith <rtl8821cerfe2@gmail.com>

[ Upstream commit 737e980e12983bb7420a2c00b981a1e607079a84 ]

When filling out the TX descriptor, Null data frames are treated like
management frames, but QOS Null data frames are treated like normal
data frames. Somehow this causes a problem for the firmware.

When connected to a network in the 2.4 GHz band, wpa_supplicant (or
NetworkManager?) triggers a scan every five minutes. During these scans
mac80211 transmits many QOS Null frames in quick succession. Because
these frames are marked with IEEE80211_TX_CTL_REQ_TX_STATUS, rtw88
asks the firmware to report the TX ACK status for each of these frames.
Sometimes the firmware can't process the TX status requests quickly
enough, they add up, it only processes some of them, and then marks
every subsequent TX status report with the wrong number.

The symptom is that after a while the warning "failed to get tx report
from firmware" appears every five minutes.

This problem apparently happens only with the older RTL8723D, RTL8821A,
RTL8812A, and probably RTL8703B chips.

Treat QOS Null data frames the same way as Null data frames. This seems
to avoid the problem.

Tested with RTL8821AU, RTL8723DU, RTL8811CU, and RTL8812BU.

Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/2b53fb0d-b1ed-47b6-8caa-2bb9ae2acb80@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/wireless/realtek/rtw88/tx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c
index 662fb27224f3d..0c8817bf46c74 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.c
+++ b/drivers/net/wireless/realtek/rtw88/tx.c
@@ -421,7 +421,7 @@ void rtw_tx_pkt_info_update(struct rtw_dev *rtwdev,
 		pkt_info->mac_id = rtwvif->mac_id;
 	}
 
-	if (ieee80211_is_mgmt(fc) || ieee80211_is_nullfunc(fc))
+	if (ieee80211_is_mgmt(fc) || ieee80211_is_any_nullfunc(fc))
 		rtw_tx_mgmt_pkt_info_update(rtwdev, pkt_info, sta, skb);
 	else if (ieee80211_is_data(fc))
 		rtw_tx_data_pkt_info_update(rtwdev, pkt_info, sta, skb);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 160/877] wifi: rtw88: Fix the random "error beacon valid" messages for USB
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (158 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 159/877] wifi: rtw88: TX QOS Null data the same way as Null data Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 161/877] Input: xpad - add support for Victrix Pro BFG Controller Greg Kroah-Hartman
                   ` (724 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bitterblue Smith, Ping-Ke Shih,
	Sasha Levin

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

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

From: Bitterblue Smith <rtl8821cerfe2@gmail.com>

[ Upstream commit f24d0d8c3cd7e4237f802c4d2f3bd4ac04572948 ]

All the USB devices have a problem in AP mode: uploading the updated
beacon to the chip's reserved page can randomly fail:

[34996.474304] rtw88_8723du 1-2:1.2: error beacon valid
[34996.474788] rtw88_8723du 1-2:1.2: failed to download drv rsvd page
[34999.956369] rtw88_8723du 1-2:1.2: error beacon valid
[34999.956846] rtw88_8723du 1-2:1.2: failed to download drv rsvd page
[34999.956855] rtw88_8723du 1-2:1.2: failed to download beacon
[35017.978296] rtw88_8723du 1-2:1.2: error beacon valid
[35017.978805] rtw88_8723du 1-2:1.2: failed to download drv rsvd page
[35017.978823] rtw88_8723du 1-2:1.2: failed to download beacon
[35023.200395] rtw88_8723du 1-2:1.2: error beacon valid
[35023.200869] rtw88_8723du 1-2:1.2: failed to download drv rsvd page
[35023.200875] rtw88_8723du 1-2:1.2: failed to download beacon
[35478.680547] rtw88_8723du 1-2:1.2: error beacon valid
[35478.681023] rtw88_8723du 1-2:1.2: failed to download drv rsvd page

Disable some beacon-related hardware functions before uploading the
beacon and enable them again after.

Tested with RTL8723DU, RTL8812BU, RTL8822CE.

Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/c248c40a-d432-47ed-90e0-d81ee6c32464@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/wireless/realtek/rtw88/fw.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c
index 43e3df6a48369..fd3bcb4466209 100644
--- a/drivers/net/wireless/realtek/rtw88/fw.c
+++ b/drivers/net/wireless/realtek/rtw88/fw.c
@@ -1446,7 +1446,7 @@ void rtw_add_rsvd_page_sta(struct rtw_dev *rtwdev,
 int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
 				u8 *buf, u32 size)
 {
-	u8 bckp[2];
+	u8 bckp[3];
 	u8 val;
 	u16 rsvd_pg_head;
 	u32 bcn_valid_addr;
@@ -1458,6 +1458,8 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
 	if (!size)
 		return -EINVAL;
 
+	bckp[2] = rtw_read8(rtwdev, REG_BCN_CTRL);
+
 	if (rtw_chip_wcpu_11n(rtwdev)) {
 		rtw_write32_set(rtwdev, REG_DWBCN0_CTRL, BIT_BCN_VALID);
 	} else {
@@ -1471,6 +1473,9 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
 	val |= BIT_ENSWBCN >> 8;
 	rtw_write8(rtwdev, REG_CR + 1, val);
 
+	rtw_write8(rtwdev, REG_BCN_CTRL,
+		   (bckp[2] & ~BIT_EN_BCN_FUNCTION) | BIT_DIS_TSF_UDT);
+
 	if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE) {
 		val = rtw_read8(rtwdev, REG_FWHW_TXQ_CTRL + 2);
 		bckp[1] = val;
@@ -1501,6 +1506,7 @@ int rtw_fw_write_data_rsvd_page(struct rtw_dev *rtwdev, u16 pg_addr,
 	rsvd_pg_head = rtwdev->fifo.rsvd_boundary;
 	rtw_write16(rtwdev, REG_FIFOPAGE_CTRL_2,
 		    rsvd_pg_head | BIT_BCN_VALID_V1);
+	rtw_write8(rtwdev, REG_BCN_CTRL, bckp[2]);
 	if (rtw_hci_type(rtwdev) == RTW_HCI_TYPE_PCIE)
 		rtw_write8(rtwdev, REG_FWHW_TXQ_CTRL + 2, bckp[1]);
 	rtw_write8(rtwdev, REG_CR + 1, bckp[0]);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 161/877] Input: xpad - add support for Victrix Pro BFG Controller
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (159 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 160/877] wifi: rtw88: Fix the random "error beacon valid" messages for USB Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 162/877] Input: xpad - add support for Azeron devices Greg Kroah-Hartman
                   ` (723 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Erich Sartison, Dmitry Torokhov

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

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

From: Erich Sartison <byt.es@mailbox.org>

commit 971fa7ea8621e123feb9c8d7dc61be1c656bd945 upstream.

The controller doesn't currently work via USB-cable.

Signed-off-by: Erich Sartison <byt.es@mailbox.org>
Link: https://patch.msgid.link/20260903103137.630170-1-byt.es@mailbox.org
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/joystick/xpad.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -256,6 +256,7 @@ static const struct xpad_device {
 	{ 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
 	{ 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
 	{ 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, XTYPE_XBOXONE },
+	{ 0x0e6f, 0x024c, "PDP Victrix Pro BFG Wired Controller for Xbox", 0, XTYPE_XBOXONE },
 	{ 0x0e6f, 0x02a0, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
 	{ 0x0e6f, 0x02a1, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
 	{ 0x0e6f, 0x02a2, "PDP Wired Controller for Xbox One - Crimson Red", 0, XTYPE_XBOXONE },



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 162/877] Input: xpad - add support for Azeron devices
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (160 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 161/877] Input: xpad - add support for Victrix Pro BFG Controller Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 163/877] Input: xpad - fix PDP Marvel Xbox 360 controller Greg Kroah-Hartman
                   ` (722 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Roberts Kursitis, Dmitry Torokhov

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

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

From: Roberts Kursitis <roberts.kursitis@azeron.eu>

commit cba76c0f47af1a389d718c5bb69e75cbd67bba98 upstream.

Azeron controllers (Cyro, Cyborg, Classic/Compact, Cyro Lefty,
Cyborg II and Keyzen) present a standard Xbox 360 controller
interface, so they work with the existing xpad driver once their
USB IDs are added.

The 0x16d0 vendor ID is a shared block, but this is safe because
xpad only binds interfaces that match the Xbox 360 signature.

Tested with an Azeron Keyzen.

Signed-off-by: Roberts Kursitis <roberts.kursitis@azeron.eu>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260906143040.162418-1-roberts.kursitis@azeron.eu
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/joystick/xpad.c |    7 +++++++
 1 file changed, 7 insertions(+)

--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -321,6 +321,12 @@ static const struct xpad_device {
 	{ 0x1689, 0xfd00, "Razer Onza Tournament Edition", 0, XTYPE_XBOX360 },
 	{ 0x1689, 0xfd01, "Razer Onza Classic Edition", 0, XTYPE_XBOX360 },
 	{ 0x1689, 0xfe00, "Razer Sabertooth", 0, XTYPE_XBOX360 },
+	{ 0x16d0, 0x1103, "Azeron Cyro", 0, XTYPE_XBOX360 },
+	{ 0x16d0, 0x113c, "Azeron Cyborg", 0, XTYPE_XBOX360 },
+	{ 0x16d0, 0x1192, "Azeron Classic/Compact", 0, XTYPE_XBOX360 },
+	{ 0x16d0, 0x1212, "Azeron Cyro Lefty", 0, XTYPE_XBOX360 },
+	{ 0x16d0, 0x12f7, "Azeron Cyborg II", 0, XTYPE_XBOX360 },
+	{ 0x16d0, 0x13ea, "Azeron Keyzen", 0, XTYPE_XBOX360 },
 	{ 0x17ef, 0x6182, "Lenovo Legion Controller for Windows", 0, XTYPE_XBOX360 },
 	{ 0x1949, 0x041a, "Amazon Game Controller", 0, XTYPE_XBOX360 },
 	{ 0x1a86, 0xe310, "Legion Go S", 0, XTYPE_XBOX360 },
@@ -555,6 +561,7 @@ static const struct usb_device_id xpad_t
 	XPAD_XBOX360_VENDOR(0x15e4),		/* Numark Xbox 360 controllers */
 	XPAD_XBOX360_VENDOR(0x162e),		/* Joytech Xbox 360 controllers */
 	XPAD_XBOX360_VENDOR(0x1689),		/* Razer Onza */
+	XPAD_XBOX360_VENDOR(0x16d0),		/* Azeron controllers */
 	XPAD_XBOX360_VENDOR(0x17ef),		/* Lenovo */
 	XPAD_XBOX360_VENDOR(0x1949),		/* Amazon controllers */
 	XPAD_XBOX360_VENDOR(0x1a86),		/* Nanjing Qinheng Microelectronics (WCH) */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 163/877] Input: xpad - fix PDP Marvel Xbox 360 controller
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (161 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 162/877] Input: xpad - add support for Azeron devices Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 164/877] ALSA: core: Fix potential UAF after asynchronous card release Greg Kroah-Hartman
                   ` (721 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Jeremy Nyberg, Dmitry Torokhov

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

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

From: Jeremy Nyberg <slickstretch3.0@gmail.com>

commit 7bc369cb3d3f3656eb77285628ee264264d28ad4 upstream.

The PDP Marvel Xbox 360 controller with USB ID 0e6f:0147 is
incorrectly classified as an Xbox One controller.

With the current XTYPE_XBOXONE classification, the controller is
detected but produces no input, while its four player LEDs continue
blinking indefinitely.

Classify USB ID 0e6f:0147 as an Xbox 360 controller instead.

Tested on a PDP Marvel Xbox 360 controller with USB ID 0e6f:0147.
All inputs register correctly and the player LED indicates the
current player.

Fixes: c225370e01b8 ("Input: xpad - sync supported devices with 360Controller")
Cc: stable@vger.kernel.org
Signed-off-by: Jeremy Nyberg <SlickStretch3.0@gmail.com>
Link: https://patch.msgid.link/20260910071627.236014-1-SlickStretch3.0@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/joystick/xpad.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -244,7 +244,7 @@ static const struct xpad_device {
 	{ 0x0e6f, 0x0139, "Afterglow Prismatic Wired Controller", 0, XTYPE_XBOXONE },
 	{ 0x0e6f, 0x013a, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },
 	{ 0x0e6f, 0x0146, "Rock Candy Wired Controller for Xbox One", 0, XTYPE_XBOXONE },
-	{ 0x0e6f, 0x0147, "PDP Marvel Xbox One Controller", 0, XTYPE_XBOXONE },
+	{ 0x0e6f, 0x0147, "PDP Marvel Xbox 360 Controller", 0, XTYPE_XBOX360 },
 	{ 0x0e6f, 0x015c, "PDP Xbox One Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE },
 	{ 0x0e6f, 0x015d, "PDP Mirror's Edge Official Wired Controller for Xbox One", 0, XTYPE_XBOXONE },
 	{ 0x0e6f, 0x0161, "PDP Xbox One Controller", 0, XTYPE_XBOXONE },



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 164/877] ALSA: core: Fix potential UAF after asynchronous card release
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (162 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 163/877] Input: xpad - fix PDP Marvel Xbox 360 controller Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 165/877] ALSA: virtio: reset device before deleting virtqueues Greg Kroah-Hartman
                   ` (720 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Farhad Alemi, Takashi Iwai

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

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

From: Takashi Iwai <tiwai@suse.de>

commit fd95e68df6fe66344161a1329cbe5e5805e7b704 upstream.

Usually a sound driver releases the resources assigned to the card via
snd_card_free(), and it synchronizes with the whole release procedure.
However, when the card is released asynchronously via
snd_card_free_when_closed() like USB-audio driver, the situation is
slightly different; although the snd_card_disconnect() call at the
disconnection guarantees that any newer accesses will be gated, the
in-flight tasks might be still accessing to the underlying card->dev
device even after the disconnection, which would cause a
use-after-free in the end, as reported by fuzzers.

For addressing the bug above, this patch takes the refcount of
card->dev at initialization of the card object, and releases at its
destructor.   This assures the availability of the card->dev in its
whole lifecycle.

Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
Closes: https://lore.kernel.org/CA+0ovChexj4TrZL_2iG_P0WBEbZc5+73GfB3DkciQi=R8pZOnA@mail.gmail.com
Closes: https://lore.kernel.org/CA+0ovCgQUQNN=Z1tJTouiCsDaXR5M-3-SQEGk-cpPXQkM5Xh+w@mail.gmail.com
Cc: <stable@vger.kernel.org>
Link: https://patch.msgid.link/20260912162150.455144-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 sound/core/init.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -309,7 +309,7 @@ static int snd_card_init(struct snd_card
 			kfree(card); /* manually free here, as no destructor called */
 		return err;
 	}
-	card->dev = parent;
+	card->dev = get_device(parent);
 	card->number = idx;
 	WARN_ON(IS_MODULE(CONFIG_SND) && !module);
 	card->module = module;
@@ -593,6 +593,7 @@ static int snd_card_do_free(struct snd_c
 		dev_warn(card->dev, "unable to free card info\n");
 		/* Not fatal error */
 	}
+	put_device(card->dev);
 	if (card->release_completion)
 		complete(card->release_completion);
 	if (!managed)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 165/877] ALSA: virtio: reset device before deleting virtqueues
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (163 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 164/877] ALSA: core: Fix potential UAF after asynchronous card release Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 166/877] ASoC: codecs: rt712-sdca-dmic: fix uninitialized stream_config->type Greg Kroah-Hartman
                   ` (719 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Yuho Choi, Takashi Iwai

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

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

From: Yuho Choi <oss.patchbox@gmail.com>

commit 6c05d00af307560e6a9f1631d6270d3df5aa2272 upstream.

virtsnd_remove() and virtsnd_freeze() delete the virtqueues before
resetting the device. del_vqs() frees the vring backing, but does not
provide a generic device quiesce operation. In particular, modern
virtio-pci keeps enabled queues active until the device is reset.

Reset the device before deleting the virtqueues so it can no longer
access the vring memory when that memory is released. This also covers
probe failures after DRIVER_OK, which unwind through virtsnd_remove().

Fixes: de3a9980d8c3 ("ALSA: virtio: add virtio sound driver")
Fixes: 575483e90a32 ("ALSA: virtio: introduce device suspend/resume support")
Cc: stable@vger.kernel.org
Signed-off-by: Yuho Choi <oss.patchbox@gmail.com>
Link: https://patch.msgid.link/20260911031121.1542502-1-oss.patchbox@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 sound/virtio/virtio_card.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/sound/virtio/virtio_card.c
+++ b/sound/virtio/virtio_card.c
@@ -359,8 +359,8 @@ static void virtsnd_remove(struct virtio
 	if (snd->card)
 		snd_card_free(snd->card);
 
-	vdev->config->del_vqs(vdev);
 	virtio_reset_device(vdev);
+	vdev->config->del_vqs(vdev);
 
 	for (i = 0; snd->substreams && i < snd->nsubstreams; ++i) {
 		struct virtio_pcm_substream *vss = &snd->substreams[i];
@@ -388,8 +388,8 @@ static int virtsnd_freeze(struct virtio_
 	virtsnd_disable_event_vq(snd);
 	virtsnd_ctl_msg_cancel_all(snd);
 
-	vdev->config->del_vqs(vdev);
 	virtio_reset_device(vdev);
+	vdev->config->del_vqs(vdev);
 
 	for (i = 0; i < snd->nsubstreams; ++i)
 		cancel_work_sync(&snd->substreams[i].elapsed_period);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 166/877] ASoC: codecs: rt712-sdca-dmic: fix uninitialized stream_config->type
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (164 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 165/877] ALSA: virtio: reset device before deleting virtqueues Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 167/877] ata: libahci: clear PxCLBU and PxFBU for AHCI_HFLAG_32BIT_ONLY Greg Kroah-Hartman
                   ` (718 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jiangshan Yi, Pierre-Louis Bossart,
	Mark Brown

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

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

From: Jiangshan Yi <yijiangshan@kylinos.cn>

commit 03a5699a0a04309c597683967aaaf25d1e555ea2 upstream.

stream_config is not initialized before being passed to
sdw_stream_add_slave().  The type field may contain garbage and is
later copied to stream->type by sdw_config_stream().

Zero-initialize stream_config so type defaults to SDW_STREAM_PCM.

While at it, use snd_sdw_params_to_config() helper instead of
open-coding the same logic.

Fixes: 63a511284c9e ("ASoC: rt712-sdca: Add RT712 SDCA driver for Mic topology")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Link: https://patch.msgid.link/20260914104712.379574-1-yijiangshan@kylinos.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 sound/soc/codecs/rt712-sdca-dmic.c |   14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

--- a/sound/soc/codecs/rt712-sdca-dmic.c
+++ b/sound/soc/codecs/rt712-sdca-dmic.c
@@ -14,6 +14,7 @@
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
+#include <sound/sdw.h>
 #include <sound/tlv.h>
 #include "rt712-sdca.h"
 #include "rt712-sdca-dmic.h"
@@ -641,10 +642,10 @@ static int rt712_sdca_dmic_hw_params(str
 {
 	struct snd_soc_component *component = dai->component;
 	struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component);
-	struct sdw_stream_config stream_config;
+	struct sdw_stream_config stream_config = {0};
 	struct sdw_port_config port_config;
 	struct sdw_stream_runtime *sdw_stream;
-	int retval, num_channels;
+	int retval;
 	unsigned int sampling_rate;
 
 	dev_dbg(dai->dev, "%s %s", __func__, dai->name);
@@ -656,13 +657,8 @@ static int rt712_sdca_dmic_hw_params(str
 	if (!rt712->slave)
 		return -EINVAL;
 
-	stream_config.frame_rate = params_rate(params);
-	stream_config.ch_count = params_channels(params);
-	stream_config.bps = snd_pcm_format_width(params_format(params));
-	stream_config.direction = SDW_DATA_DIR_TX;
-
-	num_channels = params_channels(params);
-	port_config.ch_mask = GENMASK(num_channels - 1, 0);
+	/* SoundWire specific configuration */
+	snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
 	port_config.num = 2;
 
 	retval = sdw_stream_add_slave(rt712->slave, &stream_config,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 167/877] ata: libahci: clear PxCLBU and PxFBU for AHCI_HFLAG_32BIT_ONLY
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (165 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 166/877] ASoC: codecs: rt712-sdca-dmic: fix uninitialized stream_config->type Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:17 ` [PATCH 6.12 168/877] ata: libahci_platform: Fix device reference leak in ahci_platform_get_resources() Greg Kroah-Hartman
                   ` (717 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Roland Waltersson, Damien Le Moal,
	Niklas Cassel

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

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

From: Niklas Cassel <cassel@kernel.org>

commit 82e47533221d4746947b74d2e79a478c36c6433a upstream.

A user reported that commit 105c42566a55 ("ata: ahci: force 32-bit DMA for
JMicron JMB582/JMB585") made the JMicron JMB585 unusable on his board.

The failure is seen as soon as the ahci driver is probed, and booting with
iommu=off does not solve the problem.

Looking at the AHCI specification, PxCLBU and PxFBU are both read only '0'
for HBAs that do not support 64-bit addressing.

For HBAs that do support 64-bit addressing, the registers are read write,
with a reset value that is Implementation Specific.

When using the AHCI_HFLAG_32BIT_ONLY flag, the HBA does support 64-bit
addressing, and a 32-bit DMA mask is set by simply clearing HOST_CAP_64.
Thus, in this case, we need to explicitly clear the registers to 0.

Fixes: 105c42566a55 ("ata: ahci: force 32-bit DMA for JMicron JMB582/JMB585")
Fixes: c7a42156d99b ("ahci: disable 64bit dma on sb600")
Cc: stable@vger.kernel.org
Reported-by: Roland Waltersson <roland.waltersson@netinsight.net>
Closes: https://lore.kernel.org/linux-ide/IA0PR17MB668730A4ECCD65F7A1DC3EDC9EB62@IA0PR17MB6687.namprd17.prod.outlook.com/
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Link: https://lore.kernel.org/r/20260904134310.1465051-2-cassel@kernel.org
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/ata/libahci.c |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -748,15 +748,28 @@ void ahci_start_fis_rx(struct ata_port *
 	struct ahci_port_priv *pp = ap->private_data;
 	u32 tmp;
 
-	/* set FIS registers */
+	/*
+	 * On HBAs that only support 32-bit addressing PxCLBU is read only '0'.
+	 * When applying the AHCI_HFLAG_32BIT_ONLY quirk, PxCLBU is RW, and the
+	 * reset value is Implementation Specific, so we need to clear it to 0.
+	 */
 	if (hpriv->cap & HOST_CAP_64)
 		writel((pp->cmd_slot_dma >> 16) >> 16,
 		       port_mmio + PORT_LST_ADDR_HI);
+	else if (hpriv->flags & AHCI_HFLAG_32BIT_ONLY)
+		writel(0, port_mmio + PORT_LST_ADDR_HI);
 	writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR);
 
+	/*
+	 * On HBAs that only support 32-bit addressing PxFBU is read only '0'.
+	 * When applying the AHCI_HFLAG_32BIT_ONLY quirk, PxFBU is RW, and the
+	 * reset value is Implementation Specific, so we need to clear it to 0.
+	 */
 	if (hpriv->cap & HOST_CAP_64)
 		writel((pp->rx_fis_dma >> 16) >> 16,
 		       port_mmio + PORT_FIS_ADDR_HI);
+	else if (hpriv->flags & AHCI_HFLAG_32BIT_ONLY)
+		writel(0, port_mmio + PORT_FIS_ADDR_HI);
 	writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR);
 
 	/* enable FIS reception */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 168/877] ata: libahci_platform: Fix device reference leak in ahci_platform_get_resources()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (166 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 167/877] ata: libahci: clear PxCLBU and PxFBU for AHCI_HFLAG_32BIT_ONLY Greg Kroah-Hartman
@ 2026-09-30 15:17 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 169/877] cifs: Fix server use-after-free in cifs_chan_skip_or_disable() Greg Kroah-Hartman
                   ` (716 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:17 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Wentao Liang, Damien Le Moal,
	Niklas Cassel

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

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

From: Wentao Liang <vulab@iscas.ac.cn>

commit 0d1cb83337f13af082afb68b28d3fdfe29cde7fb upstream.

of_find_device_by_node() takes a reference on the port platform device,
which is only used to look up its port regulator and is never released,
neither on success nor on the error paths. Drop the reference with
put_device() once the regulator has been obtained, which covers both the
success and error paths.

Fixes: c7d7ddee7e24 ("ata: libahci: Allow using multiple regulators")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://lore.kernel.org/r/20260915065933.1733061-1-vulab@iscas.ac.cn
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/ata/libahci_platform.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/ata/libahci_platform.c
+++ b/drivers/ata/libahci_platform.c
@@ -623,10 +623,10 @@ struct ahci_host_priv *ahci_platform_get
 			of_platform_device_create(child, NULL, NULL);
 
 			port_dev = of_find_device_by_node(child);
-
 			if (port_dev) {
 				rc = ahci_platform_get_regulator(hpriv, port,
 								&port_dev->dev);
+				put_device(&port_dev->dev);
 				if (rc == -EPROBE_DEFER)
 					goto err_out;
 			}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 169/877] cifs: Fix server use-after-free in cifs_chan_skip_or_disable()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (167 preceding siblings ...)
  2026-09-30 15:17 ` [PATCH 6.12 168/877] ata: libahci_platform: Fix device reference leak in ahci_platform_get_resources() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 170/877] exec: Cleanup POSIX timers right after de_thread() Greg Kroah-Hartman
                   ` (715 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Paulo Alcantara

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

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

From: Wentao Liang <vulab@iscas.ac.cn>

commit 717e0a25036b6c92cecace30913b2d874a4c22b8 upstream.

When a secondary channel is no longer supported by the server,
cifs_chan_skip_or_disable() drops the channel reference with
cifs_put_tcp_session() and then continues to use the server pointer by
calling cifs_signal_cifsd_for_reconnect() on it and reading its
primary_server pointer. cifs_put_tcp_session() can drop the last
reference of the channel and tear it down, so both the channel and the
primary server (whose reference is also dropped by
cifs_put_tcp_session()) can be freed before they are signaled for
reconnect.

Signal the channel and the primary server and capture the primary
server pointer before dropping the channel reference with
cifs_put_tcp_session().

Fixes: f591062bdbf4 ("cifs: handle servers that still advertise multichannel after disabling")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/smb2pdu.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -188,18 +188,19 @@ cifs_chan_skip_or_disable(struct cifs_se
 		spin_unlock(&ses->chan_lock);
 
 		/*
-		 * the above reference of server by channel
-		 * needs to be dropped without holding chan_lock
-		 * as cifs_put_tcp_session takes a higher lock
-		 * i.e. cifs_tcp_ses_lock
+		 * signal the channel and its primary server to
+		 * reconnect before dropping the above reference of
+		 * server by channel, which is done without holding
+		 * chan_lock as cifs_put_tcp_session takes a higher
+		 * lock i.e. cifs_tcp_ses_lock
 		 */
-		cifs_put_tcp_session(server, from_reconnect);
-
 		cifs_signal_cifsd_for_reconnect(server, false);
 
 		/* mark primary server as needing reconnect */
 		pserver = server->primary_server;
 		cifs_signal_cifsd_for_reconnect(pserver, false);
+
+		cifs_put_tcp_session(server, from_reconnect);
 skip_terminate:
 		return -EHOSTDOWN;
 	}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 170/877] exec: Cleanup POSIX timers right after de_thread()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (168 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 169/877] cifs: Fix server use-after-free in cifs_chan_skip_or_disable() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 171/877] rds: ib: use rds_conn_drop() on protocol version mismatch Greg Kroah-Hartman
                   ` (714 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Hyunwoo Kim, Thomas Gleixner,
	Kijo Park, Oleg Nesterov, Frederic Weisbecker

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

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

From: Hyunwoo Kim <imv4bel@gmail.com>

commit acb03d3881818581052924a9bbbe92b8741ed448 upstream.

A per-thread CPU timer holds a reference to the PID of the thread it is
attached to and, while it is armed, its node is queued in that thread's
posix_cputimers. The task is looked up by that PID.

When a non-leader thread exec()s, de_thread() changes which task owns
that PID. pid_task(timer->it.cpu.pid, PIDTYPE_PID) then returns NULL,
but the node is still queued on tsk, which is alive. timer_lock_sighand()
takes a failed lookup to mean that the node is already dequeued, so it
has nothing to undo.

begin_new_exec() calls posix_cpu_timers_exit(me) right after
exec_task_namespaces() and that removes the leftover node, so the state
normally stays invisible. But bprm->point_of_no_return is set before
de_thread(), so if unshare_files(), set_mm_exe_file(), exec_mmap() or
exec_task_namespaces() fails, the task dies before it gets there.
exit_itimers() then frees the k_itimer while its node is still queued,
and reaping tsk later erases that freed node from the rbtree.

In short:

      the non-leader thread B           the parent

  timer_create(CLOCK_THREAD_CPUTIME_ID)
  timer_settime()
    arm_timer()            // the node is queued on B
  execve()
    de_thread(B)
      exchange_tids(B, leader)  // B's PID now belongs to the leader
      release_task(leader)
        __exit_signal(leader)
          posix_cpu_timers_exit(leader)  // cleans leader's queue, not B's
          __unhash_process(leader)  // that PID has no task anymore
    exec_mmap()
      mmap_read_lock_killable(old_mm)
                                kill(B, SIGKILL)
      // -EINTR
  get_signal()
    do_exit()
      exit_itimers()
        posix_timer_delete()
          posix_cpu_timer_del()
        posix_timer_unhash_and_free()  // freed while still queued
                                wait4()
                                  release_task(B)
                                    posix_cpu_timers_exit(B)
                                      cleanup_timerqueue()
                                        timerqueue_del()  // use-after-free

Move the POSIX timer cleanup right after de_thread() before any of the
later failure conditions brings the task into do_exit().

[ tglx: Move the cleanup right after de_thread() ]

Fixes: 55e8c8eb2c7b ("posix-cpu-timers: Store a reference to a pid not a task")
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Tested-by: Kijo Park <red993688@gmail.com>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/ao7Q8miiuLAPVnWv@v4bel
Link: https://patch.msgid.link/20260911090541.627712075@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/exec.c |   29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1217,6 +1217,17 @@ void __set_task_comm(struct task_struct
 	perf_event_comm(tsk, exec);
 }
 
+static void posixtimer_exec(struct task_struct *me)
+{
+#ifdef CONFIG_POSIX_TIMERS
+	spin_lock_irq(&me->sighand->siglock);
+	posix_cpu_timers_exit(me);
+	spin_unlock_irq(&me->sighand->siglock);
+	exit_itimers(me);
+	flush_itimer_signals();
+#endif
+}
+
 /*
  * Calling this is the point of no return. None of the failures will be
  * seen by userspace since either the process is already taking a fatal
@@ -1250,6 +1261,16 @@ int begin_new_exec(struct linux_binprm *
 	retval = de_thread(me);
 	if (retval)
 		goto out;
+
+	/*
+	 * This must be done here to ensure that POSIX CPU timers which were
+	 * armed on the current task are dequeued from me::posix_cputimers.
+	 * Otherwise in case of a TID switch the deletion of the related POSIX
+	 * timer would not remove an enqueued timer because the TID lookup
+	 * of the old TID fails.
+	 */
+	posixtimer_exec(me);
+
 	/* see the comment in check_unsafe_exec() */
 	current->fs->in_exec = 0;
 	/*
@@ -1304,14 +1325,6 @@ int begin_new_exec(struct linux_binprm *
 	if (retval)
 		goto out_unlock;
 
-#ifdef CONFIG_POSIX_TIMERS
-	spin_lock_irq(&me->sighand->siglock);
-	posix_cpu_timers_exit(me);
-	spin_unlock_irq(&me->sighand->siglock);
-	exit_itimers(me);
-	flush_itimer_signals();
-#endif
-
 	/*
 	 * Make the signal table private.
 	 */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 171/877] rds: ib: use rds_conn_drop() on protocol version mismatch
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (169 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 170/877] exec: Cleanup POSIX timers right after de_thread() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 172/877] x86/microcode/intel: Reject problematic loading on Granite Rapids systems Greg Kroah-Hartman
                   ` (713 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, TencentOS Corvus AI,
	Allison Henderson, Aohan Mei, Jakub Kicinski

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

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

From: Aohan Mei <henrymei@tencent.com>

commit f97d8c7bab7843631206a114986c9059da03efeb upstream.

rds_ib_cm_connect_complete() runs from the RDMA-CM event handler with
conn->c_cm_lock held.  When the peer negotiates a protocol version
older than RDS_PROTOCOL_COMPAT_VERSION, the handler calls
rds_conn_destroy(), which is only safe in the rmmod path: it
synchronously tears the connection down and flush_work()es the
shutdown work cp_down_w.

That shutdown work (rds_conn_shutdown()) needs cp_cm_lock, which is
the very lock the event handler still holds, so the flush never
completes: the two workers wait on each other and the RDS connection
workqueues stall for good.

All other RDMA-CM failure paths (REJECTED, CONNECT_ERROR,
DISCONNECTED) use rds_conn_drop(), which marks the connection
RDS_CONN_ERROR and schedules the shutdown work asynchronously.  Use
it here as well.

Fixes: f147dd9ecabf ("RDS/IB: Disallow connections less than RDS 3.1")
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Cc: stable@vger.kernel.org
Reviewed-by: Allison Henderson <achender@kernel.org>
Signed-off-by: Aohan Mei <henrymei@tencent.com>
Link: https://patch.msgid.link/20260911073436.3542080-1-ljp1205831794@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rds/ib_cm.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/rds/ib_cm.c
+++ b/net/rds/ib_cm.c
@@ -115,7 +115,7 @@ void rds_ib_cm_connect_complete(struct r
 				  &conn->c_laddr, &conn->c_faddr,
 				  RDS_PROTOCOL_MAJOR(conn->c_version),
 				  RDS_PROTOCOL_MINOR(conn->c_version));
-			rds_conn_destroy(conn);
+			rds_conn_drop(conn);
 			return;
 		}
 	}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 172/877] x86/microcode/intel: Reject problematic loading on Granite Rapids systems
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (170 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 171/877] rds: ib: use rds_conn_drop() on protocol version mismatch Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 173/877] tcp: exclude old ACKs from tcp fast path Greg Kroah-Hartman
                   ` (712 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Chang S. Bae, Borislav Petkov (AMD),
	Dave Hansen

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

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

From: Chang S. Bae <chang.seok.bae@intel.com>

commit e7d3e2f46dd5a69046e6d95a0f189155a5516b93 upstream.

Microcode updates can usually jump revisions. However, there is an erratum on
Granite Rapids systems. If they "jump over" revision 0x1000405, they result in
an #MC. Avoid it.

Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260916225939.1144524-1-chang.seok.bae@intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/kernel/cpu/microcode/intel.c |   26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

--- a/arch/x86/kernel/cpu/microcode/intel.c
+++ b/arch/x86/kernel/cpu/microcode/intel.c
@@ -257,6 +257,26 @@ static void save_microcode_patch(struct
 		pr_err("Unable to allocate microcode memory size: %u\n", size);
 }
 
+static bool revision_is_safe(struct cpu_signature *sig, u32 rev)
+{
+	u32 vfm = IFM(x86_family(sig->sig), x86_model(sig->sig));
+
+	/*
+	 * Erratum GNR98 can cause #MCs if "jumping over" revision 0x1000405.
+	 * Avoid the jumps.
+	 */
+	if (vfm == INTEL_GRANITERAPIDS_X &&
+	    x86_stepping(sig->sig) == 1 &&
+	    sig->pf & 0x95 &&
+	    sig->rev < 0x1000405 &&
+	    rev > 0x1000405) {
+		pr_err_once("Erratum GNR98: skipping revision 0x%x.\n", rev);
+		return false;
+	}
+
+	return true;
+}
+
 /* Scan blob for microcode matching the boot CPUs family, model, stepping */
 static __init struct microcode_intel *scan_microcode(void *data, size_t size,
 						     struct ucode_cpu_info *uci,
@@ -278,6 +298,9 @@ static __init struct microcode_intel *sc
 		if (!intel_find_matching_signature(data, &uci->cpu_sig))
 			continue;
 
+		if (!revision_is_safe(&uci->cpu_sig, mc_header->rev))
+			continue;
+
 		/*
 		 * For saving the early microcode, find the matching revision which
 		 * was loaded on the BSP.
@@ -540,6 +563,9 @@ static enum ucode_state parse_microcode_
 		if (!intel_find_matching_signature(mc, &uci->cpu_sig))
 			continue;
 
+		if (!revision_is_safe(&uci->cpu_sig, mc_header.rev))
+			continue;
+
 		is_safe = ucode_validate_minrev(&mc_header);
 		if (force_minrev && !is_safe)
 			continue;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 173/877] tcp: exclude old ACKs from tcp fast path
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (171 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 172/877] x86/microcode/intel: Reject problematic loading on Granite Rapids systems Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 174/877] RDMA/ucma: Serialize join and leave on copy_to_user failure Greg Kroah-Hartman
                   ` (711 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Amit Klein, Tamir Shahar,
	Inbal Schussheim, Eric Dumazet, Paolo Abeni

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

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

From: Inbal Schussheim <inbal.lipshtat@mail.huji.ac.il>

commit f81e6c3fb06327bc49cdd6e559845293ba06a704 upstream.

Exclude old ACKs before SND.UNA from the tcp fast path
as well as ACKs after SND.NXT.

Such ACKs will fall through to the slow path, where tcp_ack()
performs the appropriate validation and challenge ACK handling
according to RFC5961 and Commit 3d501dd326fb1c7 ("tcp: do not
accept ACK of bytes we never sent").

This prevents old ACKs from being accepted
or modifying connection state as part of the fast path before
appropriate ACK validation is applied.
In particular, this prevents payload carried by a segment with
an excessively old ACK from advancing RCV.NXT before the ACK
is rejected.

Fixes: 31770e34e43d ("tcp: Revert "tcp: remove header prediction"")
Reported-by: Amit Klein <amit.klein@mail.huji.ac.il>
Reported-by: Tamir Shahar <tamir.shahar1@mail.huji.ac.il>
Reported-by: Inbal Schussheim <inbal.lipshtat@mail.huji.ac.il>
Suggested-by: Eric Dumazet <edumazet@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Inbal Schussheim <inbal.lipshtat@mail.huji.ac.il>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260914090408.1435080-2-inbal.lipshtat@mail.huji.ac.il
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv4/tcp_input.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -6138,6 +6138,7 @@ reset:
  *	  or pure receivers (this means either the sequence number or the ack
  *	  value must stay constant)
  *	- Unexpected TCP option.
+ *	- ACK sequence number is outside [SND.UNA, SND.NXT].
  *
  *	When these conditions are not satisfied it drops into a standard
  *	receive procedure patterned after RFC793 to handle all cases.
@@ -6186,7 +6187,7 @@ void tcp_rcv_established(struct sock *sk
 
 	if ((tcp_flag_word(th) & TCP_HP_BITS) == tp->pred_flags &&
 	    TCP_SKB_CB(skb)->seq == tp->rcv_nxt &&
-	    !after(TCP_SKB_CB(skb)->ack_seq, tp->snd_nxt)) {
+	    between(TCP_SKB_CB(skb)->ack_seq, tp->snd_una, tp->snd_nxt)) {
 		int tcp_header_len = tp->tcp_header_len;
 
 		/* Timestamp header prediction: tcp_header_len



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 174/877] RDMA/ucma: Serialize join and leave on copy_to_user failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (172 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 173/877] tcp: exclude old ACKs from tcp fast path Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 175/877] RDMA/core: fix refcount bug in iwpm_get_nlmsg_request() Greg Kroah-Hartman
                   ` (710 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+a6ffe86390c8a6afc818,
	Quanye Yang, Leon Romanovsky

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

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

From: Quanye Yang <quanyeyang@proton.me>

commit 662ade4de9ff5eceb0820a9f8e9fac70ba6a815b upstream.

rdma_join_multicast() queues RoCE work that later reads the ucma_multicast
through event->param.ud.private_data, then list_add()s the CMA multicast
at the head of id_priv->mc_list. rdma_leave_multicast() matches only by
sockaddr and destroys the first hit.

ucma_process_join() used to drop ctx->mutex after a successful join and
retake it only if copy_to_user() failed. Two concurrent JOIN_MCAST calls
with the same address can therefore insert a second CMA entry before the
first thread's leave. leave then cancels the newer work and the older
worker still dereferences the ucma_multicast that the first thread frees.

Keep ctx->mutex held from rdma_join_multicast() through copy_to_user() and,
on -EFAULT, through rdma_leave_multicast() so leave cannot miss this join.
Do not leave if join itself failed: that path never published this address
on mc_list, and a leave-by-addr would destroy an earlier successful join.

Reported-by: syzbot+a6ffe86390c8a6afc818@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a6ffe86390c8a6afc818
Fixes: fe454dc31e84 ("RDMA/ucma: Fix use-after-free bug in ucma_create_uevent")
Cc: stable@vger.kernel.org
Signed-off-by: Quanye Yang <quanyeyang@proton.me>
Link: https://patch.msgid.link/20260831-rdma-ucma-mc-uaf-v1-1-b8eeb7046aff@proton.me
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/infiniband/core/ucma.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -1487,9 +1487,10 @@ static ssize_t ucma_process_join(struct
 	mutex_lock(&ctx->mutex);
 	ret = rdma_join_multicast(ctx->cm_id, (struct sockaddr *)&mc->addr,
 				  join_state, mc);
-	mutex_unlock(&ctx->mutex);
-	if (ret)
+	if (ret) {
+		mutex_unlock(&ctx->mutex);
 		goto err_xa_erase;
+	}
 
 	resp.id = mc->id;
 	if (copy_to_user(u64_to_user_ptr(cmd->response),
@@ -1497,6 +1498,7 @@ static ssize_t ucma_process_join(struct
 		ret = -EFAULT;
 		goto err_leave_multicast;
 	}
+	mutex_unlock(&ctx->mutex);
 
 	xa_store(&multicast_table, mc->id, mc, 0);
 
@@ -1504,7 +1506,6 @@ static ssize_t ucma_process_join(struct
 	return 0;
 
 err_leave_multicast:
-	mutex_lock(&ctx->mutex);
 	rdma_leave_multicast(ctx->cm_id, (struct sockaddr *) &mc->addr);
 	mutex_unlock(&ctx->mutex);
 	ucma_cleanup_mc_events(mc);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 175/877] RDMA/core: fix refcount bug in iwpm_get_nlmsg_request()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (173 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 174/877] RDMA/ucma: Serialize join and leave on copy_to_user failure Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 176/877] openvswitch: avoid reallocating confirmed conntrack labels Greg Kroah-Hartman
                   ` (709 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+bd317784d628820741b5,
	Jeffin Philip, Leon Romanovsky

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

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

From: Jeffin Philip <jeffinphilip14@gmail.com>

commit 33fb59da49c4c3f5c2ec9f9d4447a56857a02c02 upstream.

iwpm_get_nlmsg_request() initializes refcount _after_ list_add_tail()
making it accessible to global list where another CPU can kref_get()
on nlmsg_request causing a refcount "addition on 0" bug. Fix this
by initializing kref _before_ list_add_tail() so refcount for
nlmsg_request can be incremented/decremented normally. In addition,
also initialize every field before list_add_tail().

Reported-by: syzbot+bd317784d628820741b5@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=bd317784d628820741b5
Fixes: 30dc5e63d6a5 ("RDMA/core: Add support for iWARP Port Mapper user space service")
Cc: stable@vger.kernel.org
Signed-off-by: Jeffin Philip <jeffinphilip14@gmail.com>
Link: https://patch.msgid.link/20260904131437.12917-1-jeffinphilip14@gmail.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/infiniband/core/iwpm_util.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

--- a/drivers/infiniband/core/iwpm_util.c
+++ b/drivers/infiniband/core/iwpm_util.c
@@ -314,10 +314,6 @@ struct iwpm_nlmsg_request *iwpm_get_nlms
 	if (!nlmsg_request)
 		return NULL;
 
-	spin_lock_irqsave(&iwpm_nlmsg_req_lock, flags);
-	list_add_tail(&nlmsg_request->inprocess_list, &iwpm_nlmsg_req_list);
-	spin_unlock_irqrestore(&iwpm_nlmsg_req_lock, flags);
-
 	kref_init(&nlmsg_request->kref);
 	kref_get(&nlmsg_request->kref);
 	nlmsg_request->nlmsg_seq = nlmsg_seq;
@@ -326,6 +322,11 @@ struct iwpm_nlmsg_request *iwpm_get_nlms
 	nlmsg_request->err_code = 0;
 	sema_init(&nlmsg_request->sem, 1);
 	down(&nlmsg_request->sem);
+
+	spin_lock_irqsave(&iwpm_nlmsg_req_lock, flags);
+	list_add_tail(&nlmsg_request->inprocess_list, &iwpm_nlmsg_req_list);
+	spin_unlock_irqrestore(&iwpm_nlmsg_req_lock, flags);
+
 	return nlmsg_request;
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 176/877] openvswitch: avoid reallocating confirmed conntrack labels
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (174 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 175/877] RDMA/core: fix refcount bug in iwpm_get_nlmsg_request() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 177/877] net: xfrm: reject unrepresentable espintcp transport headers Greg Kroah-Hartman
                   ` (708 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Zhiling Zou, Ilya Maximets,
	Aaron Conole, Jakub Kicinski

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

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

From: Zhiling Zou <zhilinz@nebusec.ai>

commit 3f118c8217c109fd13ca61caa301d72c483897ef upstream.

ovs_ct_get_conn_labels() adds the labels extension when a conntrack
entry does not have one.  Confirmed conntracks can be read locklessly,
so adding an extension may reallocate and free the extension block
while another CPU accesses it.

Only add the extension for unconfirmed conntracks.  A confirmed
conntrack without labels now fails the caller's label operation instead
of reallocating its extension storage.

Fixes: c2ac66735870 ("openvswitch: Allow matching on conntrack label")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/372fbb062b40ae6723684f55484be86ff0064f8e.1789218015.git.zhilinz@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/openvswitch/conntrack.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -366,7 +366,7 @@ static struct nf_conn_labels *ovs_ct_get
 	struct nf_conn_labels *cl;
 
 	cl = nf_ct_labels_find(ct);
-	if (!cl) {
+	if (!cl && !nf_ct_is_confirmed(ct)) {
 		nf_ct_labels_ext_add(ct);
 		cl = nf_ct_labels_find(ct);
 	}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 177/877] net: xfrm: reject unrepresentable espintcp transport headers
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (175 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 176/877] openvswitch: avoid reallocating confirmed conntrack labels Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 178/877] HID: logitech-hidpp: fix race condition when accessing stale stack pointer Greg Kroah-Hartman
                   ` (707 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Wyatt Feng, Ren Wei,
	Steffen Klassert

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

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

From: Wyatt Feng <wf.kernel.dev@gmail.com>

commit 96f01b53c2d05e003b040892256de54a586e8529 upstream.

ESP-in-TCP can hand xfrm packets whose transport header offset no longer
fits after the stream parser trims the TCP envelope. The plain transport
header reset truncates that offset and triggers the skb warning path.

Use the careful transport-header helper and drop the skb through the
existing XFRM error path when the offset cannot be represented.

Fixes: e27cca96cd68 ("xfrm: add espintcp (RFC 8229)")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: Codex:GPT-5.4
Signed-off-by: Wyatt Feng <wf.kernel.dev@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/xfrm/espintcp.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

--- a/net/xfrm/espintcp.c
+++ b/net/xfrm/espintcp.c
@@ -33,7 +33,11 @@ static void handle_esp(struct sk_buff *s
 {
 	struct tcp_skb_cb *tcp_cb = (struct tcp_skb_cb *)skb->cb;
 
-	skb_reset_transport_header(skb);
+	if (!skb_reset_transport_header_careful(skb)) {
+		XFRM_INC_STATS(sock_net(sk), LINUX_MIB_XFRMINERROR);
+		kfree_skb(skb);
+		return;
+	}
 
 	/* restore IP CB, we need at least IP6CB->nhoff */
 	memmove(skb->cb, &tcp_cb->header, sizeof(tcp_cb->header));



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 178/877] HID: logitech-hidpp: fix race condition when accessing stale stack pointer
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (176 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 177/877] net: xfrm: reject unrepresentable espintcp transport headers Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 179/877] kselftest/arm64: Fix size of thread_data values for pthread_join() Greg Kroah-Hartman
                   ` (706 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Benoît Sevens, Jiri Kosina,
	Lee Jones

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

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

From: Benoît Sevens <bsevens@google.com>

commit e2aaf2d3ad92ac4a8afa6b69ad4c38e7747d3d6e upstream.

The driver uses hidpp->send_receive_buf to point to a stack-allocated
buffer in the synchronous command path (__do_hidpp_send_message_sync).
However, this pointer is not cleared when the function returns.

If an event is processed (e.g. by a different thread) while the
send_mutex is held by a new command, but before that command has
updated send_receive_buf, the handler (hidpp_raw_hidpp_event) will
observe that the mutex is locked and dereference the stale pointer.

This results in an out-of-bounds access on a different thread's kernel
stack (or a NULL pointer dereference on the very first command).

Fix this by:
1. Clearing hidpp->send_receive_buf to NULL before releasing the mutex
   in the synchronous command path.
2. Moving the assignment of the local 'question' and 'answer' pointers
   inside the mutex_is_locked() block in the handler, and adding
   a NULL check before dereferencing.

Signed-off-by: Benoît Sevens <bsevens@google.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Cc: Lee Jones <lee@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/hid/hid-logitech-hidpp.c |   24 +++++++++++++++++-------
 1 file changed, 17 insertions(+), 7 deletions(-)

--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -305,21 +305,22 @@ static int __do_hidpp_send_message_sync(
 	if (ret) {
 		dbg_hid("__hidpp_send_report returned err: %d\n", ret);
 		memset(response, 0, sizeof(struct hidpp_report));
-		return ret;
+		goto out;
 	}
 
 	if (!wait_event_timeout(hidpp->wait, hidpp->answer_available,
 				5*HZ)) {
 		dbg_hid("%s:timeout waiting for response\n", __func__);
 		memset(response, 0, sizeof(struct hidpp_report));
-		return -ETIMEDOUT;
+		ret = -ETIMEDOUT;
+		goto out;
 	}
 
 	if (response->report_id == REPORT_ID_HIDPP_SHORT &&
 	    response->rap.sub_id == HIDPP_ERROR) {
 		ret = response->rap.params[1];
 		dbg_hid("%s:got hidpp error %02X\n", __func__, ret);
-		return ret;
+		goto out;
 	}
 
 	if ((response->report_id == REPORT_ID_HIDPP_LONG ||
@@ -327,10 +328,14 @@ static int __do_hidpp_send_message_sync(
 	    response->fap.feature_index == HIDPP20_ERROR) {
 		ret = response->fap.params[1];
 		dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret);
-		return ret;
+		goto out;
 	}
 
-	return 0;
+	ret = 0;
+
+out:
+	hidpp->send_receive_buf = NULL;
+	return ret;
 }
 
 /*
@@ -3866,8 +3871,7 @@ static int hidpp_input_configured(struct
 static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
 		int size)
 {
-	struct hidpp_report *question = hidpp->send_receive_buf;
-	struct hidpp_report *answer = hidpp->send_receive_buf;
+	struct hidpp_report *question, *answer;
 	struct hidpp_report *report = (struct hidpp_report *)data;
 	int ret;
 	int last_online;
@@ -3877,6 +3881,12 @@ static int hidpp_raw_hidpp_event(struct
 	 * previously sent command.
 	 */
 	if (unlikely(mutex_is_locked(&hidpp->send_mutex))) {
+		question = hidpp->send_receive_buf;
+		answer = hidpp->send_receive_buf;
+
+		if (!question)
+			return 0;
+
 		/*
 		 * Check for a correct hidpp20 answer or the corresponding
 		 * error



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 179/877] kselftest/arm64: Fix size of thread_data values for pthread_join()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (177 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 178/877] HID: logitech-hidpp: fix race condition when accessing stale stack pointer Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 180/877] arm64: hibernate: pass HVC_SET_VECTORS args to the resume hvc Greg Kroah-Hartman
                   ` (705 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Thomas Huth, Will Deacon

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

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

From: Thomas Huth <thuth@redhat.com>

commit 3d1ba5cbfb622025690c218d8f20da92a9ecb383 upstream.

pthread_join() stores the thread's return value (a "void *", i.e.
8 bytes on 64 bit computers) into the address that is passed as second
parameter. However, the entries of thread_data are only normal "int"s,
i.e. only 4 bytes. The additional 4 bytes of the return value clobber
whatever is adjacent on the stack, i.e. other members of the thread_data
array (which will be re-written in the next iteration of the for-loop,
so that nobody noticed this problem), or another other local variable
on the stack for the last iteration. Use "intptr_t" to declare the
thread_data array entries with the correct size.

Fixes: 29f080881601c ("kselftest/arm64: check GCR_EL1 after context switch")
Cc: stable@vger.kernel.org
Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 tools/testing/selftests/arm64/mte/check_gcr_el1_cswitch.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/tools/testing/selftests/arm64/mte/check_gcr_el1_cswitch.c
+++ b/tools/testing/selftests/arm64/mte/check_gcr_el1_cswitch.c
@@ -69,7 +69,7 @@ fail:
 int execute_test(pid_t pid)
 {
 	pthread_t thread_id[MAX_THREADS];
-	int thread_data[MAX_THREADS];
+	intptr_t thread_data[MAX_THREADS];
 
 	for (int i = 0; i < MAX_THREADS; i++)
 		pthread_create(&thread_id[i], NULL,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 180/877] arm64: hibernate: pass HVC_SET_VECTORS args to the resume hvc
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (178 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 179/877] kselftest/arm64: Fix size of thread_data values for pthread_join() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 181/877] arm64: dts: renesas: r8a779f0: Set UFS lane count Greg Kroah-Hartman
                   ` (704 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bradley Morgan, Vladimir Murzin,
	Mark Rutland, Will Deacon

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

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

From: Bradley Morgan <include@grrlz.net>

commit 955d86e5f3b95b731991fdb84966c50b16314629 upstream.

swsusp_arch_suspend_exit() reinstalls the restored kernel's hyp stub
vectors with an hvc, but never passes the arguments. x0 is not set to
HVC_SET_VECTORS and x1 is not set to the vector address, so the stub
dispatch falls through and returns without writing vbar_el2. EL2 is
left pointing at the trans_pgd copy of the vectors, a page that
swsusp_free() releases right after resume.

Set the arguments up the same way __hyp_set_vectors() does.

Without this fix, Vladimir was able to trigger a hang when resuming from
hibernation with CONFIG_PAGE_POISONING=y and page_poison=on.

Fixes: 788bfdd97434 ("arm64: trans_pgd: hibernate: Add trans_pgd_copy_el2_vectors")
Cc: stable@vger.kernel.org
Signed-off-by: Bradley Morgan <include@grrlz.net>
Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com>
Tested-by: Vladimir Murzin <vladimir.murzin@arm.com>
Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/arm64/kernel/hibernate-asm.S |    2 ++
 1 file changed, 2 insertions(+)

--- a/arch/arm64/kernel/hibernate-asm.S
+++ b/arch/arm64/kernel/hibernate-asm.S
@@ -89,6 +89,8 @@ alternative_insn "dc cvau, x4",  "dc civ
 	isb
 
 	cbz	x24, 3f		/* Do we need to re-initialise EL2? */
+	mov	x1, x24
+	mov	x0, #HVC_SET_VECTORS
 	hvc	#0
 3:	ret
 SYM_CODE_END(swsusp_arch_suspend_exit)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 181/877] arm64: dts: renesas: r8a779f0: Set UFS lane count
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (179 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 180/877] arm64: hibernate: pass HVC_SET_VECTORS args to the resume hvc Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 182/877] arm64: percpu: Fix this_cpu_write() casting Greg Kroah-Hartman
                   ` (703 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Koichiro Den, Geert Uytterhoeven

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

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

From: Koichiro Den <den@valinux.co.jp>

commit 8dc2615d5702059b2b71fca6f93c0d7d10ae54cb upstream.

Since commit e72323f3b09f ("scsi: ufs: core: Configure only active lanes
during link"), the following error is observed on R-Car S4:

    ufshcd-renesas e6860000.ufs: Tx lane mismatch [config,reported] [2,1]
    ufshcd-renesas e6860000.ufs: link startup failed -67
    ufshcd-renesas e6860000.ufs: error -ENOLINK: Initialization failed with error -67
    ufshcd-renesas e6860000.ufs: probe with driver ufshcd-renesas failed with error -67

R-Car S4 has one UFS lane per direction, as described in section 152.1
of its hardware manual.  Without lanes-per-direction, the UFS platform
driver defaults to two lanes.

Previously, the core used PA_CONNECTEDRXDATALANES and
PA_CONNECTEDTXDATALANES to configure the link without checking them
against lanes-per-direction, so the missing property did not prevent
initialization.

Explicitly set lanes-per-direction to 1, now that the validation is in
place.

Fixes: 5235d551779d ("arm64: dts: renesas: r8a779f0: Add UFS node")
Cc: stable@vger.kernel.org # 7.2+
Signed-off-by: Koichiro Den <den@valinux.co.jp>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20260911073058.253000-1-den@valinux.co.jp
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/arm64/boot/dts/renesas/r8a779f0.dtsi |    1 +
 1 file changed, 1 insertion(+)

--- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
+++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
@@ -876,6 +876,7 @@
 			clocks = <&cpg CPG_MOD 1514>, <&ufs30_clk>;
 			clock-names = "fck", "ref_clk";
 			freq-table-hz = <200000000 200000000>, <38400000 38400000>;
+			lanes-per-direction = <1>;
 			power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>;
 			resets = <&cpg 1514>;
 			status = "disabled";



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 182/877] arm64: percpu: Fix this_cpu_write() casting
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (180 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 181/877] arm64: dts: renesas: r8a779f0: Set UFS lane count Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 183/877] arm64: percpu: Fix this_cpu_and() mask generation Greg Kroah-Hartman
                   ` (702 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, David Laight, Mark Rutland,
	Jinjie Ruan, Muhammad Usama Anjum, Christopher Lameter (Ampere),
	Ada Couprie Diaz, Ard Biesheuvel, Catalin Marinas, James Morse,
	Marc Zyngier, Peter Zijlstra, Vladimir Murzin, Will Deacon,
	Yang Shi, Lorenzo Stoakes (ARM)

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

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

From: Mark Rutland <mark.rutland@arm.com>

commit 885bff055a0f251a51a0d4fd4f0a7b525582a3de upstream.

The arm64 implementation of this_cpu_write() casts 'val' to unsigned
long. This is necessary to handle cases where 'val' is a pointer type,
and to avoid spurious compiler warnings for the (unreachable!) cases
where the pointer type would be cast to a smaller integer type.

Unfortunately, the cast is applied to 'val' rather than '(val)', which
won't always generate the expected value when 'val' is an expression.

For example, for this_cpu_write(pcp, zero - 1), where 'pcp' is a u64 and
'zero' is a u32:

* 'zero'                      ===> (u32) 0x00000000
* 'zero - 1'                  ===> (u32) 0xffffffff
* '(unsigned long)zero - 1'   ===> (u64) 0xffffffffffffffff
* '(unsigned long)(zero - 1)' ===> (u64) 0x00000000ffffffff

Fix this by adding brackets around 'val'.

Fixes: 959bf2fd03b5 ("arm64: percpu: Rewrite per-cpu ops to allow use of LSE atomics")
Reported-by: David Laight <david.laight.linux@gmail.com>
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: David Laight <david.laight.linux@gmail.com>
Reviewed-by: Jinjie Ruan <ruanjinjie@huawei.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Acked-by: Christopher Lameter (Ampere) <cl@gentwo.org>
Cc: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Vladimir Murzin <vladimir.murzin@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Yang Shi <yang@os.amperecomputing.com>
Cc: stable@vger.kernel.org
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/arm64/include/asm/percpu.h |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

--- a/arch/arm64/include/asm/percpu.h
+++ b/arch/arm64/include/asm/percpu.h
@@ -172,13 +172,13 @@ PERCPU_RET_OP(add, add, ldadd)
 	_pcp_protect_return(__percpu_read_64, pcp)
 
 #define this_cpu_write_1(pcp, val)	\
-	_pcp_protect(__percpu_write_8, pcp, (unsigned long)val)
+	_pcp_protect(__percpu_write_8, pcp, (unsigned long)(val))
 #define this_cpu_write_2(pcp, val)	\
-	_pcp_protect(__percpu_write_16, pcp, (unsigned long)val)
+	_pcp_protect(__percpu_write_16, pcp, (unsigned long)(val))
 #define this_cpu_write_4(pcp, val)	\
-	_pcp_protect(__percpu_write_32, pcp, (unsigned long)val)
+	_pcp_protect(__percpu_write_32, pcp, (unsigned long)(val))
 #define this_cpu_write_8(pcp, val)	\
-	_pcp_protect(__percpu_write_64, pcp, (unsigned long)val)
+	_pcp_protect(__percpu_write_64, pcp, (unsigned long)(val))
 
 #define this_cpu_add_1(pcp, val)	\
 	_pcp_protect(__percpu_add_case_8, pcp, val)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 183/877] arm64: percpu: Fix this_cpu_and() mask generation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (181 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 182/877] arm64: percpu: Fix this_cpu_write() casting Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 184/877] Bluetooth: btusb: fix NXP IW610 composite device handling Greg Kroah-Hartman
                   ` (701 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mark Rutland, Jinjie Ruan,
	Muhammad Usama Anjum, Christopher Lameter (Ampere),
	Ada Couprie Diaz, Ard Biesheuvel, Catalin Marinas, James Morse,
	Marc Zyngier, Peter Zijlstra, Vladimir Murzin, Will Deacon,
	Yang Shi

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

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

From: Mark Rutland <mark.rutland@arm.com>

commit 44274c657256b4911de82f8104e9e22f054cf742 upstream.

The arm64 implementation of this_cpu_and(pcp, val) is built in terms of
ANDNOT operations, which requires the 'val' argument to be bitwise
negated. The bitwise negation is not implemented correctly, with two
bugs described below.

(1) The bitwise negation is performed as '~val' rather than '~(val)'.
    This won't always generate the expected value when 'val' is an
    expression.

    For example, for this_cpu_and(pcp, 1 - 1):

    * 'val'    is  '1 - 1'   ===> (int) 0x00000000
    * '~val'   is '~1 - 1'   ===> (int) 0xfffffffd
    * '~(val)' is '~(1 - 1)' ===> (int) 0xffffffff

    ... and thus bit[1] of 'pcp' would be preserved unexpectedly by the
    ANDNOT operation.

(2) The bitwise negation is performed on 'val' before it has been cast
    to (at least) the width of 'pcp'. This won't always generate the
    expected value for the upper bits.

    For example, for this_cpu_and(pcp, zero), where 'pcp' is a u64 and
    'zero' is a u32:

    * 'zero'           ===> (u32) 0x00000000
    * '~(zero)'        ===> (u32) 0xffffffff
    * '(u64)~(zero)'   ===> (u64) 0x00000000ffffffff
    * '~((u64)(zero))' ===> (u64) 0xffffffffffffffff

    ... and thus bits[63:32] of 'pcp' would be preserved unexpectedly by
    the ANDNOT operation.

Fix these issues by adding brackets around 'val', and by casting 'val'
to an appropriately-sized type before bitwise negation.

Fixes: 959bf2fd03b5 ("arm64: percpu: Rewrite per-cpu ops to allow use of LSE atomics")
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Jinjie Ruan <ruanjinjie@huawei.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Acked-by: Christopher Lameter (Ampere) <cl@gentwo.org>
Cc: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Vladimir Murzin <vladimir.murzin@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Yang Shi <yang@os.amperecomputing.com>
Cc: stable@vger.kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/arm64/include/asm/percpu.h |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

--- a/arch/arm64/include/asm/percpu.h
+++ b/arch/arm64/include/asm/percpu.h
@@ -199,13 +199,13 @@ PERCPU_RET_OP(add, add, ldadd)
 	_pcp_protect_return(__percpu_add_return_case_64, pcp, val)
 
 #define this_cpu_and_1(pcp, val)	\
-	_pcp_protect(__percpu_andnot_case_8, pcp, ~val)
+	_pcp_protect(__percpu_andnot_case_8, pcp, ~(u8)(val))
 #define this_cpu_and_2(pcp, val)	\
-	_pcp_protect(__percpu_andnot_case_16, pcp, ~val)
+	_pcp_protect(__percpu_andnot_case_16, pcp, ~(u16)(val))
 #define this_cpu_and_4(pcp, val)	\
-	_pcp_protect(__percpu_andnot_case_32, pcp, ~val)
+	_pcp_protect(__percpu_andnot_case_32, pcp, ~(u32)(val))
 #define this_cpu_and_8(pcp, val)	\
-	_pcp_protect(__percpu_andnot_case_64, pcp, ~val)
+	_pcp_protect(__percpu_andnot_case_64, pcp, ~(u64)(val))
 
 #define this_cpu_or_1(pcp, val)		\
 	_pcp_protect(__percpu_or_case_8, pcp, val)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 184/877] Bluetooth: btusb: fix NXP IW610 composite device handling
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (182 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 183/877] arm64: percpu: Fix this_cpu_and() mask generation Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 185/877] Bluetooth: eir: validate service data length before reading UUID Greg Kroah-Hartman
                   ` (700 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Nicolas Thibert,
	Luiz Augusto von Dentz

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

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

From: Nicolas Thibert <nithibert@gmail.com>

commit 2b50adefed9808a56d84d1de803cad882cc787fa upstream.

The NXP IW610 module exposes itself as a composite USB device
(0471:0215) with three interfaces: two real Bluetooth HCI interfaces
(class 0xe0) and one vendor-specific WiFi interface (class 0xff) used
by mwifiex-nxp.

The composite device's whole USB descriptor reports class 0xe0/01/01
(Bluetooth), so btusb_table's generic USB_DEVICE_INFO(0xe0, 0x01, 0x01)
entry matches every interface, not just the two real HCI ones -- btusb
ends up binding the WiFi interface too, and mwifiex-nxp never gets it.

Fix:
1. In btusb_table (the table the USB core actually matches against),
   explicitly ignore the WiFi interface via BTUSB_IGNORE, ahead of the
   generic entry.
2. In quirks_table, scope the existing BTUSB_MARVELL entry to the BT
   interface class instead of matching the whole device by VID/PID
   (harmless either way since quirks_table isn't consulted for initial
   binding, but keep it correct).

Not upstream anywhere: checked NXP's own i.MX kernel fork
(nxp-imx/linux-imx), no IW610 references in btusb.c on any branch --
their reference designs wire this chip differently (WiFi over SDIO
per their release notes), so they never hit this.

Signed-off-by: Nicolas Thibert <nithibert@gmail.com>
Cc: stable@vger.kernel.org
Assisted-by: LLM (Claude Sonnet 5, Anthropic)
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/bluetooth/btusb.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -68,6 +68,15 @@ static struct usb_driver btusb_driver;
 #define BTUSB_BARROT			BIT(28)
 
 static const struct usb_device_id btusb_table[] = {
+	/*
+	 * NXP IW610 (0471:0215): the composite device reports Bluetooth
+	 * class at the whole-device level, so the generic entry below
+	 * would also match this WiFi vendor interface. Ignore it here
+	 * first so mwifiex-nxp can bind it instead.
+	 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x0471, 0x0215, 0xff, 0xff, 0xff),
+	  .driver_info = BTUSB_IGNORE },
+
 	/* Generic Bluetooth USB device */
 	{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
 
@@ -470,6 +479,14 @@ static const struct usb_device_id quirks
 	{ USB_DEVICE(0x1286, 0x2046), .driver_info = BTUSB_MARVELL },
 	{ USB_DEVICE(0x1286, 0x204e), .driver_info = BTUSB_MARVELL },
 
+	/*
+	 * NXP IW610 BT interfaces (Marvell-lineage silicon, same quirk as
+	 * the 0x1286 entries above). Scoped to the BT interface class,
+	 * not just VID/PID -- see the btusb_table entry above.
+	 */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x0471, 0x0215, 0xe0, 0x01, 0x01),
+	  .driver_info = BTUSB_MARVELL },
+
 	/* Intel Bluetooth devices */
 	{ USB_DEVICE(0x8087, 0x0025), .driver_info = BTUSB_INTEL_COMBINED },
 	{ USB_DEVICE(0x8087, 0x0026), .driver_info = BTUSB_INTEL_COMBINED },



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 185/877] Bluetooth: eir: validate service data length before reading UUID
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (183 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 184/877] Bluetooth: btusb: fix NXP IW610 composite device handling Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 186/877] Bluetooth: hci_codec: validate vendor codec count length Greg Kroah-Hartman
                   ` (699 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Aamir Ahmed, Luiz Augusto von Dentz

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

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

From: Aamir Ahmed <elb12345@hotmail.co.uk>

commit e8241766794cf551d787fa3a77c0d54bbea6f6aa upstream.

eir_get_service_data() reads a 16-bit UUID from the service data using
get_unaligned_le16() without first checking that the data is long enough
to hold a UUID16 (2 bytes). If a malformed EIR entry has a service data
field with only 1 byte of payload (field_len=2), eir_get_data() returns
dlen=1. The subsequent get_unaligned_le16() then reads 1 byte past the
field boundary.

Additionally, if the corrupted UUID happens to match, the length
calculation "dlen - 2" underflows to SIZE_MAX since dlen is size_t.
Current callers either pass NULL for the length parameter or bounds-check
the returned length, but future callers may not.

Add a check that dlen >= sizeof(u16) and skip fields that are too short
to contain a valid UUID16.

Fixes: 8f9ae5b3ae80 ("Bluetooth: eir: Add helpers for managing service data")
Cc: stable@vger.kernel.org
Signed-off-by: Aamir Ahmed <elb12345@hotmail.co.uk>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/bluetooth/eir.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

--- a/net/bluetooth/eir.c
+++ b/net/bluetooth/eir.c
@@ -373,7 +373,15 @@ void *eir_get_service_data(u8 *eir, size
 	size_t dlen;
 
 	while ((eir = eir_get_data(eir, eir_len, EIR_SERVICE_DATA, &dlen))) {
-		u16 value = get_unaligned_le16(eir);
+		u16 value;
+
+		if (dlen < sizeof(value)) {
+			eir += dlen;
+			eir_len = eir_end - eir;
+			continue;
+		}
+
+		value = get_unaligned_le16(eir);
 
 		if (uuid == value) {
 			if (len)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 186/877] Bluetooth: hci_codec: validate vendor codec count length
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (184 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 185/877] Bluetooth: eir: validate service data length before reading UUID Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 187/877] Bluetooth: hci_sync: Serialize local codec list cleanup Greg Kroah-Hartman
                   ` (698 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Luiz Augusto von Dentz,
	Laxman Acharya Padhya, Luiz Augusto von Dentz

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

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

From: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>

commit d0795cfd6f655f4de84868a4f4bb41a03f037b3d upstream.

The Read Local Supported Codecs parsers consume the variable-sized
standard codec array before parsing the vendor codec count.  Although the
initial reply-size check includes a vendor count byte in the fixed layout,
it does not guarantee that the byte remains after the standard codec array.

If a controller reply ends immediately after that array, calculating the
vendor codec array size reads vnd_codecs->num beyond the skb data.  Use
skb_pull_data() to validate and consume each codec header before using its
count in both command variants.

Fixes: 8961987f3f5f ("Bluetooth: Enumerate local supported codec and cache details")
Fixes: 9ae664028a9e ("Bluetooth: Add support for Read Local Supported Codecs V2")
Cc: stable@vger.kernel.org
Suggested-by: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/bluetooth/hci_codec.c |   36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

--- a/net/bluetooth/hci_codec.c
+++ b/net/bluetooth/hci_codec.c
@@ -145,11 +145,12 @@ void hci_read_supported_codecs(struct hc
 
 	skb_pull(skb, sizeof(rp->status));
 
-	std_codecs = (void *)skb->data;
+	std_codecs = skb_pull_data(skb, sizeof(*std_codecs));
+	if (!std_codecs)
+		goto error;
 
 	/* validate codecs length before accessing */
-	if (skb->len < flex_array_size(std_codecs, codec, std_codecs->num)
-	    + sizeof(std_codecs->num))
+	if (skb->len < flex_array_size(std_codecs, codec, std_codecs->num))
 		goto error;
 
 	/* enumerate codec capabilities of standard codecs */
@@ -161,15 +162,14 @@ void hci_read_supported_codecs(struct hc
 					    LOCAL_CODEC_ACL_MASK | LOCAL_CODEC_SCO_MASK, &caps);
 	}
 
-	skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num)
-		 + sizeof(std_codecs->num));
+	skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num));
 
-	vnd_codecs = (void *)skb->data;
+	vnd_codecs = skb_pull_data(skb, sizeof(*vnd_codecs));
+	if (!vnd_codecs)
+		goto error;
 
 	/* validate vendor codecs length before accessing */
-	if (skb->len <
-	    flex_array_size(vnd_codecs, codec, vnd_codecs->num)
-	    + sizeof(vnd_codecs->num))
+	if (skb->len < flex_array_size(vnd_codecs, codec, vnd_codecs->num))
 		goto error;
 
 	/* enumerate vendor codec capabilities */
@@ -214,11 +214,12 @@ void hci_read_supported_codecs_v2(struct
 
 	skb_pull(skb, sizeof(rp->status));
 
-	std_codecs = (void *)skb->data;
+	std_codecs = skb_pull_data(skb, sizeof(*std_codecs));
+	if (!std_codecs)
+		goto error;
 
 	/* check for payload data length before accessing */
-	if (skb->len < flex_array_size(std_codecs, codec, std_codecs->num)
-	    + sizeof(std_codecs->num))
+	if (skb->len < flex_array_size(std_codecs, codec, std_codecs->num))
 		goto error;
 
 	memset(&caps, 0, sizeof(caps));
@@ -229,15 +230,14 @@ void hci_read_supported_codecs_v2(struct
 					    &caps);
 	}
 
-	skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num)
-		 + sizeof(std_codecs->num));
+	skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num));
 
-	vnd_codecs = (void *)skb->data;
+	vnd_codecs = skb_pull_data(skb, sizeof(*vnd_codecs));
+	if (!vnd_codecs)
+		goto error;
 
 	/* check for payload data length before accessing */
-	if (skb->len <
-	    flex_array_size(vnd_codecs, codec, vnd_codecs->num)
-	    + sizeof(vnd_codecs->num))
+	if (skb->len < flex_array_size(vnd_codecs, codec, vnd_codecs->num))
 		goto error;
 
 	for (i = 0; i < vnd_codecs->num; i++) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 187/877] Bluetooth: hci_sync: Serialize local codec list cleanup
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (185 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 186/877] Bluetooth: hci_codec: validate vendor codec count length Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 188/877] dmaengine: sun6i: fix non-atomic read of DMA position registers Greg Kroah-Hartman
                   ` (697 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Luiz Augusto von Dentz

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

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

From: Chengfeng Ye <nicoyip.dev@gmail.com>

commit 9a10987a2f160a44a638c9a35994ca6e3089696e upstream.

hci_dev_close_sync() clears hdev->local_codecs after releasing hdev->lock.
Codec list additions and both traversals in sco_sock_getsockopt() use that
lock, but the close path does not. A close and BT_CODEC query can therefore
interleave as follows:

  hci_dev_close_sync()          sco_sock_getsockopt()
                                hci_dev_lock()
                                fetch codec entry
  hci_codec_list_clear()
    kfree(entry)
                                read entry->id

The reader then accesses an entry which the close path has freed. KASAN
reported:

  BUG: KASAN: slab-use-after-free in sco_sock_getsockopt+0xfa0/0xfe0
  Read of size 1 at addr ffff8881001c3450
  Call Trace:
   sco_sock_getsockopt+0xfa0/0xfe0
   do_sock_getsockopt+0x537/0x7b0
   __sys_getsockopt+0xf2/0x170
  Allocated by task 92:
   hci_codec_list_add.isra.0+0x2c/0x440
   hci_read_codec_capabilities+0x224/0x590
   hci_read_supported_codecs+0x2c2/0x640
  Freed by task 92:
   kfree+0x131/0x3c0
   hci_codec_list_clear+0xd8/0x160
   hci_dev_close_sync+0x92a/0xfa0

Take hdev->lock around the clear operation at its existing point in the
close path. This makes the clear wait for active readers and prevents a new
traversal until the list is empty without changing teardown ordering.

Fixes: b938790e7054 ("Bluetooth: hci_codec: Fix leaking content of local_codecs")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/bluetooth/hci_sync.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -5480,7 +5480,9 @@ int hci_dev_close_sync(struct hci_dev *h
 	memset(hdev->eir, 0, sizeof(hdev->eir));
 	memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
 	bacpy(&hdev->random_addr, BDADDR_ANY);
+	hci_dev_lock(hdev);
 	hci_codec_list_clear(&hdev->local_codecs);
+	hci_dev_unlock(hdev);
 
 	hci_dev_put(hdev);
 	return err;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 188/877] dmaengine: sun6i: fix non-atomic read of DMA position registers
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (186 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 187/877] Bluetooth: hci_sync: Serialize local codec list cleanup Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 189/877] dmaengine: sun6i: fix undefined behaviour in sun6i_dma_tx_status Greg Kroah-Hartman
                   ` (696 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Christian Lugnberg, Frank Li,
	Vinod Koul

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

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

From: Christian Lugnberg <christian.lugnberg@soundtrack.io>

commit c90b6973daa37f4c283342dff881ae001dea4fe6 upstream.

sun6i_get_chan_size() reads DMA_CHAN_LLI_ADDR and DMA_CHAN_CUR_CNT in two
separate readl() calls with no synchronisation between them:

    pos   = readl(pchan->base + DMA_CHAN_LLI_ADDR);
    bytes = readl(pchan->base + DMA_CHAN_CUR_CNT);

DMA_CHAN_LLI_ADDR holds the physical address of the *next* descriptor the
engine will load once the current one completes. DMA_CHAN_CUR_CNT holds the
remaining byte count for the *current* descriptor. If the DMA engine
advances to the next LLI entry between the two reads, pos becomes stale: it
still points to what was the next descriptor at the time of the first read,
but that descriptor is now the current one and CUR_CNT reflects its initial
(full) byte count. The subsequent virtual-chain walk starts one entry too
early and accumulates an extra full period's worth of bytes into the
residue estimate.

Fix this by re-reading DMA_CHAN_LLI_ADDR after DMA_CHAN_CUR_CNT and
retrying if the value changed. This double-read pattern guarantees that
both registers were sampled during the same descriptor interval. The cost
is at most one extra readl() pair per call in the racy case, which occurs
only at descriptor boundaries (~every 2 ms) and is negligible.

Fixes: a90e173f3faf ("dmaengine: sun6i: Add cyclic capability")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Christian Lugnberg <christian.lugnberg@soundtrack.io>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260817135723.12807-2-christian.lugnberg@soundtrack.io
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/dma/sun6i-dma.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -353,8 +353,10 @@ static size_t sun6i_get_chan_size(struct
 	size_t bytes;
 	dma_addr_t pos;
 
-	pos = readl(pchan->base + DMA_CHAN_LLI_ADDR);
-	bytes = readl(pchan->base + DMA_CHAN_CUR_CNT);
+	do {
+		pos = readl(pchan->base + DMA_CHAN_LLI_ADDR);
+		bytes = readl(pchan->base + DMA_CHAN_CUR_CNT);
+	} while (pos != readl(pchan->base + DMA_CHAN_LLI_ADDR));
 
 	if (pos == LLI_LAST_ITEM)
 		return bytes;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 189/877] dmaengine: sun6i: fix undefined behaviour in sun6i_dma_tx_status
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (187 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 188/877] dmaengine: sun6i: fix non-atomic read of DMA position registers Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 190/877] dmaengine: ti: k3-udma-glue: fix NULL dereference in k3_udma_glue_release_rx_chn() Greg Kroah-Hartman
                   ` (695 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Christian Lugnberg, Frank Li,
	Vinod Koul

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

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

From: Christian Lugnberg <christian.lugnberg@soundtrack.io>

commit 9096bdc8d930147f7c39a493a859acbd3a8485d8 upstream.

sun6i_dma_tx_status() calls vchan_find_desc() to look up the virtual
descriptor for a given cookie, before checking whether the pointer
vd is NULL:

    vd = vchan_find_desc(&vchan->vc, cookie);
    txd = to_sun6i_desc(&vd->tx);   /* vd may be NULL here */

    if (vd) {
        for (lli = txd->v_lli; ...)

vchan_find_desc() returns NULL when the descriptor has already been
completed or is in-flight on a physical channel and no longer present
in the virtual channel's descriptor list. When vd is NULL,
to_sun6i_desc() is called unconditionally on &vd->tx before the NULL
check, which is undefined behaviour. Move the call inside the if (vd)
guard to ensure it is only reached with a valid pointer.

    vd = vchan_find_desc(&vchan->vc, cookie);
    if (vd) {
        struct sun6i_desc *txd = to_sun6i_desc(&vd->tx);
        for (lli = txd->v_lli; ...)

Fixes: 555859308723 ("dmaengine: sun6i: Add driver for the Allwinner A31 DMA controller")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Christian Lugnberg <christian.lugnberg@soundtrack.io>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260817135723.12807-3-christian.lugnberg@soundtrack.io
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/dma/sun6i-dma.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -970,7 +970,6 @@ static enum dma_status sun6i_dma_tx_stat
 	struct sun6i_pchan *pchan = vchan->phy;
 	struct sun6i_dma_lli *lli;
 	struct virt_dma_desc *vd;
-	struct sun6i_desc *txd;
 	enum dma_status ret;
 	unsigned long flags;
 	size_t bytes = 0;
@@ -982,9 +981,9 @@ static enum dma_status sun6i_dma_tx_stat
 	spin_lock_irqsave(&vchan->vc.lock, flags);
 
 	vd = vchan_find_desc(&vchan->vc, cookie);
-	txd = to_sun6i_desc(&vd->tx);
 
 	if (vd) {
+		struct sun6i_desc *txd = to_sun6i_desc(&vd->tx);
 		for (lli = txd->v_lli; lli != NULL; lli = lli->v_lli_next)
 			bytes += lli->len;
 	} else if (!pchan || !pchan->desc) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 190/877] dmaengine: ti: k3-udma-glue: fix NULL dereference in k3_udma_glue_release_rx_chn()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (188 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 189/877] dmaengine: sun6i: fix undefined behaviour in sun6i_dma_tx_status Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 191/877] ipv6: xfrm: use full sockets in local error paths Greg Kroah-Hartman
                   ` (694 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Pavel Zhigulin, Alexander Chesnokov,
	Frank Li, Vinod Koul

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

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

From: Alexander Chesnokov <Alexander.Chesnokov@kaspersky.com>

commit 0294b6dd515256c03ea2dbf508ddd3826d788579 upstream.

If devm_kcalloc() for rx_chn->flows fails in a channel request function,
the error path calls k3_udma_glue_release_rx_chn(), which dereferences
the NULL rx_chn->flows pointer in k3_udma_glue_release_rx_flow().

Skip the flow release loop in k3_udma_glue_release_rx_chn() when
rx_chn->flows is not allocated.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: d70241913413 ("dmaengine: ti: k3-udma: Add glue layer for non DMAengine users")
Cc: stable@vger.kernel.org
Reported-by: Pavel Zhigulin <Pavel.Zhigulin@kaspersky.com>
Signed-off-by: Alexander Chesnokov <Alexander.Chesnokov@kaspersky.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260812053426.3521589-1-Alexander.Chesnokov@kaspersky.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/dma/ti/k3-udma-glue.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/dma/ti/k3-udma-glue.c
+++ b/drivers/dma/ti/k3-udma-glue.c
@@ -1236,8 +1236,9 @@ void k3_udma_glue_release_rx_chn(struct
 		rx_chn->psil_paired = false;
 	}
 
-	for (i = 0; i < rx_chn->flow_num; i++)
-		k3_udma_glue_release_rx_flow(rx_chn, i);
+	if (rx_chn->flows)
+		for (i = 0; i < rx_chn->flow_num; i++)
+			k3_udma_glue_release_rx_flow(rx_chn, i);
 
 	if (xudma_rflow_is_gp(rx_chn->common.udmax, rx_chn->flow_id_base))
 		xudma_free_gp_rflow_range(rx_chn->common.udmax,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 191/877] ipv6: xfrm: use full sockets in local error paths
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (189 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 190/877] dmaengine: ti: k3-udma-glue: fix NULL dereference in k3_udma_glue_release_rx_chn() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 192/877] net: lan743x: fix RX checksum use-after-free Greg Kroah-Hartman
                   ` (693 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Vega, Zhiling Zou, Steffen Klassert

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

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

From: Zhiling Zou <zhilinz@nebusec.ai>

commit 6973a21ee73c5567f883813c8ef414774b45892f upstream.

xfrm6_local_rxpmtu() and xfrm6_local_error() dereference skb->sk as if it
always pointed at a full IPv6 socket.

That is not guaranteed. TCP SYN-ACK skbs can be owned by a
TCP_NEW_SYN_RECV request_sock while the output path itself is driven by the
full listener. If rerouting selects an IPv6 XFRM tunnel route with a lower
MTU, the local PMTU/error handling path can reach these callbacks with that
mini-socket still attached to the skb.

The callbacks then miscast the request socket as a full inet/IPv6 socket and
can read beyond the request_sock allocation when they access inet_sock or
ipv6_pinfo state.

Resolve the owner with skb_to_full_sk() in both callbacks and bail out when
no full socket is attached. This matches the surrounding XFRM IPv6 PMTU/error
logic, which already reasons about full sockets with skb_to_full_sk().

Fixes: dd767856a36e ("xfrm6: Don't call icmpv6_send on local error")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv6/xfrm6_output.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -19,7 +19,10 @@
 void xfrm6_local_rxpmtu(struct sk_buff *skb, u32 mtu)
 {
 	struct flowi6 fl6;
-	struct sock *sk = skb->sk;
+	struct sock *sk = skb_to_full_sk(skb);
+
+	if (!sk)
+		return;
 
 	fl6.flowi6_oif = sk->sk_bound_dev_if;
 	fl6.daddr = ipv6_hdr(skb)->daddr;
@@ -31,7 +34,10 @@ void xfrm6_local_error(struct sk_buff *s
 {
 	struct flowi6 fl6;
 	const struct ipv6hdr *hdr;
-	struct sock *sk = skb->sk;
+	struct sock *sk = skb_to_full_sk(skb);
+
+	if (!sk)
+		return;
 
 	hdr = skb->encapsulation ? inner_ipv6_hdr(skb) : ipv6_hdr(skb);
 	fl6.fl6_dport = inet_sk(sk)->inet_dport;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 192/877] net: lan743x: fix RX checksum use-after-free
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (190 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 191/877] ipv6: xfrm: use full sockets in local error paths Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 193/877] net: wwan: t7xx: validate the netif index in t7xx_ccmni_recv_skb() Greg Kroah-Hartman
                   ` (692 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mark Amirkan, Chenguang Zhao,
	Jakub Kicinski

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

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

From: Mark Amirkan <markdamirkan@gmail.com>

commit a9ce4053dc945c5372dedba5017ee675b30dc0c5 upstream.

lan743x_rx_process_buffer() adds each non-first receive buffer to the
head skb's frag_list.  On the last descriptor, lan743x_rx_trim_skb()
linearizes the head and frees the fragment skb metadata.

The checksum-success path then writes ip_summed through the local skb
pointer, which still points to the final fragment.  This causes a
use-after-free write when a packet spans more than one receive buffer.

Set ip_summed on the surviving head skb instead.  Multi-buffer receive
can occur after a live MTU increase because existing ring entries keep
their old buffer size until they are replenished.

A KUnit test invoking lan743x_rx_process_buffer() with a two-buffer
packet produced a one-byte KASAN use-after-free write before this change.
The same test passed after the change.  The driver object also builds
with W=1.  This was not tested on physical LAN743x hardware.

Fixes: cd6910501cfd ("net: lan743x: Add support for Rx IP & TCP checksum offload")
Cc: stable@vger.kernel.org
Signed-off-by: Mark Amirkan <markdamirkan@gmail.com>
Reviewed-by: Chenguang Zhao <zhaochenguang@kylinos.cn>
Link: https://patch.msgid.link/20260913-b4-send-lan743x-uaf-v1-1-73d563d08ba9@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/microchip/lan743x_main.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -2587,7 +2587,7 @@ process_extension:
 							rx->adapter->netdev);
 		if (rx->adapter->netdev->features & NETIF_F_RXCSUM) {
 			if (!is_ice && !is_tce && !is_icsm)
-				skb->ip_summed = CHECKSUM_UNNECESSARY;
+				rx->skb_head->ip_summed = CHECKSUM_UNNECESSARY;
 		}
 		netdev_dbg(netdev, "sending %d byte frame to OS",
 			   rx->skb_head->len);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 193/877] net: wwan: t7xx: validate the netif index in t7xx_ccmni_recv_skb()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (191 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 192/877] net: lan743x: fix RX checksum use-after-free Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 194/877] net: wwan: mhi_wwan_mbim: guard against a cyclic NDP chain Greg Kroah-Hartman
                   ` (691 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Guanglei Zhu, Jakub Kicinski

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

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

From: Guanglei Zhu <zhugl3@xiaopeng.com>

commit c7ead9704249d57d4693a04697e3bbd285138fa9 upstream.

The netif index carried in the DPMAIF PIT header is five bits wide,
but ccmni_inst[] only has room for NIC_DEV_MAX (21) entries.
t7xx_ccmni_recv_skb() indexes the array without a bounds check, so
indexes 21 to 31 read past it.  The out-of-bounds value lands in the
callback table that follows the array, which is never NULL, so the
existing !ccmni check does not catch it and the driver dereferences
whatever sits there as a struct t7xx_ccmni.

Drop the skb when the index is out of range.

Fixes: 05d19bf500f8 ("net: wwan: t7xx: Add WWAN network interface")
Cc: stable@vger.kernel.org
Signed-off-by: Guanglei Zhu <zhugl3@xiaopeng.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Verified in a QEMU guest with a fault injector setting the netif
index to 25: the unpatched driver reads a value past ccmni_inst[],
which lands in the callback table, and dereferences it far enough to
queue the skb.  With this check the packet is dropped.  Well-formed
traffic on index 0 is unaffected.

Changes in v2: none.

Link: https://patch.msgid.link/20260911021734.1396599-3-zhugl3@xiaopeng.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 drivers/net/wwan/t7xx/t7xx_netdev.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/drivers/net/wwan/t7xx/t7xx_netdev.c
+++ b/drivers/net/wwan/t7xx/t7xx_netdev.c
@@ -420,6 +420,10 @@ static void t7xx_ccmni_recv_skb(struct t
 
 	skb_cb = T7XX_SKB_CB(skb);
 	netif_id = skb_cb->netif_idx;
+	if (netif_id >= NIC_DEV_MAX) {
+		dev_kfree_skb(skb);
+		return;
+	}
 	ccmni = READ_ONCE(ccmni_ctlb->ccmni_inst[netif_id]);
 	if (!ccmni) {
 		dev_kfree_skb(skb);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 194/877] net: wwan: mhi_wwan_mbim: guard against a cyclic NDP chain
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (192 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 193/877] net: wwan: t7xx: validate the netif index in t7xx_ccmni_recv_skb() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 195/877] net: wwan: mhi_wwan_mbim: check skb_copy_bits() return value Greg Kroah-Hartman
                   ` (690 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Loic Poulain, Guanglei Zhu,
	Jakub Kicinski

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

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

From: Guanglei Zhu <zhugl3@xiaopeng.com>

commit 5d063822ac5184939c1ed377a339a01d8ae814e8 upstream.

The NDP traversal in mhi_mbim_rx() only stops when wNextNdpIndex is
zero.  Nothing requires the offsets to advance, so a modem that
points an NDP at itself, or at an earlier NDP, keeps the loop
spinning forever on one CPU.

Break out when the next NDP offset is not larger than the current
one.

Fixes: aa730a9905b7 ("net: wwan: Add MHI MBIM network driver")
Cc: stable@vger.kernel.org
Suggested-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
Signed-off-by: Guanglei Zhu <zhugl3@xiaopeng.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Verified in a QEMU guest with a fault injector feeding the driver's
receive callback an NTB whose single NDP points at itself: the
unpatched driver spins in mhi_mbim_rx() with one CPU pinned at 100%
and the thread never returns.  With this check the loop terminates
within one iteration.

Changes in v2: move the non-increasing check to the wNextNdpIndex
retrieval site, as suggested by Loic Poulain, instead of tracking
the previous offset in a separate variable.

Link: https://patch.msgid.link/20260911021734.1396599-1-zhugl3@xiaopeng.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 drivers/net/wwan/mhi_wwan_mbim.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

--- a/drivers/net/wwan/mhi_wwan_mbim.c
+++ b/drivers/net/wwan/mhi_wwan_mbim.c
@@ -350,9 +350,13 @@ static void mhi_mbim_rx(struct mhi_mbim_
 unlock:
 		rcu_read_unlock();
 next_ndp:
-		/* Other NDP to process? */
-		ndpoffset = (int)le16_to_cpu(ndp16.wNextNdpIndex);
-		if (!ndpoffset)
+		/* Other NDP to process?  The offsets must advance, or a
+		 * self-referencing NDP keeps the loop spinning forever.
+		 */
+		n = (int)le16_to_cpu(ndp16.wNextNdpIndex);
+		if (n > ndpoffset)
+			ndpoffset = n;
+		else
 			break;
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 195/877] net: wwan: mhi_wwan_mbim: check skb_copy_bits() return value
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (193 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 194/877] net: wwan: mhi_wwan_mbim: guard against a cyclic NDP chain Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 196/877] net/sched: act_api: release tail references on DELACTION failure Greg Kroah-Hartman
                   ` (689 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Loic Poulain, Guanglei Zhu,
	Jakub Kicinski

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

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

From: Guanglei Zhu <zhugl3@xiaopeng.com>

commit 31550d585589fde1ae95bf7f7a8188b2d2fdf1c7 upstream.

mhi_mbim_rx() ignores the return value of skb_copy_bits() when it
copies each datagram out of the NTB.  The datagram offset and length
come from the DPE, which is only checked to lie within the NTB
itself, so a modem can point a datagram outside the received skb.
The copy then fails and the freshly allocated skbn is passed to
netif_rx() with its uninitialized contents still in place, leaking
kernel heap memory into the network stack.

Free the skb and account an error when the copy fails.

Fixes: aa730a9905b7 ("net: wwan: Add MHI MBIM network driver")
Cc: stable@vger.kernel.org
Suggested-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
Signed-off-by: Guanglei Zhu <zhugl3@xiaopeng.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Verified in a QEMU guest with a fault injector pointing a DPE
outside the received NTB: the copy fails, and the unpatched driver
hands the uninitialized skbn to the network stack (observed as
"unknown protocol" on bytes that were never written).  With this
check the failed datagram is dropped and counted as an rx error.

Changes in v2: factor the free-and-count sequence out into
mhi_mbim_rx_drop(), shared with the unknown-protocol path, as
suggested by Loic Poulain.

Link: https://patch.msgid.link/20260911021734.1396599-2-zhugl3@xiaopeng.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 drivers/net/wwan/mhi_wwan_mbim.c |   18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

--- a/drivers/net/wwan/mhi_wwan_mbim.c
+++ b/drivers/net/wwan/mhi_wwan_mbim.c
@@ -252,6 +252,14 @@ static int mbim_rx_verify_ndp16(struct s
 	return ret;
 }
 
+static void mhi_mbim_rx_drop(struct mhi_mbim_link *link, struct sk_buff *skb)
+{
+	dev_kfree_skb_any(skb);
+	u64_stats_update_begin(&link->rx_syncp);
+	u64_stats_inc(&link->rx_errors);
+	u64_stats_update_end(&link->rx_syncp);
+}
+
 static void mhi_mbim_rx(struct mhi_mbim_context *mbim, struct sk_buff *skb)
 {
 	int ndpoffset;
@@ -321,7 +329,10 @@ static void mhi_mbim_rx(struct mhi_mbim_
 				continue;
 
 			skb_put(skbn, dgram_len);
-			skb_copy_bits(skb, dgram_offset, skbn->data, dgram_len);
+			if (skb_copy_bits(skb, dgram_offset, skbn->data, dgram_len)) {
+				mhi_mbim_rx_drop(link, skbn);
+				continue;
+			}
 
 			switch (skbn->data[0] & 0xf0) {
 			case 0x40:
@@ -333,10 +344,7 @@ static void mhi_mbim_rx(struct mhi_mbim_
 			default:
 				net_err_ratelimited("%s: unknown protocol\n",
 						    link->ndev->name);
-				dev_kfree_skb_any(skbn);
-				u64_stats_update_begin(&link->rx_syncp);
-				u64_stats_inc(&link->rx_errors);
-				u64_stats_update_end(&link->rx_syncp);
+				mhi_mbim_rx_drop(link, skbn);
 				continue;
 			}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 196/877] net/sched: act_api: release tail references on DELACTION failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (194 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 195/877] net: wwan: mhi_wwan_mbim: check skb_copy_bits() return value Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 197/877] net/sched: hhf: cap hh_flows_limit at change time Greg Kroah-Hartman
                   ` (688 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Xuanqiang Luo, Jakub Kicinski

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

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

From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>

commit 6e05e46fa821a5c1b281355f1f622ac76cb6080a upstream.

A batched RTM_DELACTION request takes a temporary reference on each
action before attempting any deletion. tcf_action_delete() clears
each processed slot and drops its temporary reference before attempting
the deletion. If deletion fails, tca_action_gd() calls
tcf_action_put_many() to release the remaining references, but its
tcf_act_for_each_action() iterator stops at the first NULL slot.

When a batch stops at an action bound to a filter, this leaks a
reference on each subsequent action. A later delete of an unbound
action can then return success without removing it from the IDR.

Walk the full array in tcf_action_put_many() and skip NULL slots to
release the references held on the unprocessed actions.

Fixes: a0e947c9ccff ("net/sched: act_api: avoid non-contiguous action array")
Cc: stable@vger.kernel.org
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Link: https://patch.msgid.link/20260910093413.34509-2-xuanqiang.luo@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/sched/act_api.c |   11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -1165,11 +1165,16 @@ static int tcf_action_put(struct tc_acti
 
 static void tcf_action_put_many(struct tc_action *actions[])
 {
-	struct tc_action *a;
 	int i;
 
-	tcf_act_for_each_action(i, a, actions) {
-		const struct tc_action_ops *ops = a->ops;
+	/* Deletion may have cleared entries before failing. */
+	for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
+		struct tc_action *a = actions[i];
+		const struct tc_action_ops *ops;
+
+		if (!a)
+			continue;
+		ops = a->ops;
 		if (tcf_action_put(a))
 			module_put(ops->owner);
 	}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 197/877] net/sched: hhf: cap hh_flows_limit at change time
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (195 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 196/877] net/sched: act_api: release tail references on DELACTION failure Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 198/877] net/packet: clear RX owner on VNET header error Greg Kroah-Hartman
                   ` (687 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko (gemini), Victor Nogueira,
	hybris, Jamal Hadi Salim, Simon Horman, Paolo Abeni

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

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

From: Jamal Hadi Salim <jhs@mojatatu.com>

commit 2cef2588c995722a901368def30befeef9ae55c6 upstream.

hhf_change() stores TCA_HHF_HH_FLOWS_LIMIT with no upper bound. A huge
hh_flows_limit lets each new heavy-hitter flow pass the
hh_flows_current_cnt check in alloc_new_hh() and forces a fixed-size
kzalloc(GFP_ATOMIC) per flow under spoofed traffic, for unbounded memory
growth.

Bound the attribute with NLA_POLICY_MAX() at 2*HH_FLOWS_CNT (the
hhf_init() default) and report the rejected value via extack. The
deprecated nested parse is kept: legacy tc does not set NLA_F_NESTED on
TCA_OPTIONS. Configs relying on hh_limit above the default were relying
on unbounded, unsafe behaviour and are not supported going forward.

hhf_init() also ran hhf_change() before setting the default
hh_flows_limit, so a user-supplied hh_limit at add time was clobbered
back to 2048. Set the default before hhf_change() so the configured
value sticks.

This is a follow-up to commit eb56a495f59b ("net/sched: hhf: clamp
quantum in change and init paths"), which bounded the quantum of the
same qdisc; the hh_flows_limit bound is the remaining unbounded knob of
that series' scope.

Conditions to recreate the bug: CAP_NET_ADMIN in a user namespace;
tc qdisc change dev X root hhf hh_limit 4294967295 succeeds and the
value is echoed by tc qdisc show, unbounding heavy-hitter flow
allocations; also tc qdisc add dev X root hhf hh_limit 500 stores 2048
instead of 500.

Fixes: 10239edf86f1 ("net-qdisc-hhf: Heavy-Hitter Filter (HHF) qdisc")
Cc: stable@vger.kernel.org
Reported-by: Sashiko (gemini) <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260822195509.112717-1-jhs@mojatatu.com
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Tested-by: hybris <hybris@mojatatu.ai>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/QDISC-B855.v1.20260911153152@mojatatu.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/sched/sch_hhf.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

--- a/net/sched/sch_hhf.c
+++ b/net/sched/sch_hhf.c
@@ -526,7 +526,7 @@ static void hhf_destroy(struct Qdisc *sc
 static const struct nla_policy hhf_policy[TCA_HHF_MAX + 1] = {
 	[TCA_HHF_BACKLOG_LIMIT]	 = { .type = NLA_U32 },
 	[TCA_HHF_QUANTUM]	 = { .type = NLA_U32 },
-	[TCA_HHF_HH_FLOWS_LIMIT] = { .type = NLA_U32 },
+	[TCA_HHF_HH_FLOWS_LIMIT] = NLA_POLICY_MAX(NLA_U32, 2 * HH_FLOWS_CNT),
 	[TCA_HHF_RESET_TIMEOUT]	 = { .type = NLA_U32 },
 	[TCA_HHF_ADMIT_BYTES]	 = { .type = NLA_U32 },
 	[TCA_HHF_EVICT_TIMEOUT]	 = { .type = NLA_U32 },
@@ -545,7 +545,7 @@ static int hhf_change(struct Qdisc *sch,
 	u32 new_hhf_non_hh_weight = q->hhf_non_hh_weight;
 
 	err = nla_parse_nested_deprecated(tb, TCA_HHF_MAX, opt, hhf_policy,
-					  NULL);
+					  extack);
 	if (err < 0)
 		return err;
 
@@ -621,6 +621,9 @@ static int hhf_init(struct Qdisc *sch, s
 	q->hhf_evict_timeout = HZ;      /* 1  sec */
 	q->hhf_non_hh_weight = 2;
 
+	/* Cap max active HHs at twice len of hh_flows table. */
+	q->hh_flows_limit = 2 * HH_FLOWS_CNT;
+
 	if (opt) {
 		int err = hhf_change(sch, opt, extack);
 
@@ -637,8 +640,6 @@ static int hhf_init(struct Qdisc *sch, s
 		for (i = 0; i < HH_FLOWS_CNT; i++)
 			INIT_LIST_HEAD(&q->hh_flows[i]);
 
-		/* Cap max active HHs at twice len of hh_flows table. */
-		q->hh_flows_limit = 2 * HH_FLOWS_CNT;
 		q->hh_flows_overlimit = 0;
 		q->hh_flows_total_cnt = 0;
 		q->hh_flows_current_cnt = 0;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 198/877] net/packet: clear RX owner on VNET header error
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (196 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 197/877] net/sched: hhf: cap hh_flows_limit at change time Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 199/877] net/packet: avoid truncating TPACKET_V3 private size Greg Kroah-Hartman
                   ` (686 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mark Amirkan, Willem de Bruijn,
	Jakub Kicinski

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

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

From: Mark Amirkan <markdamirkan@gmail.com>

commit 33ff111d7ba3beb86e28938d6382bb5beabd865a upstream.

Commit 61fad6816fc1 ("net/packet: tpacket_rcv: avoid a producer race
condition") added rx_owner_map and made tpacket_rcv() claim a V1 or V2
ring slot before converting the virtio-net header.  If the conversion
fails, the drop path leaves the slot claimed.

With a one-frame TPACKET_V2 ring, an unsupported UDP GSO packet leaves
the only slot unavailable, so the ring also drops the next valid packet.

Clear the ownership bit on this error path.  TPACKET_V3 already clears
its block state here.

Fixes: 61fad6816fc1 ("net/packet: tpacket_rcv: avoid a producer race condition")
Cc: stable@vger.kernel.org
Signed-off-by: Mark Amirkan <markdamirkan@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260913-b4-send-packet-vnet-v1-1-5545ffb528ae@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/packet/af_packet.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2436,7 +2436,9 @@ static int tpacket_rcv(struct sk_buff *s
 	    virtio_net_hdr_from_skb(skb, h.raw + macoff -
 				    sizeof(struct virtio_net_hdr),
 				    vio_le(), true, 0)) {
-		if (po->tp_version == TPACKET_V3)
+		if (po->tp_version <= TPACKET_V2)
+			__clear_bit(slot_id, po->rx_ring.rx_owner_map);
+		else
 			prb_clear_blk_fill_status(&po->rx_ring);
 		goto drop_n_account;
 	}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 199/877] net/packet: avoid truncating TPACKET_V3 private size
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (197 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 198/877] net/packet: clear RX owner on VNET header error Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 200/877] scsi: core: Validate MODE SENSE lengths in scsi_cdl_enable() Greg Kroah-Hartman
                   ` (685 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mark Amirkan, Willem de Bruijn,
	Jakub Kicinski

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

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

From: Mark Amirkan <markdamirkan@gmail.com>

commit 37213e61120297920ae4c937fcb326a360da5084 upstream.

tpacket_req3.tp_sizeof_priv is an unsigned int, and packet_set_ring()
validates the full value against the block size.  init_prb_bdqc() then
stores it in the unsigned short blk_sizeof_priv field.

Commit 2b6867c2ce76 ("net/packet: fix overflow in check for priv area
size") fixed the validation arithmetic, but an accepted value above
USHRT_MAX still narrows when it is stored.

For a 131072-byte block, tp_sizeof_priv=65536 is valid.  The narrowing
makes offset_to_first_pkt 48 instead of 65584, so packet records can be
placed in the private area that userspace asked the kernel to preserve.

blk_sizeof_priv is internal state, so widen it to hold the validated
UAPI value.

Fixes: f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.")
Cc: stable@vger.kernel.org
Signed-off-by: Mark Amirkan <markdamirkan@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260913-b4-send-packet-private-v1-1-925eab2cd388@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/packet/internal.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/packet/internal.h
+++ b/net/packet/internal.h
@@ -21,7 +21,7 @@ struct tpacket_kbdq_core {
 	unsigned char	reset_pending_on_curr_blk;
 	unsigned char   delete_blk_timer;
 	unsigned short	kactive_blk_num;
-	unsigned short	blk_sizeof_priv;
+	unsigned int	blk_sizeof_priv;
 
 	/* last_kactive_blk_num:
 	 * trick to see if user-space has caught up



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 200/877] scsi: core: Validate MODE SENSE lengths in scsi_cdl_enable()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (198 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 199/877] net/packet: avoid truncating TPACKET_V3 private size Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 201/877] xfrm: serialize state GC with device state flush Greg Kroah-Hartman
                   ` (684 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko AI Review,
	Pimen Flavian Dei (Drivesec S.r.l.),
	Alberto Carboneri (Drivesec S.r.l.), Damien Le Moal,
	Martin K. Petersen (Oracle)

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

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

From: Alberto Carboneri <acarboneri@drivesec.com>

commit 3d676e458fe0c566f5a62753dc696b6a862fc412 upstream.

scsi_cdl_enable() uses length fields returned by MODE SENSE to locate
the ATA feature mode page in a 64-byte stack buffer. A target can report
a total length shorter than its mode header and block descriptors. The
unsigned subtraction used for the MODE SELECT length can wrap, and the
separately computed buf_data can point beyond buf.

During automatic scan, enable is false, so the read-modify-write of
buf_data[4] can clear the low two bits of a target-selected
out-of-bounds stack byte. scsi_mode_select() can then copy up to 64
bytes from outside the buffer into the outgoing MODE SELECT payload,
disclosing stack contents to the target.

This is reachable while scanning a USB storage device that identifies as
an ATA device and advertises CDL support. No filesystem mount or
userspace access to the block device is required.

On upstream commit cee9395acd80 ("Linux 7.3-rc1"), a build-specific,
one-vCPU QEMU/Raw Gadget proof using QEMU-only multi-UDC allocator
sampling executed a fixed proof command inside the guest and created a
UID-0-owned marker during automatic enumeration, with KASLR and NX
enabled.

The issue was independently found during security research at Drivesec
S.r.l.

Cap the available length to the buffer size. Validate and consume the
mode header and block descriptor lengths before using the page, and
require the five bytes needed to access the CDL field.

Fixes: 1b22cfb14142 ("scsi: core: Allow enabling and disabling command duration limits")
Reported-by: Sashiko AI Review <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-scsi/20260717192313.93D791F000E9@smtp.kernel.org/
Link: https://lore.kernel.org/linux-scsi/20260717222931.AC4EE1F000E9@smtp.kernel.org/
Link: https://lore.kernel.org/linux-scsi/df13ec87ac9b28e3b0a2d9eb26477e276ff0278a.camel@HansenPartnership.com/
Cc: stable@vger.kernel.org
Assisted-by: LLM
Co-developed-by: Pimen Flavian Dei (Drivesec S.r.l.) <fdei@drivesec.com>
Signed-off-by: Pimen Flavian Dei (Drivesec S.r.l.) <fdei@drivesec.com>
Signed-off-by: Alberto Carboneri (Drivesec S.r.l.) <acarboneri@drivesec.com>
Link: https://lore.kernel.org/linux-scsi/20260717192313.93D791F000E9@smtp.kernel.org/
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Link: https://patch.msgid.link/20260904135410.360314-1-acarboneri@drivesec.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/scsi.c |   24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -713,6 +713,7 @@ int scsi_cdl_enable(struct scsi_device *
 		struct scsi_mode_data data;
 		struct scsi_sense_hdr sshdr;
 		char *buf_data;
+		size_t avail, offset;
 		int len;
 
 		ret = scsi_mode_sense(sdev, 0x08, 0x0a, 0xf2, buf, sizeof(buf),
@@ -721,11 +722,24 @@ int scsi_cdl_enable(struct scsi_device *
 			return -EINVAL;
 
 		/* Enable or disable CDL using the ATA feature page */
-		len = min_t(size_t, sizeof(buf),
-			    data.length - data.header_length -
-			    data.block_descriptor_length);
-		buf_data = buf + data.header_length +
-			data.block_descriptor_length;
+		avail = min_t(size_t, data.length, sizeof(buf));
+		if (data.header_length > avail)
+			return -EINVAL;
+
+		offset = data.header_length;
+		avail -= data.header_length;
+
+		if (data.block_descriptor_length > avail)
+			return -EINVAL;
+
+		offset += data.block_descriptor_length;
+		avail -= data.block_descriptor_length;
+
+		if (avail < 5)
+			return -EINVAL;
+
+		buf_data = buf + offset;
+		len = avail;
 
 		/*
 		 * If we want to enable CDL and CDL is already enabled on the



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 201/877] xfrm: serialize state GC with device state flush
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (199 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 200/877] scsi: core: Validate MODE SENSE lengths in scsi_cdl_enable() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 202/877] xfrm: use hlist_del_init_rcu for state_cache and state_cache_input Greg Kroah-Hartman
                   ` (683 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Steffen Klassert

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

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

From: Chengfeng Ye <nicoyip.dev@gmail.com>

commit 89fefad9f971bc637fb22373078144f2563c4be9 upstream.

The deferred-device pass in xfrm_dev_state_flush() finds states under
xfrm_state_dev_gc_lock, but drops the lock before calling
xfrm_dev_state_free() because the driver callback may sleep.  The device
GC list does not hold an xfrm_state reference, so the state GC worker can
destroy the same state concurrently.

The race can proceed as follows:

  CPU 0                               CPU 1
  find x on the device GC list
  drop xfrm_state_dev_gc_lock
  read x->xso.dev
                                      xfrm_state_gc_destroy(x)
                                      xfrm_dev_state_free(x)
                                      xfrm_state_free(x)
  continue xfrm_dev_state_free(x)

Both paths can invoke the driver callback and drop the device reference.
CPU 0 can also access the xfrm_state after CPU 1 has freed it.

KASAN reported:

  BUG: KASAN: slab-use-after-free in xfrm_dev_state_free+0x24c/0x2a0
  Read of size 8 at addr ffff88810bbaa960 by task poc/102

  Call Trace:
   xfrm_dev_state_free+0x24c/0x2a0
   xfrm_dev_state_flush+0x353/0x400
   xfrm_dev_event+0x26d/0x3a0
   notifier_call_chain+0xc0/0x280
   __dev_notify_flags+0x169/0x250
   netif_change_flags+0xe7/0x160
   dev_change_flags+0x96/0x220
   devinet_ioctl+0x7f4/0x1880

  Allocated by task 87:
   xfrm_state_alloc+0x1e/0x5c0
   xfrm_add_sa+0xe7f/0x5820
   xfrm_user_rcv_msg+0x4f3/0x940

  Freed by task 57:
   kmem_cache_free+0xcb/0x3d0
   xfrm_state_gc_task+0x4a8/0x650
   process_one_work+0x63a/0x1070

Serialize xfrm_state destruction against the deferred-device pass with a
mutex.  Keep xfrm_state_dev_gc_lock limited to list operations and retain
the existing callback and device-reference release ordering.

Fixes: 07b87f9eea0c ("xfrm: Fix unregister netdevice hang on hardware offload.")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/xfrm/xfrm_state.c |    5 +++++
 1 file changed, 5 insertions(+)

--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -226,6 +226,7 @@ static struct xfrm_state_afinfo __rcu *x
 
 static DEFINE_SPINLOCK(xfrm_state_gc_lock);
 static DEFINE_SPINLOCK(xfrm_state_dev_gc_lock);
+static DEFINE_MUTEX(xfrm_state_gc_mutex);
 
 int __xfrm_state_delete(struct xfrm_state *x);
 
@@ -570,8 +571,10 @@ static void xfrm_state_gc_task(struct wo
 
 	synchronize_rcu();
 
+	mutex_lock(&xfrm_state_gc_mutex);
 	hlist_for_each_entry_safe(x, tmp, &gc_list, gclist)
 		xfrm_state_gc_destroy(x);
+	mutex_unlock(&xfrm_state_gc_mutex);
 }
 
 static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me)
@@ -937,6 +940,7 @@ restart:
 out:
 	spin_unlock_bh(&net->xfrm.xfrm_state_lock);
 
+	mutex_lock(&xfrm_state_gc_mutex);
 	spin_lock_bh(&xfrm_state_dev_gc_lock);
 restart_gc:
 	hlist_for_each_entry_safe(x, tmp, &xfrm_state_dev_gc_list, dev_gclist) {
@@ -951,6 +955,7 @@ restart_gc:
 
 	}
 	spin_unlock_bh(&xfrm_state_dev_gc_lock);
+	mutex_unlock(&xfrm_state_gc_mutex);
 
 	xfrm_flush_gc();
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 202/877] xfrm: use hlist_del_init_rcu for state_cache and state_cache_input
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (200 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 201/877] xfrm: serialize state GC with device state flush Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 203/877] memstick: ms_block: destroy io_queue workqueue on removal Greg Kroah-Hartman
                   ` (682 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Siwei Zhang, Steffen Klassert

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

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

From: Siwei Zhang <fourdizhang@tencent.com>

commit 2afb8dc1f4390f164db8352f8e685e126e9db566 upstream.

Commit 14acf9652e56 ("xfrm: defensively unhash xfrm_state lists in
__xfrm_state_delete") converted bydst/bysrc/byseq/byspi from
hlist_del_rcu() to hlist_del_init_rcu() so that a second
__xfrm_state_delete() on the same object becomes a no-op rather than a
write through LIST_POISON pprev. It missed state_cache and
state_cache_input, which kept hlist_del_rcu():

- hlist_del_rcu() leaves pprev = LIST_POISON2 (non-NULL), so
  hlist_unhashed() returns false.
- hlist_del_init_rcu() leaves pprev = NULL, so hlist_unhashed()
  returns true.

A second __xfrm_state_delete() therefore enters __hlist_del() on the
already-deleted state_cache/state_cache_input nodes and does
WRITE_ONCE(*pprev, next) through LIST_POISON2 — a write use-after-free
once the slab is reused. The corruption can in turn cause a subsequent
hlist_for_each_entry_rcu traversal to follow a dangling next pointer,
producing the read use-after-free reported in xfrm_input_state_lookup().

Switch state_cache and state_cache_input to hlist_del_init_rcu() to
match the other four lists, closing the write use-after-free and, with
it, the read use-after-free it spawns.

Assisted-by: CodeBuddy:GLM-5.2
Fixes: 0045e3d80613 ("xfrm: Cache used outbound xfrm states at the policy.")
Fixes: 81a331a0e72d ("xfrm: Add an inbound percpu state cache.")
Cc: stable@vger.kernel.org
Signed-off-by: Siwei Zhang <fourdizhang@tencent.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/xfrm/xfrm_state.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -763,9 +763,9 @@ int __xfrm_state_delete(struct xfrm_stat
 		if (!hlist_unhashed(&x->byseq))
 			hlist_del_init_rcu(&x->byseq);
 		if (!hlist_unhashed(&x->state_cache))
-			hlist_del_rcu(&x->state_cache);
+			hlist_del_init_rcu(&x->state_cache);
 		if (!hlist_unhashed(&x->state_cache_input))
-			hlist_del_rcu(&x->state_cache_input);
+			hlist_del_init_rcu(&x->state_cache_input);
 
 		if (!hlist_unhashed(&x->byspi))
 			hlist_del_init_rcu(&x->byspi);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 203/877] memstick: ms_block: destroy io_queue workqueue on removal
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (201 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 202/877] xfrm: use hlist_del_init_rcu for state_cache and state_cache_input Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 204/877] mm/mlock: use the IRQ-safe accessor for NR_MLOCK in __munlock_folio() Greg Kroah-Hartman
                   ` (681 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Yifei Gao, Ulf Hansson

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

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

From: Yifei Gao <gyf161023@gmail.com>

commit 90af7fde083e1b22c349c3a8b1626728e44e474c upstream.

msb_init_disk() creates the per-card ordered workqueue msb->io_queue with
alloc_ordered_workqueue(). It is torn down with destroy_workqueue() only
on the init error path; msb_remove() never destroys it. msb_stop() merely
flushes the queue, and neither msb_data_clear() nor put_disk() free it. As
a result every card insert/remove cycle leaks the workqueue and its
kworker, exhausting kernel memory over repeated cycles.

Destroy the workqueue in msb_remove() after the disk has been removed and
the queue drained.

Fixes: 0ab30494bc4f ("memstick: add support for legacy memorysticks")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Yifei Gao <gyf161023@gmail.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/memstick/core/ms_block.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/memstick/core/ms_block.c
+++ b/drivers/memstick/core/ms_block.c
@@ -2206,6 +2206,8 @@ static void msb_remove(struct memstick_d
 	msb_data_clear(msb);
 	mutex_unlock(&msb_disk_lock);
 
+	destroy_workqueue(msb->io_queue);
+
 	put_disk(msb->disk);
 	memstick_set_drvdata(card, NULL);
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 204/877] mm/mlock: use the IRQ-safe accessor for NR_MLOCK in __munlock_folio()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (202 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 203/877] memstick: ms_block: destroy io_queue workqueue on removal Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 205/877] KEYS: encrypted: fix integer overflow of datablob_len Greg Kroah-Hartman
                   ` (680 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Shakeel Butt,
	syzbot+cd2073ee6d958a8d0fcd, Hugh Dickins, Jann Horn,
	Liam R. Howlett, Lorenzo Stoakes, Matthew Wilcox (Oracle),
	Pedro Falcato, Vlastimil Babka, Andrew Morton

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

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

From: Shakeel Butt <shakeel.butt@linux.dev>

commit e14a3454806468b086fe2e4ca2e1bff95b528531 upstream.

NR_MLOCK is updated from interrupt context.  __free_pages_prepare() clears
a stray PG_mlocked and adjusts NR_MLOCK, and a folio can reach it with the
flag still set from a bio completion handler:

  __free_pages_ok+0x6af/0x7a0
  <IRQ>
  __bio_release_pages+0xde/0x260
  __iomap_dio_bio_end_io+0x16e/0x1a0
  blk_update_request+0x14b/0x3d0
  blk_mq_end_request+0x18/0x30
  blk_done_softirq+0x49/0x60

The folio gets there like this.  A MAP_SHARED file mapping is mlocked, so
its page cache folios carry PG_mlocked, and an O_DIRECT write sourced from
that mapping GUP-pins those same folios.  munlock() then runs
mlock_vma_pages_range(), which clears VM_LOCKED before walking the page
tables to munlock each folio.  A concurrent hole punch reaches the folio
through the rmap (i_mmap_rwsem, not mmap_lock) and can land inside that
window: __folio_remove_rmap() -> munlock_vma_folio() sees VM_LOCKED
already clear, so it neither queues the folio on the mlock batch nor takes
a reference, and the pte it clears makes the pending mlock_pte_range()
walk skip the folio at its !pte_present() check.  filemap_remove_folio()
then drops the page cache reference, leaving the bio's pin as the last
one, released from the completion handler above.

So __zone_stat_mod_folio() here needs interrupts disabled, not merely
preemption, and __munlock_folio() has a path where they are not: when the
folio has already been taken off the LRU by somebody else the function
jumps straight to the counter update without taking the lruvec lock.  The
read-modify-write of the per-CPU NR_MLOCK diff can then be interrupted by
the softirq above, and one of the two decrements is lost, leaving Mlocked
in /proc/meminfo permanently overstated.

Use zone_stat_mod_folio().  mod_zone_state()'s this_cpu_try_cmpxchg() is
atomic against a same-CPU interrupt and retries, and on the path where the
lruvec lock is held its cost is negligible next to the lock itself.

The UNEVICTABLE_PG* events are deliberately left on the __ accessors: they
occupy different vm_event_states slots from the UNEVICTABLE_PGCLEARED that
__free_pages_prepare() bumps, and nothing updates those two from interrupt
context.

Link: https://lore.kernel.org/20260901180109.3797944-1-shakeel.butt@linux.dev
Fixes: 2fbb0c10d1e8 ("mm/munlock: mlock_page() munlock_page() batch by pagevec")
Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev>
Reported-by: syzbot+cd2073ee6d958a8d0fcd@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-mm/6a931c5a.08e933ee.dbf97.0093.GAE@google.com/
Acked-by: Hugh Dickins <hughd@google.com>
Cc: Jann Horn <jannh@google.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Pedro Falcato <pfalcato@suse.de>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 mm/mlock.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -141,7 +141,7 @@ static struct lruvec *__munlock_folio(st
 
 munlock:
 	if (folio_test_clear_mlocked(folio)) {
-		__zone_stat_mod_folio(folio, NR_MLOCK, -nr_pages);
+		zone_stat_mod_folio(folio, NR_MLOCK, -nr_pages);
 		if (isolated || !folio_test_unevictable(folio))
 			__count_vm_events(UNEVICTABLE_PGMUNLOCKED, nr_pages);
 		else



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 205/877] KEYS: encrypted: fix integer overflow of datablob_len
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (203 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 204/877] mm/mlock: use the IRQ-safe accessor for NR_MLOCK in __munlock_folio() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 206/877] keys: translate request_key_auth pid for the reading procfs instance Greg Kroah-Hartman
                   ` (679 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Cen Zhang, Francis Perron,
	Jarkko Sakkinen, R Nageswara Sastry

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

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

From: Cen Zhang <cenzhang@linux.microsoft.com>

commit 8697c431e297eb0d0ab13dda6bc172b48a34f05c upstream.

encrypted_key_alloc() stores datablob_len in a u16. It is computed from
multiple string and payload lengths. If the result exceeds U16_MAX, the
assignment truncates the allocation size. KASAN reports a 32760-byte
slab-out-of-bounds write when __ekey_init() copies the master key
description into the undersized buffer.

The total payload length stored in key->datalen is also a u16. Use
check_add_overflow() to reject values that do not fit either destination,
and use kzalloc_flex() for the flexible-array allocation.

Fixes: 7e70cb497850 ("keys: add new key-type encrypted")
Cc: stable@vger.kernel.org
Assisted-by: GitHub-Copilot:claude-opus-4.6
Signed-off-by: Cen Zhang <cenzhang@linux.microsoft.com>
Signed-off-by: Francis Perron <francis@akrites.dev>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>
Link: https://lore.kernel.org/r/20260909153433.83117-1-cenzhang@linux.microsoft.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 security/keys/encrypted-keys/encrypted.c |   20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -18,6 +18,7 @@
 #include <linux/parser.h>
 #include <linux/string.h>
 #include <linux/err.h>
+#include <linux/overflow.h>
 #include <keys/user-type.h>
 #include <keys/trusted-type.h>
 #include <keys/encrypted-type.h>
@@ -606,6 +607,7 @@ static struct encrypted_key_payload *enc
 {
 	struct encrypted_key_payload *epayload = NULL;
 	unsigned short datablob_len;
+	unsigned short payload_totallen;
 	unsigned short decrypted_datalen;
 	unsigned short payload_datalen;
 	unsigned int encrypted_datalen;
@@ -659,16 +661,22 @@ static struct encrypted_key_payload *enc
 
 	encrypted_datalen = roundup(decrypted_datalen, blksize);
 
-	datablob_len = format_len + 1 + strlen(master_desc) + 1
-	    + strlen(datalen) + 1 + ivsize + 1 + encrypted_datalen;
+	if (check_add_overflow(format_len + 1 + strlen(master_desc) + 1
+			       + strlen(datalen) + 1 + ivsize + 1,
+			       encrypted_datalen, &datablob_len))
+		return ERR_PTR(-EINVAL);
+
+	if (check_add_overflow(datablob_len,
+			       payload_datalen + HASH_SIZE + 1,
+			       &payload_totallen))
+		return ERR_PTR(-EINVAL);
 
-	ret = key_payload_reserve(key, payload_datalen + datablob_len
-				  + HASH_SIZE + 1);
+	ret = key_payload_reserve(key, payload_totallen);
 	if (ret < 0)
 		return ERR_PTR(ret);
 
-	epayload = kzalloc(sizeof(*epayload) + payload_datalen +
-			   datablob_len + HASH_SIZE + 1, GFP_KERNEL);
+	epayload = kzalloc_flex(*epayload, payload_data, payload_totallen,
+				GFP_KERNEL);
 	if (!epayload)
 		return ERR_PTR(-ENOMEM);
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 206/877] keys: translate request_key_auth pid for the reading procfs instance
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (204 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 205/877] KEYS: encrypted: fix integer overflow of datablob_len Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 207/877] KEYS: trusted: Fix tpm2_load_cmd() boundary check Greg Kroah-Hartman
                   ` (678 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Maoyi Xie, Jarkko Sakkinen

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

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

From: Maoyi Xie <maoyixie.tju@gmail.com>

commit 0d6a4268b06084baafd8ee5d66955c7e1c2e053b upstream.

request_key_auth_describe() prints rka->pid into /proc/keys as a raw
pid_t in the initial pid namespace. A reader can open /proc/keys through
a mount in another pid namespace. That reader sees a number with no
meaning there. The number can even name an unrelated task. The line
needs VIEW on the key. So the reader either shares the key owner's uid
or possesses the key.

The fix keeps a struct pid. Commit 4f82f45730c6 ("net ip6 flowlabel:
Make owner a union of struct pid * and kuid_t") gave
/proc/net/ip6_flowlabel the same storage. The print goes through
pid_nr_ns(). It renders against the pid namespace of the procfs instance
the line is read through. Commit ad08978ab41c ("ipv6/flowlabel: simplify
pid namespace lookup") moved that print to the same anchor. Output
through an initial namespace /proc does not change. The line shows 0 for
a requestor with no number in that namespace.

Translating at read time was the alternative. find_pid_ns() can resolve
a recycled number. The line would then name a live task with no
connection to the key. A stored struct pid gives 0 instead when the
requestor has no number there.

Link: https://lore.kernel.org/keyrings/20260809110202.2180410-1-maoyixie.tju@gmail.com/
Fixes: 78b7280cce23 ("KEYS: Improve /proc/keys")
Cc: stable@vger.kernel.org # v5.10+
Assisted-by: Claude:claude-opus-5 codeql
Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com>
Link: https://lore.kernel.org/r/20260821095935.1864998-1-maoyixie.tju@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/keys/request_key_auth-type.h |    2 +-
 security/keys/request_key_auth.c     |   12 +++++++++---
 2 files changed, 10 insertions(+), 4 deletions(-)

--- a/include/keys/request_key_auth-type.h
+++ b/include/keys/request_key_auth-type.h
@@ -22,7 +22,7 @@ struct request_key_auth {
 	const struct cred	*cred;
 	void			*callout_info;
 	size_t			callout_len;
-	pid_t			pid;
+	struct pid		*pid;
 	char			op[8];
 } __randomize_layout;
 
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -9,6 +9,8 @@
 
 #include <linux/sched.h>
 #include <linux/err.h>
+#include <linux/pid.h>
+#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
@@ -73,7 +75,10 @@ static void request_key_auth_describe(co
 	seq_puts(m, "key:");
 	seq_puts(m, key->description);
 	if (key_is_positive(key))
-		seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
+		seq_printf(m, " pid:%d ci:%zu",
+			   pid_nr_ns(rka->pid,
+				     proc_pid_ns(file_inode(m->file)->i_sb)),
+			   rka->callout_len);
 }
 
 /*
@@ -113,6 +118,7 @@ static void free_request_key_auth(struct
 	if (rka->cred)
 		put_cred(rka->cred);
 	kfree(rka->callout_info);
+	put_pid(rka->pid);
 	kfree(rka);
 }
 
@@ -226,14 +232,14 @@ struct key *request_key_auth_new(struct
 
 		irka = cred->request_key_auth->payload.data[0];
 		rka->cred = get_cred(irka->cred);
-		rka->pid = irka->pid;
+		rka->pid = get_pid(irka->pid);
 
 		up_read(&cred->request_key_auth->sem);
 	}
 	else {
 		/* it isn't - use this process as the context */
 		rka->cred = get_cred(cred);
-		rka->pid = current->pid;
+		rka->pid = get_pid(task_pid(current));
 	}
 
 	rka->target_key = key_get(target);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 207/877] KEYS: trusted: Fix tpm2_load_cmd() boundary check
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (205 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 206/877] keys: translate request_key_auth pid for the reading procfs instance Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 208/877] i2c: at91: release DMA channels on remove and probe error Greg Kroah-Hartman
                   ` (677 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, co+6a581c4284f721d4,
	Stefano Garzarella, Srish Srinivasan, Jarkko Sakkinen

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

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

From: Jarkko Sakkinen <jarkko@kernel.org>

commit 114f00d738f15dd8c7318369edcdc53dd6d08763 upstream.

tpm2_load_cmd() does boundary checks against the ASN.1 size i.e.,
payload->blob_len. Address this by passing the decoded blob size to
tpm2_load_cmd(), and use it for the boundary checks.

Cc: stable@vger.kernel.org # v5.13+
Fixes: f2219745250f ("security: keys: trusted: use ASN.1 TPM2 key format for the blobs")
Reported-by: co+6a581c4284f721d4@bugs.sh
Closes: https://bugs.sh/b/6a581c4284f721d4/
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Tested-by: Srish Srinivasan <ssrish@linux.ibm.com>
Link: https://lore.kernel.org/r/20260901205809.2028454-1-jarkko@kernel.org
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 security/keys/trusted-keys/trusted_tpm2.c |   12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

--- a/security/keys/trusted-keys/trusted_tpm2.c
+++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -108,7 +108,7 @@ struct tpm2_key_context {
 
 static int tpm2_key_decode(struct trusted_key_payload *payload,
 			   struct trusted_key_options *options,
-			   u8 **buf)
+			   u8 **buf, unsigned int *blob_len)
 {
 	int ret;
 	struct tpm2_key_context ctx;
@@ -129,6 +129,7 @@ static int tpm2_key_decode(struct truste
 		return -ENOMEM;
 
 	*buf = blob;
+	*blob_len = ctx.priv_len + ctx.pub_len;
 	options->keyhandle = ctx.parent;
 
 	memcpy(blob, ctx.priv, ctx.priv_len);
@@ -402,10 +403,11 @@ static int tpm2_load_cmd(struct tpm_chip
 	int rc;
 	u32 attrs;
 
-	rc = tpm2_key_decode(payload, options, &blob);
+	rc = tpm2_key_decode(payload, options, &blob, &blob_len);
 	if (rc) {
 		/* old form */
 		blob = payload->blob;
+		blob_len = payload->blob_len;
 		payload->old_format = 1;
 	} else {
 		/* Bind for cleanup: */
@@ -417,17 +419,17 @@ static int tpm2_load_cmd(struct tpm_chip
 		return -EINVAL;
 
 	/* must be big enough for at least the two be16 size counts */
-	if (payload->blob_len < 4)
+	if (blob_len < 4)
 		return -EINVAL;
 
 	private_len = get_unaligned_be16(blob);
 
 	/* must be big enough for following public_len */
-	if (private_len + 2 + 2 > (payload->blob_len))
+	if (private_len + 2 + 2 > blob_len)
 		return -E2BIG;
 
 	public_len = get_unaligned_be16(blob + 2 + private_len);
-	if (private_len + 2 + public_len + 2 > payload->blob_len)
+	if (private_len + 2 + public_len + 2 > blob_len)
 		return -E2BIG;
 
 	pub = blob + 2 + private_len + 2;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 208/877] i2c: at91: release DMA channels on remove and probe error
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (206 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 207/877] KEYS: trusted: Fix tpm2_load_cmd() boundary check Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 209/877] i2c: atr: fix dangling adapter pointer on add failure Greg Kroah-Hartman
                   ` (676 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Shengzhuo Wei, Mukesh Kumar Savaliya,
	Andi Shyti

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

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

From: Shengzhuo Wei <me@cherr.cc>

commit f7eeb1af8537b05953fb1c88ab8b59d94059a381 upstream.

at91_twi_configure_dma() requests exclusive tx/rx DMA channels, but
nothing ever releases them on driver detach, and the probe error path
after the channels are acquired (i2c_add_numbered_adapter() failure)
returns without releasing them either, because the remove callback is
not invoked after a failed probe.

Move the release into a helper, call it from the existing
configure-failure path, the adapter-registration failure path, and
at91_twi_remove().

Fixes: 60937b2cdbf9 ("i2c: at91: add dma support")
Assisted-by: GLM:5.3
Signed-off-by: Shengzhuo Wei <me@cherr.cc>
Cc: <stable@vger.kernel.org> # v3.8+
Acked-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260827-i2c-dma-channel-leak-v1-1-271d4adc03a0@cherr.cc
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/i2c/busses/i2c-at91-core.c   |    3 +++
 drivers/i2c/busses/i2c-at91-master.c |   12 +++++++++++-
 drivers/i2c/busses/i2c-at91.h        |    1 +
 3 files changed, 15 insertions(+), 1 deletion(-)

--- a/drivers/i2c/busses/i2c-at91-core.c
+++ b/drivers/i2c/busses/i2c-at91-core.c
@@ -255,6 +255,7 @@ static int at91_twi_probe(struct platfor
 	if (rc) {
 		pm_runtime_disable(dev->dev);
 		pm_runtime_set_suspended(dev->dev);
+		at91_twi_dma_release(dev);
 
 		return rc;
 	}
@@ -270,6 +271,8 @@ static void at91_twi_remove(struct platf
 
 	i2c_del_adapter(&dev->adapter);
 
+	at91_twi_dma_release(dev);
+
 	pm_runtime_disable(dev->dev);
 	pm_runtime_set_suspended(dev->dev);
 }
--- a/drivers/i2c/busses/i2c-at91-master.c
+++ b/drivers/i2c/busses/i2c-at91-master.c
@@ -817,11 +817,21 @@ static int at91_twi_configure_dma(struct
 error:
 	if (ret != -EPROBE_DEFER)
 		dev_info(dev->dev, "can't get DMA channel, continue without DMA support\n");
+	at91_twi_dma_release(dev);
+	return ret;
+}
+
+void at91_twi_dma_release(struct at91_twi_dev *dev)
+{
+	struct at91_twi_dma *dma = &dev->dma;
+
 	if (dma->chan_rx)
 		dma_release_channel(dma->chan_rx);
 	if (dma->chan_tx)
 		dma_release_channel(dma->chan_tx);
-	return ret;
+	dma->chan_rx = NULL;
+	dma->chan_tx = NULL;
+	dev->use_dma = false;
 }
 
 static int at91_init_twi_recovery_gpio(struct platform_device *pdev,
--- a/drivers/i2c/busses/i2c-at91.h
+++ b/drivers/i2c/busses/i2c-at91.h
@@ -172,6 +172,7 @@ void at91_twi_irq_restore(struct at91_tw
 void at91_init_twi_bus(struct at91_twi_dev *dev);
 
 void at91_init_twi_bus_master(struct at91_twi_dev *dev);
+void at91_twi_dma_release(struct at91_twi_dev *dev);
 int at91_twi_probe_master(struct platform_device *pdev, u32 phy_addr,
 			  struct at91_twi_dev *dev);
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 209/877] i2c: atr: fix dangling adapter pointer on add failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (207 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 208/877] i2c: at91: release DMA channels on remove and probe error Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 210/877] i2c: imx: release DMA channels on probe error Greg Kroah-Hartman
                   ` (675 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Linkai Gong, Andy Shevchenko,
	Andi Shyti

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

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

From: Linkai Gong <gonglinkai@kylinos.cn>

commit ad34235808b63a70ca4989b7a2852923193d06ef upstream.

i2c_atr_add_adapter() stores atr->adapter[chan_id] before
i2c_add_adapter() so that the I2C bus notifier can match child clients
during registration. On failure the channel is freed but the slot was
left pointing at freed memory, which can lead to use-after-free in
i2c_atr_del_adapter() / cleanup and also block reuse with -EEXIST.

Clear the slot on the i2c_add_adapter() error path before freeing chan.

Fixes: a076a860acae ("media: i2c: add I2C Address Translator (ATR) support")
Signed-off-by: Linkai Gong <gonglinkai@kylinos.cn>
Cc: <stable@vger.kernel.org> # v6.6+
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260907071102.1080840-1-gonglinkai@kylinos.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/i2c/i2c-atr.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/i2c/i2c-atr.c
+++ b/drivers/i2c/i2c-atr.c
@@ -632,6 +632,7 @@ int i2c_atr_add_adapter(struct i2c_atr *
 
 	ret = i2c_add_adapter(&chan->adap);
 	if (ret) {
+		atr->adapter[chan_id] = NULL;
 		dev_err(dev, "failed to add atr-adapter %u (error=%d)\n",
 			chan_id, ret);
 		goto err_fwnode_put;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 210/877] i2c: imx: release DMA channels on probe error
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (208 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 209/877] i2c: atr: fix dangling adapter pointer on add failure Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 211/877] i2c: imx: disable autosuspend on remove Greg Kroah-Hartman
                   ` (674 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Shengzhuo Wei, Frank Li, Andi Shyti

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

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

From: Shengzhuo Wei <me@cherr.cc>

commit e9f03b9625e2eeaca357b065c92d5b14064a1583 upstream.

i2c_imx_dma_request() acquires exclusive tx/rx DMA channels and is
optional: on errors other than -EPROBE_DEFER the driver falls back to
PIO mode and probe continues. If i2c_add_numbered_adapter() then fails,
probe returns through clk_notifier_unregister without releasing the
channels, because the remove callback is not invoked after a failed
probe.

Release the channels on the probe error path, mirroring
i2c_imx_remove().

Fixes: ce1a78840ff7 ("i2c: imx: add DMA support for freescale i2c driver")
Assisted-by: GLM:5.3
Signed-off-by: Shengzhuo Wei <me@cherr.cc>
Cc: <stable@vger.kernel.org> # v3.19+
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260827-i2c-dma-channel-leak-v1-2-271d4adc03a0@cherr.cc
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/i2c/busses/i2c-imx.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -1557,6 +1557,8 @@ static int i2c_imx_probe(struct platform
 
 clk_notifier_unregister:
 	clk_notifier_unregister(i2c_imx->clk, &i2c_imx->clk_change_nb);
+	if (i2c_imx->dma)
+		i2c_imx_dma_free(i2c_imx);
 	free_irq(irq, i2c_imx);
 rpm_disable:
 	pm_runtime_put_noidle(&pdev->dev);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 211/877] i2c: imx: disable autosuspend on remove
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (209 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 210/877] i2c: imx: release DMA channels on probe error Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 212/877] IB/mlx4: Fix use-after-free on pkey sysfs registration failure Greg Kroah-Hartman
                   ` (673 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Frank Li, Andi Shyti

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

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

From: Guangshuo Li <lgs201920130244@gmail.com>

commit e0c3e9d76adbe522dd420a766ce42d03ce887c29 upstream.

i2c_imx_probe() enables runtime PM autosuspend with
pm_runtime_use_autosuspend(). The probe error path correctly undoes
this setting with pm_runtime_dont_use_autosuspend(), but the normal
remove path only disables runtime PM.

The runtime PM API requires pm_runtime_use_autosuspend() to be undone
with pm_runtime_dont_use_autosuspend() at driver exit unless runtime PM
was enabled with devm_pm_runtime_enable(). Leaving the autosuspend flag
set therefore leaves the runtime PM state incompletely cleaned up after
the driver is unbound.

Add the missing pm_runtime_dont_use_autosuspend() call to the remove
path.

This issue was found by manual code inspection.

Fixes: 588eb93ea49f ("i2c: imx: add runtime pm support to improve the performance")
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Cc: <stable@vger.kernel.org> # v4.5+
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260914091544.1667137-1-lgs201920130244@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/i2c/busses/i2c-imx.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -1599,6 +1599,7 @@ static void i2c_imx_remove(struct platfo
 
 	pm_runtime_put_noidle(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
+	pm_runtime_dont_use_autosuspend(&pdev->dev);
 }
 
 static int i2c_imx_runtime_suspend(struct device *dev)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 212/877] IB/mlx4: Fix use-after-free on pkey sysfs registration failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (210 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 211/877] i2c: imx: disable autosuspend on remove Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 213/877] IB/hfi1: Resolve the credit-return buffer through the send contexts node Greg Kroah-Hartman
                   ` (672 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Shuangpeng Bai, Leon Romanovsky

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

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

From: Shuangpeng Bai <shuangpeng.kernel@gmail.com>

commit 1af874e9f4ce22ccf8b10ab5462f32c70d3be21a upstream.

register_pkey_tree() ignores errors from register_one_pkey_tree() and
continues registering the remaining slaves. The per-slave error path has
already released the pkey parent kobjects, but their pointers remain
stored in the device. A later device cleanup therefore passes the stale
pointers to kobject_put(), causing a use-after-free.

Clear the parent pointers after releasing a failed slave tree and skip
unregistered trees during device cleanup. This preserves the existing
best-effort registration behavior while preventing a second cleanup of
the failed tree.

Fixes: c1e7e466120b ("IB/mlx4: Add iov directory in sysfs under the ib device")
Cc: stable@vger.kernel.org
Signed-off-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
Link: https://patch.msgid.link/20260816044510.3848996-1-shuangpeng.kernel@gmail.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/infiniband/hw/mlx4/sysfs.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/drivers/infiniband/hw/mlx4/sysfs.c
+++ b/drivers/infiniband/hw/mlx4/sysfs.c
@@ -753,11 +753,13 @@ err_add:
 		kobject_put(p);
 	}
 	kobject_put(dev->dev_ports_parent[slave]);
+	dev->dev_ports_parent[slave] = NULL;
 
 err_ports:
 	kobject_put(dev->pkeys.device_parent[slave]);
 	/* extra put for the device_parent create_and_add */
 	kobject_put(dev->pkeys.device_parent[slave]);
+	dev->pkeys.device_parent[slave] = NULL;
 
 fail_dev:
 	kobject_put(dev->iov_parent);
@@ -787,6 +789,8 @@ static void unregister_pkey_tree(struct
 		return;
 
 	for (slave = device->dev->persist->num_vfs; slave >= 0; --slave) {
+		if (!device->pkeys.device_parent[slave])
+			continue;
 		list_for_each_entry_safe(p, t,
 					 &device->pkeys.pkey_port_list[slave],
 					 entry) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 213/877] IB/hfi1: Resolve the credit-return buffer through the send contexts node
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (211 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 212/877] IB/mlx4: Fix use-after-free on pkey sysfs registration failure Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 214/877] IB/hfi1: Fix the PIO_CRED credit-return mmap Greg Kroah-Hartman
                   ` (671 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Shuhei Takeshita, Leon Romanovsky

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

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

From: Shuhei Takeshita <jyohuku.alterego@gmail.com>

commit 975396b9e5a4028e649f4b9a6a5ca5dfb76a824b upstream.

hfi1_file_mmap()'s PIO_CRED case derives this context's credit-return
page offset, and the DMA handle for it, from dd->cr_base[uctxt->numa_id].
uctxt->numa_id is the node of whichever CPU the process happened to be
running on, but the entry itself lives in the credit-return allocation of
the send context's own node:

	sc->hw_free = &sc->dd->cr_base[sc->node].va[gc].cr[index];

and user send contexts are allocated with sc_alloc(dd, SC_USER, ...,
dd->node), the HFI-local node.  On a multi-socket host with the process
running off that node the two allocations differ, so the subtraction
produces an offset into an unrelated buffer and the DMA handle belongs to
the wrong allocation.

Use the send context's own node for all three references.  The
continuation lines are reindented at the same time; they mixed spaces and
tabs.

Fixes: 7724105686e7 ("IB/hfi1: add driver files")
Cc: stable@vger.kernel.org
Signed-off-by: Shuhei Takeshita <jyohuku.alterego@gmail.com>
Link: https://patch.msgid.link/20260809032743.2671579-2-jyohuku.alterego@gmail.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/infiniband/hw/hfi1/file_ops.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

--- a/drivers/infiniband/hw/hfi1/file_ops.c
+++ b/drivers/infiniband/hw/hfi1/file_ops.c
@@ -382,10 +382,10 @@ static int hfi1_file_mmap(struct file *f
 		 * of enabled contexts > 64 and 128 respectively).
 		 */
 		cr_page_offset = ((u64)uctxt->sc->hw_free -
-			  	     (u64)dd->cr_base[uctxt->numa_id].va) &
-				   PAGE_MASK;
-		memvirt = dd->cr_base[uctxt->numa_id].va + cr_page_offset;
-		memdma = dd->cr_base[uctxt->numa_id].dma + cr_page_offset;
+				  (u64)dd->cr_base[uctxt->sc->node].va) &
+				 PAGE_MASK;
+		memvirt = dd->cr_base[uctxt->sc->node].va + cr_page_offset;
+		memdma = dd->cr_base[uctxt->sc->node].dma + cr_page_offset;
 		memlen = PAGE_SIZE;
 		flags &= ~VM_MAYWRITE;
 		flags |= VM_DONTCOPY | VM_DONTEXPAND;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 214/877] IB/hfi1: Fix the PIO_CRED credit-return mmap
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (212 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 213/877] IB/hfi1: Resolve the credit-return buffer through the send contexts node Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 215/877] selinux: preserve user SID across nested backing files Greg Kroah-Hartman
                   ` (670 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Shuhei Takeshita, Leon Romanovsky

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

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

From: Shuhei Takeshita <jyohuku.alterego@gmail.com>

commit 62f0f34fbd2b2d5653d33d3b9d42fdcabb1c0101 upstream.

hfi1_file_mmap()'s PIO_CRED case must hand user space the single
credit-return page that holds this context's entry.  That page is the
second or third page of the per-node credit-return allocation once the
hardware send context index reaches 64 or 128, so the failure below is
intermittent: when the entry lands on the first page the offset is zero
and everything works.

Two things are wrong.

First, cr_page_offset is a byte offset but .va is a struct
credit_return *, so adding it is pointer arithmetic and scales the offset
by sizeof(struct credit_return) == 64.  memvirt then lands 256 KiB or
512 KiB past a 10240-byte allocation.  With an IOMMU translating, that
address is inside the vmalloc range but in no vm_area, so
dma_mmap_coherent() -> iommu_dma_mmap() finds no pages, vmalloc_to_pfn()
returns page_to_pfn(NULL), and remap_pfn_range() installs a frame above
MAXPHYADDR.  The first user read then takes:

  psm2_ep_open_pr: Corrupted page table at address 7a14d007e000
  PGD 800000013886a067 P4D 800000013886a067 PUD 13886b067 PMD 13886c067
                                            PTE 800049168e911235
  Oops: Bad pagetable: 000d [#1] SMP PTI

Second, and still wrong once the arithmetic is corrected,
dma_mmap_coherent() describes a whole coherent buffer and selects the
page within it with vma->vm_pgoff.  Offsetting cpu_addr has no effect:
for a vmap'd allocation iommu_dma_mmap() uses cpu_addr only to locate the
vm_area and then maps pages[vm_pgoff], which hfi1_file_mmap() has just
set to 0.  User space therefore always receives the first credit-return
page, every credit read is for the wrong context, and send PIO stalls
forever.

Use the DMA API as intended: pass the base of the allocation with its
full length and select the page with vm_pgoff.  A separate length is
needed because memlen must keep describing the VMA for the existing size
check.  The dma-direct path stays correct as well, since dma_direct_mmap()
adds the same vm_pgoff to the base pfn.

Tested on a Dell T7610 (Xeon E5-2650 v2, Intel IOMMU in DMA-FQ mode)
against a Threadripper PRO 3995WX peer, both Omni-Path 100.  Before this
change psm2_ep_open() Oopses the kernel; with only the arithmetic
corrected psm2_ep_open() succeeds but any transfer that uses send PIO
hangs, PSM2_SDMA=2 (send PIO disabled) completing normally while
PSM2_SDMA=0 (send PIO only) hangs every time.  With this change send PIO,
send DMA and the default mixed mode all work.

Fixes: 1ec82317a1da ("IB/hfi1: Use dma_mmap_coherent for matching buffers")
Cc: stable@vger.kernel.org
Signed-off-by: Shuhei Takeshita <jyohuku.alterego@gmail.com>
Link: https://patch.msgid.link/20260809032743.2671579-3-jyohuku.alterego@gmail.com
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/infiniband/hw/hfi1/file_ops.c |   21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

--- a/drivers/infiniband/hw/hfi1/file_ops.c
+++ b/drivers/infiniband/hw/hfi1/file_ops.c
@@ -326,6 +326,7 @@ static int hfi1_file_mmap(struct file *f
 	void *memvirt = NULL;
 	dma_addr_t memdma = 0;
 	u8 subctxt, mapio = 0, vmf = 0, type;
+	size_t memdmalen = 0;
 	ssize_t memlen = 0;
 	int ret = 0;
 	u16 ctxt;
@@ -371,7 +372,9 @@ static int hfi1_file_mmap(struct file *f
 		mapio = 1;
 		break;
 	case PIO_CRED: {
+		struct credit_return_base *cr = &dd->cr_base[uctxt->sc->node];
 		u64 cr_page_offset;
+
 		if (flags & VM_WRITE) {
 			ret = -EPERM;
 			goto done;
@@ -381,11 +384,18 @@ static int hfi1_file_mmap(struct file *f
 		 * second or third page allocated for credit returns (if number
 		 * of enabled contexts > 64 and 128 respectively).
 		 */
-		cr_page_offset = ((u64)uctxt->sc->hw_free -
-				  (u64)dd->cr_base[uctxt->sc->node].va) &
+		cr_page_offset = ((u64)uctxt->sc->hw_free - (u64)cr->va) &
 				 PAGE_MASK;
-		memvirt = dd->cr_base[uctxt->sc->node].va + cr_page_offset;
-		memdma = dd->cr_base[uctxt->sc->node].dma + cr_page_offset;
+		/*
+		 * dma_mmap_coherent() describes the whole coherent buffer and
+		 * selects the page within it with vma->vm_pgoff, so pass the
+		 * base of the allocation and its length and let vm_pgoff pick
+		 * the page.
+		 */
+		vma->vm_pgoff = cr_page_offset >> PAGE_SHIFT;
+		memvirt = cr->va;
+		memdma = cr->dma;
+		memdmalen = TXE_NUM_CONTEXTS * sizeof(struct credit_return);
 		memlen = PAGE_SIZE;
 		flags &= ~VM_MAYWRITE;
 		flags |= VM_DONTCOPY | VM_DONTEXPAND;
@@ -567,7 +577,8 @@ static int hfi1_file_mmap(struct file *f
 		ret = 0;
 	} else if (memdma) {
 		ret = dma_mmap_coherent(&dd->pcidev->dev, vma,
-					memvirt, memdma, memlen);
+					memvirt, memdma,
+					memdmalen ? memdmalen : memlen);
 	} else if (mapio) {
 		ret = io_remap_pfn_range(vma, vma->vm_start,
 					 PFN_DOWN(memaddr),



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 215/877] selinux: preserve user SID across nested backing files
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (213 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 214/877] IB/hfi1: Fix the PIO_CRED credit-return mmap Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 216/877] selinux: recheck intermediate backing files on mprotect() Greg Kroah-Hartman
                   ` (669 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Amir Goldstein,
	Stephen Smalley, Paul Moore

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

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

From: Karl Mehltretter <kmehltretter@gmail.com>

commit 8c0c602202b9a4909b00bc3354e3c0355bc69e65 upstream.

SELinux saves the user file SID in a backing-file security blob so it
remains available after mmap() replaces vma->vm_file with a backing file.

For nested backing files (overlayfs over overlayfs, or FUSE passthrough
backed by overlayfs), user_file may itself be a backing file.  Its
fsec->sid is the SID of the mounter that opened it, rather than the user
that opened the top-level file.  mprotect() then checks fd { use } against
the mounter SID.  This can incorrectly deny access without a domain
transition, or check the wrong target SID after one.

Copy the saved user SID when user_file is a backing file.  Keep using the
regular file SID for the first backing layer.

With two nested overlayfs mounts and SELinux enforcing,
mprotect(PROT_READ) returns EACCES with an fd { use } denial against the
mounter SID.  With this change, mprotect() succeeds.

Tested on arm64 QEMU with a small BusyBox initramfs and a purpose-built
SELinux policy.  The original test was also repeated with Fedora Cloud
Base 44 userspace and gave the same result.

Cc: stable@vger.kernel.org
Fixes: 82544d36b172 ("selinux: fix overlayfs mmap() and mprotect() access checks")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 security/selinux/hooks.c          |    9 ++++++++-
 security/selinux/include/objsec.h |    2 +-
 2 files changed, 9 insertions(+), 2 deletions(-)

--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3676,13 +3676,20 @@ static int selinux_file_alloc_security(s
 	return 0;
 }
 
+static inline u32 selinux_file_user_sid(const struct file *file)
+{
+	if (unlikely(file->f_mode & FMODE_BACKING))
+		return selinux_backing_file(file)->uf_sid;
+	return selinux_file(file)->sid;
+}
+
 static int selinux_backing_file_alloc(struct file *backing_file,
 				      const struct file *user_file)
 {
 	struct backing_file_security_struct *bfsec;
 
 	bfsec = selinux_backing_file(backing_file);
-	bfsec->uf_sid = selinux_file(user_file)->sid;
+	bfsec->uf_sid = selinux_file_user_sid(user_file);
 
 	return 0;
 }
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -62,7 +62,7 @@ struct file_security_struct {
 };
 
 struct backing_file_security_struct {
-	u32 uf_sid; /* associated user file fsec->sid */
+	u32 uf_sid; /* top-level user file fsec->sid */
 };
 
 struct superblock_security_struct {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 216/877] selinux: recheck intermediate backing files on mprotect()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (214 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 215/877] selinux: preserve user SID across nested backing files Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 217/877] selinux: always fill AVC decision in avc_has_perm_noaudit() Greg Kroah-Hartman
                   ` (668 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Stephen Smalley,
	Paul Moore

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

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

From: Karl Mehltretter <kmehltretter@gmail.com>

commit 78fc54b934bfb2c18aad8154c7302067146946f9 upstream.

mprotect() can be used to bypass the SELinux checks that mmap() performs
against the intermediate layers of a stacked filesystem.

mmap() checks every backing layer as the request descends through the
stack.  mprotect() only has the lowest backing file in vma->vm_file, so it
rechecks the top-level user and the lowest mounter, but skips the mounters
of every layer in between.  With two nested overlayfs mounts and a policy
denying mounter_t -> middle_file_t:file { execute }, a direct
mmap(PROT_EXEC) is denied:

  avc:  denied  { execute } for  pid=71 comm="nested_exec"
    path="/payload" dev="overlay" ino=9
    scontext=user_u:base_r:mounter_t
    tcontext=user_u:object_r:middle_file_t tclass=file permissive=0

while mmap(PROT_NONE) followed by mprotect(PROT_EXEC) succeeds.

Preserve each intermediate path, mounter SID and file-description SID in
the backing-file security blob, copying the saved entries when another
backing layer is opened.  Allocate the array only for nested backing files,
and release it and the path references in the backing_file_free hook.

During mprotect(), recheck fd { use } and the requested inode permissions
for every saved mounter, and include the intermediate layers in the execmod
checks.  Policy for nested stacking may then need to grant intermediate
mounters what a direct mmap() already requires, and execmod on intermediate
labels for binaries using text relocations.

Tested on arm64 QEMU with a small BusyBox initramfs and a purpose-built
SELinux policy, on a mainline tree containing
commit f2381b546e7e ("fs: fix user path of nested backing files").

Cc: stable@vger.kernel.org
Fixes: 82544d36b172 ("selinux: fix overlayfs mmap() and mprotect() access checks")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com>
[PM: subject tweak]
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 security/selinux/hooks.c          |  141 +++++++++++++++++++++++++++++++++-----
 security/selinux/include/objsec.h |    8 ++
 2 files changed, 133 insertions(+), 16 deletions(-)

--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1656,26 +1656,32 @@ static int cred_has_capability(const str
 	return rc;
 }
 
-/* Check whether a task has a particular permission to an inode.
-   The 'adp' parameter is optional and allows other audit
-   data to be passed (e.g. the dentry). */
-static int inode_has_perm(const struct cred *cred,
-			  struct inode *inode,
-			  u32 perms,
-			  struct common_audit_data *adp)
+/*
+ * Check whether a SID has a particular permission to an inode.  The 'adp'
+ * parameter is optional and allows other audit data to be passed (e.g. the
+ * dentry).
+ */
+static int inode_sid_has_perm(u32 sid, struct inode *inode, u32 perms,
+			      struct common_audit_data *adp)
 {
 	struct inode_security_struct *isec;
-	u32 sid;
 
 	if (unlikely(IS_PRIVATE(inode)))
 		return 0;
 
-	sid = cred_sid(cred);
 	isec = selinux_inode(inode);
 
 	return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp);
 }
 
+static int inode_has_perm(const struct cred *cred,
+			  struct inode *inode,
+			  u32 perms,
+			  struct common_audit_data *adp)
+{
+	return inode_sid_has_perm(cred_sid(cred), inode, perms, adp);
+}
+
 /* Same as inode_has_perm, but pass explicit audit data containing
    the dentry to help the auditing code to more easily generate the
    pathname if needed. */
@@ -3687,13 +3693,63 @@ static int selinux_backing_file_alloc(st
 				      const struct file *user_file)
 {
 	struct backing_file_security_struct *bfsec;
+	const struct backing_file_security_struct *ubfsec;
+	struct backing_file_security_layer *layer;
+	u32 i;
 
 	bfsec = selinux_backing_file(backing_file);
 	bfsec->uf_sid = selinux_file_user_sid(user_file);
+	if (!(user_file->f_mode & FMODE_BACKING))
+		return 0;
+
+	ubfsec = selinux_backing_file(user_file);
+	/* a wrapped count would make kmalloc_array() return ZERO_SIZE_PTR */
+	if (unlikely(ubfsec->layer_count == U32_MAX))
+		return -EOVERFLOW;
+
+	/*
+	 * The final VMA only retains the lowest backing file, so record the
+	 * whole chain here rather than in the mmap hook, where concurrent
+	 * mappings would have to be serialized.  Size it dynamically: erofs
+	 * inode sharing adds a backing file without bumping s_stack_depth.
+	 */
+	bfsec->layers = kmalloc_array(ubfsec->layer_count + 1,
+				      sizeof(*bfsec->layers), GFP_KERNEL);
+	if (!bfsec->layers)
+		return -ENOMEM;
+
+	for (i = 0; i < ubfsec->layer_count; i++) {
+		layer = &bfsec->layers[i];
+		*layer = ubfsec->layers[i];
+		path_get(&layer->path);
+	}
+
+	/* f_path, not file_user_path(): this layer, not the top-level file */
+	layer = &bfsec->layers[i];
+	layer->path = user_file->f_path;
+	layer->mounter_sid = cred_sid(user_file->f_cred);
+	layer->fd_sid = selinux_file(user_file)->sid;
+	path_get(&layer->path);
+	bfsec->layer_count = ubfsec->layer_count + 1;
 
 	return 0;
 }
 
+static void selinux_backing_file_free(struct file *backing_file)
+{
+	struct backing_file_security_struct *bfsec;
+
+	/* security_backing_file_free() may be called twice after an error */
+	if (!backing_file_security(backing_file))
+		return;
+
+	bfsec = selinux_backing_file(backing_file);
+	while (bfsec->layer_count)
+		path_put(&bfsec->layers[--bfsec->layer_count].path);
+	kfree(bfsec->layers);
+	bfsec->layers = NULL;
+}
+
 /*
  * Check whether a task has the ioctl permission and cmd
  * operation to an inode.
@@ -3811,6 +3867,53 @@ static int selinux_file_ioctl_compat(str
 
 static int default_noexec __ro_after_init;
 
+static u32 file_map_prot_to_av(unsigned long prot, bool shared)
+{
+	u32 av = FILE__READ;
+
+	if (shared && (prot & PROT_WRITE))
+		av |= FILE__WRITE;
+	if (prot & PROT_EXEC)
+		av |= FILE__EXECUTE;
+
+	return av;
+}
+
+static int backing_mounters_has_perm(const struct file *file, u32 av)
+{
+	const struct backing_file_security_struct *bfsec;
+	const struct backing_file_security_layer *layer;
+	struct common_audit_data ad;
+	struct inode *inode;
+	u32 i;
+	int rc;
+
+	if (WARN_ON_ONCE(!(file->f_mode & FMODE_BACKING)))
+		return -EIO;
+
+	bfsec = selinux_backing_file(file);
+	for (i = 0; i < bfsec->layer_count; i++) {
+		layer = &bfsec->layers[i];
+		inode = d_inode(layer->path.dentry);
+
+		ad.type = LSM_AUDIT_DATA_PATH;
+		ad.u.path = layer->path;
+
+		if (layer->mounter_sid != layer->fd_sid) {
+			rc = avc_has_perm(layer->mounter_sid, layer->fd_sid,
+					  SECCLASS_FD, FD__USE, &ad);
+			if (rc)
+				return rc;
+		}
+
+		rc = inode_sid_has_perm(layer->mounter_sid, inode, av, &ad);
+		if (rc)
+			return rc;
+	}
+
+	return 0;
+}
+
 static int __file_map_prot_check(const struct file *file, unsigned long prot,
 				 bool shared, bool mounter_check,
 				 bool bf_user_file)
@@ -3844,14 +3947,10 @@ static int __file_map_prot_check(const s
 	if (file) {
 		const struct cred *cred = mounter_check ?
 				file->f_cred : current_cred();
-		/* "read" always possible, "write" only if shared */
-		u32 av = FILE__READ;
-		if (shared && prot_write)
-			av |= FILE__WRITE;
-		if (prot_exec)
-			av |= FILE__EXECUTE;
 
-		return __file_has_perm(cred, file, av, bf_user_file);
+		return __file_has_perm(cred, file,
+				       file_map_prot_to_av(prot, shared),
+				       bf_user_file);
 	}
 
 	return 0;
@@ -3946,6 +4045,7 @@ static int selinux_file_mprotect(struct
 	int rc;
 	const struct cred *cred = current_cred();
 	u32 sid = cred_sid(cred);
+	u32 av;
 	const struct file *file = vma->vm_file;
 	bool backing_file;
 	bool shared = vma->vm_flags & VM_SHARED;
@@ -3989,6 +4089,10 @@ static int selinux_file_mprotect(struct
 			if (rc)
 				return rc;
 			if (backing_file) {
+				rc = backing_mounters_has_perm(file,
+							       FILE__EXECMOD);
+				if (rc)
+					return rc;
 				rc = file_has_perm(file->f_cred, file,
 						   FILE__EXECMOD);
 				if (rc)
@@ -4001,6 +4105,10 @@ static int selinux_file_mprotect(struct
 	if (rc)
 		return rc;
 	if (backing_file) {
+		av = file_map_prot_to_av(prot, shared);
+		rc = backing_mounters_has_perm(file, av);
+		if (rc)
+			return rc;
 		rc = file_map_prot_check(file, prot, shared, true);
 		if (rc)
 			return rc;
@@ -7309,6 +7417,7 @@ static struct security_hook_list selinux
 	LSM_HOOK_INIT(file_permission, selinux_file_permission),
 	LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
 	LSM_HOOK_INIT(backing_file_alloc, selinux_backing_file_alloc),
+	LSM_HOOK_INIT(backing_file_free, selinux_backing_file_free),
 	LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl),
 	LSM_HOOK_INIT(file_ioctl_compat, selinux_file_ioctl_compat),
 	LSM_HOOK_INIT(mmap_file, selinux_mmap_file),
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -61,8 +61,16 @@ struct file_security_struct {
 	u32 pseqno; /* Policy seqno at the time of file open */
 };
 
+struct backing_file_security_layer {
+	struct path path; /* this layer's real path */
+	u32 mounter_sid; /* SID of the mounter that opened it */
+	u32 fd_sid; /* SID of its open file description */
+};
+
 struct backing_file_security_struct {
 	u32 uf_sid; /* top-level user file fsec->sid */
+	u32 layer_count; /* number of intermediate backing files */
+	struct backing_file_security_layer *layers;
 };
 
 struct superblock_security_struct {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 217/877] selinux: always fill AVC decision in avc_has_perm_noaudit()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (215 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 216/877] selinux: recheck intermediate backing files on mprotect() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 218/877] power: sequencing: dont call .post_enable() if pwrseq_unit_enable() failed Greg Kroah-Hartman
                   ` (667 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Christian Göttsche,
	Stephen Smalley, Paul Moore

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

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

From: Christian Göttsche <cgzones@googlemail.com>

commit 8861db305103107199b1426f25fde1fb6d465583 upstream.

avc_has_perm_noaudit() is documented to return a copy of the access
decision in @avd, but its early return for an empty requested permission
set leaves the buffer untouched.  All callers pass an uninitialized
stack variable and afterwards feed it to avc_audit(), and the inode hook
even stores it in the per-task decision cache.

Fill in a deny-all, audit-all decision, similar to avd_init(), so every
caller receives a defined value at no cost on the hot path.

Cc: stable@vger.kernel.org
Fixes: e6f2f381e4015386 ("selinux: replace BUG_ONs with WARN_ONs in avc.c")
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 security/selinux/avc.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -1143,8 +1143,11 @@ inline int avc_has_perm_noaudit(u32 ssid
 	u32 denied;
 	struct avc_node *node;
 
-	if (WARN_ON(!requested))
+	if (WARN_ON(!requested)) {
+		/* Provide a deny-all, audit-all decision to the caller. */
+		*avd = (struct av_decision){ .auditdeny = 0xffffffff };
 		return -EACCES;
+	}
 
 	rcu_read_lock();
 	node = avc_lookup(ssid, tsid, tclass);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 218/877] power: sequencing: dont call .post_enable() if pwrseq_unit_enable() failed
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (216 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 217/877] selinux: always fill AVC decision in avc_has_perm_noaudit() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 219/877] power: sequencing: fix NULL-pointer dereference in pwrseq_unit_new() Greg Kroah-Hartman
                   ` (666 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bartosz Golaszewski

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

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

From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

commit 5f90f85eae4e9d2e9628b2019870994ba830b533 upstream.

If the call to pwrseq_unit_enable() failed in pwrseq_enable(), bail out
instead of calling target->post_enable() which assumes the target was
successfully enabled.

Fixes: 249ebf3f65f8 ("power: sequencing: implement the pwrseq core")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260909-pwrseq-kunit-v2-1-ef496afc89d2@oss.qualcomm.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/power/sequencing/core.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/power/sequencing/core.c
+++ b/drivers/power/sequencing/core.c
@@ -913,6 +913,8 @@ int pwrseq_power_on(struct pwrseq_desc *
 		if (!ret)
 			desc->powered_on = true;
 	}
+	if (ret)
+		return ret;
 
 	if (target->post_enable) {
 		ret = target->post_enable(pwrseq);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 219/877] power: sequencing: fix NULL-pointer dereference in pwrseq_unit_new()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (217 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 218/877] power: sequencing: dont call .post_enable() if pwrseq_unit_enable() failed Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 220/877] power: sequencing: fix NULL-pointer dereference in pwrseq_device_register() Greg Kroah-Hartman
                   ` (665 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, sashiko-bot, Bartosz Golaszewski

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

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

From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

commit 115b303e8e093d964089ec6f3c40d984d77b33d0 upstream.

If memory allocation fails in pwrseq_unit_setup_deps(), pwrseq_unit_put()
is called to release the partially initialized unit. However, we've
never initialized unit->list and pwrseq_unit_release() will
unconditionally call list_del() on it. Initialize unit->list right after
allocating the unit struct.

Fixes: 249ebf3f65f8 ("power: sequencing: implement the pwrseq core")
Cc: stable@vger.kernel.org
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260903-pwrseq-kunit-v1-0-1f893d2cabc2%40oss.qualcomm.com?part=1
Link: https://patch.msgid.link/20260909-pwrseq-kunit-v2-2-ef496afc89d2@oss.qualcomm.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/power/sequencing/core.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/power/sequencing/core.c
+++ b/drivers/power/sequencing/core.c
@@ -101,6 +101,7 @@ static struct pwrseq_unit *pwrseq_unit_n
 	}
 
 	kref_init(&unit->ref);
+	INIT_LIST_HEAD(&unit->list);
 	INIT_LIST_HEAD(&unit->deps);
 	unit->enable = data->enable;
 	unit->disable = data->disable;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 220/877] power: sequencing: fix NULL-pointer dereference in pwrseq_device_register()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (218 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 219/877] power: sequencing: fix NULL-pointer dereference in pwrseq_unit_new() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 221/877] mmc: core: Cancel SDIO IRQ work before freeing host Greg Kroah-Hartman
                   ` (664 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, sashiko-bot, Bartosz Golaszewski

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

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

From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

commit 242da4318d97380741516b595af3920207b2f0f1 upstream.

If dev_set_name() fails in pwrseq_device_register(), we jump to the
err_put_pwrseq label before initializing pwrseq->targets.
pwrseq_release() will try to iterate over targets unconditionally and
subsequently dereference an invalid pointer. Move the call to
dev_set_name() after the list head is initialized.

Fixes: 249ebf3f65f8 ("power: sequencing: implement the pwrseq core")
Cc: stable@vger.kernel.org
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260903-pwrseq-kunit-v1-0-1f893d2cabc2%40oss.qualcomm.com?part=2
Link: https://patch.msgid.link/20260909-pwrseq-kunit-v2-3-ef496afc89d2@oss.qualcomm.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/power/sequencing/core.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/power/sequencing/core.c b/drivers/power/sequencing/core.c
index 7751ce8cd8f5..392d72537485 100644
--- a/drivers/power/sequencing/core.c
+++ b/drivers/power/sequencing/core.c
@@ -505,10 +505,6 @@ pwrseq_device_register(const struct pwrseq_config *config)
 	 */
 	device_initialize(&pwrseq->dev);
 
-	ret = dev_set_name(&pwrseq->dev, "pwrseq.%d", pwrseq->id);
-	if (ret)
-		goto err_put_pwrseq;
-
 	pwrseq->owner = config->owner ?: THIS_MODULE;
 	pwrseq->match = config->match;
 
@@ -517,6 +513,10 @@ pwrseq_device_register(const struct pwrseq_config *config)
 	INIT_LIST_HEAD(&pwrseq->targets);
 	INIT_LIST_HEAD(&pwrseq->units);
 
+	ret = dev_set_name(&pwrseq->dev, "pwrseq.%d", pwrseq->id);
+	if (ret)
+		goto err_put_pwrseq;
+
 	ret = pwrseq_setup_targets(config->targets, pwrseq);
 	if (ret)
 		goto err_put_pwrseq;
-- 
2.55.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 221/877] mmc: core: Cancel SDIO IRQ work before freeing host
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (219 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 220/877] power: sequencing: fix NULL-pointer dereference in pwrseq_device_register() Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 222/877] mmc: core: Fix OF node reference leak on card add failure Greg Kroah-Hartman
                   ` (663 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Ulf Hansson

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

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

From: Fan Wu <fanwu01@zju.edu.cn>

commit 6feadbecdae60a6324c967f3b1493741083793a3 upstream.

A host controller that uses sdio_signal_irq() schedules host->sdio_irq_work
from its interrupt handler.  That work is only cancelled on the suspend
path (mmc_sdio_suspend()), not on the remove/free path, so a worker armed
just before the controller freed its IRQ can run after
mmc_host_classdev_release() has freed the host and dereference it through
container_of().

Cancel host->sdio_irq_work in mmc_free_host(), like the existing
host->detect drain added by commit 1036f69e2513 ("mmc: core: Cancel
delayed work before releasing host").

This issue was found by an in-house static analysis tool.

Fixes: 682696605c70 ("mmc: sdio: Add API to manage SDIO IRQs from a workqueue")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/core/host.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -690,6 +690,7 @@ EXPORT_SYMBOL(mmc_remove_host);
 void mmc_free_host(struct mmc_host *host)
 {
 	cancel_delayed_work_sync(&host->detect);
+	cancel_work_sync(&host->sdio_irq_work);
 	mmc_pwrseq_free(host);
 	put_device(&host->class_dev);
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 222/877] mmc: core: Fix OF node reference leak on card add failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (220 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 221/877] mmc: core: Cancel SDIO IRQ work before freeing host Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 223/877] mmc: hsq: Fix use-after-free in retry work Greg Kroah-Hartman
                   ` (662 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Zhu Ling, Shawn Lin, Ulf Hansson

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

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

From: Zhu Ling <zhuling0805@qq.com>

commit 08b54e16d547d5c1aa61bf7a3595bb1620975eeb upstream.

mmc_of_find_child_device() returns a device node with its reference count
incremented. mmc_add_card() stores the reference before calling
device_add(), while the card is marked present only after device_add()
succeeds.

If device_add() fails, the callers release the card through
mmc_remove_card(). However, mmc_remove_card() only drops the OF node
reference for a present card, leaking the reference on this error path.

Move of_node_put() outside the present-card conditional so the reference
is released for both registered cards and card-add failures.

Fixes: 25185f3f31c9 ("mmc: Add SDIO function devicetree subnode parsing")
Cc: stable@vger.kernel.org
Signed-off-by: Zhu Ling <zhuling0805@qq.com>
Reviewed-by: Shawn Lin <shawn.lin@linux.dev>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/core/bus.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -399,8 +399,8 @@ void mmc_remove_card(struct mmc_card *ca
 				mmc_hostname(card->host), card->rca);
 		}
 		device_del(&card->dev);
-		of_node_put(card->dev.of_node);
 	}
+	of_node_put(card->dev.of_node);
 
 	if (host->cqe_enabled) {
 		host->cqe_ops->cqe_disable(host);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 223/877] mmc: hsq: Fix use-after-free in retry work
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (221 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 222/877] mmc: core: Fix OF node reference leak on card add failure Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 224/877] mmc: mmci: Fix use-after-free in busy-timeout work Greg Kroah-Hartman
                   ` (661 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Ulf Hansson

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

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

From: Fan Wu <fanwu01@zju.edu.cn>

commit 5d132990475f02cfa1debe03d50b479432864ebd upstream.

mmc_hsq_pump_requests() queues retry_work when request_atomic() returns
-EBUSY; today sdhci-sprd is the only consumer that implements
request_atomic(). The work is embedded in a devm-allocated mmc_hsq, but
is never cancelled during driver removal. Work still pending at unbind
can therefore run after the devm allocation has been released and
dereference hsq->mmc and hsq->mrq.

Use devm_work_autocancel() to cancel and drain retry_work before the devm
allocation is released. By the time devres cleanup begins,
mmc_remove_host() has already stopped the host, so no new requests can
arm the work.

This issue was found by an in-house static analysis tool.

Fixes: 6db96e5810e0 ("mmc: host: Introduce the request_atomic() for the host")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/host/mmc_hsq.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

--- a/drivers/mmc/host/mmc_hsq.c
+++ b/drivers/mmc/host/mmc_hsq.c
@@ -7,6 +7,7 @@
  * Author: Baolin Wang <baolin.wang@linaro.org>
  */
 
+#include <linux/devm-helpers.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
 #include <linux/module.h>
@@ -345,6 +346,7 @@ static const struct mmc_cqe_ops mmc_hsq_
 
 int mmc_hsq_init(struct mmc_hsq *hsq, struct mmc_host *mmc)
 {
+	int ret;
 	int i;
 	hsq->num_slots = HSQ_NUM_SLOTS;
 	hsq->next_tag = HSQ_INVALID_TAG;
@@ -363,7 +365,11 @@ int mmc_hsq_init(struct mmc_hsq *hsq, st
 	for (i = 0; i < HSQ_NUM_SLOTS; i++)
 		hsq->tag_slot[i] = HSQ_INVALID_TAG;
 
-	INIT_WORK(&hsq->retry_work, mmc_hsq_retry_handler);
+	ret = devm_work_autocancel(mmc_dev(mmc), &hsq->retry_work,
+				   mmc_hsq_retry_handler);
+	if (ret)
+		return ret;
+
 	spin_lock_init(&hsq->lock);
 	init_waitqueue_head(&hsq->wait_queue);
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 224/877] mmc: mmci: Fix use-after-free in busy-timeout work
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (222 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 223/877] mmc: hsq: Fix use-after-free in retry work Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 225/877] mmc: mxcmmc: cancel data work and watchdog on remove Greg Kroah-Hartman
                   ` (660 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Linus Walleij, Ulf Hansson

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

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

From: Fan Wu <fanwu01@zju.edu.cn>

commit 2b19cf3e50cddaff07b657dae1a8f30f06032852 upstream.

ux500_busy_complete() can queue ux500_busy_timeout_work for an R1b
command, but mmci_remove() never cancels it. The work can subsequently
dereference the devm-allocated mmci_host after it has been released.

Mask the controller interrupts and disable the delayed work during
removal. This drains any queued instance and stops an IRQ handler that
is still in progress from queueing the work again once it has been
disabled.

This issue was found by an in-house static analysis tool.

Fixes: b1a665932dc2 ("mmc: mmci: Add support for SW busy-end timeouts")
Cc: stable@vger.kernel.org # v6.10+
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/host/mmci.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -2520,6 +2520,9 @@ static void mmci_remove(struct amba_devi
 		writel(0, host->base + MMCICOMMAND);
 		writel(0, host->base + MMCIDATACTRL);
 
+		if (variant->busy_detect)
+			disable_delayed_work_sync(&host->ux500_busy_timeout_work);
+
 		mmci_dma_release(host);
 		clk_disable_unprepare(host->clk);
 		mmc_free_host(mmc);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 225/877] mmc: mxcmmc: cancel data work and watchdog on remove
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (223 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 224/877] mmc: mmci: Fix use-after-free in busy-timeout work Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 226/877] mmc: rtsx_pci_sdmmc: ignore broken write-protect on ThinkPad X260 Greg Kroah-Hartman
                   ` (659 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Ulf Hansson

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

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

From: Fan Wu <fanwu01@zju.edu.cn>

commit d3a421c82412344022982d5b91ba23194a0a6f29 upstream.

mxcmci_remove() frees the host through the devm tail, but neither it nor
mmc_remove_host() drains the driver's own asynchronous state.
host->watchdog, a 10 s timer armed on the DMA path in mxcmci_setup_data(),
is deleted only by the DMA- and IRQ-complete paths, which the remove path
does not explicitly drain; it can therefore fire after the host is freed
and dereference it in mxcmci_watchdog().  host->datawork, armed from the
IRQ handler on the PIO path, is not cancelled by the remove path either.

Free the devm-registered IRQ, then cancel datawork and delete the watchdog
in mxcmci_remove(), before dma_release_channel().  Freeing the IRQ first
keeps a trailing handler from re-arming datawork between the cancel and
the host free.  Both callbacks are non-self-rearming.

This issue was found by an in-house static analysis tool.

Fixes: f6ad0a481342 ("mmc: mxcmmc: fix bug that may block a data transfer forever")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/host/mxcmmc.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -1182,6 +1182,10 @@ static void mxcmci_remove(struct platfor
 
 	mmc_remove_host(mmc);
 
+	devm_free_irq(&pdev->dev, platform_get_irq(pdev, 0), host);
+	cancel_work_sync(&host->datawork);
+	timer_delete_sync(&host->watchdog);
+
 	if (host->pdata && host->pdata->exit)
 		host->pdata->exit(&pdev->dev, mmc);
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 226/877] mmc: rtsx_pci_sdmmc: ignore broken write-protect on ThinkPad X260
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (224 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 225/877] mmc: mxcmmc: cancel data work and watchdog on remove Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 227/877] mmc: sdhci-of-aspeed: Remove children before releasing SDC resources Greg Kroah-Hartman
                   ` (658 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Florian Maillard, Ulf Hansson

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

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

From: Florian Maillard <florian.maillard@mailoo.org>

commit 9c182bc5d7817437a7d04ab96133f9191846d93d upstream.

The Realtek RTS522A card reader in the Lenovo ThinkPad X260
(subsystem 17aa:504a) incorrectly reports inserted SD cards as
write-protected.

This causes the MMC core to expose the card as read-only:

  mmcblk0: mmc0:aaaa SN256 238 GiB (ro)

and /sys/block/mmcblk0/ro reports 1.

Setting MMC_CAP2_NO_WRITE_PROTECT makes the card writable again.
Limit the quirk to the affected Lenovo subsystem.

Assisted-by: ChatGPT:GPT-5.6 Sol
Signed-off-by: Florian Maillard <florian.maillard@mailoo.org>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/host/rtsx_pci_sdmmc.c |    5 +++++
 1 file changed, 5 insertions(+)

--- a/drivers/mmc/host/rtsx_pci_sdmmc.c
+++ b/drivers/mmc/host/rtsx_pci_sdmmc.c
@@ -1503,6 +1503,11 @@ static void realtek_init_host(struct rea
 		mmc->caps = mmc->caps | MMC_CAP_AGGRESSIVE_PM;
 	mmc->caps2 = MMC_CAP2_NO_PRESCAN_POWERUP | MMC_CAP2_FULL_PWR_CYCLE |
 		MMC_CAP2_NO_SDIO;
+
+	if (pcr->pci->device == 0x522a &&
+	    pcr->pci->subsystem_vendor == PCI_VENDOR_ID_LENOVO &&
+	    pcr->pci->subsystem_device == 0x504a)
+		mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;
 	mmc->max_current_330 = 400;
 	mmc->max_current_180 = 800;
 	mmc->ops = &realtek_pci_sdmmc_ops;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 227/877] mmc: sdhci-of-aspeed: Remove children before releasing SDC resources
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (225 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 226/877] mmc: rtsx_pci_sdmmc: ignore broken write-protect on ThinkPad X260 Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:18 ` [PATCH 6.12 228/877] mmc: sdio_uart: fix xmit_fifo leak when the port table is full Greg Kroah-Hartman
                   ` (657 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak, Ulf Hansson

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

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

From: Myeonghun Pak <mhun512@gmail.com>

commit 4396d70bb7fec531bcf934fed016b2f3300c670b upstream.

Probe failure and removal leave SDHCI child devices registered after the
parent clock and managed resources are released.

Unregister the OF children in reverse order before disabling the parent
clock on both paths. Use of_platform_device_destroy() because manual
child creation does not set the flag required by of_platform_depopulate().

This issue was identified during our ongoing static-analysis research
while reviewing kernel code.

Fixes: bb7b8ec62dfb ("mmc: sdhci-of-aspeed: Add support for the ASPEED SD controller")
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Assisted-by: OpenAI:GPT-5.6
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/host/sdhci-of-aspeed.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

--- a/drivers/mmc/host/sdhci-of-aspeed.c
+++ b/drivers/mmc/host/sdhci-of-aspeed.c
@@ -561,12 +561,14 @@ static int aspeed_sdc_probe(struct platf
 		if (!cpdev) {
 			of_node_put(child);
 			ret = -ENODEV;
-			goto err_clk;
+			goto err_children;
 		}
 	}
 
 	return 0;
 
+err_children:
+	device_for_each_child_reverse(&pdev->dev, NULL, of_platform_device_destroy);
 err_clk:
 	clk_disable_unprepare(sdc->clk);
 	return ret;
@@ -576,6 +578,7 @@ static void aspeed_sdc_remove(struct pla
 {
 	struct aspeed_sdc *sdc = dev_get_drvdata(&pdev->dev);
 
+	device_for_each_child_reverse(&pdev->dev, NULL, of_platform_device_destroy);
 	clk_disable_unprepare(sdc->clk);
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 228/877] mmc: sdio_uart: fix xmit_fifo leak when the port table is full
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (226 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 227/877] mmc: sdhci-of-aspeed: Remove children before releasing SDC resources Greg Kroah-Hartman
@ 2026-09-30 15:18 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 229/877] mmc: sh_mmcif: initialize IRQ-thread mutex before requesting interrupt Greg Kroah-Hartman
                   ` (656 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:18 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Felix Gu, Ulf Hansson

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

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

From: Felix Gu <ustc.gu@gmail.com>

commit 53823e25793a97d07e6e98e0904bbf74cac8bc76 upstream.

sdio_uart_add_port() allocates the transmit fifo before claiming a
slot in sdio_uart_table[].  When all UART_NR slots are taken, it
returns -EBUSY with the fifo still allocated, but the probe error
path only kfree()s the port, leaking the transmit fifo.

Free the fifo in the failure path of sdio_uart_add_port() itself so
the function retains nothing on error.

Fixes: 8b197a5ce7a7 ("sdio_uart: Use kfifo instead of the messy circ stuff")
Signed-off-by: Felix Gu <ustc.gu@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/core/sdio_uart.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/mmc/core/sdio_uart.c
+++ b/drivers/mmc/core/sdio_uart.c
@@ -104,6 +104,9 @@ static int sdio_uart_add_port(struct sdi
 	}
 	spin_unlock(&sdio_uart_table_lock);
 
+	if (ret)
+		kfifo_free(&port->xmit_fifo);
+
 	return ret;
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 229/877] mmc: sh_mmcif: initialize IRQ-thread mutex before requesting interrupt
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (227 preceding siblings ...)
  2026-09-30 15:18 ` [PATCH 6.12 228/877] mmc: sdio_uart: fix xmit_fifo leak when the port table is full Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 230/877] mmc: spi: reset bytes_xfered before retrying CRC failures Greg Kroah-Hartman
                   ` (655 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Ulf Hansson

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

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

From: Runyu Xiao <runyu.xiao@seu.edu.cn>

commit d5ea0d226e8f0801d78702142a124d78c317d822 upstream.

The threaded IRQ handler can run before devm_request_threaded_irq()
returns, but thread_lock was initialized afterwards. Initialize it before
requesting either interrupt.

Fixes: 8047310ee984 ("mmc: sh_mmcif: fix a race, causing an Oops on SMP")
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/host/sh_mmcif.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -1461,6 +1461,7 @@ static int sh_mmcif_probe(struct platfor
 	host->pd = pdev;
 
 	spin_lock_init(&host->lock);
+	mutex_init(&host->thread_lock);
 
 	mmc->ops = &sh_mmcif_ops;
 	sh_mmcif_init_ocr(host);
@@ -1521,8 +1522,6 @@ static int sh_mmcif_probe(struct platfor
 		}
 	}
 
-	mutex_init(&host->thread_lock);
-
 	ret = mmc_add_host(mmc);
 	if (ret < 0)
 		goto err_clk;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 230/877] mmc: spi: reset bytes_xfered before retrying CRC failures
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (228 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 229/877] mmc: sh_mmcif: initialize IRQ-thread mutex before requesting interrupt Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 231/877] mmc: sdhci_am654: Move tuning_loop to local variable Greg Kroah-Hartman
                   ` (654 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Xu Rao, Ulf Hansson

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

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

From: Xu Rao <raoxu@uniontech.com>

commit 8b0cc8707f65e0f51912e764e1b309b2559db1ec upstream.

mmc_spi_data_do() updates data->bytes_xfered after each block has been
transferred successfully.  If a later block in the same data request
fails with a CRC error, data->bytes_xfered may therefore contain the
number of bytes completed before the failing block.

mmc_spi_request() has a private recovery path for such CRC failures.  It
sends STOP_TRANSMISSION, clears data->error and jumps back to
crc_recover to issue the same command and data request again.  However,
it does not clear data->bytes_xfered before the retry.

If the retry succeeds, the request is completed with the bytes from the
failed attempt still included in data->bytes_xfered.  For a multi-block
request this can make the completed request report more bytes than were
transferred by the successful retry, and can even exceed the request size
when most blocks completed before the CRC error.

This is most likely to be observed on MMC-over-SPI systems where long
multi-block transfers occasionally hit a data CRC error but the
mmc_spi-internal retry succeeds.  The data itself is retried, but the
completion accounting is not.

Clear data->bytes_xfered together with data->error before repeating the
request so the final completion reports only the bytes transferred by the
successful attempt.

Fixes: 061c6c847eeb ("mmc_spi: Recover from CRC errors for r/w operation over SPI.")
Cc: stable@vger.kernel.org
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/host/mmc_spi.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -952,6 +952,7 @@ crc_recover:
 			status = mmc_spi_command_send(host, mrq, &stop, 0);
 			crc_retry--;
 			mrq->data->error = 0;
+			mrq->data->bytes_xfered = 0;
 			goto crc_recover;
 		}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 231/877] mmc: sdhci_am654: Move tuning_loop to local variable
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (229 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 230/877] mmc: spi: reset bytes_xfered before retrying CRC failures Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 232/877] mmc: sdhci_am654: Reset command and data lines on failed tuning Greg Kroah-Hartman
                   ` (653 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Diogo Ivo (Schneider Electric),
	Judith Mendez, Adrian Hunter, Ulf Hansson

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

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

From: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>

commit ff894dced1a7ad7523f9c65dbdb53d02474cca0f upstream.

The tuning_loop field in struct sdhci_am654_data is only used within
sdhci_am654_platform_execute_tuning() as a loop counter that is
initialized to 0 in sdhci_am654_init(). Since it shouldn't persist across
function calls, otherwise every failure expends its "budget", move it to a
local variable and remove the struct field along with the now-unnecessary
initialization.

Signed-off-by: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
Reviewed-by: Judith Mendez <jm@ti.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Fixes: de31f6ab68a3 ("mmc: sdhci_am654: Reset Command and Data line after tuning")
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/host/sdhci_am654.c |    7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

--- a/drivers/mmc/host/sdhci_am654.c
+++ b/drivers/mmc/host/sdhci_am654.c
@@ -152,7 +152,6 @@ struct sdhci_am654_data {
 	u32 flags;
 	u32 quirks;
 	bool dll_enable;
-	u32 tuning_loop;
 
 #define SDHCI_AM654_QUIRK_FORCE_CDTEST BIT(0)
 #define SDHCI_AM654_QUIRK_DISABLE_HS400 BIT(1)
@@ -552,13 +551,14 @@ static int sdhci_am654_platform_execute_
 	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
 	unsigned char timing = host->mmc->ios.timing;
 	struct device *dev = mmc_dev(host->mmc);
+	unsigned int tuning_loop = 0;
 	int itapdly;
 
 	do {
 		itapdly = sdhci_am654_do_tuning(host, opcode);
 		if (itapdly >= 0)
 			break;
-	} while (++sdhci_am654->tuning_loop < RETRY_TUNING_MAX);
+	} while (++tuning_loop < RETRY_TUNING_MAX);
 
 	if (itapdly < 0) {
 		dev_err(dev, "Failed to find itapdly, fail tuning\n");
@@ -776,9 +776,6 @@ static int sdhci_am654_init(struct sdhci
 	regmap_update_bits(sdhci_am654->base, CTL_CFG_3, TUNINGFORSDR50_MASK,
 			   TUNINGFORSDR50_MASK);
 
-	/* Use to re-execute tuning */
-	sdhci_am654->tuning_loop = 0;
-
 	ret = sdhci_setup_host(host);
 	if (ret)
 		return ret;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 232/877] mmc: sdhci_am654: Reset command and data lines on failed tuning
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (230 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 231/877] mmc: sdhci_am654: Move tuning_loop to local variable Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 233/877] mmc: sdhci_am654: Clear ITAPDLY on tuning failure Greg Kroah-Hartman
                   ` (652 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Diogo Ivo (Schneider Electric),
	Judith Mendez, Adrian Hunter, Ulf Hansson

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

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

From: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>

commit 7197d9107d9545730153b82ea5a411c5208b443f upstream.

The CMD/DATA reset after tuning should be performed regardless of
whether tuning succeeded or failed, since tuning data may remain in
the buffer in either case. Move the error return after the reset so
that the controller is always cleaned up.

Fixes: de31f6ab68a3 ("mmc: sdhci_am654: Reset Command and Data line after tuning")
Cc: stable@vger.kernel.org
Signed-off-by: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
Reviewed-by: Judith Mendez <jm@ti.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/host/sdhci_am654.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

--- a/drivers/mmc/host/sdhci_am654.c
+++ b/drivers/mmc/host/sdhci_am654.c
@@ -418,15 +418,13 @@ static int sdhci_am654_execute_tuning(st
 	struct sdhci_host *host = mmc_priv(mmc);
 	int err = sdhci_execute_tuning(mmc, opcode);
 
-	if (err)
-		return err;
 	/*
 	 * Tuning data remains in the buffer after tuning.
 	 * Do a command and data reset to get rid of it
 	 */
 	sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
 
-	return 0;
+	return err;
 }
 
 static u32 sdhci_am654_cqhci_irq(struct sdhci_host *host, u32 intmask)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 233/877] mmc: sdhci_am654: Clear ITAPDLY on tuning failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (231 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 232/877] mmc: sdhci_am654: Reset command and data lines on failed tuning Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 234/877] mmc: sdhci_am654: Fallback to DT-provided itap delay on DDR50 " Greg Kroah-Hartman
                   ` (651 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Diogo Ivo (Schneider Electric),
	Judith Mendez, Adrian Hunter, Ulf Hansson

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

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

From: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>

commit c9f47cc8c37f7659897142ffe216c250fbc1d4ed upstream.

When tuning fails, stale ITAPDLY values can persist and interfere with
subsequent I/O accesses, for example in DDR50 mode in cards with no tuning
support. Move the ITAPDLY enable setting out of the tuning loop to after
successful tuning, and explicitly clear ITAPDLY (delay and enable) when
tuning fails so that we are sure only working values are actually left in
hardware.

Fixes: 901d16e46296 ("mmc: sdhci_am654: Add retry tuning")
Cc: stable@vger.kernel.org
Signed-off-by: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
Reviewed-by: Judith Mendez <jm@ti.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/host/sdhci_am654.c |   12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

--- a/drivers/mmc/host/sdhci_am654.c
+++ b/drivers/mmc/host/sdhci_am654.c
@@ -503,7 +503,6 @@ static int sdhci_am654_do_tuning(struct
 {
 	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
 	struct sdhci_am654_data *sdhci_am654 = sdhci_pltfm_priv(pltfm_host);
-	unsigned char timing = host->mmc->ios.timing;
 	struct window fail_window[ITAPDLY_LENGTH];
 	struct device *dev = mmc_dev(host->mmc);
 	u8 curr_pass, itap;
@@ -512,11 +511,8 @@ static int sdhci_am654_do_tuning(struct
 
 	memset(fail_window, 0, sizeof(fail_window));
 
-	/* Enable ITAPDLY */
-	sdhci_am654->itap_del_ena[timing] = 0x1;
-
 	for (itap = 0; itap < ITAPDLY_LENGTH; itap++) {
-		sdhci_am654_write_itapdly(sdhci_am654, itap, sdhci_am654->itap_del_ena[timing]);
+		sdhci_am654_write_itapdly(sdhci_am654, itap, 0x1);
 
 		curr_pass = !mmc_send_tuning(host->mmc, opcode, NULL);
 
@@ -560,10 +556,16 @@ static int sdhci_am654_platform_execute_
 
 	if (itapdly < 0) {
 		dev_err(dev, "Failed to find itapdly, fail tuning\n");
+		sdhci_am654_write_itapdly(sdhci_am654, 0, 0);
+		sdhci_am654->itap_del_ena[timing] = 0;
+		sdhci_am654->itap_del_sel[timing] = 0;
 		return -1;
 	}
 
 	dev_dbg(dev, "Passed tuning, final itapdly=%d\n", itapdly);
+
+	/* Enable ITAPDLY */
+	sdhci_am654->itap_del_ena[timing] = 0x1;
 	sdhci_am654_write_itapdly(sdhci_am654, itapdly, sdhci_am654->itap_del_ena[timing]);
 	/* Save ITAPDLY */
 	sdhci_am654->itap_del_sel[timing] = itapdly;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 234/877] mmc: sdhci_am654: Fallback to DT-provided itap delay on DDR50 tuning failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (232 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 233/877] mmc: sdhci_am654: Clear ITAPDLY on tuning failure Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 235/877] Input: adp5588-keys - cache GPIO state before registering the gpiochip Greg Kroah-Hartman
                   ` (650 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Diogo Ivo (Schneider Electric),
	Adrian Hunter, Judith Mendez, Ulf Hansson

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

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

From: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>

commit 308d05225281d86150d88141990d6caf8c902349 upstream.

DDR50 mode is not required to support the tuning command CMD19, meaning
that calibration may fail on cards that do not implement it, in which
case a known-good itap delay value should be programmed into the host
controller.

Do this by reading the (already defined) itap delay DT property for DDR50
and, if tuning fails for this mode, fall back to the DT-provided itap delay
value. If the DT does not provide a value for DDR50 fallback then this
simply disables using itapdly.

Fixes: 901d16e46296 ("mmc: sdhci_am654: Add retry tuning")
Cc: stable@vger.kernel.org
Signed-off-by: Diogo Ivo (Schneider Electric) <diogo.ivo@bootlin.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Judith Mendez <jm@ti.com>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/host/sdhci_am654.c |   26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

--- a/drivers/mmc/host/sdhci_am654.c
+++ b/drivers/mmc/host/sdhci_am654.c
@@ -127,7 +127,7 @@ static const struct timing_data td[] = {
 				   NULL,
 				   MMC_CAP_UHS_SDR104},
 	[MMC_TIMING_UHS_DDR50]	= {"ti,otap-del-sel-ddr50",
-				   NULL,
+				   "ti,itap-del-sel-ddr50",
 				   MMC_CAP_UHS_DDR50},
 	[MMC_TIMING_MMC_DDR52]	= {"ti,otap-del-sel-ddr52",
 				   "ti,itap-del-sel-ddr52",
@@ -145,6 +145,8 @@ struct sdhci_am654_data {
 	u32 otap_del_sel[ARRAY_SIZE(td)];
 	u32 itap_del_sel[ARRAY_SIZE(td)];
 	u32 itap_del_ena[ARRAY_SIZE(td)];
+	u32 itap_del_sel_dt_ddr50;
+	u32 itap_del_ena_dt_ddr50;
 	int clkbuf_sel;
 	int trm_icp;
 	int drv_strength;
@@ -555,10 +557,19 @@ static int sdhci_am654_platform_execute_
 	} while (++tuning_loop < RETRY_TUNING_MAX);
 
 	if (itapdly < 0) {
-		dev_err(dev, "Failed to find itapdly, fail tuning\n");
-		sdhci_am654_write_itapdly(sdhci_am654, 0, 0);
-		sdhci_am654->itap_del_ena[timing] = 0;
-		sdhci_am654->itap_del_sel[timing] = 0;
+		if (timing == MMC_TIMING_UHS_DDR50) {
+			dev_dbg(dev, "Failed DDR50 tuning, fallback to DT ITAP\n");
+			sdhci_am654->itap_del_sel[timing] = sdhci_am654->itap_del_sel_dt_ddr50;
+			sdhci_am654->itap_del_ena[timing] = sdhci_am654->itap_del_ena_dt_ddr50;
+		} else {
+			dev_err(dev, "Failed to find itapdly, fail tuning\n");
+			sdhci_am654->itap_del_ena[timing] = 0;
+			sdhci_am654->itap_del_sel[timing] = 0;
+		}
+
+		sdhci_am654_write_itapdly(sdhci_am654,
+					  sdhci_am654->itap_del_sel[timing],
+					  sdhci_am654->itap_del_ena[timing]);
 		return -1;
 	}
 
@@ -728,6 +739,11 @@ static int sdhci_am654_get_otap_delay(st
 		}
 	}
 
+	sdhci_am654->itap_del_sel_dt_ddr50 =
+		sdhci_am654->itap_del_sel[MMC_TIMING_UHS_DDR50];
+	sdhci_am654->itap_del_ena_dt_ddr50 =
+		sdhci_am654->itap_del_ena[MMC_TIMING_UHS_DDR50];
+
 	return 0;
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 235/877] Input: adp5588-keys - cache GPIO state before registering the gpiochip
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (233 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 234/877] mmc: sdhci_am654: Fallback to DT-provided itap delay on DDR50 " Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 236/877] Input: atkbd - skip deactivate for Xiaomi Redmi Book Pro 16 2026 Greg Kroah-Hartman
                   ` (649 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Alvin Šipraga, Nuno Sá,
	Dmitry Torokhov

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

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

From: Alvin Šipraga <alvin.sipraga@analog.com>

commit 21efadc62272cabee9bec27777ae75d84a9ca8a8 upstream.

So as not to clobber any pre-programmed GPIO state in the execution
of its gpiochip ops, the driver caches things during probe time.
However, since those ops can be called both during and immediately after
the call to devm_gpiochip_add_data(), it is imperative that things are
cached before that. That's not the case right now, so reorder the two
steps to prevent any clobbering.

In the concrete example which motivated this change, a bootloader was
preconfiguring an important GPIO output to HIGH before booting the
kernel. Linux would then inadvertently set that output to LOW while
configuring a GPIO hog on a discrete GPIO line within the same 8-bit
bank (because the cached value was 0=LOW).

Fixes: ba9f507a1bea ("Input: adp5588-keys - export unused GPIO pins")
Signed-off-by: Alvin Šipraga <alvin.sipraga@analog.com>
Reviewed-by: Nuno Sá <nuno.sa@analog.com>
Link: https://patch.msgid.link/20260818-adp5588-gpio-cache-v1-1-650a2674fc0d@analog.com
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/keyboard/adp5588-keys.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

--- a/drivers/input/keyboard/adp5588-keys.c
+++ b/drivers/input/keyboard/adp5588-keys.c
@@ -446,12 +446,6 @@ static int adp5588_gpio_add(struct adp55
 
 	mutex_init(&kpad->gpio_lock);
 
-	error = devm_gpiochip_add_data(dev, &kpad->gc, kpad);
-	if (error) {
-		dev_err(dev, "gpiochip_add failed: %d\n", error);
-		return error;
-	}
-
 	for (i = 0; i <= ADP5588_BANK(ADP5588_MAXGPIO); i++) {
 		kpad->dat_out[i] = adp5588_read(kpad->client,
 						GPIO_DAT_OUT1 + i);
@@ -459,6 +453,12 @@ static int adp5588_gpio_add(struct adp55
 		kpad->pull_dis[i] = adp5588_read(kpad->client, GPIO_PULL1 + i);
 	}
 
+	error = devm_gpiochip_add_data(dev, &kpad->gc, kpad);
+	if (error) {
+		dev_err(dev, "gpiochip_add failed: %d\n", error);
+		return error;
+	}
+
 	return 0;
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 236/877] Input: atkbd - skip deactivate for Xiaomi Redmi Book Pro 16 2026
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (234 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 235/877] Input: adp5588-keys - cache GPIO state before registering the gpiochip Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 237/877] Input: cyttsp5 - clamp the HID report size before memcpy Greg Kroah-Hartman
                   ` (648 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Alexei Turtanov, Dmitry Torokhov

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

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

From: Alexei Turtanov <9alexei9@gmail.com>

commit aefbda23eeba234c3ff0f135dc5be6e294bd25a6 upstream.

The internal keyboard of the Xiaomi Redmi Book Pro 16 2026 (board TM2425)
does not work: atkbd_probe() succeeds and every command is ACKed, but no
scancodes ever arrive afterwards.

Testing on the hardware through serio_raw shows that ATKBD_CMD_RESET_DIS
(0xF5) is the culprit. After 0xF5 the embedded controller keeps ACKing
commands but stops delivering scancodes, and neither ATKBD_CMD_ENABLE
(0xF4) nor ATKBD_CMD_RESET_BAT (0xFF) bring them back. Only re-enabling
the keyboard interface at the controller level (i8042 command 0xAE, or
rewriting the command byte as i8042_port_close() does) revives it.
Running the init sequence without 0xF5 (0xED 0x00, 0xF3 0x00, 0xF4)
keeps the keyboard working.

'i8042.dumbkbd=1' also works around this, but then the driver never
writes to the keyboard and the LEDs cannot be controlled. Use the
existing atkbd_deactivate_fixup quirk instead, as done for the sibling
TM2424 by commit 3a046db33bb9 ("Input: atkbd - skip deactivate for
Xiaomi Book Pro 14's internal keyboard"). Tested on v7.2: keyboard,
Caps Lock LED and s2idle suspend/resume all work.

DMI: XIAOMI REDMI Book Pro 16 2026/TM2425, BIOS RMAPT6B0P0909 05/22/2026

Fixes: 9cf6e24c9fbf ("Input: atkbd - do not skip atkbd_deactivate() when skipping ATKBD_CMD_GETID")
Cc: stable@vger.kernel.org
Signed-off-by: Alexei Turtanov <9alexei9@gmail.com>
Link: https://patch.msgid.link/20260828112239.18081-1-9alexei9@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/keyboard/atkbd.c |    8 ++++++++
 1 file changed, 8 insertions(+)

--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -1975,6 +1975,14 @@ static const struct dmi_system_id atkbd_
 		},
 		.callback = atkbd_deactivate_fixup,
 	},
+	{
+		/* Xiaomi Redmi Book Pro 16 2026 (TM2425) */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "XIAOMI"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "REDMI Book Pro 16 2026"),
+		},
+		.callback = atkbd_deactivate_fixup,
+	},
 	{ }
 };
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 237/877] Input: cyttsp5 - clamp the HID report size before memcpy
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (235 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 236/877] Input: atkbd - skip deactivate for Xiaomi Redmi Book Pro 16 2026 Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 238/877] Input: evdev - zero absinfo before partial copy in EVIOCSABS Greg Kroah-Hartman
                   ` (647 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Linkai Gong, Dmitry Torokhov

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

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

From: Linkai Gong <gonglinkai@kylinos.cn>

commit 85f080fb87ed5cd3e46121be677f52c82f26a0ab upstream.

The size field comes from the device and is used as the memcpy()
length into response_buf, which is CY_MAX_INPUT bytes.

Fixes: 5b0c03e24a06 ("Input: Add driver for Cypress Generation 5 touchscreen")
Signed-off-by: Linkai Gong <gonglinkai@kylinos.cn>
Link: https://patch.msgid.link/20260901122649.1173066-1-gonglinkai@kylinos.cn
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/touchscreen/cyttsp5.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/input/touchscreen/cyttsp5.c
+++ b/drivers/input/touchscreen/cyttsp5.c
@@ -711,6 +711,7 @@ static irqreturn_t cyttsp5_handle_irq(in
 		size = 2;
 	} else {
 		report_id = ts->input_buf[2];
+		size = min(size, CY_MAX_INPUT);
 	}
 
 	switch (report_id) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 238/877] Input: evdev - zero absinfo before partial copy in EVIOCSABS
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (236 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 237/877] Input: cyttsp5 - clamp the HID report size before memcpy Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 239/877] Input: i8042 - add quirk for Acer Aspire Go 15 AG15-42P Greg Kroah-Hartman
                   ` (646 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Iván Ezequiel Rodriguez,
	Dmitry Torokhov

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

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

From: Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>

commit 8b852965b8eaf910c314dc346967ed82c8d4f235 upstream.

The EVIOCSABS handler copies at most the user supplied ioctl size into
an uninitialized on-stack struct input_absinfo:

	if (copy_from_user(&abs, p, min_t(size_t,
			size, sizeof(struct input_absinfo))))

The size comes from _IOC_SIZE() of the ioctl command and is therefore
fully controlled by userspace. A short size leaves the trailing part of
the structure holding whatever was on the kernel stack, and the whole
structure is then stored into the device:

	dev->absinfo[t] = abs;

EVIOCGABS hands that back to userspace, disclosing the stale stack
bytes. Only the resolution field is currently cleared, which covers the
legacy struct layout but not an arbitrarily short size.

Zero the structure before the copy so any part not supplied by the
caller reads back as zero. The existing resolution fixup is kept, since
it also handles a size that partially overlaps that field.

Fixes: 448cd1664a57 ("Input: evdev - rearrange ioctl handling")
Cc: stable@vger.kernel.org
Signed-off-by: Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>
Link: https://patch.msgid.link/20260901130629.24078-2-ivanrwcm25@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/evdev.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -1229,6 +1229,8 @@ static long evdev_do_ioctl(struct file *
 
 			t = _IOC_NR(cmd) & ABS_MAX;
 
+			memset(&abs, 0, sizeof(abs));
+
 			if (copy_from_user(&abs, p, min_t(size_t,
 					size, sizeof(struct input_absinfo))))
 				return -EFAULT;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 239/877] Input: i8042 - add quirk for Acer Aspire Go 15 AG15-42P
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (237 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 238/877] Input: evdev - zero absinfo before partial copy in EVIOCSABS Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 240/877] Input: rmi_smbus - fix out-of-bounds read in rmi_smb_write_block() Greg Kroah-Hartman
                   ` (645 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Chris Sommers, Dmitry Torokhov

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

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

From: Chris Sommers <chris.sommers@icloud.com>

commit 25e424eb4ae1a662d9c3573218d06ac32f797fc5 upstream.

On the Acer Aspire Go 15 (AG15-42P), the internal keyboard drops out
~5 seconds after boot on both Linux and Linux-LTS kernels. Keystrokes on
the built-in keyboard stop registering while the trackpad and external
keyboards remain functional.

Testing confirms that booting with the i8042.reset kernel parameter
resolves the issue and keeps the internal keyboard responsive.

Add SERIO_QUIRK_RESET_ALWAYS to i8042_dmi_quirk_table for the Acer
Aspire AG15-42P to automatically apply this quirk on boot.

Signed-off-by: Chris Sommers <chris.sommers@icloud.com>
Link: https://patch.msgid.link/20260907182723.2709981-1-chris.sommers@icloud.com
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/serio/i8042-acpipnpio.h |    7 +++++++
 1 file changed, 7 insertions(+)

--- a/drivers/input/serio/i8042-acpipnpio.h
+++ b/drivers/input/serio/i8042-acpipnpio.h
@@ -261,6 +261,13 @@ static const struct dmi_system_id i8042_
 	{
 		.matches = {
 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire AG15-42P"),
+		},
+		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)
+	},
+	{
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire ES1-132"),
 		},
 		.driver_data = (void *)(SERIO_QUIRK_RESET_ALWAYS)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 240/877] Input: rmi_smbus - fix out-of-bounds read in rmi_smb_write_block()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (238 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 239/877] Input: i8042 - add quirk for Acer Aspire Go 15 AG15-42P Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 241/877] Input: soc_button_array - fix MS Surface Pro 11 probe failure Greg Kroah-Hartman
                   ` (644 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, sashiko-bot, Dmitry Torokhov

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

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

From: Dmitry Torokhov <dmitry.torokhov@gmail.com>

commit 51cfe54f815ae175c7d1126b983d4d7c89715004 upstream.

When chunking writes into SMBus blocks in rmi_smb_write_block(), the
loop calculates block_len using the original total length (len) instead
of the remaining length (cur_len).

If len is greater than 32 bytes (SMB_MAX_COUNT), block_len remains 32
for every iteration, even on the final partial chunk where fewer than 32
bytes remain. This causes smb_block_write() to read 32 bytes from the
advanced data buffer pointer, reading past the end of the input buffer.

Fix this by calculating block_len using cur_len and advancing the buffer
and address pointers by block_len.

Fixes: 82264d0cf7ae ("Input: synaptics-rmi4 - add SMBus support")
Cc: stable@vger.kernel.org
Reported-by: sashiko-bot@kernel.org
Assisted-by: LLM
Link: https://patch.msgid.link/anLFSMKSoKyyZ272@google.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/rmi4/rmi_smbus.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

--- a/drivers/input/rmi4/rmi_smbus.c
+++ b/drivers/input/rmi4/rmi_smbus.c
@@ -140,7 +140,7 @@ static int rmi_smb_write_block(struct rm
 	u8 commandcode;
 	struct rmi_smb_xport *rmi_smb =
 		container_of(xport, struct rmi_smb_xport, xport);
-	int cur_len = (int)len;
+	size_t cur_len = len;
 
 	mutex_lock(&rmi_smb->page_mutex);
 
@@ -148,7 +148,7 @@ static int rmi_smb_write_block(struct rm
 		/*
 		 * break into 32 bytes chunks to write get command code
 		 */
-		int block_len = min_t(int, len, SMB_MAX_COUNT);
+		int block_len = min_t(size_t, cur_len, SMB_MAX_COUNT);
 
 		retval = rmi_smb_get_command_code(xport, rmiaddr, block_len,
 						  false, &commandcode);
@@ -161,9 +161,9 @@ static int rmi_smb_write_block(struct rm
 			goto exit;
 
 		/* prepare to write next block of bytes */
-		cur_len -= SMB_MAX_COUNT;
-		databuff += SMB_MAX_COUNT;
-		rmiaddr += SMB_MAX_COUNT;
+		cur_len -= block_len;
+		databuff += block_len;
+		rmiaddr += block_len;
 	}
 exit:
 	mutex_unlock(&rmi_smb->page_mutex);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 241/877] Input: soc_button_array - fix MS Surface Pro 11 probe failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (239 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 240/877] Input: rmi_smbus - fix out-of-bounds read in rmi_smb_write_block() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 242/877] Input: soc_button_array - check btns_desc->package.count Greg Kroah-Hartman
                   ` (643 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sergey Lebedev, Hans de Goede,
	Dmitry Torokhov

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

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

From: Hans de Goede <johannes.goede@oss.qualcomm.com>

commit ed22ad5fdbdbf9b4cb4ad3003f60314b5a5eb89d upstream.

On the MS Surface Pro 11 soc_button_array probing races with the GPIO
driver probing. If soc_button_array wins the race then gpiod_get() returns
EPROBE_DEFER, which should normally take care of retrying later, but
the soc_button_array code deliberately ignores EPROBE_DEFER causing it
to fail its probe() which causes the volume and power buttons to now work.

The ignoring of EPROBE_DEFER is there to deal with a problem specific to
older Bay Trail (BYT) and Cherry Trail (CHT) tablets which often use this
driver. Modify the error handling to only ignore EPROBE_DEFER on BYT and
CHT platforms and propagate EPROBE_DEFER normally on other platforms.

Fixes: bcf059578980 ("Input: soc_button_array - partial revert of support for newer surface devices")
Cc: stable@vger.kernel.org
Reported-by: Sergey Lebedev <lsa.uz@pm.me>
Closes: https://lore.kernel.org/lkml/20260830141355.55898-1-lsa.uz@pm.me/
Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Tested-by: Sergey Lebedev <lsa.uz@pm.me>
Link: https://patch.msgid.link/20260909093934.29411-1-johannes.goede@oss.qualcomm.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/misc/soc_button_array.c |   14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

--- a/drivers/input/misc/soc_button_array.c
+++ b/drivers/input/misc/soc_button_array.c
@@ -16,6 +16,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/gpio_keys.h>
 #include <linux/gpio.h>
+#include <linux/platform_data/x86/soc.h>
 #include <linux/platform_device.h>
 
 static bool use_low_level_irq;
@@ -160,7 +161,7 @@ soc_button_device_create(struct platform
 	struct gpio_keys_platform_data *gpio_keys_pdata;
 	const struct dmi_system_id *dmi_id;
 	int invalid_acpi_index = -1;
-	int error, gpio, irq;
+	int error, gpio, irq = 0;
 	int n_buttons = 0;
 
 	for (info = button_info; info->name; info++)
@@ -191,8 +192,9 @@ soc_button_device_create(struct platform
 		error = soc_button_lookup_gpio(&pdev->dev, info->acpi_index, &gpio, &irq);
 		if (error || irq < 0) {
 			/*
-			 * Skip GPIO if not present. Note we deliberately
-			 * ignore -EPROBE_DEFER errors here. On some devices
+			 * Propagate -EPROBE_DEFER, skip button on other errors.
+			 *
+			 * -EPROBE_DEFER is ignored on Bay & Cherry Trail. Here
 			 * Intel is using so called virtual GPIOs which are not
 			 * GPIOs at all but some way for AML code to check some
 			 * random status bits without need a custom opregion.
@@ -201,6 +203,12 @@ soc_button_device_create(struct platform
 			 * we do not have a driver for these so they will never
 			 * show up, therefore we ignore -EPROBE_DEFER.
 			 */
+			if ((error == -EPROBE_DEFER || irq == -EPROBE_DEFER) &&
+			    !(soc_intel_is_byt() || soc_intel_is_cht())) {
+				error = -EPROBE_DEFER;
+				goto err_free_mem;
+			}
+
 			continue;
 		}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 242/877] Input: soc_button_array - check btns_desc->package.count
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (240 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 241/877] Input: soc_button_array - fix MS Surface Pro 11 probe failure Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 243/877] Input: synaptics - disable InterTouch on ThinkPad T440p (board id 2722) Greg Kroah-Hartman
                   ` (642 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Shashiko, Hans de Goede,
	Dmitry Torokhov

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

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

From: Hans de Goede <johannes.goede@oss.qualcomm.com>

commit fb5022278b6ea7f1838e3ef78028d5d5e3375f65 upstream.

Check that btns_desc->package.count is not 0 before accessing
btns_desc->package.elements[0].

Fixes: 4c3362f44980 ("Input: soc_button_array - add support for ACPI 6.0 Generic Button Device")
Cc: stable@vger.kernel.org
Reported-by: Shashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-input/20260909091440.3384C1F00A3A@smtp.kernel.org/
Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Link: https://patch.msgid.link/20260909093934.29411-2-johannes.goede@oss.qualcomm.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/misc/soc_button_array.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/input/misc/soc_button_array.c
+++ b/drivers/input/misc/soc_button_array.c
@@ -377,7 +377,7 @@ static struct soc_button_info *soc_butto
 		}
 	}
 
-	if (!btns_desc) {
+	if (!btns_desc || !btns_desc->package.count) {
 		dev_err(dev, "ACPI Button Descriptors not found\n");
 		button_info = ERR_PTR(-ENODEV);
 		goto out;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 243/877] Input: synaptics - disable InterTouch on ThinkPad T440p (board id 2722)
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (241 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 242/877] Input: soc_button_array - check btns_desc->package.count Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 244/877] Input: synaptics-rmi4 - fix GPF in suspend and resume when unbound Greg Kroah-Hartman
                   ` (641 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Raphaël Larocque,
	Dmitry Torokhov

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

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

From: Raphaël Larocque <rlarocque@disroot.org>

commit 26eb3d92c7a4d7adb1ae1740ca6e8e100b11d1ec upstream.

The Lenovo ThinkPad T440p (PNP ID LEN0036, board id 2722) has a
Synaptics touchpad whose SMBus companion is not ready at boot and
takes roughly 200 seconds to appear. During this window the touchpad
and TrackPoint are completely unresponsive on approximately 50% of
boots, making the machine unusable until the companion finally
registers.

The device is in the topbuttonpad_pnp_ids[] SMBus allowlist, so the
kernel attempts to use SMBus/RMI4 mode by default. When the companion
is not ready, psmouse_smbus_init() leaves breadcrumbs and returns
-EAGAIN, the PS/2 fallback path is taken, but the device does not
function properly until the companion appears and RMI4 takes over.

Disable SMBus InterTouch for board id 2722 so the touchpad and
TrackPoint work immediately via PS/2 from boot. Users can still force
SMBus with psmouse.synaptics_intertouch=1 if needed.

Tested-by: Raphaël Larocque <rlarocque@disroot.org>
Signed-off-by: Raphaël Larocque <rlarocque@disroot.org>
Link: https://patch.msgid.link/20260910164425.12832-1-rlarocque@disroot.org
Cc: stable@vger.kernel.org
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/mouse/synaptics.c |    8 ++++++++
 1 file changed, 8 insertions(+)

--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -1837,6 +1837,14 @@ static int synaptics_setup_intertouch(st
 
 			return -ENXIO;
 		}
+
+		/* Disable intertouch on known-broken board revisions */
+		if (info->board_id == 2722) {
+			psmouse_info(psmouse,
+				     "Disabling intertouch for board id %u\n",
+				     info->board_id);
+			return -ENXIO;
+		}
 	}
 
 	psmouse_info(psmouse, "Trying to set up SMBus access\n");



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 244/877] Input: synaptics-rmi4 - fix GPF in suspend and resume when unbound
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (242 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 243/877] Input: synaptics - disable InterTouch on ThinkPad T440p (board id 2722) Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 245/877] Input: zero ff_effect before compat copy in input_ff_effect_from_user Greg Kroah-Hartman
                   ` (640 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+09103639e39c989e3ed3,
	Dmitry Torokhov

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

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

From: Dmitry Torokhov <dmitry.torokhov@gmail.com>

commit fe10579b6dc3f0dac61e51e1797cacbba5039ac2 upstream.

Transport drivers (such as rmi_i2c and rmi_spi) invoke
rmi_driver_suspend() and rmi_driver_resume() on their child rmi_dev
device during system power management events. However, transport drivers
are fully registered and operational even if the physical RMI driver
failed to bind or probe the rmi_dev device.

When rmi_driver_suspend() or rmi_driver_resume() is called on an unbound
rmi_dev, dev_get_drvdata() returns NULL. Calling rmi_disable_irq() or
rmi_enable_irq() without driver data attached causes a NULL pointer
dereference and General Protection Fault when attempting to lock
data->enabled_mutex.

Fix this by checking if driver data is attached to rmi_dev in
rmi_driver_suspend() and rmi_driver_resume(), exiting early if
no driver data is present.

Fixes: 2b6a321da9a2 ("Input: synaptics-rmi4 - add support for Synaptics RMI4 devices")
Reported-by: syzbot+09103639e39c989e3ed3@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=09103639e39c989e3ed3
Cc: stable@vger.kernel.org
Assisted-by: LLM
Link: https://patch.msgid.link/anQe8UiyUR4x0flD@google.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/rmi4/rmi_driver.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -946,6 +946,15 @@ int rmi_driver_suspend(struct rmi_device
 {
 	int retval;
 
+	/*
+	 * Transport driver will try to suspend RMI device even if physical
+	 * driver did not bind to the RMI device, because transport device
+	 * (I2C, SPI) is fully registered and operational. Exit early if
+	 * there is no driver data attached to the RMI device.
+	 */
+	if (!dev_get_drvdata(&rmi_dev->dev))
+		return 0;
+
 	retval = rmi_suspend_functions(rmi_dev);
 	if (retval)
 		dev_warn(&rmi_dev->dev, "Failed to suspend functions: %d\n",
@@ -960,6 +969,10 @@ int rmi_driver_resume(struct rmi_device
 {
 	int retval;
 
+	/* Skip if not fully bound to RMI driver */
+	if (!dev_get_drvdata(&rmi_dev->dev))
+		return 0;
+
 	rmi_enable_irq(rmi_dev, clear_wake);
 
 	retval = rmi_resume_functions(rmi_dev);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 245/877] Input: zero ff_effect before compat copy in input_ff_effect_from_user
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (243 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 244/877] Input: synaptics-rmi4 - fix GPF in suspend and resume when unbound Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 246/877] hwmon: (hp-wmi-sensors) Fix use-after-free in fungible_show() Greg Kroah-Hartman
                   ` (639 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Iván Ezequiel Rodriguez,
	Dmitry Torokhov

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

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

From: Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>

commit f84819ef8d66931ee3998fee3c4f03230f4cb6cc upstream.

In the compat path input_ff_effect_from_user() aliases the caller's
native struct ff_effect with the smaller struct ff_effect_compat and
copies only the compat sized prefix:

	compat_effect = (struct ff_effect_compat *)effect;

	if (copy_from_user(compat_effect, buffer,
			   sizeof(struct ff_effect_compat)))

The tail of the native structure is never written. Callers pass an
uninitialized on-stack object, for example evdev_do_ioctl() for
EVIOCSFF, so those bytes keep their previous stack contents.
input_ff_upload() then stores the full native structure in
ff->effects[id], from where a uinput based force feedback daemon can
read it back via UI_BEGIN_FF_UPLOAD, disclosing kernel stack memory to
userspace.

Zero the effect before the compat copy.

Fixes: 2d56f3a32c0e ("Input: refactor evdev 32bit compat to be shareable with uinput")
Cc: stable@vger.kernel.org
Signed-off-by: Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>
Link: https://patch.msgid.link/20260901130629.24078-3-ivanrwcm25@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/input-compat.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/input/input-compat.c
+++ b/drivers/input/input-compat.c
@@ -75,6 +75,8 @@ int input_ff_effect_from_user(const char
 		 */
 		compat_effect = (struct ff_effect_compat *)effect;
 
+		memset(effect, 0, sizeof(*effect));
+
 		if (copy_from_user(compat_effect, buffer,
 				   sizeof(struct ff_effect_compat)))
 			return -EFAULT;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 246/877] hwmon: (hp-wmi-sensors) Fix use-after-free in fungible_show()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (244 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 245/877] Input: zero ff_effect before compat copy in input_ff_effect_from_user Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 247/877] hwmon: (pmbus/core) increase number of phases and add new mask Greg Kroah-Hartman
                   ` (638 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Muhammad Bilal, James Seo,
	Guenter Roeck

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

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

From: Muhammad Bilal <meatuni001@gmail.com>

commit e6cb0b4d4ecb8e71fd2200d907ab2e9663356f69 upstream.

nsensor->current_state is dynamically replaced as the sensor's state
changes. update_numeric_sensor_from_wobj() does this by freeing the
old string and installing a new one:

	if (strcmp(trimmed, nsensor->current_state)) {
		new_string = hp_wmi_strdup(dev, trimmed);
		if (new_string) {
			devm_kfree(dev, nsensor->current_state);
			nsensor->current_state = new_string;
		}
	}

This function is only ever called from hp_wmi_update_info() while
state->lock is held, so the free-and-replace itself is properly
serialized against concurrent updates.

fungible_show(), however, reads the same pointer after the lock has
already been dropped:

	err = hp_wmi_update_info(state, info);
	if (err)
		return err;

	switch (prop) {
	...
	case HP_WMI_PROPERTY_CURRENT_STATE:
		seq_printf(seqf, "%s\n", nsensor->current_state);
		break;

hp_wmi_update_info() takes state->lock internally and releases it
before returning, so by the time fungible_show() dereferences
nsensor->current_state in seq_printf(), no lock is held. Two
processes reading a sensor's current_state debugfs entry at
overlapping times (or one reading it while another read of the same
sensor triggers a refresh) can race: one thread's seq_printf() can
be part-way through printing the string at the moment another
thread's call into update_numeric_sensor_from_wobj() frees it with
devm_kfree() and installs a new pointer, causing a use-after-free
read.

Take state->lock around the read in fungible_show() as well, so it
can never run concurrently with the free-and-replace in
update_numeric_sensor_from_wobj().

Fixes: 23902f98f8d4 ("hwmon: add HP WMI Sensors driver")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Acked-by: James Seo <james@equiv.tech>
Link: https://patch.msgid.link/20260916002926.161595-1-meatuni001@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/hwmon/hp-wmi-sensors.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/hwmon/hp-wmi-sensors.c
+++ b/drivers/hwmon/hp-wmi-sensors.c
@@ -1247,7 +1247,9 @@ static int fungible_show(struct seq_file
 		break;
 
 	case HP_WMI_PROPERTY_CURRENT_STATE:
+		mutex_lock(&state->lock);
 		seq_printf(seqf, "%s\n", nsensor->current_state);
+		mutex_unlock(&state->lock);
 		break;
 
 	case HP_WMI_PROPERTY_UNIT_MODIFIER:



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 247/877] hwmon: (pmbus/core) increase number of phases and add new mask
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (245 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 246/877] hwmon: (hp-wmi-sensors) Fix use-after-free in fungible_show() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 248/877] hwmon: (pmbus/tps53679) Fix TPS53676 phase page decoding Greg Kroah-Hartman
                   ` (637 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Nuno Sá, Guenter Roeck

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

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

From: Nuno Sá <nuno.sa@analog.com>

commit 06bd6794b5fd2163880ac3bfe973d4cc61f359f3 upstream.

Increase the number of phases to 16 as a new upcoming device supports
such a number.

While at it, add a new mask for controlling the source of the output
voltage.

Note (groeck):

This patch was meant to prepare for support of MAX20826 and compatible
devices, which support more than 10 phases per page. However, Sashiko
reports that the mp2975 driver already supports up to 14 phases, and the
mp2856 driver supports up to 12 phases. This already has the potential for
out-of-bounds writes when probing the affected chips, making this patch a
bug fix.

Fixes: 2c6fcbb21149 ("hwmon: (pmbus) Add support for MPS Multi-phase mp2975 controller")
Fixes: f9e5f289b686 ("hwmon: (pmbus) Add support for MPS Multi-phase mp2856/mp2857 controller")
Signed-off-by: Nuno Sá <nuno.sa@analog.com>
Link: https://patch.msgid.link/20260911-hwmon-max20826-support-v2-1-5e30cbd97d84@analog.com
Cc: stable@vger.kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/hwmon/pmbus/pmbus.h |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/hwmon/pmbus/pmbus.h
+++ b/drivers/hwmon/pmbus/pmbus.h
@@ -241,6 +241,7 @@ enum pmbus_regs {
 /*
  * OPERATION
  */
+#define PB_OPERATION_CONTROL_V_SRC	GENMASK(5, 4)
 #define PB_OPERATION_CONTROL_ON		BIT(7)
 
 /*
@@ -385,7 +386,7 @@ enum pmbus_sensor_classes {
 };
 
 #define PMBUS_PAGES	32	/* Per PMBus specification */
-#define PMBUS_PHASES	10	/* Maximum number of phases per page */
+#define PMBUS_PHASES	16	/* Maximum number of phases per page */
 
 /* Functionality bit mask */
 #define PMBUS_HAVE_VIN		BIT(0)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 248/877] hwmon: (pmbus/tps53679) Fix TPS53676 phase page decoding
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (246 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 247/877] hwmon: (pmbus/core) increase number of phases and add new mask Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 249/877] hwmon: (pmbus/tps53679) Select page 0 for single-page TPS53676 Greg Kroah-Hartman
                   ` (636 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Sanman Pradhan, Guenter Roeck

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

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

From: Sanman Pradhan <psanman@juniper.net>

commit 1d12fb94ac0975566545871dda100df34df5f845 upstream.

tps53676_identify() reads the USER_DATA_03 phase configuration to count
the phases assigned to each channel and derive the number of PMBus pages.
In each 16-bit phase descriptor the channel (PAGE) is encoded in bit 4 and
the firing order in bits 3:0, but the code tested bit 3 (0x08), which is
part of the firing-order field.

TPS53676 supports up to seven phases, so firing-order bit 3 is never set.
As a result the existing test classifies every enabled phase as channel A.
On a dual-channel configuration the phases assigned to channel B are
therefore miscounted as channel A and page 1 is not exposed.

Test the PAGE field (bit 4) instead.

Fixes: cb3d37b59012 ("hwmon: (pmbus/tps53679) Add support for TI TPS53676")
Cc: stable@vger.kernel.org
Signed-off-by: Sanman Pradhan <psanman@juniper.net>
Link: https://patch.msgid.link/20260915164823.160977-2-sanman.pradhan@hpe.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/hwmon/pmbus/tps53679.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/hwmon/pmbus/tps53679.c
+++ b/drivers/hwmon/pmbus/tps53679.c
@@ -168,7 +168,7 @@ static int tps53676_identify(struct i2c_
 		return -EIO;
 	for (i = 0; i < 2 * TPS53676_MAX_PHASES; i += 2) {
 		if (buf[i + 1] & 0x80) {
-			if (buf[i] & 0x08)
+			if (buf[i] & BIT(4))
 				phases_b++;
 			else
 				phases_a++;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 249/877] hwmon: (pmbus/tps53679) Select page 0 for single-page TPS53676
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (247 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 248/877] hwmon: (pmbus/tps53679) Fix TPS53676 phase page decoding Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 250/877] hwmon: (w83791d) remove fan/pwm 4-5 sysfs group on remove Greg Kroah-Hartman
                   ` (635 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Sanman Pradhan, Guenter Roeck

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

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

From: Sanman Pradhan <psanman@juniper.net>

commit 089070b51ccbac411462a30a454690274c6e4270 upstream.

tps53676_identify() derives the number of PMBus pages but does not
ensure that page 0 is selected for single-page configurations.
pmbus_set_page() does not update the PAGE register when info->pages is
1, so if boot firmware leaves PAGE set to another value subsequent
register accesses may target the wrong page.

For single-page devices, select page 0 explicitly.

Fixes: cb3d37b59012 ("hwmon: (pmbus/tps53679) Add support for TI TPS53676")
Cc: stable@vger.kernel.org
Signed-off-by: Sanman Pradhan <psanman@juniper.net>
Link: https://patch.msgid.link/20260916235406.681131-2-sanman.pradhan@hpe.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/hwmon/pmbus/tps53679.c |    9 +++++++++
 1 file changed, 9 insertions(+)

--- a/drivers/hwmon/pmbus/tps53679.c
+++ b/drivers/hwmon/pmbus/tps53679.c
@@ -181,6 +181,15 @@ static int tps53676_identify(struct i2c_
 	if (phases_b > 0) {
 		info->pages = 2;
 		info->phases[1] = phases_b;
+	} else {
+		/*
+		 * pmbus_set_page() does not update the PAGE register on
+		 * single-page devices, so select page 0 explicitly in case
+		 * the boot firmware left the device on another page.
+		 */
+		ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
+		if (ret < 0)
+			return ret;
 	}
 	return 0;
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 250/877] hwmon: (w83791d) remove fan/pwm 4-5 sysfs group on remove
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (248 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 249/877] hwmon: (pmbus/tps53679) Select page 0 for single-page TPS53676 Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 251/877] hwmon: (w83793) release probe data through kref Greg Kroah-Hartman
                   ` (634 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Guenter Roeck

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

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

From: Guangshuo Li <lgs201920130244@gmail.com>

commit 0ff9c7775e51ac6d47b1bb5c46f06b1434fe58a8 upstream.

When the fan/pwm 4-5 pins are not used as GPIO, w83791d_probe()
creates the w83791d_group_fanpwm45 sysfs group on the I2C client
device.

The probe error path removes this group when a later initialization
step fails, but the normal remove path only removes w83791d_group.
As a result, the optional fan/pwm 4-5 sysfs files can remain after the
driver is unbound.

The callbacks associated with these files access the driver data,
which is devm allocated and released after driver unbind. Leaving the
sysfs files behind can therefore result in accesses to stale driver
data.

Remove w83791d_group_fanpwm45 during normal teardown as well.

This issue was found by manual code inspection.

Fixes: 6e1ecd9b8f13 ("hwmon: (w83791d) fan 4/5 pins can also be used for gpio")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Link: https://patch.msgid.link/20260914062809.1650538-1-lgs201920130244@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/hwmon/w83791d.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -1415,6 +1415,7 @@ static void w83791d_remove(struct i2c_cl
 	struct w83791d_data *data = i2c_get_clientdata(client);
 
 	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &w83791d_group_fanpwm45);
 	sysfs_remove_group(&client->dev.kobj, &w83791d_group);
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 251/877] hwmon: (w83793) release probe data through kref
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (249 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 250/877] hwmon: (w83791d) remove fan/pwm 4-5 sysfs group on remove Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 252/877] watchdog: da9063: fix suspend/resume handling of HW_RUNNING watchdog Greg Kroah-Hartman
                   ` (633 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Guenter Roeck

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

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

From: Guangshuo Li <lgs201920130244@gmail.com>

commit c702a5f18b780e477eccbbab558e590e9673e4cb upstream.

w83793_probe() initializes data->kref to manage the lifetime of the
driver data. The normal remove path drops the driver-owned reference
with kref_put(), while watchdog users take and release additional
references through the same kref.

However, the probe error path still frees data directly with kfree().
This bypasses the kref-managed lifetime and discards the initial
reference without a matching kref_put(), leaving the reference
accounting unbalanced.

Drop the probe-owned reference with kref_put() instead and let
w83793_release_resources() perform the final free, matching the normal
remove path.

This issue was found by manual code inspection.

Fixes: 5852f9609d21 ("hwmon: (w83793) Add watchdog functionality")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Link: https://patch.msgid.link/20260914073638.1662500-1-lgs201920130244@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/hwmon/w83793.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -1928,7 +1928,9 @@ exit_remove:
 	for (i = 0; i < ARRAY_SIZE(w83793_temp); i++)
 		device_remove_file(dev, &w83793_temp[i].dev_attr);
 free_mem:
-	kfree(data);
+	mutex_lock(&watchdog_data_mutex);
+	kref_put(&data->kref, w83793_release_resources);
+	mutex_unlock(&watchdog_data_mutex);
 exit:
 	return err;
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 252/877] watchdog: da9063: fix suspend/resume handling of HW_RUNNING watchdog
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (250 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 251/877] hwmon: (w83793) release probe data through kref Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 253/877] watchdog: digicolor: Avoid division by zero Greg Kroah-Hartman
                   ` (632 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Li Jun, Guenter Roeck

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

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

From: Li Jun <lijun01@kylinos.cn>

commit 7cb575b71ab98194d2e040bded3a7281e089c5ed upstream.

da9063_wdt_suspend() and da9063_wdt_resume() only check watchdog_active(),
when the watchdog is left running by the driver sets
WDOG_HW_RUNNING in da9063_wdt_probe() but userspace never opens the
device, so WDOG_ACTIVE remains cleared, the wdt_disable() will not be
executed in da9063_wdt_suspend. In this case, the suspend callback is
a no-op and the watchdog keeps counting during system suspend,
leading to an unexpected system reset.
Check WDOG_HW_RUNNING and wdd,can fix this issue.

Fixes: a7ceca4398bc8 ("watchdog: da9063: optionally disable watchdog during suspend")
Cc: stable@vger.kernel.org
Signed-off-by: Li Jun <lijun01@kylinos.cn>
Link: https://patch.msgid.link/20260917013710.2754679-1-lijun01@kylinos.cn
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/watchdog/da9063_wdt.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/watchdog/da9063_wdt.c
+++ b/drivers/watchdog/da9063_wdt.c
@@ -271,7 +271,7 @@ static int __maybe_unused da9063_wdt_sus
 	if (!use_sw_pm)
 		return 0;
 
-	if (watchdog_active(wdd))
+	if (watchdog_active(wdd) || watchdog_hw_running(wdd))
 		return da9063_wdt_stop(wdd);
 
 	return 0;
@@ -284,7 +284,7 @@ static int __maybe_unused da9063_wdt_res
 	if (!use_sw_pm)
 		return 0;
 
-	if (watchdog_active(wdd))
+	if (watchdog_active(wdd) || watchdog_hw_running(wdd))
 		return da9063_wdt_start(wdd);
 
 	return 0;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 253/877] watchdog: digicolor: Avoid division by zero
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (251 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 252/877] watchdog: da9063: fix suspend/resume handling of HW_RUNNING watchdog Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 254/877] watchdog: msc313e: Fix premature reset during timeout update Greg Kroah-Hartman
                   ` (631 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Baruch Siach,
	Guenter Roeck

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

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

From: Tzung-Bi Shih <tzungbi@kernel.org>

commit 400cb663ca019bae6eb878f06f1094ddf7c0b0df upstream.

clk_get_rate() could return 0.  Avoid a division by zero panic.

Since get_timeleft() cannot propagate errors, check the clock rate early
in probe() and cache the rate in the driver data as it is unlikely to
change at runtime.

Fixes: 336694a01dae ("watchdog: digicolor: driver for Conexant Digicolor CX92755 SoC")
Cc: stable@vger.kernel.org
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Acked-by: Baruch Siach <baruch@tkos.co.il>
Link: https://patch.msgid.link/20260913064851.8239-2-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/watchdog/digicolor_wdt.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

--- a/drivers/watchdog/digicolor_wdt.c
+++ b/drivers/watchdog/digicolor_wdt.c
@@ -25,6 +25,7 @@ struct dc_wdt {
 	void __iomem		*base;
 	struct clk		*clk;
 	spinlock_t		lock;
+	unsigned long		rate;
 };
 
 static unsigned timeout;
@@ -61,7 +62,7 @@ static int dc_wdt_start(struct watchdog_
 {
 	struct dc_wdt *wdt = watchdog_get_drvdata(wdog);
 
-	dc_wdt_set(wdt, wdog->timeout * clk_get_rate(wdt->clk));
+	dc_wdt_set(wdt, wdog->timeout * wdt->rate);
 
 	return 0;
 }
@@ -79,7 +80,7 @@ static int dc_wdt_set_timeout(struct wat
 {
 	struct dc_wdt *wdt = watchdog_get_drvdata(wdog);
 
-	dc_wdt_set(wdt, t * clk_get_rate(wdt->clk));
+	dc_wdt_set(wdt, t * wdt->rate);
 	wdog->timeout = t;
 
 	return 0;
@@ -90,7 +91,7 @@ static unsigned int dc_wdt_get_timeleft(
 	struct dc_wdt *wdt = watchdog_get_drvdata(wdog);
 	uint32_t count = readl_relaxed(wdt->base + TIMER_A_COUNT);
 
-	return count / clk_get_rate(wdt->clk);
+	return count / wdt->rate;
 }
 
 static const struct watchdog_ops dc_wdt_ops = {
@@ -130,7 +131,11 @@ static int dc_wdt_probe(struct platform_
 	wdt->clk = devm_clk_get(dev, NULL);
 	if (IS_ERR(wdt->clk))
 		return PTR_ERR(wdt->clk);
-	dc_wdt_wdd.max_timeout = U32_MAX / clk_get_rate(wdt->clk);
+
+	wdt->rate = clk_get_rate(wdt->clk);
+	if (!wdt->rate)
+		return -EINVAL;
+	dc_wdt_wdd.max_timeout = U32_MAX / wdt->rate;
 	dc_wdt_wdd.timeout = dc_wdt_wdd.max_timeout;
 	dc_wdt_wdd.parent = dev;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 254/877] watchdog: msc313e: Fix premature reset during timeout update
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (252 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 253/877] watchdog: digicolor: Avoid division by zero Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 255/877] watchdog: msc313e: Propagate error code in resume() Greg Kroah-Hartman
                   ` (630 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Guenter Roeck

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

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

From: Tzung-Bi Shih <tzungbi@kernel.org>

commit 22737cfced627ffcb4b5c36d63bb3d4476f63213 upstream.

Updating the 32-bit hardware timeout requires writing to two 16-bit
registers sequentially.  If the watchdog is actively running, this
non-atomic update might trigger a premature system reset.

Clear the watchdog counter before updating the registers to prevent the
timer from timing out prematurely against an intermediate threshold.

Fixes: e9800b799464 ("watchdog: Add Mstar MSC313e WDT driver")
Cc: stable@vger.kernel.org
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260913065126.8350-1-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/watchdog/msc313e_wdt.c |    6 ++++++
 1 file changed, 6 insertions(+)

--- a/drivers/watchdog/msc313e_wdt.c
+++ b/drivers/watchdog/msc313e_wdt.c
@@ -47,6 +47,9 @@ static void msc313e_wdt_set_hw_timeout(s
 {
 	u32 t = timeout * clk_get_rate(priv->clk);
 
+	/* Clear before to prevent premature reset during non-atomic updates. */
+	writew(1, priv->base + REG_WDT_CLR);
+
 	writew(t & 0xffff, priv->base + REG_WDT_MAX_PRD_L);
 	writew((t >> 16) & 0xffff, priv->base + REG_WDT_MAX_PRD_H);
 	writew(1, priv->base + REG_WDT_CLR);
@@ -77,6 +80,9 @@ static int msc313e_wdt_stop(struct watch
 {
 	struct msc313e_wdt_priv *priv = watchdog_get_drvdata(wdev);
 
+	/* Clear before to prevent premature reset during non-atomic updates. */
+	writew(1, priv->base + REG_WDT_CLR);
+
 	writew(0, priv->base + REG_WDT_MAX_PRD_L);
 	writew(0, priv->base + REG_WDT_MAX_PRD_H);
 	writew(0, priv->base + REG_WDT_CLR);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 255/877] watchdog: msc313e: Propagate error code in resume()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (253 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 254/877] watchdog: msc313e: Fix premature reset during timeout update Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 256/877] watchdog: rtd119x: Avoid division by zero Greg Kroah-Hartman
                   ` (629 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Guenter Roeck

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

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

From: Tzung-Bi Shih <tzungbi@kernel.org>

commit 1d9763f34a85680db1e8233d654fdb85e5f897cc upstream.

If msc313e_wdt_start() fails during system resume, the error is
currently ignored.  Consequently, the watchdog isn't running without the
user's knowledge.

Propagate the error code and print a message if msc313e_wdt_start()
fails.

Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Fixes: e9800b7994642 ("watchdog: Add Mstar MSC313e WDT driver")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260912163334.28636-1-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/watchdog/msc313e_wdt.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

--- a/drivers/watchdog/msc313e_wdt.c
+++ b/drivers/watchdog/msc313e_wdt.c
@@ -198,11 +198,15 @@ static int __maybe_unused msc313e_wdt_su
 static int __maybe_unused msc313e_wdt_resume(struct device *dev)
 {
 	struct msc313e_wdt_priv *priv = dev_get_drvdata(dev);
+	int ret = 0;
 
-	if (watchdog_active(&priv->wdev) || watchdog_hw_running(&priv->wdev))
-		msc313e_wdt_start(&priv->wdev);
+	if (watchdog_active(&priv->wdev) || watchdog_hw_running(&priv->wdev)) {
+		ret = msc313e_wdt_start(&priv->wdev);
+		if (ret)
+			dev_err(dev, "Failed to restart watchdog (err=%d)\n", ret);
+	}
 
-	return 0;
+	return ret;
 }
 
 static SIMPLE_DEV_PM_OPS(msc313e_wdt_pm_ops, msc313e_wdt_suspend, msc313e_wdt_resume);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 256/877] watchdog: rtd119x: Avoid division by zero
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (254 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 255/877] watchdog: msc313e: Propagate error code in resume() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 257/877] watchdog: sp5100_tco: Fix pci_dev reference leak in sp5100_tco_init() Greg Kroah-Hartman
                   ` (628 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Guenter Roeck

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

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

From: Tzung-Bi Shih <tzungbi@kernel.org>

commit 5af7d2cbd20f893def03c8310a460ade66a5d822 upstream.

clk_get_rate() could return 0.  Avoid a division by zero panic.

Fixes: 2bdf6acbfead ("watchdog: Add Realtek RTD1295")
Cc: stable@vger.kernel.org
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260913064851.8239-3-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/watchdog/rtd119x_wdt.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

--- a/drivers/watchdog/rtd119x_wdt.c
+++ b/drivers/watchdog/rtd119x_wdt.c
@@ -98,6 +98,7 @@ static int rtd119x_wdt_probe(struct plat
 {
 	struct device *dev = &pdev->dev;
 	struct rtd119x_watchdog_device *data;
+	unsigned long rate;
 
 	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 	if (!data)
@@ -111,10 +112,14 @@ static int rtd119x_wdt_probe(struct plat
 	if (IS_ERR(data->clk))
 		return PTR_ERR(data->clk);
 
+	rate = clk_get_rate(data->clk);
+	if (!rate)
+		return -EINVAL;
+
 	data->wdt_dev.info = &rtd119x_wdt_info;
 	data->wdt_dev.ops = &rtd119x_wdt_ops;
 	data->wdt_dev.timeout = 120;
-	data->wdt_dev.max_timeout = 0xffffffff / clk_get_rate(data->clk);
+	data->wdt_dev.max_timeout = 0xffffffff / rate;
 	data->wdt_dev.min_timeout = 1;
 	data->wdt_dev.parent = dev;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 257/877] watchdog: sp5100_tco: Fix pci_dev reference leak in sp5100_tco_init()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (255 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 256/877] watchdog: rtd119x: Avoid division by zero Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 258/877] watchdog: starfive-wdt: Fix runtime PM leak in starfive_wdt_pm_start() Greg Kroah-Hartman
                   ` (627 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Guenter Roeck

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

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

From: Wentao Liang <vulab@iscas.ac.cn>

commit 88f113634028ca90a857031837d8061d1a9e1a7b upstream.

sp5100_tco_init() stores the PCI device matched by for_each_pci_dev()
in the global sp5100_tco_pci and keeps its reference for the lifetime
of the driver, but neither sp5100_tco_exit() nor the error paths of
sp5100_tco_init() call pci_dev_put(), leaking the reference on driver
registration failure and on every module load/unload cycle.

Drop the reference when the platform driver or device registration
fails and when the module is unloaded.

Fixes: 15e28bf13008 ("watchdog: Add support for sp5100 chipset TCO")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260916170511.2086199-1-vulab@iscas.ac.cn
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/watchdog/sp5100_tco.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

--- a/drivers/watchdog/sp5100_tco.c
+++ b/drivers/watchdog/sp5100_tco.c
@@ -605,8 +605,10 @@ static int __init sp5100_tco_init(void)
 	pr_info("SP5100/SB800 TCO WatchDog Timer Driver\n");
 
 	err = platform_driver_register(&sp5100_tco_driver);
-	if (err)
+	if (err) {
+		pci_dev_put(sp5100_tco_pci);
 		return err;
+	}
 
 	sp5100_tco_platform_device =
 		platform_device_register_simple(TCO_DRIVER_NAME, -1, NULL, 0);
@@ -619,6 +621,7 @@ static int __init sp5100_tco_init(void)
 
 unreg_platform_driver:
 	platform_driver_unregister(&sp5100_tco_driver);
+	pci_dev_put(sp5100_tco_pci);
 	return err;
 }
 
@@ -626,6 +629,7 @@ static void __exit sp5100_tco_exit(void)
 {
 	platform_device_unregister(sp5100_tco_platform_device);
 	platform_driver_unregister(&sp5100_tco_driver);
+	pci_dev_put(sp5100_tco_pci);
 }
 
 module_init(sp5100_tco_init);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 258/877] watchdog: starfive-wdt: Fix runtime PM leak in starfive_wdt_pm_start()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (256 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 257/877] watchdog: sp5100_tco: Fix pci_dev reference leak in sp5100_tco_init() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 259/877] wifi: brcmsmac: fix UAF in brcms_free_timer() Greg Kroah-Hartman
                   ` (626 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Guenter Roeck

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

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

From: Wentao Liang <vulab@iscas.ac.cn>

commit 8f0ca55016a7647109ae2bc91bcb346fc8b13785 upstream.

starfive_wdt_pm_start() takes a runtime PM reference with
pm_runtime_get_sync(), which increments the usage counter even when it
fails, and returns the error without dropping it again.  The watchdog
core does not invoke the stop callback when start fails, so the
reference taken on the error path is leaked.

Use pm_runtime_resume_and_get() instead, which keeps the usage counter
balanced when the resume fails.

Fixes: db728ea9c7be ("drivers: watchdog: Add StarFive Watchdog driver")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260916170704.2086331-1-vulab@iscas.ac.cn
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/watchdog/starfive-wdt.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/watchdog/starfive-wdt.c
+++ b/drivers/watchdog/starfive-wdt.c
@@ -371,7 +371,7 @@ static void starfive_wdt_stop(struct sta
 static int starfive_wdt_pm_start(struct watchdog_device *wdd)
 {
 	struct starfive_wdt *wdt = watchdog_get_drvdata(wdd);
-	int ret = pm_runtime_get_sync(wdd->parent);
+	int ret = pm_runtime_resume_and_get(wdd->parent);
 
 	if (ret < 0)
 		return ret;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 259/877] wifi: brcmsmac: fix UAF in brcms_free_timer()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (257 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 258/877] watchdog: starfive-wdt: Fix runtime PM leak in starfive_wdt_pm_start() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 260/877] wifi: iwlegacy: fix broadcast stations deallocation Greg Kroah-Hartman
                   ` (625 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jiangshan Yi, Arend van Spriel,
	Johannes Berg

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

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

From: Jiangshan Yi <yijiangshan@kylinos.cn>

commit 1eeca1d5e0920fbdad6449768fd2d4364e714180 upstream.

brcms_free_timer() calls brcms_del_timer() which uses the non-synchronous
cancel_delayed_work() to cancel the timer's underlying delayed work.  If
the work callback (_brcms_timer) is already running, cancel_delayed_work()
returns false without waiting, and brcms_free_timer() proceeds to kfree(t)
while the callback still accesses t through container_of().

Add an explicit cancel_delayed_work_sync() after brcms_del_timer() to
guarantee that any in-flight callback has completed before the timer
structure is freed.

Fixes: 5b435de0d786 ("net: wireless: add brcm80211 drivers")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260815121043.938414-1-yijiangshan@kylinos.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
@@ -1569,6 +1569,10 @@ void brcms_free_timer(struct brcms_timer
 
 	/* delete the timer in case it is active */
 	brcms_del_timer(t);
+	/* Ensure the callback has finished before freeing the timer
+	 * structure, since brcms_del_timer() uses non-synchronous cancel.
+	 */
+	cancel_delayed_work_sync(&t->dly_wrk);
 
 	if (wl->timers == t) {
 		wl->timers = wl->timers->next;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 260/877] wifi: iwlegacy: fix broadcast stations deallocation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (258 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 259/877] wifi: brcmsmac: fix UAF in brcms_free_timer() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 261/877] wifi: libertas_tf: fix UAF in lbtf_free_adapter() Greg Kroah-Hartman
                   ` (624 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Stanislaw Gruszka, Johannes Berg,
	Martin-Éric Racine

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

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

From: Stanislaw Gruszka <stf_xl@wp.pl>

commit b5526b780f8b297a76030410b96ba29153afb98f upstream.

On the error path of __il4965_up(), il_dealloc_bcast_stations() clears
only IL_STA_UCODE_ACTIVE, leaving IL_STA_BCAST set. This causes the
same broadcast stations to be deallocated again by __il4965_down().

This can occur when RF_KILL is toggled during driver startup.

To fix clear the entire 'used' field, since we will not do any
other operations on the station.

Reported-and-tested-by: Martin-Éric Racine <martin-eric.racine+kernel-bugzilla@iki.fi>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221733
Fixes: c2fd34469d16 ("iwl4965: Fix a memory leak in error handling code of __il4965_up")
Cc: <stable@vger.kernel.org> # 7.1.x: 57aa1718d595 wifi: iwlegacy: replace BUG_ON() with WARN_ON() on num_stations check
Cc: <stable@vger.kernel.org> # 6.x.x: 57aa1718d595 wifi: iwlegacy: replace BUG_ON() with WARN_ON() on num_stations check
Cc: <stable@vger.kernel.org> # 5.x.x: 57aa1718d595 wifi: iwlegacy: replace BUG_ON() with WARN_ON() on num_stations check
Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
Link: https://patch.msgid.link/20260820093059.18779-1-stf_xl@wp.pl
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/intel/iwlegacy/common.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/net/wireless/intel/iwlegacy/common.c
+++ b/drivers/net/wireless/intel/iwlegacy/common.c
@@ -2327,7 +2327,7 @@ il_dealloc_bcast_stations(struct il_priv
 		if (!(il->stations[i].used & IL_STA_BCAST))
 			continue;
 
-		il->stations[i].used &= ~IL_STA_UCODE_ACTIVE;
+		il->stations[i].used = 0;
 		il->num_stations--;
 		BUG_ON(il->num_stations < 0);
 		kfree(il->stations[i].lq);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 261/877] wifi: libertas_tf: fix UAF in lbtf_free_adapter()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (259 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 260/877] wifi: iwlegacy: fix broadcast stations deallocation Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 262/877] wifi: rsi: fix heap OOB write on key removal Greg Kroah-Hartman
                   ` (623 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Jiangshan Yi, Johannes Berg

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

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

From: Jiangshan Yi <yijiangshan@kylinos.cn>

commit bbb9a0ab96d44a64529aafc7a16de460a1712f6a upstream.

lbtf_free_adapter() calls lbtf_free_cmd_buffer() to free the command
buffers before calling timer_delete_sync() to wait for the command
timer callback.  If the timer callback (command_timer_fn) is already
running when lbtf_free_cmd_buffer() frees the command array, the
callback dereferences priv->cur_cmd->cmdbuf which points to freed
memory.

Swap the order so that timer_delete_sync() runs first, ensuring any
in-flight callback has completed before the command buffers are freed.

Fixes: 06b16ae53192 ("libertas_tf: main.c, data paths and mac80211 handlers")
Cc: stable@vger.kernel.org
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Link: https://patch.msgid.link/20260815115724.920628-1-yijiangshan@kylinos.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/marvell/libertas_tf/main.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/net/wireless/marvell/libertas_tf/main.c
+++ b/drivers/net/wireless/marvell/libertas_tf/main.c
@@ -173,8 +173,8 @@ static int lbtf_init_adapter(struct lbtf
 static void lbtf_free_adapter(struct lbtf_private *priv)
 {
 	lbtf_deb_enter(LBTF_DEB_MAIN);
-	lbtf_free_cmd_buffer(priv);
 	timer_delete_sync(&priv->command_timer);
+	lbtf_free_cmd_buffer(priv);
 	lbtf_deb_leave(LBTF_DEB_MAIN);
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 262/877] wifi: rsi: fix heap OOB write on key removal
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (260 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 261/877] wifi: libertas_tf: fix UAF in lbtf_free_adapter() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 263/877] wifi: wlcore: release runtime PM ref on regdomain config failure Greg Kroah-Hartman
                   ` (622 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Tianchu Chen, Johannes Berg

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

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

From: Tianchu Chen <flynnnchen@tencent.com>

commit e6c5ed7a98d7bc8b0f7918246f1c90ddb3f79dfa upstream.

When a key is removed (data == NULL), rsi_hal_load_key() runs:

	memset(&set_key[FRAME_DESC_SZ], 0, frame_len - FRAME_DESC_SZ);

set_key is a struct rsi_set_key *, so the subscript is scaled by
sizeof(struct rsi_set_key) (160 bytes): &set_key[FRAME_DESC_SZ] is
skb->data + 2560, and the memset writes 144 zero bytes starting
2.4KB past the end of the 160-byte skb data buffer, corrupting
unrelated heap objects. The intended byte offset would have been
(u8 *)set_key + FRAME_DESC_SZ.

The write fires on every DISABLE_KEY callback, so plain disconnects,
roams and interface teardowns trigger it on real networks.

The memset is redundant: the whole buffer is zeroed right after
allocation, so the frame sent to the device is byte-identical
without it. Drop the else branch; normal operation is unaffected.

Discovered by Atuin - Automated Vulnerability Discovery Engine.

Fixes: dad0d04fa7ba ("rsi: Add RS9113 wireless driver")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Tianchu Chen <flynnnchen@tencent.com>
Link: https://patch.msgid.link/90bb2b07007942064c04aa3729cedd9eb1e930b1@linux.dev
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/rsi/rsi_91x_mgmt.c |    2 --
 1 file changed, 2 deletions(-)

--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -852,8 +852,6 @@ int rsi_hal_load_key(struct rsi_common *
 			memcpy(set_key->tx_mic_key, &data[16], 8);
 			memcpy(set_key->rx_mic_key, &data[24], 8);
 		}
-	} else {
-		memset(&set_key[FRAME_DESC_SZ], 0, frame_len - FRAME_DESC_SZ);
 	}
 
 	skb_put(skb, frame_len);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 263/877] wifi: wlcore: release runtime PM ref on regdomain config failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (261 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 262/877] wifi: rsi: fix heap OOB write on key removal Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 264/877] wifi: wilc1000: fix out-of-bounds read in P2P public action frames Greg Kroah-Hartman
                   ` (621 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Johannes Berg

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

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

From: Runyu Xiao <runyu.xiao@seu.edu.cn>

commit 8a1f3cf89ddcc700e25afe42cfad333059adcc94 upstream.

wlcore_regdomain_config() gets a runtime PM reference before sending
the regulatory-domain command. When
wlcore_cmd_regdomain_config_locked() fails, the function queues recovery
and returns without dropping that reference.

Release the reference after handling the command result so both success
and failure paths balance the preceding
pm_runtime_resume_and_get(). The recovery worker takes a separate
runtime PM reference and cannot release the reference held here.

Fixes: fa2648a34e73 ("wlcore: Add support for runtime PM")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Link: https://patch.msgid.link/20260820125126.12757-1-runyu.xiao@seu.edu.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/ti/wlcore/main.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -3718,10 +3718,8 @@ void wlcore_regdomain_config(struct wl12
 		goto out;
 
 	ret = wlcore_cmd_regdomain_config_locked(wl);
-	if (ret < 0) {
+	if (ret < 0)
 		wl12xx_queue_recovery_work(wl);
-		goto out;
-	}
 
 	pm_runtime_mark_last_busy(wl->dev);
 	pm_runtime_put_autosuspend(wl->dev);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 264/877] wifi: wilc1000: fix out-of-bounds read in P2P public action frames
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (262 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 263/877] wifi: wlcore: release runtime PM ref on regdomain config failure Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 265/877] wifi: wilc1000: fix RX buffer OOB-write in wilc_wlan_handle_isr_ext() Greg Kroah-Hartman
                   ` (620 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Ali Ahmet Memis, Johannes Berg

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

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

From: Ali Ahmet Memis <ali@iusegentoo.com>

commit ba6cb7c0868a412c2eb68e8efd5aa38bfb258a14 upstream.

wilc_wfi_p2p_rx() and mgmt_tx() start parsing a frame once
ieee80211_is_public_action() returns true. That helper only verifies the
frame is long enough for the action category field, that is
offsetofend(struct ieee80211_mgmt, u.action.category), 25 bytes. Both
functions then read the P2P public action header up to oui_subtype at
offset 30 and pass "size - ie_offset" to cfg80211_find_vendor_ie(), where
ie_offset is offsetof(struct ieee80211_mgmt, u) + sizeof(*d), i.e. 32.

A public action frame of 25 to 31 bytes passes the check but is shorter
than that 32 byte header, so oui_subtype can be read out of bounds, and
because the length is unsigned, "size - ie_offset" underflows to a value
close to 4 GiB. cfg80211_find_vendor_ie() takes an unsigned int length,
so even the size_t subtraction in mgmt_tx() is truncated to the same
value. It then walks far past the buffer searching for a vendor element
until it reaches unmapped memory.

In the receive path the frame arrives over the air and needs no
association, so a nearby unauthenticated device can crash the host while
it is in P2P listen. Reject frames shorter than the P2P public action
header in both paths before dereferencing it.

Fixes: 4fb8b5aa2a11 ("staging: wilc1000: refactor p2p action frames handling API's")
Cc: stable@vger.kernel.org
Signed-off-by: Ali Ahmet Memis <ali@iusegentoo.com>
Link: https://patch.msgid.link/20260807115230.136767-1-ali@iusegentoo.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/microchip/wilc1000/cfg80211.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)

--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
@@ -1066,6 +1066,13 @@ void wilc_wfi_p2p_rx(struct wilc_vif *vi
 	if (!ieee80211_is_public_action((struct ieee80211_hdr *)buff, size))
 		goto out_rx_mgmt;
 
+	/* ieee80211_is_public_action() only validates up to the category
+	 * byte, so reject frames too short for the P2P public action header
+	 * before dereferencing it or computing size - ie_offset.
+	 */
+	if (size < ie_offset)
+		goto out_rx_mgmt;
+
 	d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
 	if (d->oui_subtype != GO_NEG_REQ && d->oui_subtype != GO_NEG_RSP &&
 	    d->oui_subtype != P2P_INV_REQ && d->oui_subtype != P2P_INV_RSP)
@@ -1214,6 +1221,13 @@ static int mgmt_tx(struct wiphy *wiphy,
 		goto out_set_timeout;
 	}
 
+	/* ieee80211_is_public_action() only validates up to the category
+	 * byte, so reject frames too short for the P2P public action header
+	 * before dereferencing it or computing len - ie_offset.
+	 */
+	if (len < ie_offset)
+		goto out_set_timeout;
+
 	d = (struct wilc_p2p_pub_act_frame *)(&mgmt->u.action);
 	if (d->oui_type != WLAN_OUI_TYPE_WFA_P2P ||
 	    d->oui_subtype != GO_NEG_CONF) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 265/877] wifi: wilc1000: fix RX buffer OOB-write in wilc_wlan_handle_isr_ext()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (263 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 264/877] wifi: wilc1000: fix out-of-bounds read in P2P public action frames Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 266/877] wifi: p54: validate curve data length in the calibration curve converters Greg Kroah-Hartman
                   ` (619 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Tianchu Chen, Johannes Berg

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

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

From: Tianchu Chen <flynnnchen@tencent.com>

commit c1ba7f7f18465e259cf1b4d9c73fc73853d7f790 upstream.

wilc_wlan_handle_isr_ext() takes the RX transfer size from the
device-reported interrupt status register (a 15-bit field shifted left by 2,
up to 131068 bytes) and reads that many bytes from the device into
rx_buffer, which is only WILC_RX_BUFF_SIZE (96K) large. The wrap
check only handles the current offset; the size itself is never
compared against the buffer, so a bogus SDIO device can make the driver
OOB-write rx_buffer by up to ~32K with data it controls.

The oversized transfer also leaves rx_buffer_offset past the end of
the buffer, after which the unsigned wrap check stops working and
the overflow can repeat.

Drop any transfer whose size exceeds the RX buffer, acknowledging
the data interrupt and re-arming the RX engine so the bogus frame is
discarded and reception can continue. This also restores the
rx_buffer_offset <= WILC_RX_BUFF_SIZE invariant the wrap check
relies on.

This is not expected to change driver behavior in most cases:
without this check, an oversized transfer would most likely
corrupt neighboring kernel memory instead of completing anyway, and
the drop path performs the same interrupt acknowledgment and RX
engine re-arming as the normal path, so subsequent transfers are
received unaffected.

Discovered by Atuin - Automated Vulnerability Discovery Engine.

Fixes: c5c77ba18ea6 ("staging: wilc1000: Add SDIO/SPI 802.11 driver")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Tianchu Chen <flynnnchen@tencent.com>
Link: https://patch.msgid.link/7c971924c6bdccf6c2f75704a5a746e9303aaf64@linux.dev
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/microchip/wilc1000/wlan.c |    9 +++++++++
 1 file changed, 9 insertions(+)

--- a/drivers/net/wireless/microchip/wilc1000/wlan.c
+++ b/drivers/net/wireless/microchip/wilc1000/wlan.c
@@ -1035,6 +1035,15 @@ static void wilc_wlan_handle_isr_ext(str
 	if (size <= 0)
 		return;
 
+	/* A size exceeding the RX buffer is bogus; drop the transfer
+	 * instead of overflowing the buffer.
+	 */
+	if (size > WILC_RX_BUFF_SIZE) {
+		wilc->hif_func->hif_clear_int_ext(wilc,
+						  DATA_INT_CLR | ENABLE_RX_VMM);
+		return;
+	}
+
 	if (WILC_RX_BUFF_SIZE - offset < size)
 		offset = 0;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 266/877] wifi: p54: validate curve data length in the calibration curve converters
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (264 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 265/877] wifi: wilc1000: fix RX buffer OOB-write in wilc_wlan_handle_isr_ext() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 267/877] wifi: p54: require a full exp_if record in PDR_INTERFACE_LIST Greg Kroah-Hartman
                   ` (618 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Shengzhuo Wei, Johannes Berg

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

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

From: Shengzhuo Wei <me@cherr.cc>

commit ce858fa6b8a214dee5adb82358885fa024cdd887 upstream.

p54_convert_rev0() and p54_convert_rev1() read calibration curve
data from the device-supplied EEPROM entry using channel and
points-per-channel counts taken verbatim from that same entry, so
an entry that declares more data than it carries drives an
out-of-bounds read past the EEPROM buffer (verified with a KASAN
reproducer of the conversion loop). The sibling converters
p54_convert_output_limits() and p54_convert_db() already validate
their counts against the entry length; this path was missed.

Reject the entry when the counts do not fit in the entry data.

Fixes: eff1a59c48e3 ("[P54]: add mac80211-based driver for prism54 softmac hardware")
Cc: stable@vger.kernel.org
Assisted-by: GLM:5.3
Signed-off-by: Shengzhuo Wei <me@cherr.cc>
Link: https://patch.msgid.link/20260831-p54-pda-validation-v2-1-dae566b388c8@cherr.cc
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/intersil/p54/eeprom.c |   19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

--- a/drivers/net/wireless/intersil/p54/eeprom.c
+++ b/drivers/net/wireless/intersil/p54/eeprom.c
@@ -418,17 +418,22 @@ free:
 }
 
 static int p54_convert_rev0(struct ieee80211_hw *dev,
-			    struct pda_pa_curve_data *curve_data)
+			    struct pda_pa_curve_data *curve_data, size_t len)
 {
 	struct p54_common *priv = dev->priv;
 	struct p54_pa_curve_data_sample *dst;
 	struct pda_pa_curve_data_sample_rev0 *src;
+	size_t needed = curve_data->channels *
+		(sizeof(*src) * curve_data->points_per_channel + 2);
 	size_t cd_len = sizeof(*curve_data) +
 		(curve_data->points_per_channel*sizeof(*dst) + 2) *
 		 curve_data->channels;
 	unsigned int i, j;
 	void *source, *target;
 
+	if (len < sizeof(*curve_data) + needed)
+		return -EINVAL;
+
 	priv->curve_data = kmalloc(sizeof(*priv->curve_data) + cd_len,
 				   GFP_KERNEL);
 	if (!priv->curve_data)
@@ -470,17 +475,22 @@ static int p54_convert_rev0(struct ieee8
 }
 
 static int p54_convert_rev1(struct ieee80211_hw *dev,
-			    struct pda_pa_curve_data *curve_data)
+			    struct pda_pa_curve_data *curve_data, size_t len)
 {
 	struct p54_common *priv = dev->priv;
 	struct p54_pa_curve_data_sample *dst;
 	struct pda_pa_curve_data_sample_rev1 *src;
+	size_t needed = curve_data->channels *
+		(sizeof(*src) * curve_data->points_per_channel + 3);
 	size_t cd_len = sizeof(*curve_data) +
 		(curve_data->points_per_channel*sizeof(*dst) + 2) *
 		 curve_data->channels;
 	unsigned int i, j;
 	void *source, *target;
 
+	if (len < sizeof(*curve_data) + needed)
+		return -EINVAL;
+
 	priv->curve_data = kzalloc(cd_len + sizeof(*priv->curve_data),
 				   GFP_KERNEL);
 	if (!priv->curve_data)
@@ -767,6 +777,7 @@ int p54_parse_eeprom(struct ieee80211_hw
 		case PDR_PRISM_PA_CAL_CURVE_DATA: {
 			struct pda_pa_curve_data *curve_data =
 				(struct pda_pa_curve_data *)entry->data;
+
 			if (data_len < sizeof(*curve_data)) {
 				err = -EINVAL;
 				goto err;
@@ -774,10 +785,10 @@ int p54_parse_eeprom(struct ieee80211_hw
 
 			switch (curve_data->cal_method_rev) {
 			case 0:
-				err = p54_convert_rev0(dev, curve_data);
+				err = p54_convert_rev0(dev, curve_data, data_len);
 				break;
 			case 1:
-				err = p54_convert_rev1(dev, curve_data);
+				err = p54_convert_rev1(dev, curve_data, data_len);
 				break;
 			default:
 				wiphy_err(dev->wiphy,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 267/877] wifi: p54: require a full exp_if record in PDR_INTERFACE_LIST
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (265 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 266/877] wifi: p54: validate curve data length in the calibration curve converters Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 268/877] wifi: mwifiex: bound the pairwise-cipher OUI walk to the IE length Greg Kroah-Hartman
                   ` (617 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Christian Lamparter, Shengzhuo Wei,
	Johannes Berg

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

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

From: Shengzhuo Wei <me@cherr.cc>

commit d8efd84f49379ed28624098821f80e992657d935 upstream.

The PDR_INTERFACE_LIST loop only checks that the record start is within
the entry before reading an entire struct exp_if from it. A truncated
trailing record makes the if_id/variant reads cross the entry boundary
into the heap beyond the EEPROM buffer (verified with a KASAN
reproducer of the loop). The variant also feeds the synth front-end
selection, so this is not only a leak.

Advance only while a full record still fits in the entry.

Fixes: eff1a59c48e3 ("[P54]: add mac80211-based driver for prism54 softmac hardware")
Cc: stable@vger.kernel.org
Acked-by: Christian Lamparter <chunkeey@gmail.com>
Assisted-by: GLM:5.3
Signed-off-by: Shengzhuo Wei <me@cherr.cc>
Link: https://patch.msgid.link/20260831-p54-pda-validation-v2-2-dae566b388c8@cherr.cc
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/intersil/p54/eeprom.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/net/wireless/intersil/p54/eeprom.c
+++ b/drivers/net/wireless/intersil/p54/eeprom.c
@@ -816,7 +816,8 @@ int p54_parse_eeprom(struct ieee80211_hw
 			break;
 		case PDR_INTERFACE_LIST:
 			tmp = entry->data;
-			while ((u8 *)tmp < entry->data + data_len) {
+			while ((u8 *)tmp + sizeof(struct exp_if) <=
+			       entry->data + data_len) {
 				struct exp_if *exp_if = tmp;
 				if (exp_if->if_id == cpu_to_le16(IF_ID_ISL39000))
 					synth = le16_to_cpu(exp_if->variant);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 268/877] wifi: mwifiex: bound the pairwise-cipher OUI walk to the IE length
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (266 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 267/877] wifi: p54: require a full exp_if record in PDR_INTERFACE_LIST Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 269/877] wifi: mwifiex: validate scan response extents Greg Kroah-Hartman
                   ` (616 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Doruk Tan Ozturk, Johannes Berg

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

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

From: Doruk Tan Ozturk <doruk@0sec.ai>

commit e667aee1c192d67d27c803007bfa9c6e0873e959 upstream.

mwifiex_search_oui_in_ie() reads a pairwise-cipher (PTK) count from a
beacon/probe-response RSN or WPA information element and then walks that
many 4-byte OUIs, comparing each with memcmp(). The count comes straight
from the (attacker-supplied) IE and is never checked against the
element's own length, and the callers admit the element on element_id
alone (has_ieee_hdr() / has_vendor_hdr(), no length check). A crafted
RSN/WPA IE with a large pairwise count therefore makes the walk read up
to 255 * 4 bytes past the element -- an out-of-bounds read of the
kmemdup()'d beacon buffer, reachable from any AP whose beacon/probe
response is processed during scan-result parsing.

Pass the number of IE bytes available at the OUI list and bound the walk
to the element. Keep the length signed and reject a negative value
before any unsigned arithmetic, so a small or zero IE length cannot
underflow to a large size_t and defeat the bound.

Found by 0sec automated security-research tooling (https://0sec.ai).

Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:multi-model
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Link: https://patch.msgid.link/20260814134704.85902-1-doruk@0sec.ai
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/marvell/mwifiex/scan.c |   25 ++++++++++++++++++++++---
 1 file changed, 22 insertions(+), 3 deletions(-)

--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -104,12 +104,24 @@ has_vendor_hdr(struct ieee_types_vendor_
  * a given oui in PTK.
  */
 static u8
-mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui)
+mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui, int ie_len)
 {
+	const size_t ptk_body_offset = offsetof(struct ie_body, ptk_body);
 	u8 count;
 
+	/* ie_len is the number of bytes available at iebody. Keep it signed
+	 * and reject a negative (underflowed) length before the unsigned
+	 * comparisons below, so a small or zero IE length cannot wrap.
+	 */
+	if (ie_len < 0 || (size_t)ie_len < ptk_body_offset)
+		return MWIFIEX_OUI_NOT_PRESENT;
+
 	count = iebody->ptk_cnt[0];
 
+	/* Reject an OUI count whose list would run past the element. */
+	if (ptk_body_offset + count * sizeof(iebody->ptk_body) > (size_t)ie_len)
+		return MWIFIEX_OUI_NOT_PRESENT;
+
 	/* There could be multiple OUIs for PTK hence
 	   1) Take the length.
 	   2) Check all the OUIs for AES.
@@ -143,11 +155,14 @@ mwifiex_is_rsn_oui_present(struct mwifie
 	u8 ret = MWIFIEX_OUI_NOT_PRESENT;
 
 	if (has_ieee_hdr(bss_desc->bcn_rsn_ie, WLAN_EID_RSN)) {
+		int ie_len = (int)bss_desc->bcn_rsn_ie->ieee_hdr.len -
+			RSN_GTK_OUI_OFFSET;
+
 		iebody = (struct ie_body *)
 			 (((u8 *) bss_desc->bcn_rsn_ie->data) +
 			  RSN_GTK_OUI_OFFSET);
 		oui = &mwifiex_rsn_oui[cipher][0];
-		ret = mwifiex_search_oui_in_ie(iebody, oui);
+		ret = mwifiex_search_oui_in_ie(iebody, oui, ie_len);
 		if (ret)
 			return ret;
 	}
@@ -169,10 +184,14 @@ mwifiex_is_wpa_oui_present(struct mwifie
 	u8 ret = MWIFIEX_OUI_NOT_PRESENT;
 
 	if (has_vendor_hdr(bss_desc->bcn_wpa_ie, WLAN_EID_VENDOR_SPECIFIC)) {
+		int ie_len = (int)bss_desc->bcn_wpa_ie->vend_hdr.len -
+			(int)sizeof(bss_desc->bcn_wpa_ie->vend_hdr.oui) -
+			WPA_GTK_OUI_OFFSET;
+
 		iebody = (struct ie_body *)((u8 *)bss_desc->bcn_wpa_ie->data +
 					    WPA_GTK_OUI_OFFSET);
 		oui = &mwifiex_wpa_oui[cipher][0];
-		ret = mwifiex_search_oui_in_ie(iebody, oui);
+		ret = mwifiex_search_oui_in_ie(iebody, oui, ie_len);
 		if (ret)
 			return ret;
 	}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 269/877] wifi: mwifiex: validate scan response extents
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (267 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 268/877] wifi: mwifiex: bound the pairwise-cipher OUI walk to the IE length Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 270/877] wifi: mwifiex: prevent authentication frame length truncation Greg Kroah-Hartman
                   ` (615 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, Johannes Berg

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

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

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

commit 3687d7d48070838cc2953431b3a27717cab0aaf6 upstream.

mwifiex_ret_802_11_scan() subtracts the fixed response fields and the
firmware-provided BSS length from resp->size without first proving that
either extent fits. A short response or oversized BSS length can
therefore underflow tlv_buf_size and make the TLV parser walk beyond the
command response.

Compute the fixed extent from the selected normal or background scan
response. Validate that the fixed fields and BSS data fit before deriving
the TLV extent and entering the parser.

Fixes: 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260815135227.50392-1-pengpeng@iscas.ac.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/marvell/mwifiex/scan.c |   29 ++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

--- a/drivers/net/wireless/marvell/mwifiex/scan.c
+++ b/drivers/net/wireless/marvell/mwifiex/scan.c
@@ -2117,6 +2117,7 @@ int mwifiex_ret_802_11_scan(struct mwifi
 	u32 bytes_left;
 	u32 idx;
 	u32 tlv_buf_size;
+	size_t fixed_size;
 	struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv;
 	struct chan_band_param_set *chan_band;
 	u8 is_bgscan_resp;
@@ -2132,6 +2133,14 @@ int mwifiex_ret_802_11_scan(struct mwifi
 	else
 		scan_rsp = &resp->params.scan_resp;
 
+	scan_resp_size = le16_to_cpu(resp->size);
+	fixed_size = scan_rsp->bss_desc_and_tlv_buffer - (u8 *)resp;
+	if (scan_resp_size < fixed_size) {
+		mwifiex_dbg(adapter, ERROR,
+			    "SCAN_RESP: response is too short\n");
+		ret = -1;
+		goto check_next_scan;
+	}
 
 	if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) {
 		mwifiex_dbg(adapter, ERROR,
@@ -2149,8 +2158,6 @@ int mwifiex_ret_802_11_scan(struct mwifi
 		    "info: SCAN_RESP: bss_descript_size %d\n",
 		    bytes_left);
 
-	scan_resp_size = le16_to_cpu(resp->size);
-
 	mwifiex_dbg(adapter, INFO,
 		    "info: SCAN_RESP: returned %d APs before parsing\n",
 		    scan_rsp->number_of_sets);
@@ -2158,15 +2165,17 @@ int mwifiex_ret_802_11_scan(struct mwifi
 	bss_info = scan_rsp->bss_desc_and_tlv_buffer;
 
 	/*
-	 * The size of the TLV buffer is equal to the entire command response
-	 *   size (scan_resp_size) minus the fixed fields (sizeof()'s), the
-	 *   BSS Descriptions (bss_descript_size as bytesLef) and the command
-	 *   response header (S_DS_GEN)
+	 * The TLV buffer follows the command-specific fixed fields and the BSS
+	 * descriptions. Background-scan responses have an additional fixed
+	 * field before scan_rsp, which is included in fixed_size.
 	 */
-	tlv_buf_size = scan_resp_size - (bytes_left
-					 + sizeof(scan_rsp->bss_descript_size)
-					 + sizeof(scan_rsp->number_of_sets)
-					 + S_DS_GEN);
+	if (bytes_left > scan_resp_size - fixed_size) {
+		mwifiex_dbg(adapter, ERROR,
+			    "SCAN_RESP: BSS data exceeds response\n");
+		ret = -1;
+		goto check_next_scan;
+	}
+	tlv_buf_size = scan_resp_size - fixed_size - bytes_left;
 
 	tlv_data = (struct mwifiex_ie_types_data *) (scan_rsp->
 						 bss_desc_and_tlv_buffer +



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 270/877] wifi: mwifiex: prevent authentication frame length truncation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (268 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 269/877] wifi: mwifiex: validate scan response extents Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 271/877] wifi: mwifiex: validate action frame fixed fields Greg Kroah-Hartman
                   ` (614 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Linmao Li, Johannes Berg

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

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

From: Linmao Li <lilinmao@kylinos.cn>

commit fa00193eb991f92b007aefe7afb6a7566976dacf upstream.

mwifiex_cfg80211_authenticate() derives the authentication frame length
from req->ie_len and req->auth_data_len, both of type size_t, but stores
it in a u16.

NL80211_ATTR_AUTH_DATA only has a minimum length policy. Since nla_len is
a u16, a single attribute can carry up to 65531 bytes of payload, so the
sum can exceed U16_MAX before it is assigned to pkt_len. The truncated
pkt_len determines the skb frame area, while the copy length remains
req->auth_data_len - 4, resulting in a heap buffer overflow.

For example, with auth_data_len equal to 65510 and no IEs, the sum is
65546. It is truncated to 10 and then reduced by four to 6. The driver
appends only six bytes to the skb with skb_put(), but then copies 65506
user-provided bytes into the authentication body.

Reaching this path requires CAP_NET_ADMIN in the user namespace owning
the network namespace, an up station netdev, and a suitable BSS/SAE
authentication request.

Compute the length in size_t, reject values that cannot be represented by
the firmware's u16 frame length field, and only then assign it to pkt_len.

Fixes: 36995892c271 ("wifi: mwifiex: add host mlme for client mode")
Cc: stable@vger.kernel.org # 6.12+
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Link: https://patch.msgid.link/20260820062155.3981976-1-lilinmao@kylinos.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/marvell/mwifiex/cfg80211.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -4278,6 +4278,7 @@ mwifiex_cfg80211_authenticate(struct wip
 	struct mwifiex_adapter *adapter = priv->adapter;
 	struct sk_buff *skb;
 	u16 pkt_len, auth_alg;
+	size_t frame_len;
 	int ret;
 	struct mwifiex_ieee80211_mgmt *mgmt;
 	struct mwifiex_txinfo *tx_info;
@@ -4350,10 +4351,17 @@ mwifiex_cfg80211_authenticate(struct wip
 
 	mwifiex_cancel_scan(adapter);
 
-	pkt_len = (u16)req->ie_len + req->auth_data_len +
+	frame_len = req->ie_len + req->auth_data_len +
 		MWIFIEX_MGMT_HEADER_LEN + MWIFIEX_AUTH_BODY_LEN;
 	if (req->auth_data_len >= 4)
-		pkt_len -= 4;
+		frame_len -= 4;
+
+	if (frame_len > U16_MAX) {
+		mwifiex_dbg(priv->adapter, ERROR,
+			    "auth frame too long: %zu bytes\n", frame_len);
+		return -EINVAL;
+	}
+	pkt_len = frame_len;
 
 	skb = dev_alloc_skb(MWIFIEX_MIN_DATA_HEADER_LEN +
 			    MWIFIEX_MGMT_FRAME_HEADER_SIZE +



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 271/877] wifi: mwifiex: validate action frame fixed fields
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (269 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 270/877] wifi: mwifiex: prevent authentication frame length truncation Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 272/877] wifi: mac80211: avoid WARN in set_bitrate_mask when sdata not in driver Greg Kroah-Hartman
                   ` (613 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Johannes Berg, Brian Norris, Zhao Li,
	Johannes Berg

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

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

From: Zhao Li <enderaoelyther@gmail.com>

commit 1c25bfad93e69ce13f744a2fb919f02ea396a985 upstream.

mwifiex_process_mgmt_packet() accepts an rx_pkt_length as small as a
four-address struct ieee80211_hdr plus the two-byte firmware length prefix.
After stripping the prefix, mwifiex_parse_mgmt_packet() can receive a
frame equal to sizeof(struct ieee80211_hdr).

For action frames, the parser reads the category byte immediately after
that header and, for a public action frame, reads the following action
code byte without verifying that either field is present. A truncated frame
can therefore make the parser consume up to two bytes past the
firmware-declared frame length. If those bytes look like a TDLS discovery
response, the malformed frame can spuriously update peer signal state.

Require the category and public action-code fields before reading them.
Use sizeof(*ieee_hdr) so the checks and field accesses directly match the
firmware four-address layout being parsed before address4 is removed.

Suggested-by: Johannes Berg <johannes@sipsolutions.net>
Suggested-by: Brian Norris <briannorris@chromium.org>
Fixes: 72e5aa8d2a6d ("mwifiex: support for parsing TDLS discovery frames")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/all/66f148d83eb9f0970b9abbccc85d1b61244e54ad.camel@sipsolutions.net/
Link: https://lore.kernel.org/all/20260708195911.84365-8-enderaoelyther@gmail.com/
Link: https://lore.kernel.org/all/20260723011013.76968-1-enderaoelyther@gmail.com/
Link: https://lore.kernel.org/all/20260723202257.688-1-enderaoelyther@gmail.com/
Link: https://lore.kernel.org/all/anuWyiPQja6_5vly@google.com/
Assisted-by: Codex:gpt-5
Assisted-by: Kimi:K3
Signed-off-by: Zhao Li <enderaoelyther@gmail.com>
Link: https://patch.msgid.link/20260825112523.95774-1-enderaoelyther@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/marvell/mwifiex/util.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

--- a/drivers/net/wireless/marvell/mwifiex/util.c
+++ b/drivers/net/wireless/marvell/mwifiex/util.c
@@ -335,10 +335,16 @@ mwifiex_parse_mgmt_packet(struct mwifiex
 
 	switch (stype) {
 	case IEEE80211_STYPE_ACTION:
-		category = *(payload + sizeof(struct ieee80211_hdr));
+		if (len < sizeof(*ieee_hdr) + 1)
+			return -1;
+
+		category = *(payload + sizeof(*ieee_hdr));
 		switch (category) {
 		case WLAN_CATEGORY_PUBLIC:
-			action_code = *(payload + sizeof(struct ieee80211_hdr)
+			if (len < sizeof(*ieee_hdr) + 2)
+				return -1;
+
+			action_code = *(payload + sizeof(*ieee_hdr)
 					+ 1);
 			if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) {
 				addr2 = ieee_hdr->addr2;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 272/877] wifi: mac80211: avoid WARN in set_bitrate_mask when sdata not in driver
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (270 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 271/877] wifi: mwifiex: validate action frame fixed fields Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 273/877] drm/gud: fix out-of-bounds write in gud_plane_atomic_check() Greg Kroah-Hartman
                   ` (612 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+af177aa139efdd13a9da,
	Rik van Riel, syzbot+dcaca020ca8377e7ced0, Johannes Berg

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

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

From: Rik van Riel <riel@surriel.com>

commit da2ca406f45a6e21760243152ed8d2e8e72915c2 upstream.

ieee80211_set_bitrate_mask() checks if the interface is running via
ieee80211_sdata_running(), but it does not check if the interface is
still present in the driver.

When sdata is running but IEEE80211_SDATA_IN_DRIVER is not set, the
call reaches drv_set_bitrate_mask() in driver-ops.h which hits

  wlan1: Failed check-sdata-in-driver check, flags: 0x0
  WARNING: net/mac80211/driver-ops.h:884 at drv_set_bitrate_mask

Syzkaller triggers this via wext SIOCSIWRATE ioctl. The Call Trace shows
wext_ioctl_dispatch() in wext-core.c dispatching the ioctl, calling
ioctl_standard_call() for SIOCSIWRATE, which calls cfg80211_wext_siwrate()
in wext-compat.c. That builds a bitrate mask and calls
rdev_set_bitrate_mask() which ends up in ieee80211_set_bitrate_mask() in
cfg.c. The interface is marked running via SDATA_STATE_RUNNING but
flags is 0, so check_sdata_in_driver() fails.

When the interface is being torn down, or when wext ioctl is issued
during interface bringup before drv_add_interface() sets IN_DRIVER, the
running check passes while IN_DRIVER is clear.

Check IEEE80211_SDATA_IN_DRIVER in ieee80211_set_bitrate_mask() before
calling the driver, returning -ENETDOWN. This avoids the WARN_ONCE in
driver-ops.h and matches other cfg.c operations that bail early when not
in driver.

This change should be safe because wiphy mutex is held in
cfg80211_wext_siwrate() via guard(wiphy), and IN_DRIVER is set/cleared
under RTNL and wiphy paths in drv_add_interface() and
drv_remove_interface() in driver-ops.c, so the check is race-free
against driver add/remove. Returning -ENETDOWN is the same error other
not-running paths use and does not introduce new locking.

Reported-by: syzbot+af177aa139efdd13a9da@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=af177aa139efdd13a9da
Link: https://lore.kernel.org/all/6a75205c.59b6c763.2bba34.00c3.GAE@google.com/
Fixes: 554a43d5e77e ("mac80211: check sdata_running on ieee80211_set_bitrate_mask")
Cc: stable@vger.kernel.org
Assisted-by: Hermes:muse-spark-1.2 syzkaller
Signed-off-by: Rik van Riel <riel@surriel.com>
Link: https://patch.msgid.link/20260808104755.319c686e@fangorn
Reported-by: syzbot+dcaca020ca8377e7ced0@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=dcaca020ca8377e7ced0
[also add second syzbot report]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mac80211/cfg.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3426,6 +3426,9 @@ static int ieee80211_set_bitrate_mask(st
 	if (!ieee80211_sdata_running(sdata))
 		return -ENETDOWN;
 
+	if (!(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
+		return -ENETDOWN;
+
 	/*
 	 * If active validate the setting and reject it if it doesn't leave
 	 * at least one basic rate usable, since we really have to be able



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 273/877] drm/gud: fix out-of-bounds write in gud_plane_atomic_check()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (271 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 272/877] wifi: mac80211: avoid WARN in set_bitrate_mask when sdata not in driver Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 274/877] drm/msm/adreno: fix autosuspend cleanup during teardown Greg Kroah-Hartman
                   ` (611 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Sajal Gupta, Ruben Wauters

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

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

From: Sajal Gupta <sajal2005gupta@gmail.com>

commit 59ced288fcba9e91bd38e61a972ad782c4edb7d0 upstream.

The plane property loop uses req->properties[num_properties + i] as write
index while simultaneously incrementing `num_properties` inside the loop.
At iteration i, num_properties has also incremented by i, so the write
is done at `initial_num_properties + 2*i`, skipping every other index and
advancing by 2 per iteration.

With just 2 connector and 32 plane properties the last write happens at
index 64, one slot past the end of the 64-slot (indices 0–63)
allocation. A USB device can trigger OOB by advertising the maximum
number of properties.

Fix by dropping the redundant `+ i`; num_properties is already the correct
running index, as gud_connector_fill_properties() fills the preceding
slots.

Fixes: 40e1a70b4aed ("drm: Add GUD USB Display driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260821071812.16500-1-sajal2005gupta%40gmail.com?part=1
Signed-off-by: Sajal Gupta <sajal2005gupta@gmail.com>
Cc: <stable@vger.kernel.org>
Acked-by: Ruben Wauters <rubenru09@aol.com>
Signed-off-by: Ruben Wauters <rubenru09@aol.com>
Link: https://patch.msgid.link/20260902123254.36987-1-sajal2005gupta@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/gud/gud_pipe.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -544,8 +544,8 @@ int gud_pipe_check(struct drm_simple_dis
 			goto out;
 		}
 
-		req->properties[num_properties + i].prop = cpu_to_le16(prop);
-		req->properties[num_properties + i].val = cpu_to_le64(val);
+		req->properties[num_properties].prop = cpu_to_le16(prop);
+		req->properties[num_properties].val = cpu_to_le64(val);
 		num_properties++;
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 274/877] drm/msm/adreno: fix autosuspend cleanup during teardown
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (272 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 273/877] drm/gud: fix out-of-bounds write in gud_plane_atomic_check() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 275/877] drm/msm/hdmi_phy: fix runtime PM cleanup on probe failure Greg Kroah-Hartman
                   ` (610 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Dmitry Baryshkov

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

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

From: Guangshuo Li <lgs201920130244@gmail.com>

commit 6fbbf1e152f34ad3913e4a6476680aba672c5068 upstream.

adreno_gpu_init() calls pm_runtime_use_autosuspend(), but
adreno_gpu_cleanup() does not call the matching
pm_runtime_dont_use_autosuspend() during teardown.

If the autosuspend delay is set to a negative value while autosuspend
is enabled, the runtime PM core increments usage_count to prevent
runtime suspend. Without calling pm_runtime_dont_use_autosuspend()
during teardown, this reference is not dropped and usage_count remains
unbalanced.

The documentation for pm_runtime_use_autosuspend() also notes that it
is important to undo it with pm_runtime_dont_use_autosuspend() at
driver exit time, unless runtime PM was initially enabled with
devm_pm_runtime_enable().

Add the missing pm_runtime_dont_use_autosuspend() call to
adreno_gpu_cleanup().

This issue was found by manual code inspection.

Fixes: eeb754746b14 ("drm/msm/gpu: use pm-runtime")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/745110/
Link: https://lore.kernel.org/r/20260808131624.2854412-1-lgs201920130244@gmail.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/msm/adreno/adreno_gpu.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -1141,6 +1141,8 @@ void adreno_gpu_cleanup(struct adreno_gp
 	for (i = 0; i < ARRAY_SIZE(adreno_gpu->info->fw); i++)
 		release_firmware(adreno_gpu->fw[i]);
 
+	pm_runtime_dont_use_autosuspend(&gpu->pdev->dev);
+
 	if (priv && pm_runtime_enabled(&priv->gpu_pdev->dev))
 		pm_runtime_disable(&priv->gpu_pdev->dev);
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 275/877] drm/msm/hdmi_phy: fix runtime PM cleanup on probe failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (273 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 274/877] drm/msm/adreno: fix autosuspend cleanup during teardown Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 276/877] smb: client: cancel reconnect work in clean_demultiplex_info() Greg Kroah-Hartman
                   ` (609 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Krzysztof Kozlowski,
	Dmitry Baryshkov

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

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

From: Guangshuo Li <lgs201920130244@gmail.com>

commit f4fae975db08a9aeec0b15e145c7d4d0fe02a0ec upstream.

msm_hdmi_phy_probe() enables runtime PM before enabling the PHY
resources and initializing the PLL, but failures from either operation
return without calling the matching pm_runtime_disable().

The remove path disables runtime PM, but it is not called when probe
fails. As a result, runtime PM remains enabled after an unsuccessful
probe.

Route failures after pm_runtime_enable() through a common error path
and disable runtime PM before returning.

This issue was found by manual code inspection.

Fixes: 15b4a4523859 ("drm/msm/hdmi: Create a separate HDMI PHY driver")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Patchwork: https://patchwork.freedesktop.org/patch/753043/
Link: https://lore.kernel.org/r/20260913085814.1509352-1-lgs201920130244@gmail.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/msm/hdmi/hdmi_phy.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

--- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
@@ -164,13 +164,13 @@ static int msm_hdmi_phy_probe(struct pla
 
 	ret = msm_hdmi_phy_resource_enable(phy);
 	if (ret)
-		return ret;
+		goto err_pm_disable;
 
 	ret = msm_hdmi_phy_pll_init(pdev, phy->cfg->type);
 	if (ret) {
 		DRM_DEV_ERROR(dev, "couldn't init PLL\n");
 		msm_hdmi_phy_resource_disable(phy);
-		return ret;
+		goto err_pm_disable;
 	}
 
 	msm_hdmi_phy_resource_disable(phy);
@@ -178,6 +178,10 @@ static int msm_hdmi_phy_probe(struct pla
 	platform_set_drvdata(pdev, phy);
 
 	return 0;
+
+err_pm_disable:
+	pm_runtime_disable(dev);
+	return ret;
 }
 
 static void msm_hdmi_phy_remove(struct platform_device *pdev)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 276/877] smb: client: cancel reconnect work in clean_demultiplex_info()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (274 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 275/877] drm/msm/hdmi_phy: fix runtime PM cleanup on probe failure Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 277/877] smb: client: fix rlist race and missing initialization Greg Kroah-Hartman
                   ` (608 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+5003556314abc915a71f,
	Namjae Jeon, Paulo Alcantara, David Howells, Shyam Prasad N,
	Ronnie Sahlberg, Tom Talpey, Bharath SM

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

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

From: Paulo Alcantara <pc@manguebit.org>

commit c65eae6f61d1778ff7a82e4aae4080e26f486af1 upstream.

clean_demultiplex_info() cancels server->echo delayed work but not
server->reconnect, which can cause a use-after-free when the
demultiplex thread exits while a reconnect work is still queued:

  cifs_demultiplex_thread()
    cifs_readv_from_socket()
      cifs_reconnect()
        __cifs_reconnect()
          cifs_queue_server_reconn()
            mod_delayed_work(cifsiod_wq, &server->reconnect, 0)
    clean_demultiplex_info()
      cancel_delayed_work_sync(&server->echo)   // echo canceled
                                                 // reconnect NOT canceled
      kfree_sensitive(server)                    // server freed

  ...later, on cifsiod_wq:

  smb2_reconnect_server()
    server->srv_count  // UAF read of freed server

Fix this by canceling server->reconnect delayed work in
clean_demultiplex_info() before the server is freed, the same way
cifs_put_tcp_session() already does.

Reported-by: syzbot+5003556314abc915a71f@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/r/6aa4a12d.f81106d8.2ab401.0023.GAE@google.com
Fixes: 53e0e11efe92 ("CIFS: Fix a possible memory corruption during reconnect")
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/connect.c |    1 +
 1 file changed, 1 insertion(+)

--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -982,6 +982,7 @@ clean_demultiplex_info(struct TCP_Server
 	spin_unlock(&server->srv_lock);
 
 	cancel_delayed_work_sync(&server->echo);
+	cancel_delayed_work_sync(&server->reconnect);
 
 	spin_lock(&server->srv_lock);
 	server->tcpStatus = CifsExiting;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 277/877] smb: client: fix rlist race and missing initialization
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (275 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 276/877] smb: client: cancel reconnect work in clean_demultiplex_info() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 278/877] smb: client: reject short Next offsets in parse_server_interfaces() Greg Kroah-Hartman
                   ` (607 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
	David Howells, Shyam Prasad N, Ronnie Sahlberg, Tom Talpey,
	Bharath SM

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

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

From: Paulo Alcantara <pc@manguebit.org>

commit 5f270f091256da1338c3631083e15d7f83cc05e1 upstream.

TCP_Server_Info.rlist is allocated via kzalloc which zeros both ->next
and ->prev to NULL instead of pointing to itself, making list_empty()
always return false and list_add() dereference a NULL ->prev pointer.

Also, cifs_signal_cifsd_for_reconnect() can be called concurrently
from multiple cifsd threads, allowing the same server's rlist node to
be added twice into the local list, corrupting it.

Closes: https://sashiko.dev/#/patchset/20260911204446.1719356-1-pc%40manguebit.org
Fixes: df0e03a4fb94 ("smb: client: fix potential deadlock when reconnecting channels")
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/connect.c |    7 +++++++
 1 file changed, 7 insertions(+)

--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -187,6 +187,8 @@ cifs_signal_cifsd_for_reconnect(struct T
 				nserver = ses->chans[i].server;
 				if (!nserver)
 					continue;
+				if (!list_empty(&nserver->rlist))
+					continue;
 				nserver->srv_count++;
 				list_add(&nserver->rlist, &reco);
 			}
@@ -195,11 +197,15 @@ cifs_signal_cifsd_for_reconnect(struct T
 		}
 	}
 
+	spin_lock(&cifs_tcp_ses_lock);
 	list_for_each_entry_safe(server, nserver, &reco, rlist) {
 		list_del_init(&server->rlist);
 		set_need_reco(server);
+		spin_unlock(&cifs_tcp_ses_lock);
 		cifs_put_tcp_session(server, 0);
+		spin_lock(&cifs_tcp_ses_lock);
 	}
+	spin_unlock(&cifs_tcp_ses_lock);
 }
 
 /*
@@ -1768,6 +1774,7 @@ cifs_get_tcp_session(struct smb3_fs_cont
 	spin_lock_init(&tcp_ses->mid_lock);
 	INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
 	INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
+	INIT_LIST_HEAD(&tcp_ses->rlist);
 	INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
 	INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server);
 	mutex_init(&tcp_ses->reconnect_mutex);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 278/877] smb: client: reject short Next offsets in parse_server_interfaces()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (276 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 277/877] smb: client: fix rlist race and missing initialization Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 279/877] smb: client: fix smbd_connection leak on cifs_get_tcp_session() error Greg Kroah-Hartman
                   ` (606 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
	Paulo Alcantara

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

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

From: Frank Sorenson <sorenson@redhat.com>

commit 1b3221bb121079ad79a1f3c3aa360ba649832e7a upstream.

In parse_server_interfaces(), the server-supplied Next offset is
validated against bytes_left, but not against the size of the interface
structure itself.

A small, non-zero Next value can pass the bounds check but advance the
pointer by less than sizeof(*p). This causes the next iteration of the
loop to read misaligned, overlapping structure fields.

Fix this by ensuring the Next offset is at least sizeof(*p).

Fixes: 7d34ec36abb8 ("smb3: fix for slab out of bounds on mount to ksmbd")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/smb2ops.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -786,9 +786,9 @@ next_iface:
 			break;
 		}
 		/* Validate that Next doesn't point beyond the buffer */
-		if (next > bytes_left) {
-			cifs_dbg(VFS, "%s: invalid Next pointer %zu > %zd\n",
-				 __func__, next, bytes_left);
+		if (next < sizeof(*p) || next > bytes_left) {
+			cifs_dbg(VFS, "%s: invalid Next pointer %zu out of range [%zu, %zd]\n",
+				 __func__, next, sizeof(*p), bytes_left);
 			rc = -EINVAL;
 			goto out;
 		}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 279/877] smb: client: fix smbd_connection leak on cifs_get_tcp_session() error
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (277 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 278/877] smb: client: reject short Next offsets in parse_server_interfaces() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 280/877] smb: client: fix unaligned access in WSL reparse point parser Greg Kroah-Hartman
                   ` (605 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
	Tom Talpey, Stefan Metzmacher, Shyam Prasad N, Ronnie Sahlberg,
	Bharath SM

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

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

From: Paulo Alcantara <pc@manguebit.org>

commit e75c96157d45e498970158c8f7373d90102e33b9 upstream.

When an RDMA connection is successfully established via
smbd_get_connection() but cifs_get_tcp_session() later fails (e.g.
kthread_create() returns an error), the error path frees tcp_ses
without first destroying the smbd_connection.

Fix this by calling smbd_destroy() in the out_err cleanup path before
kfree(tcp_ses).  smbd_destroy() safely handles the case where
smbd_conn is NULL, so it can be called unconditionally.

Closes: https://sashiko.dev/#/patchset/20260912165503.521597-1-pc%40manguebit.org
Fixes: 2f8946464b11 ("CIFS: SMBD: Upper layer connects to SMBDirect session")
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Tom Talpey <tom@talpey.com>
Cc: Stefan Metzmacher <metze@samba.org>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/connect.c |    1 +
 1 file changed, 1 insertion(+)

--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -1885,6 +1885,7 @@ out_err:
 		kfree(tcp_ses->leaf_fullpath);
 		if (tcp_ses->ssocket)
 			sock_release(tcp_ses->ssocket);
+		smbd_destroy(tcp_ses);
 		kfree(tcp_ses);
 	}
 	return ERR_PTR(rc);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 280/877] smb: client: fix unaligned access in WSL reparse point parser
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (278 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 279/877] smb: client: fix smbd_connection leak on cifs_get_tcp_session() error Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 281/877] smb: client: fix next_buffer UAF and NextCommand bounds in compound PDUs Greg Kroah-Hartman
                   ` (604 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
	David Howells, Tom Talpey, Shyam Prasad N, Ronnie Sahlberg,
	Bharath SM

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

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

From: Paulo Alcantara <pc@manguebit.org>

commit e1aeaf79dea51e6065da56924bc07e22d59012ac upstream.

When wsl_to_fattr() parses WSL extended attributes, it computes a
payload pointer from ea->ea_data + ea_name_length + 1.  Since the
smb2_file_full_ea_info struct is __packed and all WSL xattr names are
6 bytes long, the value pointer always lands at an odd byte offset,
never satisfying __le32 or __le64 alignment requirements.

The code then casts this pointer to __le32 * or __le64 * and
dereferences it directly, which may cause alignment faults on some
architectures.

Replace all such casts with get_unaligned_le32() and
get_unaligned_le64() in reparse_mkdev(), wsl_make_kuid(),
wsl_make_kgid() and wsl_to_fattr().

Closes: https://sashiko.dev/#/patchset/20260906200517.725015-1-pc%40manguebit.org
Fixes: 78e26bec4d6d ("smb: client: parse uid, gid, mode and dev from WSL reparse points")
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/reparse.c |    4 ++--
 fs/smb/client/reparse.h |    7 ++++---
 2 files changed, 6 insertions(+), 5 deletions(-)

--- a/fs/smb/client/reparse.c
+++ b/fs/smb/client/reparse.c
@@ -726,9 +726,9 @@ static bool wsl_to_fattr(struct cifs_ope
 			fattr->cf_gid = wsl_make_kgid(cifs_sb, v);
 		else if (!strncmp(name, SMB2_WSL_XATTR_MODE, nlen)) {
 			/* File type in reparse point tag and in xattr mode must match. */
-			if (S_DT(fattr->cf_mode) != S_DT(le32_to_cpu(*(__le32 *)v)))
+			if (S_DT(fattr->cf_mode) != S_DT(get_unaligned_le32(v)))
 				return false;
-			fattr->cf_mode = (umode_t)le32_to_cpu(*(__le32 *)v);
+			fattr->cf_mode = (umode_t)get_unaligned_le32(v);
 		} else if (!strncmp(name, SMB2_WSL_XATTR_DEV, nlen)) {
 			fattr->cf_rdev = reparse_mkdev(v);
 			have_xattr_dev = true;
--- a/fs/smb/client/reparse.h
+++ b/fs/smb/client/reparse.h
@@ -9,6 +9,7 @@
 #include <linux/fs.h>
 #include <linux/stat.h>
 #include <linux/uidgid.h>
+#include <linux/unaligned.h>
 #include "fs_context.h"
 #include "cifsglob.h"
 
@@ -22,7 +23,7 @@
 
 static inline dev_t reparse_mkdev(void *ptr)
 {
-	u64 v = le64_to_cpu(*(__le64 *)ptr);
+	u64 v = get_unaligned_le64(ptr);
 
 	return MKDEV(v & 0xffffffff, v >> 32);
 }
@@ -30,7 +31,7 @@ static inline dev_t reparse_mkdev(void *
 static inline kuid_t wsl_make_kuid(struct cifs_sb_info *cifs_sb,
 				   void *ptr)
 {
-	u32 uid = le32_to_cpu(*(__le32 *)ptr);
+	u32 uid = get_unaligned_le32(ptr);
 
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
 		return cifs_sb->ctx->linux_uid;
@@ -40,7 +41,7 @@ static inline kuid_t wsl_make_kuid(struc
 static inline kgid_t wsl_make_kgid(struct cifs_sb_info *cifs_sb,
 				   void *ptr)
 {
-	u32 gid = le32_to_cpu(*(__le32 *)ptr);
+	u32 gid = get_unaligned_le32(ptr);
 
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
 		return cifs_sb->ctx->linux_gid;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 281/877] smb: client: fix next_buffer UAF and NextCommand bounds in compound PDUs
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (279 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 280/877] smb: client: fix unaligned access in WSL reparse point parser Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 282/877] smb: client: fix potential OOB read in smb3_enum_snapshots() Greg Kroah-Hartman
                   ` (603 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
	Paulo Alcantara

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

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

From: Frank Sorenson <sorenson@redhat.com>

commit 05762c5bc1cfdcac36747994fde2c04387a457f1 upstream.

Fix several related bounds checking and pointer lifecycle issues in
receive_encrypted_standard()'s handling of compound encrypted frames:

- Clear next_buffer after assigning it to server->bigbuf. A stale
  next_buffer pointer can lead to a use-after-free on subsequent
  error paths.
- Update pdu_length to the decrypted plaintext size (buf_size). Using
  the pre-decryption length allows NextCommand to point into stale
  ciphertext residue.
- Reject next_cmd values smaller than MID_HEADER_SIZE(server).
- Fix an integer overflow in the upper bound check by verifying
  pdu_length - next_cmd < MID_HEADER_SIZE(server), ensuring the
  trailing slice is large enough for a header.

Fixes: b24df3e30cbf ("cifs: update receive_encrypted_standard to handle compounded responses")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/smb2ops.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -5237,6 +5237,7 @@ receive_encrypted_standard(struct TCP_Se
 	length = decrypt_raw_data(server, buf, buf_size, NULL, false);
 	if (length)
 		return length;
+	pdu_length = buf_size;
 
 	next_is_large = server->large_buf;
 one_more:
@@ -5249,8 +5250,15 @@ one_more:
 	}
 
 	if (next_cmd) {
-		if (WARN_ON_ONCE(next_cmd > pdu_length))
+		if (next_cmd < MID_HEADER_SIZE(server) ||
+		    next_cmd > pdu_length ||
+		    pdu_length - next_cmd < MID_HEADER_SIZE(server)) {
+			unsigned int max_next = pdu_length > (unsigned int)MID_HEADER_SIZE(server) ?
+					pdu_length - (unsigned int)MID_HEADER_SIZE(server) : 0;
+			cifs_server_dbg(VFS, "invalid NextCommand offset %u out of range [%zu, %u]\n",
+					next_cmd, MID_HEADER_SIZE(server), max_next);
 			return -1;
+		}
 		if (next_is_large)
 			next_buffer = (char *)cifs_buf_get();
 		else
@@ -5286,6 +5294,7 @@ one_more:
 			server->bigbuf = buf = next_buffer;
 		else
 			server->smallbuf = buf = next_buffer;
+		next_buffer = NULL;
 		goto one_more;
 	} else if (ret != 0) {
 		/*



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 282/877] smb: client: fix potential OOB read in smb3_enum_snapshots()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (280 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 281/877] smb: client: fix next_buffer UAF and NextCommand bounds in compound PDUs Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 283/877] smb: client: fix server->total_read for compound encrypted PDUs Greg Kroah-Hartman
                   ` (602 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
	Paulo Alcantara

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

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

From: Frank Sorenson <sorenson@redhat.com>

commit 4775c3b7a597907e0b97556c7986fda238a377ae upstream.

If snapshot_array_size is smaller than GMT_TOKEN_SIZE,
smb3_enum_snapshots() sets ret_data_len to
sizeof(struct smb_snapshot_array) without verifying the actual length
of the server's reply.

Because SMB2_ioctl() places no lower bound on the server-supplied
OutputCount and allocates retbuf to exactly that length, a short reply
results in ret_data_len exceeding the size of retbuf. The subsequent
copy_to_user() then reads past the end of retbuf, leaking adjacent slab
memory to userspace.  The subsequent clamp check is ineffective as it
only reduces ret_data_len.

Fix this by rejecting replies shorter than
sizeof(struct smb_snapshot_array) with -EIO. Note that the bound is set
to the 12-byte struct size rather than the 16-byte
MIN_SNAPSHOT_ARRAY_SIZE defined in MS-SMB2 3.3.5.15.1, because 12 bytes
is exactly what copy_to_user() attempts to read.

Fixes: e02789a53d71 ("smb3: enumerating snapshots was leaving part of the data off end")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/smb2ops.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -2422,8 +2422,14 @@ smb3_enum_snapshots(const unsigned int x
 		 * and retry the ioctl again with larger array size sufficient
 		 * to hold all of the snapshot GMT tokens on the second try.
 		 */
-		if (snapshot_in.snapshot_array_size < GMT_TOKEN_SIZE)
+		if (snapshot_in.snapshot_array_size < GMT_TOKEN_SIZE) {
+			if (ret_data_len < sizeof(struct smb_snapshot_array)) {
+				rc = -EIO;
+				kfree(retbuf);
+				return rc;
+			}
 			ret_data_len = sizeof(struct smb_snapshot_array);
+		}
 
 		/*
 		 * We return struct SRV_SNAPSHOT_ARRAY, followed by



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 283/877] smb: client: fix server->total_read for compound encrypted PDUs
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (281 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 282/877] smb: client: fix potential OOB read in smb3_enum_snapshots() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 284/877] smb: client: fix missing lower-bound check on DFS referral string offsets Greg Kroah-Hartman
                   ` (601 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
	Paulo Alcantara

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

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

From: Frank Sorenson <sorenson@redhat.com>

commit f73726b83e4756fdaa099e1bc1143293bd57ad79 upstream.

In receive_encrypted_standard(), server->total_read is left at the
full decrypted frame size when walking sub-PDUs of a compound encrypted
frame. As a result, cifs_handle_standard() passes this full size
to smb2_check_message(), causing the PDU length guards to incorrectly
validate the entire compound frame instead of the current sub-PDU.

This allows truncated non-last sub-PDUs to bypass length validation,
leading to out-of-bounds reads in smb2_get_data_area_len().

Fix this by setting server->total_read to the true length of the
current sub-PDU: next_cmd for non-last sub-PDUs, and the remaining
pdu_length for the last one.

Fixes: b24df3e30cbf ("cifs: update receive_encrypted_standard to handle compounded responses")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/smb2ops.c |    1 +
 1 file changed, 1 insertion(+)

--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -5249,6 +5249,7 @@ receive_encrypted_standard(struct TCP_Se
 one_more:
 	shdr = (struct smb2_hdr *)buf;
 	next_cmd = le32_to_cpu(shdr->NextCommand);
+	server->total_read = next_cmd ? next_cmd : pdu_length;
 
 	if (*num_mids >= MAX_COMPOUND) {
 		cifs_server_dbg(VFS, "too many PDUs in compound\n");



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 284/877] smb: client: fix missing lower-bound check on DFS referral string offsets
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (282 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 283/877] smb: client: fix server->total_read for compound encrypted PDUs Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 285/877] smb: client: fix missing iov bounds check in parse_posix_sids() Greg Kroah-Hartman
                   ` (600 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
	Paulo Alcantara

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

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

From: Frank Sorenson <sorenson@redhat.com>

commit e83330c55edc0c3ac08aa6c95e49e4694c65523b upstream.

parse_dfs_referrals() checks that DfsPathOffset and NetworkAddressOffset
do not exceed the buffer end, but fails to check that they don't point
inside the referral header itself.

If a server provides an offset smaller than
sizeof(struct dfs_referral_level_3), the derived string pointer overlaps
with the struct fields, causing cifs_strndup_from_utf16() to interpret
header data as UTF-16 strings.

Fix this by enforcing that string offsets are at least sizeof(*ref).

Fixes: 4ecce920e13a ("CIFS: move DFS response parsing out of SMB1 code")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/misc.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

--- a/fs/smb/client/misc.c
+++ b/fs/smb/client/misc.c
@@ -1046,7 +1046,11 @@ parse_dfs_referrals(struct get_dfs_refer
 		node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
 
 		/* copy DfsPath */
-		if (le16_to_cpu(ref->DfsPathOffset) > data_end - (char *)ref) {
+		if (le16_to_cpu(ref->DfsPathOffset) < sizeof(*ref) ||
+		    le16_to_cpu(ref->DfsPathOffset) > data_end - (char *)ref) {
+			cifs_dbg(VFS, "%s: DfsPathOffset %u out of range [%zu, %td]\n",
+				 __func__, le16_to_cpu(ref->DfsPathOffset),
+				 sizeof(*ref), data_end - (char *)ref);
 			rc = -EINVAL;
 			goto parse_DFS_referrals_exit;
 		}
@@ -1060,7 +1064,11 @@ parse_dfs_referrals(struct get_dfs_refer
 		}
 
 		/* copy link target UNC */
-		if (le16_to_cpu(ref->NetworkAddressOffset) > data_end - (char *)ref) {
+		if (le16_to_cpu(ref->NetworkAddressOffset) < sizeof(*ref) ||
+		    le16_to_cpu(ref->NetworkAddressOffset) > data_end - (char *)ref) {
+			cifs_dbg(VFS, "%s: NetworkAddressOffset %u out of range [%zu, %td]\n",
+				 __func__, le16_to_cpu(ref->NetworkAddressOffset),
+				 sizeof(*ref), data_end - (char *)ref);
 			rc = -EINVAL;
 			goto parse_DFS_referrals_exit;
 		}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 285/877] smb: client: fix missing iov bounds check in parse_posix_sids()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (283 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 284/877] smb: client: fix missing lower-bound check on DFS referral string offsets Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 286/877] HID: asus: fortify keyboard handshake Greg Kroah-Hartman
                   ` (599 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
	Paulo Alcantara

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

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

From: Frank Sorenson <sorenson@redhat.com>

commit b09d092eb24ad0110f16a9b7c1ed5d2a0c1733dc upstream.

In parse_posix_sids(), sidsbuf_end is calculated using the server-supplied
out_len without being validated against the actual length of the received
iov (iov_len).

If a server provides an inflated out_len, sidsbuf_end will point past the
end of the iov. This defeats the bounds guards in posix_info_sid_size(),
allowing out-of-bounds reads into adjacent kernel memory.

Fix this by rejecting responses where the calculated sidsbuf_end would
exceed the received iov boundaries or cause pointer wraparound.

Fixes: a90f37e3d7ac ("smb: client: parse owner/group when creating reparse points")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/smb2inode.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

--- a/fs/smb/client/smb2inode.c
+++ b/fs/smb/client/smb2inode.c
@@ -71,6 +71,17 @@ static int parse_posix_sids(struct cifs_
 
 	sidsbuf = (u8 *)qi + le16_to_cpu(qi->OutputBufferOffset) + qi_len;
 	sidsbuf_end = sidsbuf + out_len - qi_len;
+	if (sidsbuf_end < sidsbuf) {
+		cifs_dbg(VFS, "%s: server-supplied out_len %u caused pointer wraparound\n",
+			 __func__, out_len);
+		return -EINVAL;
+	}
+	if (sidsbuf_end > (u8 *)rsp_iov->iov_base + rsp_iov->iov_len) {
+		cifs_dbg(VFS, "%s: server-supplied out_len %u overruns iov by %td bytes\n",
+			 __func__, out_len,
+			 sidsbuf_end - ((u8 *)rsp_iov->iov_base + rsp_iov->iov_len));
+		return -EINVAL;
+	}
 
 	owner_len = posix_info_sid_size(sidsbuf, sidsbuf_end);
 	if (owner_len == -1)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 286/877] HID: asus: fortify keyboard handshake
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (284 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 285/877] smb: client: fix missing iov bounds check in parse_posix_sids() Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 287/877] ksmbd: fix partial normalized name responses Greg Kroah-Hartman
                   ` (598 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Benjamin Tissoires, Denis Benato,
	Antheas Kapenekakis, Ilpo Järvinen, Sasha Levin

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

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

From: Antheas Kapenekakis <lkml@antheas.dev>

[ Upstream commit e82ae34af29e910c96d33c8b3a90c60e27f1625e ]

Handshaking with an Asus device involves sending it a feature report
with the string "ASUS Tech.Inc." and then reading it back to verify the
handshake was successful, under the feature ID the interaction will
take place.

Currently, the driver only does the first part. Add the readback to
verify the handshake was successful. As this could cause breakages,
allow the verification to fail with a dmesg error until we verify
all devices work with it (they seem to).

Since the response is more than 16 bytes, increase the buffer size
to 64 as well to avoid overflow errors. In addition, add the report
ID to prints, to help identify failed handshakes.

Reviewed-by: Benjamin Tissoires <bentiss@kernel.org>
Reviewed-by: Denis Benato <benato.denis96@gmail.com>
Acked-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
Link: https://patch.msgid.link/20260122075044.5070-5-lkml@antheas.dev
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/hid/hid-asus.c | 34 ++++++++++++++++++++++++++++++----
 1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index 28426337a2f11..1708396a04502 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -48,7 +48,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
 #define FEATURE_REPORT_ID 0x0d
 #define INPUT_REPORT_ID 0x5d
 #define FEATURE_KBD_REPORT_ID 0x5a
-#define FEATURE_KBD_REPORT_SIZE 16
+#define FEATURE_KBD_REPORT_SIZE 64
 #define FEATURE_KBD_LED_REPORT_ID1 0x5d
 #define FEATURE_KBD_LED_REPORT_ID2 0x5e
 
@@ -393,15 +393,41 @@ static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t bu
 
 static int asus_kbd_init(struct hid_device *hdev, u8 report_id)
 {
+	/*
+	 * The handshake is first sent as a set_report, then retrieved
+	 * from a get_report. They should be equal.
+	 */
 	const u8 buf[] = { report_id, 0x41, 0x53, 0x55, 0x53, 0x20, 0x54,
 		     0x65, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x63, 0x2e, 0x00 };
 	int ret;
 
 	ret = asus_kbd_set_report(hdev, buf, sizeof(buf));
-	if (ret < 0)
-		hid_err(hdev, "Asus failed to send init command: %d\n", ret);
+	if (ret < 0) {
+		hid_err(hdev, "Asus handshake %02x failed to send: %d\n",
+			report_id, ret);
+		return ret;
+	}
 
-	return ret;
+	u8 *readbuf __free(kfree) = kzalloc(FEATURE_KBD_REPORT_SIZE, GFP_KERNEL);
+	if (!readbuf)
+		return -ENOMEM;
+
+	ret = hid_hw_raw_request(hdev, report_id, readbuf,
+				 FEATURE_KBD_REPORT_SIZE, HID_FEATURE_REPORT,
+				 HID_REQ_GET_REPORT);
+	if (ret < 0) {
+		hid_warn(hdev, "Asus handshake %02x failed to receive ack: %d\n",
+			 report_id, ret);
+	} else if (memcmp(readbuf, buf, sizeof(buf)) != 0) {
+		hid_warn(hdev, "Asus handshake %02x returned invalid response: %*ph\n",
+			 report_id, FEATURE_KBD_REPORT_SIZE, readbuf);
+	}
+
+	/*
+	 * Do not return error if handshake is wrong until this is
+	 * verified to work for all devices.
+	 */
+	return 0;
 }
 
 static int asus_kbd_get_functions(struct hid_device *hdev,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 287/877] ksmbd: fix partial normalized name responses
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (285 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 286/877] HID: asus: fortify keyboard handshake Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:19 ` [PATCH 6.12 288/877] spi: spi-zynqmp-gqspi: stop the controller on shutdown Greg Kroah-Hartman
                   ` (597 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mobin Aydinfar, ChenXiaoSong,
	Namjae Jeon

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

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

From: Namjae Jeon <linkinjeon@kernel.org>

commit f4fafaf02174c32bce2f9bb4196fadf13f1fd96e upstream.

Windows may request FILE_NORMALIZED_NAME_INFORMATION with an output
buffer that only fits the fixed portion of the variable-length response.
Treat the fixed portion as FILE_NORMALIZED_NAME_INFORMATION_SIZE so ksmbd
returns STATUS_BUFFER_OVERFLOW instead of STATUS_INFO_LENGTH_MISMATCH.

This avoids rejecting valid partial normalized-name responses.

Fixes: 6b8b79226bc3 ("ksmbd: fix partial file information responses")
Reported-by: Mobin Aydinfar <mobin@mobintestserver.ir>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/server/smb2pdu.c |    3 +++
 fs/smb/server/smb2pdu.h |    1 +
 2 files changed, 4 insertions(+)

--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -5530,6 +5530,9 @@ static int smb2_get_info_file(struct ksm
 		case FILE_ALTERNATE_NAME_INFORMATION:
 			fixed_len = FILE_ALTERNATE_NAME_INFORMATION_SIZE;
 			break;
+		case FILE_NORMALIZED_NAME_INFORMATION:
+			fixed_len = FILE_NORMALIZED_NAME_INFORMATION_SIZE;
+			break;
 		case FILE_STREAM_INFORMATION:
 			fixed_len = FILE_STREAM_INFORMATION_SIZE;
 			break;
--- a/fs/smb/server/smb2pdu.h
+++ b/fs/smb/server/smb2pdu.h
@@ -219,6 +219,7 @@ struct file_sparse {
 #define FILE_ALLOCATION_INFORMATION_SIZE      19
 #define FILE_END_OF_FILE_INFORMATION_SIZE     20
 #define FILE_ALTERNATE_NAME_INFORMATION_SIZE  8
+#define FILE_NORMALIZED_NAME_INFORMATION_SIZE 8
 #define FILE_STREAM_INFORMATION_SIZE          32
 #define FILE_PIPE_INFORMATION_SIZE            23
 #define FILE_PIPE_LOCAL_INFORMATION_SIZE      24



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 288/877] spi: spi-zynqmp-gqspi: stop the controller on shutdown
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (286 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 287/877] ksmbd: fix partial normalized name responses Greg Kroah-Hartman
@ 2026-09-30 15:19 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 289/877] smb: client: fix busy dentry warning on unmount after DIO Greg Kroah-Hartman
                   ` (596 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:19 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Itai Handler, Mark Brown,
	Sasha Levin

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

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

From: Itai Handler <itai.handler@gmail.com>

commit e922bad8b2d5028c51a096d083fea41cd0987154 upstream.

The driver has no ->shutdown, and platform_drv_shutdown() has no
fallback of its own.  Unlike pci_device_shutdown(), which clears bus
mastering when kexec_in_progress, nothing on the platform bus disarms a
device that can still write to memory.  The normal kexec path never
calls ->suspend either, so the quiesce in zynqmp_qspi_suspend() is not
reached.

A controller that is still executing a DMA read may therefore keep
writing to memory across a kexec.  QSPIDMA_DST_ADDR still points at
memory owned by the kernel that called kexec, DST_SIZE is non-zero and
the flash is still clocked, so data can keep landing in RAM while the
new kernel is being relocated, and after it has started executing.

That destination is a physical address which means nothing to the new
kernel, so the writes can corrupt whatever now occupies it: kernel text
or data, page tables, or the initrd.  Nothing reports an error and the
resulting behaviour is undefined.

This can be observed by reading GQSPI_EN (offset 0x114) and
QSPIDMA_DST_ADDR/SIZE/STS/CTRL (offsets 0x800 to 0x80c) early in the new
kernel, before the driver probes: without this patch GQSPI_EN reads 1
and QSPIDMA_DST_ADDR still points into the previous kernel's memory.

Add a ->shutdown that stops the controller the way zynqmp_qspi_suspend()
already does.  spi_controller_suspend() stops the queue, waits for a
message that is already executing and makes any later transfer fail with
-ESHUTDOWN, so nothing can be cut short by the register write that
follows.  It may sleep, which is fine here: device_shutdown() runs in
process context.  Unlike ->suspend this cannot abort on error, because a
controller left mastering the bus is worse than a truncated transfer, so
a failure to drain is only logged.

GQSPI_EN_OFST is then cleared, as zynqmp_qspi_remove() and
zynqmp_qspi_suspend() already do.  Skip that write only when
pm_runtime_get_if_in_use() returns 0, i.e. runtime suspended: the clocks
are gated, so the registers are unreachable and the controller cannot be
mastering the bus.  A negative return is not the same thing - it is what
the CONFIG_PM=n stub always returns, and there probe() has enabled pclk
and refclk for good, so the controller is running and must be stopped.

Fixes: dfe11a11d523 ("spi: Add support for Zynq Ultrascale+ MPSoC GQSPI controller")
Cc: stable@vger.kernel.org
Signed-off-by: Itai Handler <itai.handler@gmail.com>
Link: https://patch.msgid.link/20260910174832.873352-1-itai.handler@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
[ itai: context only - the platform_driver callback is still spelled
  .remove_new in this tree, renamed back to .remove upstream by commit
  494c3dc46776 ("spi: Switch back to struct platform_driver::remove()") ]
Signed-off-by: Itai Handler <itai.handler@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/spi/spi-zynqmp-gqspi.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c
index 143c572b263e2..4fa68b11709b3 100644
--- a/drivers/spi/spi-zynqmp-gqspi.c
+++ b/drivers/spi/spi-zynqmp-gqspi.c
@@ -1385,11 +1385,45 @@ static void zynqmp_qspi_remove(struct platform_device *pdev)
 	clk_disable_unprepare(xqspi->pclk);
 }
 
+static void zynqmp_qspi_shutdown(struct platform_device *pdev)
+{
+	struct zynqmp_qspi *xqspi = platform_get_drvdata(pdev);
+	int ret;
+
+	/*
+	 * Stop the queue and reject any later transfer first, so the write
+	 * below cannot cut into a message that is still being executed.
+	 * Unlike ->suspend this cannot abort on error: a controller left
+	 * mastering the bus is worse than a truncated transfer.
+	 */
+	ret = spi_controller_suspend(xqspi->ctlr);
+	if (ret)
+		dev_warn(&pdev->dev, "could not stop the queue: %d\n", ret);
+
+	/*
+	 * Only a runtime suspended controller can be left alone: its clocks
+	 * are gated, so it cannot be mastering the bus, and its registers
+	 * must not be accessed either.  Any other answer means it may be
+	 * running and has to be stopped.  In particular, on a kernel built
+	 * without runtime PM this returns -EINVAL, and there the clocks
+	 * enabled in probe() are never gated at all.
+	 */
+	ret = pm_runtime_get_if_in_use(&pdev->dev);
+	if (!ret)
+		return;
+
+	zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0);
+
+	if (ret > 0)
+		pm_runtime_put_noidle(&pdev->dev);
+}
+
 MODULE_DEVICE_TABLE(of, zynqmp_qspi_of_match);
 
 static struct platform_driver zynqmp_qspi_driver = {
 	.probe = zynqmp_qspi_probe,
 	.remove_new = zynqmp_qspi_remove,
+	.shutdown = zynqmp_qspi_shutdown,
 	.driver = {
 		.name = "zynqmp-qspi",
 		.of_match_table = zynqmp_qspi_of_match,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 289/877] smb: client: fix busy dentry warning on unmount after DIO
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (287 preceding siblings ...)
  2026-09-30 15:19 ` [PATCH 6.12 288/877] spi: spi-zynqmp-gqspi: stop the controller on shutdown Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 290/877] xfs: dont stash removename operations with unknown ftype Greg Kroah-Hartman
                   ` (595 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Zizhi Wo, Steve French, Sasha Levin

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

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

From: Zizhi Wo <wozizhi@huawei.com>

[ Upstream commit 75f5c412fa867efa0bf9b646bffe0d912109e84a ]

Commit c68337442f03 ("cifs: Fix busy dentry used after unmounting") fixed
the issue in cifs where deferred close of a file led to a dentry reference
count not being released in umount, by flushing deferredclose_wq in
cifs_kill_sb() to solve it.

However, the cifs DIO path suffers from the same busy-dentry problem caused
by a delayed dentry reference-count release:

	[dio]			[cifsd]			[close + umount]
netfs_unbuffered_write_iter_locked
...
				cifs_demultiplex_thread
 netfs_unbuffered_write
  cifs_issue_write
  netfs_wait_for_in_progress_stream [1]
				...
				 netfs_write_subrequest_terminated
				  netfs_subreq_clear_in_progress
				   netfs_wake_collector // wake [1]
				  netfs_put_subrequest
 netfs_put_request
  queue_work(system_dfl_wq, xxx) [2]
 // dio write return					cifs_close
							 _cifsFileInfo_put
							  // cfile->count 2->1
							  --cfile->count [3]

							// umount
							cifs_kill_sb
							 kill_anon_super
							  // warning triggered!
							  shrink_dcache_for_umount [4]
[system_dfl_wq] [5]
netfs_free_request
 ...
 _cifsFileInfo_put
  // cfile->count 1->0
  --cfile->count
  queue_work(fileinfo_put_wq, xxx)

[fileinfo_put_wq] [6]
cifsFileInfo_put_work
 cifsFileInfo_put_final
  dput

If the umount path is triggered before [5], it results warning:
BUG: Dentry 00000000eab1f070{i=9a917b66ae404fec,n=test}  still in use (1)
[unmount of cifs cifs]

The existing per-inode ictx->io_count wait in cifs_evict_inode() does not
help: it lives in the inode eviction path, which runs after
shrink_dcache_for_umount() has already warned about the busy dentries.

Fix it by adding a per-superblock outstanding-rreq counter that is
incremented in cifs_init_request() and decremented in cifs_free_request().
In cifs_kill_sb(), before kill_anon_super(), wait for this counter to reach
0 - which guarantees that all cleanup_work for this sb have run and thus
all relevant cfile puts are queued on fileinfo_put_wq or serverclose_wq.
Then drain the workqueue so the dentry refs are dropped.

This is a targeted wait, not a flush of the system-wide system_dfl_wq.

Fixes: 340cea84f691c ("cifs: open files should not hold ref on superblock")
Signed-off-by: Zizhi Wo <wozizhi@huawei.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/smb/client/cifs_fs_sb.h |  1 +
 fs/smb/client/cifsfs.c     | 12 ++++++++++++
 fs/smb/client/connect.c    |  1 +
 fs/smb/client/file.c       |  5 +++++
 4 files changed, 19 insertions(+)

diff --git a/fs/smb/client/cifs_fs_sb.h b/fs/smb/client/cifs_fs_sb.h
index 6517591922801..2b4850566f15b 100644
--- a/fs/smb/client/cifs_fs_sb.h
+++ b/fs/smb/client/cifs_fs_sb.h
@@ -55,6 +55,7 @@ struct cifs_sb_info {
 	struct smb3_fs_context *ctx;
 	atomic_t active;
 	unsigned int mnt_cifs_flags;
+	atomic_t outstanding_rreq;	/* nr of rreqs not yet fully deinitialized */
 	struct delayed_work prune_tlinks;
 	struct rcu_head rcu;
 
diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index a14f24f8d4a51..f22c79179a23a 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -302,6 +302,18 @@ static void cifs_kill_sb(struct super_block *sb)
 		/* Wait for all opened files to release */
 		flush_workqueue(deferredclose_wq);
 
+		/*
+		 * Wait for all in-flight netfs I/O requests to finish their
+		 * cleanup_work so that any cifsFileInfo final puts they queue
+		 * to fileinfo_put_wq/serverclose_wq have been queued, then
+		 * drain the workqueue so the cfile dentry refs are dropped to
+		 * avoid the busy dentry warning.
+		 */
+		wait_var_event(&cifs_sb->outstanding_rreq,
+			       !atomic_read(&cifs_sb->outstanding_rreq));
+		flush_workqueue(serverclose_wq);
+		flush_workqueue(fileinfo_put_wq);
+
 		/* finally release root dentry */
 		dput(cifs_sb->root);
 		cifs_sb->root = NULL;
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 026c1a30816c4..a7261fb38379f 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -3399,6 +3399,7 @@ int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)
 
 	spin_lock_init(&cifs_sb->tlink_tree_lock);
 	cifs_sb->tlink_tree = RB_ROOT;
+	atomic_set(&cifs_sb->outstanding_rreq, 0);
 
 	cifs_dbg(FYI, "file mode: %04ho  dir mode: %04ho\n",
 		 ctx->file_mode, ctx->dir_mode);
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c
index 339346a82ecff..79cf5829411c2 100644
--- a/fs/smb/client/file.c
+++ b/fs/smb/client/file.c
@@ -276,6 +276,7 @@ static int cifs_init_request(struct netfs_io_request *rreq, struct file *file)
 		return -EIO;
 	}
 
+	atomic_inc(&cifs_sb->outstanding_rreq);
 	return 0;
 }
 
@@ -297,9 +298,13 @@ static void cifs_rreq_done(struct netfs_io_request *rreq)
 static void cifs_free_request(struct netfs_io_request *rreq)
 {
 	struct cifs_io_request *req = container_of(rreq, struct cifs_io_request, rreq);
+	struct cifs_sb_info *cifs_sb = CIFS_SB(rreq->inode->i_sb);
 
 	if (req->cfile)
 		cifsFileInfo_put(req->cfile);
+
+	if (atomic_dec_and_test(&cifs_sb->outstanding_rreq))
+		wake_up_var(&cifs_sb->outstanding_rreq);
 }
 
 static void cifs_free_subrequest(struct netfs_io_subrequest *subreq)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 290/877] xfs: dont stash removename operations with unknown ftype
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (288 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 289/877] smb: client: fix busy dentry warning on unmount after DIO Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 291/877] erofs: fix large folio race in erofs_fscache_req_complete Greg Kroah-Hartman
                   ` (594 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino, Sasha Levin

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

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

From: Darrick J. Wong <djwong@kernel.org>

[ Upstream commit 865b751e75039fc07838b3200f9740256653da9a ]

LOLLM notices that the behavior of xrep_dir_replay_update changes based
on the ftype recorded in the stashed removename information.  It also
notices that the unlink iops sometimes set that ftype to FT_UNKNOWN
because the regular directory tree update code paths don't need to know
the ftype of the child.

Unfortunately, this results in incorrect link counts, which eventually
trips link count errors in later phases of xfs_scrub, or in xfs_repair.
Fix this by creating a second xfs_name with the type set correctly.

Cc: stable@vger.kernel.org # v6.10
Fixes: 8559b21a64d983 ("xfs: implement live updates for directory repairs")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/xfs/scrub/dir_repair.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/fs/xfs/scrub/dir_repair.c b/fs/xfs/scrub/dir_repair.c
index 53272c2540200..bea08dcae5b3d 100644
--- a/fs/xfs/scrub/dir_repair.c
+++ b/fs/xfs/scrub/dir_repair.c
@@ -1379,9 +1379,24 @@ xrep_dir_live_update(
 		if (p->delta > 0)
 			error = xrep_dir_stash_createname(rd, p->name,
 					p->ip->i_ino);
-		else
-			error = xrep_dir_stash_removename(rd, p->name,
+		else {
+			/*
+			 * xfs_dentry_to_name in unlink or rename-exchange can
+			 * pass us names with ftype FT_UNKNOWN, but we really
+			 * must know the ftype of the child that is being
+			 * removed so that we can do nlink updates correctly
+			 * without holding inode references.
+			 */
+			struct xfs_name	name = {
+				.name	= p->name->name,
+				.len	= p->name->len,
+				.type	= xfs_mode_to_ftype(
+						VFS_IC(p->ip)->i_mode),
+			};
+
+			error = xrep_dir_stash_removename(rd, &name,
 					p->ip->i_ino);
+		}
 		mutex_unlock(&rd->pscan.lock);
 		if (error)
 			goto out_abort;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 291/877] erofs: fix large folio race in erofs_fscache_req_complete
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (289 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 290/877] xfs: dont stash removename operations with unknown ftype Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 292/877] ALSA: hda/realtek: Limit Star Labs internal mic boost Greg Kroah-Hartman
                   ` (593 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Wenwu Hou, Gao Xiang, Sasha Levin

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

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

From: Wenwu Hou <hwenwur@gmail.com>

This patch is for stable only. Commit c37460cd9b2fc ("erofs: remove fscache
backend entirely") upstream removed this code.

xas_for_each() iteration can race with reclamation of an unlocked large
folio and splitting of its replacement shadow entry. Fix this by
advancing past the entire folio before unlocking it.

For example:
CPU A: EROFS completion               Other CPUs
----------------------------------   -----------------------------------
Find F at index 0.
Mark F uptodate.
Unlock F.

                                     Reclaim F.
                                     Replace indices 0–3 with a
                                     multi-index workingset shadow.

                                     Another reader inserts a smaller
                                     folio, e.g. order-0 at index 0.
                                     Split the large shadow entry:
                                       index 0: new folio
                                       index 1: shadow
                                       index 2: shadow
                                       index 3: shadow
Find a shadow at index 1.
folio_mark_uptodate(folio).

This can cause a kernel panic such as:
[1030374.432778] [     C31] BUG: unable to handle page fault for address: 00001846af017b01
[1030374.432971] [     C31] #PF: supervisor write access in kernel mode
[1030374.432973] [     C31] #PF: error_code(0x0002) - not-present page
[1030374.433543] [     C31] PGD 5a44f75067 P4D 5a44f75067 PUD 0
[1030374.433546] [     C31] Oops: 0002 [#1] PREEMPT SMP NOPTI
[1030374.433549] [     C31] CPU: 31 PID: 2425624 Comm: node Kdump: loaded Tainted: G           OE K    6.6.88-****
[1030374.434154] [     C31] Hardware name: Alibaba Cloud Alibaba Cloud ECS, BIOS ?-20260421_110423-CN.l65g09119.cloud.sqa.na131 04/01/2014
[1030374.434156] [     C31] RIP: 0010:erofs_fscache_req_complete+0xc1/0x1a0 [erofs]
[1030374.434764] [     C31] Code: 17 c5 c3 48 89 c7 48 85 c0 0f 84 af 00 00 00 48 81 ff 06 04 00 00 74 1b 48 81 ff 02 04 00 00 0f 84 b9 00 00 00 66 85 ed 75 04 <f0> 80 0f 08 e8 96 04 24 c3 48 8b 54 24 18 f6 c2 03 0f 95 c0 48 85
[1030374.435044] [     C31] RSP: 0000:ffffb8f2fc973cc0 EFLAGS: 00010046
[1030374.435641] [     C31]
[1030374.435642] [     C31] RAX: 00001846af017b01 RBX: 000000000000000f RCX: 0000000000000001
[1030374.436885] [     C31] RDX: 000000000000000c RSI: ffffa02ab337d468 RDI: 00001846af017b01
[1030374.437127] [     C31] RBP: 0000000000000000 R08: ffffffffffffffc0 R09: 0000000000000002
[1030374.437672] [     C31] R10: 0000000000000005 R11: 0000000000000191 R12: ffffa0060ec72300
[1030374.437673] [     C31] R13: 0000000008000000 R14: ffffffffc11b1990 R15: 0000000000007000
[1030374.437677] [     C31] FS:  00007f4928cdec80(0000) GS:ffffa07dc5f80000(0000) knlGS:0000000000000000
[1030374.437678] [     C31] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[1030374.437680] [     C31] CR2: 00001846af017b01 CR3: 00000063d5356006 CR4: 0000000000770ee0
[1030374.437681] [     C31] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[1030374.437682] [     C31] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400
[1030374.437684] [     C31] PKRU: 55555558
[1030374.437684] [     C31] Call Trace:
[1030374.437687] [     C31]  <TASK>
[1030374.437692] [     C31]  erofs_fscache_req_put+0x27/0x40 [erofs]
[1030374.438900] [     C31]  cachefiles_read_complete+0x48/0x110 [cachefiles]
[1030374.440448] [     C31]  iomap_dio_bio_end_io+0x128/0x160
[1030374.440456] [     C31]  ? __pfx_stripe_end_io+0x10/0x10 [dm_mod]
[1030374.440950] [     C31]  clone_endio+0x123/0x1f0 [dm_mod]
[1030374.441550] [     C31]  blk_mq_end_request_batch+0xf4/0x440
[1030374.441556] [     C31]  ? nohz_balancer_kick+0x31/0x270
[1030374.441561] [     C31]  ? dma_direct_unmap_sg+0x48/0x1d0
[1030374.441565] [     C31]  ? dma_pool_free+0x22/0x60
[1030374.441569] [     C31]  ? nvme_pci_complete_batch+0xaf/0xc0 [nvme]
[1030374.442070] [     C31]  nvme_irq+0x6e/0x80 [nvme]
[1030374.442422] [     C31]  ? __pfx_nvme_pci_complete_batch+0x10/0x10 [nvme]
[1030374.442428] [     C31]  __handle_irq_event_percpu+0x46/0x1a0
[1030374.442431] [     C31]  handle_irq_event+0x37/0x80
[1030374.442433] [     C31]  handle_edge_irq+0x93/0x240
[1030374.442436] [     C31]  __common_interrupt+0x3b/0xa0
[1030374.442441] [     C31]  common_interrupt+0x3f/0xa0
[1030374.442446] [     C31]  asm_common_interrupt+0x22/0x40

Fixes: d435d53228dd ("erofs: change to use asynchronous io for fscache readpage/readahead")
Signed-off-by: Wenwu Hou <hwenwur@gmail.com>
Reviewed-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/erofs/fscache.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c
index 20e2cb18ed1d4..06987f7f6a195 100644
--- a/fs/erofs/fscache.c
+++ b/fs/erofs/fscache.c
@@ -67,6 +67,8 @@ static void erofs_fscache_req_complete(struct erofs_fscache_rq *req)
 			continue;
 		if (!failed)
 			folio_mark_uptodate(folio);
+		/* Skip the entire folio before unlocking allows it to be split. */
+		xas_advance(&xas, folio_next_index(folio) - 1);
 		folio_unlock(folio);
 	}
 	rcu_read_unlock();
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 292/877] ALSA: hda/realtek: Limit Star Labs internal mic boost
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (290 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 291/877] erofs: fix large folio race in erofs_fscache_req_complete Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 293/877] ALSA: hda/realtek: Add StarFighter HDA SSID Greg Kroah-Hartman
                   ` (592 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Sean Rhodes, Takashi Iwai,
	Sasha Levin

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

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

From: Sean Rhodes <sean@starlabs.systems>

[ Upstream commit 186d4adbb40138e7cb7cffc87a81e95630ced123 ]

The 30 dB internal mic boost is too high for laptops, especially with fans. Limit Star Labs internal mic boost to 10 dB.

Signed-off-by: Sean Rhodes <sean@starlabs.systems>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/be87292613b24150d6321adac102b4b25d00e9e6.1785532385.git.sean@starlabs.systems
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/pci/hda/patch_realtek.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 4b0ccb3b48b2b..e9913767b0b84 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -8243,6 +8243,7 @@ enum {
 	ALC245_FIXUP_CLEVO_NOISY_MIC,
 	ALC269_FIXUP_VAIO_VJFH52_MIC_NO_PRESENCE,
 	ALC233_FIXUP_MEDION_MTL_SPK,
+	ALC269_FIXUP_STARLABS_LIMIT_INT_MIC_BOOST,
 	ALC233_FIXUP_STARLABS_STARFIGHTER,
 	ALC294_FIXUP_BASS_SPEAKER_15,
 	ALC283_FIXUP_DELL_HP_RESUME,
@@ -10652,6 +10653,10 @@ static const struct hda_fixup alc269_fixups[] = {
 			{ }
 		},
 	},
+	[ALC269_FIXUP_STARLABS_LIMIT_INT_MIC_BOOST] = {
+		.type = HDA_FIXUP_FUNC,
+		.v.func = alc269_fixup_limit_int_mic_boost,
+	},
 	[ALC233_FIXUP_STARLABS_STARFIGHTER] = {
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc233_fixup_starlabs_starfighter,
@@ -11770,6 +11775,7 @@ static const struct hda_quirk alc269_fixup_vendor_tbl[] = {
 	SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
 	SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI),
 	SND_PCI_QUIRK_VENDOR(0x19e5, "Huawei Matebook", ALC255_FIXUP_MIC_MUTE_LED),
+	SND_PCI_QUIRK_VENDOR(0x2145, "Star Labs", ALC269_FIXUP_STARLABS_LIMIT_INT_MIC_BOOST),
 	{}
 };
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 293/877] ALSA: hda/realtek: Add StarFighter HDA SSID
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (291 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 292/877] ALSA: hda/realtek: Limit Star Labs internal mic boost Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 294/877] netfilter: nf_tables: Tolerate chains with no remaining hooks Greg Kroah-Hartman
                   ` (591 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Sean Rhodes, Takashi Iwai,
	Sasha Levin

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

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

From: Sean Rhodes <sean@starlabs.systems>

[ Upstream commit cd401c70df472d3eddd0b6b055726a03c212181a ]

Support the new StarFighter HDA SSID while keeping the existing SSID chained to the same quirk until the new match reaches backports.

Signed-off-by: Sean Rhodes <sean@starlabs.systems>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/06865eaedf3de8dff199e9aa7e86cd135572f20f.1785532385.git.sean@starlabs.systems
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 sound/pci/hda/patch_realtek.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index e9913767b0b84..72d540182f8d0 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -10660,6 +10660,8 @@ static const struct hda_fixup alc269_fixups[] = {
 	[ALC233_FIXUP_STARLABS_STARFIGHTER] = {
 		.type = HDA_FIXUP_FUNC,
 		.v.func = alc233_fixup_starlabs_starfighter,
+		.chained = true,
+		.chain_id = ALC269_FIXUP_STARLABS_LIMIT_INT_MIC_BOOST,
 	},
 	[ALC294_FIXUP_BASS_SPEAKER_15] = {
 		.type = HDA_FIXUP_FUNC,
@@ -11698,6 +11700,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
 	SND_PCI_QUIRK(0x1f66, 0x0105, "Ayaneo Portable Game Player", ALC287_FIXUP_CS35L41_I2C_2),
 	SND_PCI_QUIRK(0x2014, 0x800a, "Positivo ARN50", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
 	SND_PCI_QUIRK(0x2039, 0x0001, "Inspur S14-G1", ALC295_FIXUP_CHROME_BOOK),
+	SND_PCI_QUIRK(0x2145, 0x0001, "Star Labs StarFighter", ALC233_FIXUP_STARLABS_STARFIGHTER),
 	SND_PCI_QUIRK(0x2782, 0x0214, "VAIO VJFE-CL", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
 	SND_PCI_QUIRK(0x2782, 0x0228, "Infinix ZERO BOOK 13", ALC269VB_FIXUP_INFINIX_ZERO_BOOK_13),
 	SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO),
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 294/877] netfilter: nf_tables: Tolerate chains with no remaining hooks
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (292 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 293/877] ALSA: hda/realtek: Add StarFighter HDA SSID Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 295/877] netfilter: nf_tables: Simplify chain netdev notifier Greg Kroah-Hartman
                   ` (590 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Phil Sutter, Pablo Neira Ayuso,
	Yu Junzhe, Sasha Levin

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

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

From: Phil Sutter <phil@nwl.cc>

commit fc0133428e7ad65aa6b7c8e65ccfe86e469e4512 upstream.

Do not drop a netdev-family chain if the last interface it is registered
for vanishes. Users dumping and storing the ruleset upon shutdown to
restore it upon next boot may otherwise lose the chain and all contained
rules. They will still lose the list of devices, a later patch will fix
that. For now, this aligns the event handler's behaviour with that for
flowtables.
The controversal situation at netns exit should be no problem here:
event handler will unregister the hooks, core nftables cleanup code will
drop the chain itself.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Yu Junzhe <junzheyu1@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/net/netfilter/nf_tables.h |  2 --
 net/netfilter/nf_tables_api.c     | 41 -------------------------------
 net/netfilter/nft_chain_filter.c  | 29 ++++++----------------
 3 files changed, 7 insertions(+), 65 deletions(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index f4b59915a49c5..923b2c0d6e844 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -1238,8 +1238,6 @@ static inline bool nft_is_base_chain(const struct nft_chain *chain)
 	return chain->flags & NFT_CHAIN_BASE;
 }
 
-int __nft_release_basechain(struct nft_ctx *ctx);
-
 unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
 
 static inline bool nft_use_inc(u32 *use)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 2613ebfdc854e..af9df95ddf055 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -11362,47 +11362,6 @@ int nft_data_dump(struct sk_buff *skb, int attr, const struct nft_data *data,
 }
 EXPORT_SYMBOL_GPL(nft_data_dump);
 
-static void __nft_release_basechain_now(struct nft_ctx *ctx)
-{
-	struct nft_rule *rule, *nr;
-
-	list_for_each_entry_safe(rule, nr, &ctx->chain->rules, list) {
-		list_del(&rule->list);
-		nf_tables_rule_release(ctx, rule);
-	}
-	nf_tables_chain_destroy(ctx->chain);
-}
-
-int __nft_release_basechain(struct nft_ctx *ctx)
-{
-	struct nft_rule *rule;
-
-	if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain)))
-		return 0;
-
-	nf_tables_unregister_hook(ctx->net, ctx->chain->table, ctx->chain);
-	list_for_each_entry(rule, &ctx->chain->rules, list)
-		nft_use_dec(&ctx->chain->use);
-
-	nft_chain_del(ctx->chain);
-	nft_use_dec(&ctx->table->use);
-
-	if (!maybe_get_net(ctx->net)) {
-		__nft_release_basechain_now(ctx);
-		return 0;
-	}
-
-	/* wait for ruleset dumps to complete.  Owning chain is no longer in
-	 * lists, so new dumps can't find any of these rules anymore.
-	 */
-	synchronize_rcu();
-
-	__nft_release_basechain_now(ctx);
-	put_net(ctx->net);
-	return 0;
-}
-EXPORT_SYMBOL_GPL(__nft_release_basechain);
-
 static void __nft_release_hook(struct net *net, struct nft_table *table)
 {
 	struct nft_flowtable *flowtable;
diff --git a/net/netfilter/nft_chain_filter.c b/net/netfilter/nft_chain_filter.c
index 7010541fcca66..543f258b7c6ba 100644
--- a/net/netfilter/nft_chain_filter.c
+++ b/net/netfilter/nft_chain_filter.c
@@ -322,34 +322,19 @@ static void nft_netdev_event(unsigned long event, struct net_device *dev,
 			     struct nft_ctx *ctx)
 {
 	struct nft_base_chain *basechain = nft_base_chain(ctx->chain);
-	struct nft_hook *hook, *found = NULL;
-	int n = 0;
+	struct nft_hook *hook;
 
 	list_for_each_entry(hook, &basechain->hook_list, list) {
-		if (hook->ops.dev == dev)
-			found = hook;
-
-		n++;
-	}
-	if (!found)
-		return;
+		if (hook->ops.dev != dev)
+			continue;
 
-	if (n > 1) {
 		if (!(ctx->chain->table->flags & NFT_TABLE_F_DORMANT))
-			nf_unregister_net_hook(ctx->net, &found->ops);
+			nf_unregister_net_hook(ctx->net, &hook->ops);
 
-		list_del_rcu(&found->list);
-		kfree_rcu(found, rcu);
-		return;
+		list_del_rcu(&hook->list);
+		kfree_rcu(hook, rcu);
+		break;
 	}
-
-	/* UNREGISTER events are also happening on netns exit.
-	 *
-	 * Although nf_tables core releases all tables/chains, only this event
-	 * handler provides guarantee that hook->ops.dev is still accessible,
-	 * so we cannot skip exiting net namespaces.
-	 */
-	__nft_release_basechain(ctx);
 }
 
 static int nf_tables_netdev_event(struct notifier_block *this,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 295/877] netfilter: nf_tables: Simplify chain netdev notifier
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (293 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 294/877] netfilter: nf_tables: Tolerate chains with no remaining hooks Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 296/877] xfrm: Refactor xfrm_input lock to reduce contention with RSS Greg Kroah-Hartman
                   ` (589 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Phil Sutter, Pablo Neira Ayuso,
	Yu Junzhe, Sasha Levin

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

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

From: Phil Sutter <phil@nwl.cc>

commit 375f222800bc001bb9cbd2baa1daec006430aeba upstream.

With conditional chain deletion gone, callback code simplifies: Instead
of filling an nft_ctx object, just pass basechain to the per-chain
function. Also plain list_for_each_entry() is safe now.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Yu Junzhe <junzheyu1@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/netfilter/nft_chain_filter.c | 21 +++++++--------------
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/net/netfilter/nft_chain_filter.c b/net/netfilter/nft_chain_filter.c
index 543f258b7c6ba..19a553550c769 100644
--- a/net/netfilter/nft_chain_filter.c
+++ b/net/netfilter/nft_chain_filter.c
@@ -319,17 +319,16 @@ static const struct nft_chain_type nft_chain_filter_netdev = {
 };
 
 static void nft_netdev_event(unsigned long event, struct net_device *dev,
-			     struct nft_ctx *ctx)
+			     struct nft_base_chain *basechain)
 {
-	struct nft_base_chain *basechain = nft_base_chain(ctx->chain);
 	struct nft_hook *hook;
 
 	list_for_each_entry(hook, &basechain->hook_list, list) {
 		if (hook->ops.dev != dev)
 			continue;
 
-		if (!(ctx->chain->table->flags & NFT_TABLE_F_DORMANT))
-			nf_unregister_net_hook(ctx->net, &hook->ops);
+		if (!(basechain->chain.table->flags & NFT_TABLE_F_DORMANT))
+			nf_unregister_net_hook(dev_net(dev), &hook->ops);
 
 		list_del_rcu(&hook->list);
 		kfree_rcu(hook, rcu);
@@ -343,25 +342,20 @@ static int nf_tables_netdev_event(struct notifier_block *this,
 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct nft_base_chain *basechain;
 	struct nftables_pernet *nft_net;
-	struct nft_chain *chain, *nr;
+	struct nft_chain *chain;
 	struct nft_table *table;
-	struct nft_ctx ctx = {
-		.net	= dev_net(dev),
-	};
 
 	if (event != NETDEV_UNREGISTER)
 		return NOTIFY_DONE;
 
-	nft_net = nft_pernet(ctx.net);
+	nft_net = nft_pernet(dev_net(dev));
 	mutex_lock(&nft_net->commit_mutex);
 	list_for_each_entry(table, &nft_net->tables, list) {
 		if (table->family != NFPROTO_NETDEV &&
 		    table->family != NFPROTO_INET)
 			continue;
 
-		ctx.family = table->family;
-		ctx.table = table;
-		list_for_each_entry_safe(chain, nr, &table->chains, list) {
+		list_for_each_entry(chain, &table->chains, list) {
 			if (!nft_is_base_chain(chain))
 				continue;
 
@@ -370,8 +364,7 @@ static int nf_tables_netdev_event(struct notifier_block *this,
 			    basechain->ops.hooknum != NF_INET_INGRESS)
 				continue;
 
-			ctx.chain = chain;
-			nft_netdev_event(event, dev, &ctx);
+			nft_netdev_event(event, dev, basechain);
 		}
 	}
 	mutex_unlock(&nft_net->commit_mutex);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 296/877] xfrm: Refactor xfrm_input lock to reduce contention with RSS
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (294 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 295/877] netfilter: nf_tables: Simplify chain netdev notifier Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 297/877] xfrm: Fix dev use-after-free in xfrm async resumption Greg Kroah-Hartman
                   ` (588 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jianbo Liu, Cosmin Ratiu,
	Steffen Klassert, Sasha Levin

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

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

From: Jianbo Liu <jianbol@nvidia.com>

[ Upstream commit 10a11861943902fda74f37f456b45183b2bca270 ]

With newer NICs like mlx5 supporting RSS for IPsec crypto offload,
packets for a single Security Association (SA) are scattered across
multiple CPU cores for parallel processing. The xfrm_state spinlock
(x->lock) is held for each packet during xfrm processing.

When multiple connections or flows share the same SA, this parallelism
causes high lock contention on x->lock, creating a performance
bottleneck and limiting scalability.

The original xfrm_input() function exacerbated this issue by releasing
and immediately re-acquiring x->lock. For hardware crypto offload
paths, this unlock/relock sequence is unnecessary and introduces
significant overhead. This patch refactors the function to relocate
the type_offload->input_tail call for the offload path, performing all
necessary work while continuously holding the lock. This reordering is
safe, since packets which don't pass the checks below will still fail
them with the new code.

Performance testing with iperf using multiple parallel streams over a
single IPsec SA shows significant improvement in throughput as the
number of queues (and thus CPU cores) increases:

+-----------+---------------+--------------+-----------------+
| RX queues | Before (Gbps) | After (Gbps) | Improvement (%) |
+-----------+---------------+--------------+-----------------+
|         2 |          32.3 |         34.4 |             6.5 |
|         4 |          34.4 |         40.0 |            16.3 |
|         6 |          24.5 |         38.3 |            56.3 |
|         8 |          23.1 |         38.3 |            65.8 |
|        12 |          18.1 |         29.9 |            65.2 |
|        16 |          16.0 |         25.2 |            57.5 |
+-----------+---------------+--------------+-----------------+

Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Stable-dep-of: 3cf5cdecd99c ("xfrm: save input state data before secpath resets")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/xfrm/xfrm_input.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 1be187b980461..444334feece7b 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -493,6 +493,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 		if (encap_type == -1) {
 			async = 1;
 			seq = XFRM_SKB_CB(skb)->seq.input.low;
+			spin_lock(&x->lock);
 			goto resume;
 		}
 		/* GRO call */
@@ -529,6 +530,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 				XFRM_INC_STATS(net, LINUX_MIB_XFRMINHDRERROR);
 				goto drop;
 			}
+
+			nexthdr = x->type_offload->input_tail(x, skb);
 		}
 
 		goto lock;
@@ -626,11 +629,9 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 			goto drop_unlock;
 		}
 
-		spin_unlock(&x->lock);
-
 		if (xfrm_tunnel_check(skb, x, family)) {
 			XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEMODEERROR);
-			goto drop;
+			goto drop_unlock;
 		}
 
 		seq_hi = htonl(xfrm_replay_seqhi(x, seq));
@@ -638,9 +639,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 		XFRM_SKB_CB(skb)->seq.input.low = seq;
 		XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
 
-		if (crypto_done) {
-			nexthdr = x->type_offload->input_tail(x, skb);
-		} else {
+		if (!crypto_done) {
+			spin_unlock(&x->lock);
 			dev_hold(skb->dev);
 
 			nexthdr = x->type->input(x, skb);
@@ -651,9 +651,9 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 			}
 
 			dev_put(skb->dev);
+			spin_lock(&x->lock);
 		}
 resume:
-		spin_lock(&x->lock);
 		if (nexthdr < 0) {
 			if (nexthdr == -EBADMSG) {
 				xfrm_audit_state_icvfail(x, skb,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 297/877] xfrm: Fix dev use-after-free in xfrm async resumption
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (295 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 296/877] xfrm: Refactor xfrm_input lock to reduce contention with RSS Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 298/877] xfrm: save input state data before secpath resets Greg Kroah-Hartman
                   ` (587 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Xu Chunxiao, Dong Chenchen,
	Steffen Klassert, Sasha Levin

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

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

From: Dong Chenchen <dongchenchen2@huawei.com>

[ Upstream commit 8045c0df98d4f14c54e5cb875f1c9c0ce89fe4ff ]

xfrm async resumption hold skb->dev refcnt until after transport_finish.
However, xfrm_rcv_cb may modify skb->dev to tunnel dev without taking
device reference, such as vti_rcv_cb. The subsequent async resumption
will decrement the tunnel device's reference count, which lead to uaf
of tunnel dev and refcnt leak of orig dev as below:

unregister_netdevice: waiting for vti1 to become free. Usage count = -2

Stash the original skb->dev to fix refcnt imbalance. The new skb->dev set
by xfrm_rcv_cb can race with device teardown. Extend rcu protection over
xfrm_rcv_cb and transport_finish to prevent races.

Fixes: 1c428b038400 ("xfrm: hold dev ref until after transport_finish NF_HOOK")
Reported-by: Xu Chunxiao <xuchunxiao3@huawei.com>
Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>

Backport to 6.12: retain the synchronous xfrm_inner_mode_input()
error handling. This tree lacks the mode_cbs infrastructure that
introduced the -EINPROGRESS branch, so omit the dev_put() conversion
for that absent branch. Keep the original-device reference handling
and extended RCU protection for the existing receive paths.

This supplies the receive, transport-finish and drop-path context for
3cf5cdecd99c ("xfrm: save input state data before secpath resets"),
which applies without further changes.

Stable-dep-of: 3cf5cdecd99c ("xfrm: save input state data before secpath resets")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv4/xfrm4_input.c |  2 --
 net/ipv6/xfrm6_input.c |  2 --
 net/xfrm/xfrm_input.c  | 27 +++++++++++++++------------
 3 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index adf21d6b6076c..9deee1558e3d6 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -76,8 +76,6 @@ int xfrm4_transport_finish(struct sk_buff *skb, int async)
 	NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
 		dev_net(dev), NULL, skb, dev, NULL,
 		xfrm4_rcv_encap_finish);
-	if (async)
-		dev_put(dev);
 	return 0;
 }
 
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c
index c9e208c57a6b5..07edef2589844 100644
--- a/net/ipv6/xfrm6_input.c
+++ b/net/ipv6/xfrm6_input.c
@@ -71,8 +71,6 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async)
 	NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING,
 		dev_net(dev), NULL, skb, dev, NULL,
 		xfrm6_transport_finish2);
-	if (async)
-		dev_put(dev);
 	return 0;
 }
 
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 444334feece7b..ba512e9293201 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -457,6 +457,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 {
 	const struct xfrm_state_afinfo *afinfo;
 	struct net *net = dev_net(skb->dev);
+	struct net_device *dev = skb->dev;
 	int err;
 	__be32 seq;
 	__be32 seq_hi;
@@ -483,7 +484,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 					       LINUX_MIB_XFRMINSTATEINVALID);
 
 			if (encap_type == -1)
-				dev_put(skb->dev);
+				dev_put(dev);
 			goto drop;
 		}
 
@@ -641,16 +642,16 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 
 		if (!crypto_done) {
 			spin_unlock(&x->lock);
-			dev_hold(skb->dev);
+			dev_hold(dev);
 
 			nexthdr = x->type->input(x, skb);
 			if (nexthdr == -EINPROGRESS) {
 				if (async)
-					dev_put(skb->dev);
+					dev_put(dev);
 				return 0;
 			}
 
-			dev_put(skb->dev);
+			dev_put(dev);
 			spin_lock(&x->lock);
 		}
 resume:
@@ -707,9 +708,12 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 		crypto_done = false;
 	} while (!err);
 
+	rcu_read_lock();
 	err = xfrm_rcv_cb(skb, family, x->type->proto, 0);
-	if (err)
+	if (err) {
+		rcu_read_unlock();
 		goto drop;
+	}
 
 	nf_reset_ct(skb);
 
@@ -720,8 +724,9 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 		if (skb_valid_dst(skb))
 			skb_dst_drop(skb);
 		if (async)
-			dev_put(skb->dev);
+			dev_put(dev);
 		gro_cells_receive(&gro_cells, skb);
+		rcu_read_unlock();
 		return 0;
 	} else {
 		xo = xfrm_offload(skb);
@@ -729,23 +734,21 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 			xfrm_gro = xo->flags & XFRM_GRO;
 
 		err = -EAFNOSUPPORT;
-		rcu_read_lock();
 		afinfo = xfrm_state_afinfo_get_rcu(x->props.family);
 		if (likely(afinfo))
 			err = afinfo->transport_finish(skb, xfrm_gro || async);
-		rcu_read_unlock();
 		if (xfrm_gro) {
 			sp = skb_sec_path(skb);
 			if (sp)
 				sp->olen = 0;
 			if (skb_valid_dst(skb))
 				skb_dst_drop(skb);
-			if (async)
-				dev_put(skb->dev);
 			gro_cells_receive(&gro_cells, skb);
-			return err;
 		}
 
+		if (async)
+			dev_put(dev);
+		rcu_read_unlock();
 		return err;
 	}
 
@@ -753,7 +756,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 	spin_unlock(&x->lock);
 drop:
 	if (async)
-		dev_put(skb->dev);
+		dev_put(dev);
 	xfrm_rcv_cb(skb, family, x && x->type ? x->type->proto : nexthdr, -1);
 	kfree_skb(skb);
 	return 0;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 298/877] xfrm: save input state data before secpath resets
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (296 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 297/877] xfrm: Fix dev use-after-free in xfrm async resumption Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 299/877] remoteproc: qcom_q6v5_adsp: Fix iommu_unmap() usage Greg Kroah-Hartman
                   ` (586 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Zhiling Zou, Steffen Klassert,
	Sasha Levin

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

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

From: Zhiling Zou <zhilinz@nebusec.ai>

[ Upstream commit 3cf5cdecd99c9c186a5ea518d93bbf3045b6e3aa ]

xfrm_input() stores the current xfrm_state in the skb secpath while it
continues receive-side processing. Some input paths can reset that secpath
before xfrm_input() has finished dereferencing the state.

Receive callback users such as VTI and XFRM interfaces can reset the
secpath. The VTI receive path does so before checking whether the packet
crosses network namespaces, while the XFRM interface path does so only for
cross-network-namespace packets. The XFRM_MAX_DEPTH error path can also
reset the secpath before the final drop callback reports the current
state's protocol.

If secpath_reset() drops the last state reference while the state is
concurrently deleted, xfrm_input() can still dereference the freed state
when selecting transport_finish() or reporting the drop callback protocol.

Save the state protocol on the stack while the state is still valid,
and use the already saved address family for transport_finish(). A larval
XFRM_STATE_ACQ state has no type, so retain nexthdr as its protocol. This
preserves the existing drop-path fallback while avoiding the post-reset
state dereferences without adding an extra state reference to every
received packet.

Fixes: df3893c176e9 ("vti: Update the ipv4 side to use it's own receive hook.")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/xfrm/xfrm_input.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index ba512e9293201..63d1504b50a92 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -464,6 +464,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 	struct xfrm_state *x = NULL;
 	xfrm_address_t *daddr;
 	u32 mark = skb->mark;
+	u8 xfrm_proto = nexthdr;
 	unsigned int family = AF_UNSPEC;
 	int decaps = 0;
 	int async = 0;
@@ -475,6 +476,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 	if (encap_type < 0 || (xo && (xo->flags & XFRM_GRO || encap_type == 0 ||
 				      encap_type == UDP_ENCAP_ESPINUDP))) {
 		x = xfrm_input_state(skb);
+		xfrm_proto = x->type ? x->type->proto : nexthdr;
 
 		if (unlikely(x->km.state != XFRM_STATE_VALID)) {
 			if (x->km.state == XFRM_STATE_ACQ)
@@ -578,11 +580,13 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 
 		x = xfrm_input_state_lookup(net, mark, daddr, spi, nexthdr, family);
 		if (x == NULL) {
+			xfrm_proto = nexthdr;
 			secpath_reset(skb);
 			XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOSTATES);
 			xfrm_audit_state_notfound(skb, family, spi, seq);
 			goto drop;
 		}
+		xfrm_proto = x->type ? x->type->proto : nexthdr;
 
 		if (unlikely(x->dir && x->dir != XFRM_SA_DIR_IN)) {
 			secpath_reset(skb);
@@ -590,6 +594,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 			xfrm_audit_state_notfound(skb, family, spi, seq);
 			xfrm_state_put(x);
 			x = NULL;
+			xfrm_proto = nexthdr;
 			goto drop;
 		}
 
@@ -709,7 +714,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 	} while (!err);
 
 	rcu_read_lock();
-	err = xfrm_rcv_cb(skb, family, x->type->proto, 0);
+	err = xfrm_rcv_cb(skb, family, xfrm_proto, 0);
 	if (err) {
 		rcu_read_unlock();
 		goto drop;
@@ -734,7 +739,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 			xfrm_gro = xo->flags & XFRM_GRO;
 
 		err = -EAFNOSUPPORT;
-		afinfo = xfrm_state_afinfo_get_rcu(x->props.family);
+		afinfo = xfrm_state_afinfo_get_rcu(family);
 		if (likely(afinfo))
 			err = afinfo->transport_finish(skb, xfrm_gro || async);
 		if (xfrm_gro) {
@@ -757,7 +762,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 drop:
 	if (async)
 		dev_put(dev);
-	xfrm_rcv_cb(skb, family, x && x->type ? x->type->proto : nexthdr, -1);
+	xfrm_rcv_cb(skb, family, xfrm_proto, -1);
 	kfree_skb(skb);
 	return 0;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 299/877] remoteproc: qcom_q6v5_adsp: Fix iommu_unmap() usage
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (297 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 298/877] xfrm: save input state data before secpath resets Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 300/877] KVM: s390: Fix IRQ injection with SIGP Stop and Store Status Greg Kroah-Hartman
                   ` (585 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mostafa Saleh, Bjorn Andersson,
	Sasha Levin

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

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

From: Mostafa Saleh <smostafa@google.com>

[ Upstream commit 0d8e2195bce6f08c1c53c5ef4d7347fe46418101 ]

During adsp_map_carveout, the IOVA is computed by combining the
physical address and the SID:
    iova = adsp->mem_phys | (sid << 32);

However, adsp_unmap_carveout() uses the physical address and not
the IOVA in iommu_unmap(), causing the unmap to fail or leak
mappings because the address doesn't match the original IOVA.

Cache the constructed IOVA within the qcom_adsp device struct
during mapping and use it during unmapping.

Fixes: f22eedff28af ("remoteproc: qcom: Add support for memory sandbox")
Signed-off-by: Mostafa Saleh <smostafa@google.com>
Link: https://lore.kernel.org/r/20260827203055.640116-1-smostafa@google.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/remoteproc/qcom_q6v5_adsp.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/remoteproc/qcom_q6v5_adsp.c b/drivers/remoteproc/qcom_q6v5_adsp.c
index 80ac739621bed..0345940268126 100644
--- a/drivers/remoteproc/qcom_q6v5_adsp.c
+++ b/drivers/remoteproc/qcom_q6v5_adsp.c
@@ -104,6 +104,7 @@ struct qcom_adsp {
 	struct completion stop_done;
 
 	phys_addr_t mem_phys;
+	unsigned long iova;
 	phys_addr_t mem_reloc;
 	void *mem_region;
 	size_t mem_size;
@@ -333,7 +334,7 @@ static void adsp_unmap_carveout(struct rproc *rproc)
 	struct qcom_adsp *adsp = rproc->priv;
 
 	if (adsp->has_iommu)
-		iommu_unmap(rproc->domain, adsp->mem_phys, adsp->mem_size);
+		iommu_unmap(rproc->domain, adsp->iova, adsp->mem_size);
 }
 
 static int adsp_map_carveout(struct rproc *rproc)
@@ -341,7 +342,6 @@ static int adsp_map_carveout(struct rproc *rproc)
 	struct qcom_adsp *adsp = rproc->priv;
 	struct of_phandle_args args;
 	long long sid;
-	unsigned long iova;
 	int ret;
 
 	if (!adsp->has_iommu)
@@ -358,9 +358,9 @@ static int adsp_map_carveout(struct rproc *rproc)
 	of_node_put(args.np);
 
 	/* Add SID configuration for ADSP Firmware to SMMU */
-	iova =  adsp->mem_phys | (sid << 32);
+	adsp->iova = adsp->mem_phys | (sid << 32);
 
-	ret = iommu_map(rproc->domain, iova, adsp->mem_phys,
+	ret = iommu_map(rproc->domain, adsp->iova, adsp->mem_phys,
 			adsp->mem_size,	IOMMU_READ | IOMMU_WRITE,
 			GFP_KERNEL);
 	if (ret) {
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 300/877] KVM: s390: Fix IRQ injection with SIGP Stop and Store Status
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (298 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 299/877] remoteproc: qcom_q6v5_adsp: Fix iommu_unmap() usage Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 301/877] bpf: Fix bpf_skb_change_tail wrt csum partial skbs Greg Kroah-Hartman
                   ` (584 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Claudio Imbrenda, Sasha Levin

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

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

From: Claudio Imbrenda <imbrenda@linux.ibm.com>

[ Upstream commit d343407b728a80b74be3c24b59f15e60289ea527 ]

When __inject_sigp_stop() is called for a Stop and Store Status
operation, if the vCPU is running, the interrupt is marked as pending
and the status is stored by the thread performing the KVM_RUN IOCTL.

If the vCPU is already stopped, the status is stored immediately.

Storing the status means writing into userspace, which might fault, and
__inject_sigp_stop() is called from do_inject_vcpu() which in turn is
always called holding a spinlock, which is obviously an issue.

Fix this by returning -EWOULDBLOCK from __inject_sigp_stop(), and
adding a bool flag to indicate whether a store status is needed. The
callers of do_inject_vcpu() are modified to pass the pointer to the
bool flag; whenever a Store Status operation is needed, the callers can
now perform it outside the spinlock.

Opportunistically refactor kvm_s390_set_irq_state() to use
scoped_guard() and __free().

Fixes: 6cddd432e3da ("KVM: s390: handle stop irqs without action_bits")
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
[ Added Fixes tag while picking -- Claudio ]
Message-ID: <20260812104436.109741-7-imbrenda@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/s390/kvm/interrupt.c | 70 +++++++++++++++++++++------------------
 1 file changed, 38 insertions(+), 32 deletions(-)

diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c
index 3fc07da7fd7a5..0f3ad8c80381f 100644
--- a/arch/s390/kvm/interrupt.c
+++ b/arch/s390/kvm/interrupt.c
@@ -1586,23 +1586,21 @@ static int __inject_set_prefix(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
 }
 
 #define KVM_S390_STOP_SUPP_FLAGS (KVM_S390_STOP_FLAG_STORE_STATUS)
-static int __inject_sigp_stop(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
+static int __inject_sigp_stop(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq, bool *storestatus)
 {
 	struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
 	struct kvm_s390_stop_info *stop = &li->irq.stop;
-	int rc = 0;
 
 	vcpu->stat.inject_stop_signal++;
 	trace_kvm_s390_inject_vcpu(vcpu->vcpu_id, KVM_S390_SIGP_STOP, 0, 0);
 
 	if (irq->u.stop.flags & ~KVM_S390_STOP_SUPP_FLAGS)
 		return -EINVAL;
-
 	if (is_vcpu_stopped(vcpu)) {
-		if (irq->u.stop.flags & KVM_S390_STOP_FLAG_STORE_STATUS)
-			rc = kvm_s390_store_status_unloaded(vcpu,
-						KVM_S390_STORE_STATUS_NOADDR);
-		return rc;
+		if (!(irq->u.stop.flags & KVM_S390_STOP_FLAG_STORE_STATUS))
+			return 0;
+		*storestatus = true;
+		return -EWOULDBLOCK;
 	}
 
 	if (test_and_set_bit(IRQ_PEND_SIGP_STOP, &li->pending_irqs))
@@ -2142,7 +2140,7 @@ void kvm_s390_clear_stop_irq(struct kvm_vcpu *vcpu)
 	spin_unlock(&li->lock);
 }
 
-static int do_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
+static int do_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq, bool *storestatus)
 {
 	int rc;
 
@@ -2154,7 +2152,7 @@ static int do_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
 		rc = __inject_set_prefix(vcpu, irq);
 		break;
 	case KVM_S390_SIGP_STOP:
-		rc = __inject_sigp_stop(vcpu, irq);
+		rc = __inject_sigp_stop(vcpu, irq, storestatus);
 		break;
 	case KVM_S390_RESTART:
 		rc = __inject_sigp_restart(vcpu);
@@ -2190,11 +2188,16 @@ static int do_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
 int kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, struct kvm_s390_irq *irq)
 {
 	struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
+	bool storestatus = false;
 	int rc;
 
 	spin_lock(&li->lock);
-	rc = do_inject_vcpu(vcpu, irq);
+	rc = do_inject_vcpu(vcpu, irq, &storestatus);
 	spin_unlock(&li->lock);
+
+	if (rc == -EWOULDBLOCK && storestatus)
+		rc = kvm_s390_store_status_unloaded(vcpu, KVM_S390_STORE_STATUS_NOADDR);
+
 	if (!rc)
 		kvm_s390_vcpu_wakeup(vcpu);
 	return rc;
@@ -2930,7 +2933,8 @@ int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, struct kvm *kvm,
 int kvm_s390_set_irq_state(struct kvm_vcpu *vcpu, void __user *irqstate, int len)
 {
 	struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
-	struct kvm_s390_irq *buf;
+	struct kvm_s390_irq *buf __free(kvfree) = NULL;
+	bool tmp, storestatus = false;
 	int r = 0;
 	int n;
 
@@ -2938,31 +2942,33 @@ int kvm_s390_set_irq_state(struct kvm_vcpu *vcpu, void __user *irqstate, int len
 	if (!buf)
 		return -ENOMEM;
 
-	if (copy_from_user((void *) buf, irqstate, len)) {
-		r = -EFAULT;
-		goto out_free;
-	}
+	if (copy_from_user((void *)buf, irqstate, len))
+		return -EFAULT;
 
-	/*
-	 * Don't allow setting the interrupt state
-	 * when there are already interrupts pending
-	 */
-	spin_lock(&li->lock);
-	if (li->pending_irqs) {
-		r = -EBUSY;
-		goto out_unlock;
-	}
+	scoped_guard(spinlock, &li->lock) {
+		/*
+		 * Don't allow setting the interrupt state
+		 * when there are already interrupts pending
+		 */
+		if (li->pending_irqs)
+			return -EBUSY;
 
-	for (n = 0; n < len / sizeof(*buf); n++) {
-		r = do_inject_vcpu(vcpu, &buf[n]);
-		if (r)
-			break;
+		for (n = 0; n < len / sizeof(*buf); n++) {
+			tmp = false;
+			r = do_inject_vcpu(vcpu, &buf[n], &tmp);
+			if (r == -EWOULDBLOCK && tmp) {
+				storestatus = true;
+				r = 0;
+			}
+			if (r)
+				break;
+		}
 	}
 
-out_unlock:
-	spin_unlock(&li->lock);
-out_free:
-	vfree(buf);
+	if (storestatus) {
+		n = kvm_s390_store_status_unloaded(vcpu, KVM_S390_STORE_STATUS_NOADDR);
+		return r ? r : n;
+	}
 
 	return r;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 301/877] bpf: Fix bpf_skb_change_tail wrt csum partial skbs
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (299 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 300/877] KVM: s390: Fix IRQ injection with SIGP Stop and Store Status Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 302/877] bpf: Disallow bpf_skb_pull_data() for LWT_SEG6LOCAL Greg Kroah-Hartman
                   ` (583 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Tom Hadlaw, Yusuke Suzuki,
	Daniel Borkmann, Alexei Starovoitov, Sasha Levin

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

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

From: Daniel Borkmann <daniel@iogearbox.net>

[ Upstream commit 3b55f350c68a0aceff108f47f9d31f47ebffaf7b ]

Cilium generates ICMP "frag needed" replies from BPF when a LB DSR
packet exceeds the egress MTU. The reply is built by first trimming the
packet down to target size via bpf_skb_change_tail(), and then pushing
the ICMP error headers in front of it.

The trim is rejected for skbs which carry a checksum offload, e.g. TCP
packets aggregated by GRO on ingress where tcp_gro_complete() leaves
the skb as CHECKSUM_PARTIAL. __bpf_skb_min_len() raises the minimum
length to the end of the L4 checksum field, so a trim to 42 bytes bails
out with -EINVAL given a min_len of 52 in this case, and due to that
the ICMP generator fails. This is not the case if GRO is turned off.

Fix this bpf_skb_change_tail() restriction and drop the checksum offload
when the new length no longer covers the checksum field. The BPF program
rewrites the skb into an ICMP error and computes the checksum itself
anyway.

Fixes: 5293efe62df8 ("bpf: add bpf_skb_change_tail helper")
Reported-by: Tom Hadlaw <tom.hadlaw@isovalent.com>
Reported-by: Yusuke Suzuki <yusuke.suzuki@isovalent.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/r/20260907121025.1923656-1-daniel@iogearbox.net
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/filter.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/net/core/filter.c b/net/core/filter.c
index e0f757ffcfc5b..9a6106ae7bb55 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -3833,12 +3833,6 @@ static u32 __bpf_skb_min_len(const struct sk_buff *skb)
 		if (offset > 0)
 			min_len = offset;
 	}
-	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		offset = skb_checksum_start_offset(skb) +
-			 skb->csum_offset + sizeof(__sum16);
-		if (offset > 0)
-			min_len = offset;
-	}
 	return min_len;
 }
 
@@ -3855,6 +3849,11 @@ static int bpf_skb_grow_rcsum(struct sk_buff *skb, unsigned int new_len)
 
 static int bpf_skb_trim_rcsum(struct sk_buff *skb, unsigned int new_len)
 {
+	if (skb->ip_summed == CHECKSUM_PARTIAL &&
+	    new_len < skb_checksum_start_offset(skb) + skb->csum_offset +
+		      sizeof(__sum16))
+		skb->ip_summed = CHECKSUM_NONE;
+
 	return __skb_trim_rcsum(skb, new_len);
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 302/877] bpf: Disallow bpf_skb_pull_data() for LWT_SEG6LOCAL
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (300 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 301/877] bpf: Fix bpf_skb_change_tail wrt csum partial skbs Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 303/877] selftests/ftrace: Fix unique symbol check in kprobe_non_uniq_symbol.tc Greg Kroah-Hartman
                   ` (582 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, co+adfca3e91be95776,
	Alexei Starovoitov, Weiming Shi, Daniel Borkmann, Emil Tsalapatis,
	Sasha Levin

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

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

From: Weiming Shi <bestswngs@gmail.com>

[ Upstream commit e4a62833adff6ef0fe7c0b90393204fe3c26b5c5 ]

An LWT_SEG6LOCAL program can invalidate its cached SRH with
bpf_lwt_seg6_adjust_srh() and then call bpf_skb_pull_data(). The latter
may reallocate skb->head, leaving the per-CPU SRH pointer dangling.
Post-program SRH validation then writes through that pointer.

Disallow bpf_skb_pull_data() for LWT_SEG6LOCAL programs so the verifier
rejects this unsafe helper combination. Other LWT program types continue
to expose the helper through lwt_out_func_proto().

Fixes: 004d4b274e2a ("ipv6: sr: Add seg6local action End.BPF")
Reported-by: co+adfca3e91be95776@bugs.sh
Suggested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Closes: https://lore.kernel.org/all/GCy0KRM2IcQGoJQTjJEU9D0maBxXzEDHuQpq@bugs.sh/
Link: https://lore.kernel.org/bpf/DL9COXZQXX4V.1FN45QO2Q77ZH@gmail.com/
Link: https://lore.kernel.org/bpf/20260909040807.3885815-2-bestswngs@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/filter.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/net/core/filter.c b/net/core/filter.c
index 9a6106ae7bb55..e1d0a9bdde87e 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -8666,6 +8666,8 @@ static const struct bpf_func_proto *
 lwt_seg6local_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 {
 	switch (func_id) {
+	case BPF_FUNC_skb_pull_data:
+		return NULL;
 #if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
 	case BPF_FUNC_lwt_seg6_store_bytes:
 		return &bpf_lwt_seg6_store_bytes_proto;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 303/877] selftests/ftrace: Fix unique symbol check in kprobe_non_uniq_symbol.tc
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (301 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 302/877] bpf: Disallow bpf_skb_pull_data() for LWT_SEG6LOCAL Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 304/877] bpf: Fix divide-by-zero in btf_struct_walk() Greg Kroah-Hartman
                   ` (581 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sven Schnelle, Steven Rostedt,
	Masami Hiramatsu (Google), Sasha Levin

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

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

From: Sven Schnelle <svens@linux.ibm.com>

[ Upstream commit d22c3e0088e85be8131f7a9283f759cdbb20726d ]

The current regex also matches symbols in modules, which makes the
test fail on s390 where name_show is present only once in the kernel,
but also multiple times in modules:

000001b1401cdc20 t name_show
000001b0c05e6c40 t name_show    [mdev]
000001b0c0495f30 t name_show    [i2c_core]

Fix this by changing the regular expression to only match the function
name.

Link: https://lore.kernel.org/all/20260909092954.2200558-1-svens@linux.ibm.com/

Fixes: 03b80ff8023a ("selftests/ftrace: Add new test case which checks non unique symbol")
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 .../selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc
index bc9514428dbaf..07b1177c16344 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_non_uniq_symbol.tc
@@ -6,7 +6,7 @@
 SYMBOL='name_show'
 
 # We skip this test on kernel where SYMBOL is unique or does not exist.
-if [ "$(grep -c -E "[[:alnum:]]+ t ${SYMBOL}" /proc/kallsyms)" -le '1' ]; then
+if [ "$(grep -c -E "[[:alnum:]]+ t ${SYMBOL}$" /proc/kallsyms)" -le '1' ]; then
 	exit_unsupported
 fi
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 304/877] bpf: Fix divide-by-zero in btf_struct_walk()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (302 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 303/877] selftests/ftrace: Fix unique symbol check in kprobe_non_uniq_symbol.tc Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 305/877] bpf: Fix out-of-bounds read of sk_protocol in bpf_sock_destroy() Greg Kroah-Hartman
                   ` (580 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jiayuan Chen, Eduard Zingerman,
	Alexei Starovoitov, Sasha Levin

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

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

From: Jiayuan Chen <jiayuan.chen@linux.dev>

[ Upstream commit b0b3dc66529676228cb938cbcad66920f735c223 ]

When an access goes past the struct and the last member is a flexible
array, btf_struct_walk() folds the offset back into a single element with
(off - moff) % t->size, but never checks that the element type has a size.

BTF takes an empty struct, so this in program BTF

	/* event could be empty */
	struct event {
 #ifdef HAVE_TIMESTAMP
		__u64 ts;
 #endif
	};

	struct batch {
		int nr;
		struct event events[];
	};

divides by zero at prog load time. Getting there needs a PTR_TO_BTF_ID that
is not MEM_ALLOC, e.g. a plain read of a local kptr stashed in a map from a
sleepable program.

Oops: divide error: 0000 [#1] SMP KASAN PTI
RIP: 0010:btf_struct_walk+0x53f/0x1570
Call Trace:
 <TASK>
 btf_struct_access+0x42a/0xcd0
 check_ptr_to_btf_access+0x4dc/0x1160
 check_mem_access+0x3a45/0x8740
 check_load_mem+0x36a/0xd10
 do_check_common+0x3ef0/0xb210
 bpf_check+0x6d3b/0x8580
 bpf_prog_load+0xf7c/0x2720
 __sys_bpf+0xa83/0x3690
 __x64_sys_bpf+0xc7/0x150
 x64_sys_call+0x1f3f/0x27e0
 do_syscall_64+0xe5/0x610
 entry_SYSCALL_64_after_hwframe+0x76/0x7e
 </TASK>

Reject a zero-sized element type. The fixed array path in the same function
already bails out on the same thing:

	btf_struct_walk()
	...
		/* skip empty array */
		if (moff == mtrue_end)
			continue;

		msize /= total_nelems;

Fixes: 9c5f8a1008a1 ("bpf: Support variable length array in tracing programs")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260910122316.186384-1-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/btf.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index f219a03ceefff..0c040c2e8c4f5 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -6851,7 +6851,7 @@ static int btf_struct_walk(struct bpf_verifier_log *log, const struct btf *btf,
 		if (btf_type_is_int(t))
 			return WALK_SCALAR;
 
-		if (!btf_type_is_struct(t))
+		if (!btf_type_is_struct(t) || !t->size)
 			goto error;
 
 		off = (off - moff) % t->size;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 305/877] bpf: Fix out-of-bounds read of sk_protocol in bpf_sock_destroy()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (303 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 304/877] bpf: Fix divide-by-zero in btf_struct_walk() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 306/877] tcp: Skip cond_resched() in inet_csk_listen_stop() under BPF context Greg Kroah-Hartman
                   ` (579 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Xiang Mei (Microsoft), Jiayuan Chen,
	Kuniyuki Iwashima, Alexei Starovoitov, Sasha Levin

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

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

From: Jiayuan Chen <jiayuan.chen@linux.dev>

[ Upstream commit 01b245ba016d44861690594e10f67e026ce8552f ]

sk_protocol lives in struct sock, not in struct sock_common. A timewait
or request sock handed to bpf_sock_destroy() by the tcp iterator is
neither, so reading sk->sk_protocol runs past the object:

==================================================================
BUG: KASAN: slab-out-of-bounds in bpf_sock_destroy+0xc7/0xe0
Read of size 2 at addr ffff8881047d11b4 by task test_progs/428

Tainted: [W]=WARN
Call Trace:
 <TASK>
 dump_stack_lvl+0x91/0xf0
 print_report+0xd1/0x630
 kasan_report+0xf3/0x130
 __asan_report_load2_noabort+0x14/0x30
 bpf_sock_destroy+0xc7/0xe0
 bpf_prog_c3dd61f9d9cd9f37_iter_tcp6_timewait+0x9f/0xb7
 bpf_iter_run_prog+0x538/0xde0
 bpf_iter_tcp_seq_show+0x26b/0x4b0
 bpf_seq_read+0x424/0x1210
 vfs_read+0x197/0xe40
 ksys_read+0x119/0x240
 __x64_sys_read+0x72/0xc0
 x64_sys_call+0x647/0x27e0
 do_syscall_64+0xe5/0x610
 entry_SYSCALL_64_after_hwframe+0x76/0x7e

Only check sk_protocol on full socks. tcp_abort() already knows how to
deal with TIME_WAIT and NEW_SYN_RECV socks. Also fix the comment, it
never matched the code.

Fixes: 4ddbcb886268 ("bpf: Add bpf_sock_destroy kfunc")
Reported-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
Closes: https://lore.kernel.org/bpf/20260702224519.800135-1-xmei5@asu.edu/
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://lore.kernel.org/r/20260910112634.152195-1-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/filter.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/net/core/filter.c b/net/core/filter.c
index e1d0a9bdde87e..25777837af690 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -12262,8 +12262,9 @@ __bpf_kfunc_start_defs();
  * @sock: Pointer to socket to be destroyed
  *
  * Return:
- * On error, may return EPROTONOSUPPORT, EINVAL.
- * EPROTONOSUPPORT if protocol specific destroy handler is not supported.
+ * On error, may return EOPNOTSUPP, or whatever the protocol specific
+ * destroy handler returns.
+ * EOPNOTSUPP if protocol specific destroy handler is not supported.
  * 0 otherwise
  */
 __bpf_kfunc int bpf_sock_destroy(struct sock_common *sock)
@@ -12275,8 +12276,12 @@ __bpf_kfunc int bpf_sock_destroy(struct sock_common *sock)
 	 * Supporting protocols will need to acquire sock lock in the BPF context
 	 * prior to invoking this kfunc.
 	 */
-	if (!sk->sk_prot->diag_destroy || (sk->sk_protocol != IPPROTO_TCP &&
-					   sk->sk_protocol != IPPROTO_UDP))
+	if (!sk->sk_prot->diag_destroy)
+		return -EOPNOTSUPP;
+
+	if (sk_fullsock(sk) &&
+	    sk->sk_protocol != IPPROTO_TCP &&
+	    sk->sk_protocol != IPPROTO_UDP)
 		return -EOPNOTSUPP;
 
 	return sk->sk_prot->diag_destroy(sk, ECONNABORTED);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 306/877] tcp: Skip cond_resched() in inet_csk_listen_stop() under BPF context
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (304 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 305/877] bpf: Fix out-of-bounds read of sk_protocol in bpf_sock_destroy() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 307/877] HID: elecom: fix bus type for M-XGL20DLBK Greg Kroah-Hartman
                   ` (578 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jiayuan Chen, Alexei Starovoitov,
	Sasha Levin

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

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

From: Jiayuan Chen <jiayuan.chen@linux.dev>

[ Upstream commit eaab8cab451b9502ce224cd202550375b894a467 ]

bpf_sock_destroy() runs from the tcp iterator, under rcu_read_lock(). If
the sock is a listener that still has children in its accept queue,
tcp_abort() ends up in inet_csk_listen_stop() and the cond_resched()
there trips the debug check:

BUG: sleeping function called from invalid context at net/ipv4/inet_connection_sock.c:1523
in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 628, name: test_progs
preempt_count: 0, expected: 0
RCU nest depth: 1, expected: 0
locks held by test_progs/628: 3, last CPU#3:
 #0: ffff8881158cee18 (&p->lock){+.+.}-{4:4}, at: bpf_seq_read+0x56/0x1210
 #1: ffff8881106bb858 (sk_lock-AF_INET6){+.+.}-{0:0}, at: bpf_iter_tcp_seq_show+0x32b/0x4b0
 #2: ffffffffb435af20 (rcu_read_lock){....}-{1:3}, at: bpf_iter_run_prog+0x46b/0xde0
CPU: 3 UID: 0 PID: 628 Comm: test_progs Tainted: G        W           7.2.0+ #65 PREEMPT
Tainted: [W]=WARN
Call Trace:
 <TASK>
 dump_stack_lvl+0xc1/0xf0
 dump_stack+0x10/0x20
 __might_resched+0x3d2/0x610
 inet_csk_listen_stop+0x7b/0xbf0
 tcp_abort+0x23b/0x3b0
 bpf_sock_destroy+0xfc/0x140
 bpf_prog_448133d24601754f_iter_tcp6_server+0x81/0x8a
 bpf_iter_run_prog+0x538/0xde0
 bpf_iter_tcp_seq_show+0x26b/0x4b0
 bpf_seq_read+0x424/0x1210
 vfs_read+0x197/0xe40
 ksys_read+0x119/0x240
 __x64_sys_read+0x72/0xc0
 x64_sys_call+0x647/0x27e0
 do_syscall_64+0xe5/0x610
 entry_SYSCALL_64_after_hwframe+0x76/0x7e
RIP: 0033:0x7fad39b28aca
RSP: 002b:00007ffc381c61c0 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
RAX: ffffffffffffffda RBX: 00007ffc381c6a88 RCX: 00007fad39b28aca
RDX: 0000000000000032 RSI: 00007ffc381c6250 RDI: 0000000000000014
RBP: 00007ffc381c61e0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000003
R13: 0000000000000000 R14: 000055f077c1bbb0 R15: 00007fad3a0f3000
 </TASK>

The commit that added the kfunc already guards lock_sock() in tcp_abort()
and udp_abort() with has_current_bpf_ctx(), but missed the listener path.
Do the same for the cond_resched(). The loop runs inside the iterator's
rcu_read_lock(), it must not reschedule or report a quiescent state there.

Fixes: 4ddbcb886268 ("bpf: Add bpf_sock_destroy kfunc")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://lore.kernel.org/r/20260910112736.153710-1-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv4/inet_connection_sock.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 117a424d1fee3..632434743683e 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -1541,7 +1541,8 @@ void inet_csk_listen_stop(struct sock *sk)
 		local_bh_enable();
 		sock_put(child);
 
-		cond_resched();
+		if (!has_current_bpf_ctx())
+			cond_resched();
 	}
 	if (queue->fastopenq.rskq_rst_head) {
 		/* Free all the reqs queued in rskq_rst_head. */
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 307/877] HID: elecom: fix bus type for M-XGL20DLBK
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (305 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 306/877] tcp: Skip cond_resched() in inet_csk_listen_stop() under BPF context Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 308/877] KVM: x86/pmu: Move Intel PMU global MSRs to intel_is_valid_msr() Greg Kroah-Hartman
                   ` (577 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Oscar Priego Verdugo, Jiri Kosina,
	Sasha Levin

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

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

From: Oscar Priego Verdugo <oscar.priegov@gmail.com>

[ Upstream commit 8e2a4b458ad25e13422bb059758c30a6562aa9cf ]

The M-XGL20DLBK is matched as a USB device by hid-elecom, but
its entry in hid_have_special_driver[] uses HID_BLUETOOTH_DEVICE.

This prevents the special-driver quirk entry from matching the USB
device handled by hid-elecom. Use HID_USB_DEVICE there as well.

Fixes: 55633e681afb ("HID: elecom: add support for EX-G M-XGL20DLBK wireless mouse")
Signed-off-by: Oscar Priego Verdugo <oscar.priegov@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/hid/hid-quirks.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index 39d81777cb7e2..2f086ac897605 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -416,7 +416,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
 #endif
 #if IS_ENABLED(CONFIG_HID_ELECOM)
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
-	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AC) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) },
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 308/877] KVM: x86/pmu: Move Intel PMU global MSRs to intel_is_valid_msr()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (306 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 307/877] HID: elecom: fix bus type for M-XGL20DLBK Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 309/877] bpf: Avoid soft lockup in __htab_map_lookup_and_delete_batch() Greg Kroah-Hartman
                   ` (576 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jim Mattson, Like Xu, Sandipan Das,
	Sean Christopherson, Sasha Levin

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

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

From: Jim Mattson <jmattson@google.com>

[ Upstream commit 79a71cc2568f4b5d42284da2aa26f3b4f47ce01b ]

Commit c85cdc1cc1ea ("KVM: x86/pmu: Move handling PERF_GLOBAL_CTRL and
friends to common x86") moved the existence check for the following Intel
PMU MSRs to kvm_pmu_is_valid_msr():
 - MSR_CORE_PERF_GLOBAL_STATUS
 - MSR_CORE_PERF_GLOBAL_CTRL
 - MSR_CORE_PERF_GLOBAL_OVF_CTRL

That commit deemed these MSRs valid whenever pmu->version > 1. It intended
to share the check with AMD PerfMonV2 because both vendor implementations
require version 2 or greater for global PMU controls.  However, as noted in
the commit message, AMD uses different MSR indices for its global PMU
registers.

Commit 4a2771895ca6 ("KVM: x86/svm/pmu: Add AMD PerfMonV2 support")
subsequently added AMD PerfMonV2 support and set pmu->version = 2.  Because
kvm_pmu_is_valid_msr() validated the Intel MSRs whenever pmu->version > 1,
KVM incorrectly permitted AMD guests with PerfMonV2 to access these Intel
MSRs without a #GP.

Move the validation of these Intel MSRs to intel_is_valid_msr() and remove
the common switch statement from kvm_pmu_is_valid_msr(). AMD already
validates its own global PMU MSRs in amd_is_valid_msr().

Fixes: 4a2771895ca6 ("KVM: x86/svm/pmu: Add AMD PerfMonV2 support")
Signed-off-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Like Xu <likexu@tencent.com>
Reviewed-by: Sandipan Das <sandipan.das@amd.com>
Link: https://patch.msgid.link/20260902184711.138538-1-jmattson@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/x86/kvm/pmu.c           | 8 --------
 arch/x86/kvm/vmx/pmu_intel.c | 3 +++
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
index a26e8f5ad7901..a0efe59aa0794 100644
--- a/arch/x86/kvm/pmu.c
+++ b/arch/x86/kvm/pmu.c
@@ -614,14 +614,6 @@ void kvm_pmu_deliver_pmi(struct kvm_vcpu *vcpu)
 
 bool kvm_pmu_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
 {
-	switch (msr) {
-	case MSR_CORE_PERF_GLOBAL_STATUS:
-	case MSR_CORE_PERF_GLOBAL_CTRL:
-	case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
-		return kvm_pmu_has_perf_global_ctrl(vcpu_to_pmu(vcpu));
-	default:
-		break;
-	}
 	return kvm_pmu_call(msr_idx_to_pmc)(vcpu, msr) ||
 	       kvm_pmu_call(is_valid_msr)(vcpu, msr);
 }
diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
index a5edc623166ac..4f6fa564028f8 100644
--- a/arch/x86/kvm/vmx/pmu_intel.c
+++ b/arch/x86/kvm/vmx/pmu_intel.c
@@ -154,6 +154,9 @@ static bool intel_is_valid_msr(struct kvm_vcpu *vcpu, u32 msr)
 	int ret;
 
 	switch (msr) {
+	case MSR_CORE_PERF_GLOBAL_STATUS:
+	case MSR_CORE_PERF_GLOBAL_CTRL:
+	case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
 	case MSR_CORE_PERF_FIXED_CTR_CTRL:
 		return kvm_pmu_has_perf_global_ctrl(pmu);
 	case MSR_IA32_PEBS_ENABLE:
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 309/877] bpf: Avoid soft lockup in __htab_map_lookup_and_delete_batch()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (307 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 308/877] KVM: x86/pmu: Move Intel PMU global MSRs to intel_is_valid_msr() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 310/877] bpf: Fix out-of-bounds read of rtt_min in sock_ops Greg Kroah-Hartman
                   ` (575 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Paul E. McKenney, Rik van Riel,
	Jose Fernandez (Anthropic), Josef Bacik, Alexei Starovoitov,
	Sasha Levin

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

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

From: Jose Fernandez (Anthropic) <jose.fernandez@linux.dev>

[ Upstream commit 85136bf22404474a815fc0ed26ec0d1cbc1bc3f9 ]

__htab_map_lookup_and_delete_batch() has no rescheduling point. The
batch count bounds how many entries are copied out, not how many
buckets are visited, so one BPF_MAP_LOOKUP_BATCH call can walk the
map end to end. The empty-bucket fast path is worse: it stays inside
a single rcu_read_lock() / bpf_disable_instrumentation() section for
any run of consecutive empty buckets.

That holds up on small maps, but it falls apart at scale. On a
144-CPU arm64 host running a CONFIG_PREEMPT_NONE kernel, periodic
BPF_MAP_LOOKUP_BATCH calls against an LRU hash map with 16,777,216
buckets held a CPU inside the batch op for 77+ seconds and triggered
the soft lockup watchdog.

Commit 75134f16e7dd ("bpf: Add schedule points in batch ops") fixed this
same problem in the generic batch ops, but not in this htab-native path,
which every htab-based hash map variant uses for its lookup[_and_delete]
batch ops.

Complete that fix here. Leave the critical section after 64 consecutive
empty buckets, call cond_resched_tasks_rcu_qs(), and resume at the saved
bucket cursor. No locks are held at that point, and resuming from the
cursor is already the function's behavior for non-empty buckets. Add the
same call to the per-bucket loop after copy_to_user(), where every lock
has been dropped. cond_resched_rcu() is not enough here: sleeping with
bpf_prog_active elevated makes tracing programs on that CPU silently
skip their invocations.

Plain cond_resched() is not enough either. It is a no-op under PREEMPT
and PREEMPT_LAZY, the only models arm64 and x86 have offered since
commit 7dadeaa6e851 ("sched: Further restrict the preemption modes").
It is also never a Tasks RCU quiescent state, in any model: the
reschedule counts as a preemption. The walking task stays a holdout and
stalls every synchronize_rcu_tasks() caller, ftrace and BPF trampoline
teardown included, until the syscall returns [1].
cond_resched_tasks_rcu_qs() is the usual tool for that [2]. It reports
the quiescent state at each yield and still reschedules as
cond_resched() does on PREEMPT_NONE and PREEMPT_VOLUNTARY kernels.

Fixes: 057996380a42 ("bpf: Add batch ops to all htab bpf map")
Cc: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Rik van Riel <riel@surriel.com>
Link: https://lore.kernel.org/bpf/20260715215314.44423f47@fangorn/ [1]
Link: https://lore.kernel.org/bpf/9d444098-7c03-4163-af12-bd0a79a51443@paulmck-laptop/ [2]
Assisted-by: LLM
Signed-off-by: Jose Fernandez (Anthropic) <jose.fernandez@linux.dev>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Rik van Riel <riel@surriel.com>
Link: https://lore.kernel.org/r/20260909-b4-htab-batch-resched-v2-1-0cb529d8f95a@toxicpanda.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/hashtab.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 66eaf95f9dbea..49db2d0e32157 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -1706,6 +1706,12 @@ static int htab_lru_percpu_map_lookup_and_delete_elem(struct bpf_map *map,
 						 flags);
 }
 
+/*
+ * Max consecutive empty buckets to walk in one RCU +
+ * instrumentation-disabled section before rescheduling.
+ */
+#define HTAB_BATCH_EMPTY_RESCHED 64
+
 static int
 __htab_map_lookup_and_delete_batch(struct bpf_map *map,
 				   const union bpf_attr *attr,
@@ -1727,6 +1733,7 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,
 	unsigned long flags = 0;
 	bool locked = false;
 	struct htab_elem *l;
+	u32 empty_cnt = 0;
 	struct bucket *b;
 	int ret = 0;
 
@@ -1896,12 +1903,21 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,
 	}
 
 next_batch:
-	/* If we are not copying data, we can go to next bucket and avoid
-	 * unlocking the rcu.
+	/*
+	 * If we are not copying data, we can go to next bucket and avoid
+	 * unlocking the rcu. Bound the walk though: after
+	 * HTAB_BATCH_EMPTY_RESCHED consecutive empty buckets, fully exit
+	 * the critical section (no locks are held here) and reschedule.
 	 */
 	if (!bucket_cnt && (batch + 1 < htab->n_buckets)) {
 		batch++;
-		goto again_nocopy;
+		if (++empty_cnt < HTAB_BATCH_EMPTY_RESCHED)
+			goto again_nocopy;
+		empty_cnt = 0;
+		rcu_read_unlock();
+		bpf_enable_instrumentation();
+		cond_resched_tasks_rcu_qs();
+		goto again;
 	}
 
 	rcu_read_unlock();
@@ -1915,11 +1931,13 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,
 	}
 
 	total += bucket_cnt;
+	empty_cnt = 0;
 	batch++;
 	if (batch >= htab->n_buckets) {
 		ret = -ENOENT;
 		goto after_loop;
 	}
+	cond_resched_tasks_rcu_qs();
 	goto again;
 
 after_loop:
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 310/877] bpf: Fix out-of-bounds read of rtt_min in sock_ops
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (308 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 309/877] bpf: Avoid soft lockup in __htab_map_lookup_and_delete_batch() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 311/877] bpf: Remove migrate_{disable|enable} in ->map_for_each_callback Greg Kroah-Hartman
                   ` (574 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, VEGA, Jiayuan Chen, Emil Tsalapatis,
	Alexei Starovoitov, Sasha Levin

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

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

From: Jiayuan Chen <jiayuan.chen@linux.dev>

[ Upstream commit 75f8cf22463d82bb1fb0239a3d485fc8f4c8ef03 ]

A sockops prog reading skops->rtt_min never checks the sk type: on the
tcp_conn_request() path sock_ops->sk is a request_sock (non-full), and the
ctx rewrite casts it to a tcp_sock (full) and reads rtt_min past the end of
the request_sock, returning dirty adjacent memory.

	SEC("sockops")
	int prog(struct bpf_sock_ops *skops)
	{
		switch (skops->op) {
		case BPF_SOCK_OPS_RWND_INIT:
			leak = skops->rtt_min;   /* reads the request_sock OOB */
		...
		}
	}

For instance one such read returned rtt_min=0xffff8881, the high half of a
leaked kernel pointer.

Guarding that cast is exactly what SOCK_OPS_GET_FIELD() does -- it checks
is_locked_tcp_sock and returns 0 when sock_ops->sk is not a locked full
socket. Every other tcp_sock field in sock_ops goes through it; rtt_min is
the only one open-coded, so it skips the check.

Read rtt_min through SOCK_OPS_GET_FIELD() too. rtt_min is a bit special:
it is a struct minmax and we only want the current min, so pass
rtt_min.s[0].v. That is equivalent to the old hand-computed offset

	offsetof(struct tcp_sock, rtt_min) + sizeof_field(struct minmax_sample, t)

(s[0] sits at rtt_min + 0 and .v at + sizeof(.t), i.e. what minmax_get()
returns), so the loaded field is unchanged and only the full-sock guard is
added. The two BUILD_BUG_ON()s that protected the hand-computed offset
are no longer needed.

Before patch:

	0: r1 = *(u64 *)(r1 +0)      ; r1 = skops->sk
	1: r1 = *(u32 *)(r1 +2324)   ; ((tcp_sock *)sk)->rtt_min.s[0].v

After patch:

	0: *(u64 *)(r1 +56) = r9
	1: r9 = *(u8 *)(r1 +50)      ; is_locked_tcp_sock
	2: if r9 == 0 goto pc+4      ; not a locked full sock -> 0
	3: r9 = *(u64 *)(r1 +56)
	4: r1 = *(u64 *)(r1 +0)      ; r1 = skops->sk
	5: r1 = *(u32 *)(r1 +2324)   ; rtt_min.s[0].v
	6: goto pc+2
	7: r9 = *(u64 *)(r1 +56)
	8: r1 = 0

Fixes: 44f0e43037d3 ("bpf: Add support for reading sk_state and more")
Reported-by: VEGA <vega@nebusec.ai>
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Link: https://lore.kernel.org/r/20260903100921.113374-1-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/filter.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/net/core/filter.c b/net/core/filter.c
index 25777837af690..7114a64e1898e 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -10731,18 +10731,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
 		break;
 
 	case offsetof(struct bpf_sock_ops, rtt_min):
-		BUILD_BUG_ON(sizeof_field(struct tcp_sock, rtt_min) !=
-			     sizeof(struct minmax));
-		BUILD_BUG_ON(sizeof(struct minmax) <
-			     sizeof(struct minmax_sample));
-
-		*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
-						struct bpf_sock_ops_kern, sk),
-				      si->dst_reg, si->src_reg,
-				      offsetof(struct bpf_sock_ops_kern, sk));
-		*insn++ = BPF_LDX_MEM(BPF_W, si->dst_reg, si->dst_reg,
-				      offsetof(struct tcp_sock, rtt_min) +
-				      sizeof_field(struct minmax_sample, t));
+		SOCK_OPS_GET_FIELD(rtt_min, rtt_min.s[0].v, struct tcp_sock);
 		break;
 
 	case offsetof(struct bpf_sock_ops, bpf_sock_ops_cb_flags):
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 311/877] bpf: Remove migrate_{disable|enable} in ->map_for_each_callback
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (309 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 310/877] bpf: Fix out-of-bounds read of rtt_min in sock_ops Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 312/877] bpf: Bail out early in __htab_map_lookup_and_delete_elem() Greg Kroah-Hartman
                   ` (573 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Hou Tao, Alexei Starovoitov,
	Sasha Levin

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

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

From: Hou Tao <houtao1@huawei.com>

[ Upstream commit ea5b229630a631ee6a72e1f58bc40029efc1daf8 ]

BPF program may call bpf_for_each_map_elem(), and it will call
the ->map_for_each_callback callback of related bpf map. Considering the
running context of bpf program has already disabled migration, remove
the unnecessary migrate_{disable|enable} pair in the implementations of
->map_for_each_callback. To ensure the guarantee will not be voilated
later, also add cant_migrate() check in the implementations.

Signed-off-by: Hou Tao <houtao1@huawei.com>
Link: https://lore.kernel.org/r/20250108010728.207536-3-houtao@huaweicloud.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Stable-dep-of: 1c21452d02ee ("bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/arraymap.c |  6 ++----
 kernel/bpf/hashtab.c  | 11 +++++------
 2 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index 7ec69545fe056..fcc0ca7ee8831 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -735,13 +735,13 @@ static long bpf_for_each_array_elem(struct bpf_map *map, bpf_callback_t callback
 	u64 ret = 0;
 	void *val;
 
+	cant_migrate();
+
 	if (flags != 0)
 		return -EINVAL;
 
 	is_percpu = map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY;
 	array = container_of(map, struct bpf_array, map);
-	if (is_percpu)
-		migrate_disable();
 	for (i = 0; i < map->max_entries; i++) {
 		if (is_percpu)
 			val = this_cpu_ptr(array->pptrs[i]);
@@ -756,8 +756,6 @@ static long bpf_for_each_array_elem(struct bpf_map *map, bpf_callback_t callback
 			break;
 	}
 
-	if (is_percpu)
-		migrate_enable();
 	return num_elems;
 }
 
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 49db2d0e32157..6df745abb88a7 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -2225,17 +2225,18 @@ static long bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_
 	bool is_percpu;
 	u64 ret = 0;
 
+	cant_migrate();
+
 	if (flags != 0)
 		return -EINVAL;
 
 	is_percpu = htab_is_percpu(htab);
 
 	roundup_key_size = round_up(map->key_size, 8);
-	/* disable migration so percpu value prepared here will be the
-	 * same as the one seen by the bpf program with bpf_map_lookup_elem().
+	/* migration has been disabled, so percpu value prepared here will be
+	 * the same as the one seen by the bpf program with
+	 * bpf_map_lookup_elem().
 	 */
-	if (is_percpu)
-		migrate_disable();
 	for (i = 0; i < htab->n_buckets; i++) {
 		b = &htab->buckets[i];
 		rcu_read_lock();
@@ -2261,8 +2262,6 @@ static long bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_
 		rcu_read_unlock();
 	}
 out:
-	if (is_percpu)
-		migrate_enable();
 	return num_elems;
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 312/877] bpf: Bail out early in __htab_map_lookup_and_delete_elem()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (310 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 311/877] bpf: Remove migrate_{disable|enable} in ->map_for_each_callback Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 313/877] bpf: Factor out htab_elem_value helper() Greg Kroah-Hartman
                   ` (572 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Hou Tao,
	Toke Høiland-Jørgensen, Alexei Starovoitov, Sasha Levin

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

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

From: Hou Tao <houtao1@huawei.com>

[ Upstream commit 588c6ead325aecc9894c9925cf1f771b77437bee ]

Use goto statement to bail out early when the target element is not
found, instead of using a large else branch to handle the more likely
case. This change doesn't affect functionality and simply make the code
cleaner.

Signed-off-by: Hou Tao <houtao1@huawei.com>
Reviewed-by: Toke Høiland-Jørgensen <toke@kernel.org>
Link: https://lore.kernel.org/r/20250117101816.2101857-3-houtao@huaweicloud.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Stable-dep-of: 1c21452d02ee ("bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/hashtab.c | 51 ++++++++++++++++++++++----------------------
 1 file changed, 26 insertions(+), 25 deletions(-)

diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 6df745abb88a7..22cc255519ce8 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -1637,37 +1637,38 @@ static int __htab_map_lookup_and_delete_elem(struct bpf_map *map, void *key,
 	l = lookup_elem_raw(head, hash, key, key_size);
 	if (!l) {
 		ret = -ENOENT;
-	} else {
-		if (is_percpu) {
-			u32 roundup_value_size = round_up(map->value_size, 8);
-			void __percpu *pptr;
-			int off = 0, cpu;
+		goto out_unlock;
+	}
 
-			pptr = htab_elem_get_ptr(l, key_size);
-			for_each_possible_cpu(cpu) {
-				copy_map_value_long(&htab->map, value + off, per_cpu_ptr(pptr, cpu));
-				check_and_init_map_value(&htab->map, value + off);
-				off += roundup_value_size;
-			}
-		} else {
-			u32 roundup_key_size = round_up(map->key_size, 8);
+	if (is_percpu) {
+		u32 roundup_value_size = round_up(map->value_size, 8);
+		void __percpu *pptr;
+		int off = 0, cpu;
 
-			if (flags & BPF_F_LOCK)
-				copy_map_value_locked(map, value, l->key +
-						      roundup_key_size,
-						      true);
-			else
-				copy_map_value(map, value, l->key +
-					       roundup_key_size);
-			/* Zeroing special fields in the temp buffer */
-			check_and_init_map_value(map, value);
+		pptr = htab_elem_get_ptr(l, key_size);
+		for_each_possible_cpu(cpu) {
+			copy_map_value_long(&htab->map, value + off, per_cpu_ptr(pptr, cpu));
+			check_and_init_map_value(&htab->map, value + off);
+			off += roundup_value_size;
 		}
+	} else {
+		u32 roundup_key_size = round_up(map->key_size, 8);
 
-		hlist_nulls_del_rcu(&l->hash_node);
-		if (!is_lru_map)
-			free_htab_elem(htab, l);
+		if (flags & BPF_F_LOCK)
+			copy_map_value_locked(map, value, l->key +
+					      roundup_key_size,
+					      true);
+		else
+			copy_map_value(map, value, l->key +
+				       roundup_key_size);
+		/* Zeroing special fields in the temp buffer */
+		check_and_init_map_value(map, value);
 	}
+	hlist_nulls_del_rcu(&l->hash_node);
+	if (!is_lru_map)
+		free_htab_elem(htab, l);
 
+out_unlock:
 	htab_unlock_bucket(htab, b, hash, bflags);
 
 	if (is_lru_map && l)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 313/877] bpf: Factor out htab_elem_value helper()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (311 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 312/877] bpf: Bail out early in __htab_map_lookup_and_delete_elem() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 314/877] bpf: Register dtor for freeing special fields Greg Kroah-Hartman
                   ` (571 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Andrii Nakryiko, Hou Tao,
	Alexei Starovoitov, Sasha Levin

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

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

From: Hou Tao <houtao1@huawei.com>

[ Upstream commit ba2b31b0f39fca12abbd21c53a92838bbc026023 ]

All hash maps store map key and map value together. The relative offset
of the map value compared to the map key is round_up(key_size, 8).
Therefore, factor out a common helper htab_elem_value() to calculate the
address of the map value instead of duplicating the logic.

Acked-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Hou Tao <houtao1@huawei.com>
Link: https://lore.kernel.org/r/20250401062250.543403-2-houtao@huaweicloud.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Stable-dep-of: 1c21452d02ee ("bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/hashtab.c | 64 +++++++++++++++++++++-----------------------
 1 file changed, 30 insertions(+), 34 deletions(-)

diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 22cc255519ce8..0d1aeafe5eb14 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -195,20 +195,25 @@ static bool htab_is_percpu(const struct bpf_htab *htab)
 		htab->map.map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH;
 }
 
+static inline void *htab_elem_value(struct htab_elem *l, u32 key_size)
+{
+	return l->key + round_up(key_size, 8);
+}
+
 static inline void htab_elem_set_ptr(struct htab_elem *l, u32 key_size,
 				     void __percpu *pptr)
 {
-	*(void __percpu **)(l->key + roundup(key_size, 8)) = pptr;
+	*(void __percpu **)htab_elem_value(l, key_size) = pptr;
 }
 
 static inline void __percpu *htab_elem_get_ptr(struct htab_elem *l, u32 key_size)
 {
-	return *(void __percpu **)(l->key + roundup(key_size, 8));
+	return *(void __percpu **)htab_elem_value(l, key_size);
 }
 
 static void *fd_htab_map_get_ptr(const struct bpf_map *map, struct htab_elem *l)
 {
-	return *(void **)(l->key + roundup(map->key_size, 8));
+	return *(void **)htab_elem_value(l, map->key_size);
 }
 
 static struct htab_elem *get_htab_elem(struct bpf_htab *htab, int i)
@@ -235,10 +240,10 @@ static void htab_free_prealloced_timers_and_wq(struct bpf_htab *htab)
 		elem = get_htab_elem(htab, i);
 		if (btf_record_has_field(htab->map.record, BPF_TIMER))
 			bpf_obj_free_timer(htab->map.record,
-					   elem->key + round_up(htab->map.key_size, 8));
+					   htab_elem_value(elem, htab->map.key_size));
 		if (btf_record_has_field(htab->map.record, BPF_WORKQUEUE))
 			bpf_obj_free_workqueue(htab->map.record,
-					       elem->key + round_up(htab->map.key_size, 8));
+					       htab_elem_value(elem, htab->map.key_size));
 		cond_resched();
 	}
 }
@@ -265,7 +270,8 @@ static void htab_free_prealloced_fields(struct bpf_htab *htab)
 				cond_resched();
 			}
 		} else {
-			bpf_obj_free_fields(htab->map.record, elem->key + round_up(htab->map.key_size, 8));
+			bpf_obj_free_fields(htab->map.record,
+					    htab_elem_value(elem, htab->map.key_size));
 			cond_resched();
 		}
 		cond_resched();
@@ -703,7 +709,7 @@ static void *htab_map_lookup_elem(struct bpf_map *map, void *key)
 	struct htab_elem *l = __htab_map_lookup_elem(map, key);
 
 	if (l)
-		return l->key + round_up(map->key_size, 8);
+		return htab_elem_value(l, map->key_size);
 
 	return NULL;
 }
@@ -742,7 +748,7 @@ static __always_inline void *__htab_lru_map_lookup_elem(struct bpf_map *map,
 	if (l) {
 		if (mark)
 			bpf_lru_node_set_ref(&l->lru_node);
-		return l->key + round_up(map->key_size, 8);
+		return htab_elem_value(l, map->key_size);
 	}
 
 	return NULL;
@@ -793,7 +799,7 @@ static void check_and_free_fields(struct bpf_htab *htab,
 		for_each_possible_cpu(cpu)
 			bpf_obj_free_fields(htab->map.record, per_cpu_ptr(pptr, cpu));
 	} else {
-		void *map_value = elem->key + round_up(htab->map.key_size, 8);
+		void *map_value = htab_elem_value(elem, htab->map.key_size);
 
 		bpf_obj_free_fields(htab->map.record, map_value);
 	}
@@ -1076,11 +1082,9 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key,
 			htab_elem_set_ptr(l_new, key_size, pptr);
 	} else if (fd_htab_map_needs_adjust(htab)) {
 		size = round_up(size, 8);
-		memcpy(l_new->key + round_up(key_size, 8), value, size);
+		memcpy(htab_elem_value(l_new, key_size), value, size);
 	} else {
-		copy_map_value(&htab->map,
-			       l_new->key + round_up(key_size, 8),
-			       value);
+		copy_map_value(&htab->map, htab_elem_value(l_new, key_size), value);
 	}
 
 	l_new->hash = hash;
@@ -1142,7 +1146,7 @@ static long htab_map_update_elem(struct bpf_map *map, void *key, void *value,
 		if (l_old) {
 			/* grab the element lock and update value in place */
 			copy_map_value_locked(map,
-					      l_old->key + round_up(key_size, 8),
+					      htab_elem_value(l_old, key_size),
 					      value, false);
 			return 0;
 		}
@@ -1170,7 +1174,7 @@ static long htab_map_update_elem(struct bpf_map *map, void *key, void *value,
 		 * and update element in place
 		 */
 		copy_map_value_locked(map,
-				      l_old->key + round_up(key_size, 8),
+				      htab_elem_value(l_old, key_size),
 				      value, false);
 		ret = 0;
 		goto err;
@@ -1255,8 +1259,7 @@ static long htab_lru_map_update_elem(struct bpf_map *map, void *key, void *value
 	l_new = prealloc_lru_pop(htab, key, hash);
 	if (!l_new)
 		return -ENOMEM;
-	copy_map_value(&htab->map,
-		       l_new->key + round_up(map->key_size, 8), value);
+	copy_map_value(&htab->map, htab_elem_value(l_new, map->key_size), value);
 
 	ret = htab_lock_bucket(htab, b, hash, &flags);
 	if (ret)
@@ -1533,10 +1536,10 @@ static void htab_free_malloced_timers_and_wq(struct bpf_htab *htab)
 			/* We only free timer on uref dropping to zero */
 			if (btf_record_has_field(htab->map.record, BPF_TIMER))
 				bpf_obj_free_timer(htab->map.record,
-						   l->key + round_up(htab->map.key_size, 8));
+						   htab_elem_value(l, htab->map.key_size));
 			if (btf_record_has_field(htab->map.record, BPF_WORKQUEUE))
 				bpf_obj_free_workqueue(htab->map.record,
-						       l->key + round_up(htab->map.key_size, 8));
+						       htab_elem_value(l, htab->map.key_size));
 		}
 		cond_resched_rcu();
 	}
@@ -1652,15 +1655,12 @@ static int __htab_map_lookup_and_delete_elem(struct bpf_map *map, void *key,
 			off += roundup_value_size;
 		}
 	} else {
-		u32 roundup_key_size = round_up(map->key_size, 8);
+		void *src = htab_elem_value(l, map->key_size);
 
 		if (flags & BPF_F_LOCK)
-			copy_map_value_locked(map, value, l->key +
-					      roundup_key_size,
-					      true);
+			copy_map_value_locked(map, value, src, true);
 		else
-			copy_map_value(map, value, l->key +
-				       roundup_key_size);
+			copy_map_value(map, value, src);
 		/* Zeroing special fields in the temp buffer */
 		check_and_init_map_value(map, value);
 	}
@@ -1721,12 +1721,12 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,
 				   bool is_percpu)
 {
 	struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
-	u32 bucket_cnt, total, key_size, value_size, roundup_key_size;
 	void *keys = NULL, *values = NULL, *value, *dst_key, *dst_val;
 	void __user *uvalues = u64_to_user_ptr(attr->batch.values);
 	void __user *ukeys = u64_to_user_ptr(attr->batch.keys);
 	void __user *ubatch = u64_to_user_ptr(attr->batch.in_batch);
 	u32 batch, max_count, size, bucket_size, map_id;
+	u32 bucket_cnt, total, key_size, value_size;
 	struct htab_elem *node_to_free = NULL;
 	u64 elem_map_flags, map_flags;
 	struct hlist_nulls_head *head;
@@ -1762,7 +1762,6 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,
 		return -ENOENT;
 
 	key_size = htab->map.key_size;
-	roundup_key_size = round_up(htab->map.key_size, 8);
 	value_size = htab->map.value_size;
 	size = round_up(value_size, 8);
 	if (is_percpu)
@@ -1854,7 +1853,7 @@ __htab_map_lookup_and_delete_batch(struct bpf_map *map,
 				off += size;
 			}
 		} else {
-			value = l->key + roundup_key_size;
+			value = htab_elem_value(l, key_size);
 			if (map->map_type == BPF_MAP_TYPE_HASH_OF_MAPS) {
 				struct bpf_map **inner_map = value;
 
@@ -2116,11 +2115,11 @@ static void *bpf_hash_map_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 static int __bpf_hash_map_seq_show(struct seq_file *seq, struct htab_elem *elem)
 {
 	struct bpf_iter_seq_hash_map_info *info = seq->private;
-	u32 roundup_key_size, roundup_value_size;
 	struct bpf_iter__bpf_map_elem ctx = {};
 	struct bpf_map *map = info->map;
 	struct bpf_iter_meta meta;
 	int ret = 0, off = 0, cpu;
+	u32 roundup_value_size;
 	struct bpf_prog *prog;
 	void __percpu *pptr;
 
@@ -2130,10 +2129,9 @@ static int __bpf_hash_map_seq_show(struct seq_file *seq, struct htab_elem *elem)
 		ctx.meta = &meta;
 		ctx.map = info->map;
 		if (elem) {
-			roundup_key_size = round_up(map->key_size, 8);
 			ctx.key = elem->key;
 			if (!info->percpu_value_buf) {
-				ctx.value = elem->key + roundup_key_size;
+				ctx.value = htab_elem_value(elem, map->key_size);
 			} else {
 				roundup_value_size = round_up(map->value_size, 8);
 				pptr = htab_elem_get_ptr(elem, map->key_size);
@@ -2218,7 +2216,6 @@ static long bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_
 	struct hlist_nulls_head *head;
 	struct hlist_nulls_node *n;
 	struct htab_elem *elem;
-	u32 roundup_key_size;
 	int i, num_elems = 0;
 	void __percpu *pptr;
 	struct bucket *b;
@@ -2233,7 +2230,6 @@ static long bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_
 
 	is_percpu = htab_is_percpu(htab);
 
-	roundup_key_size = round_up(map->key_size, 8);
 	/* migration has been disabled, so percpu value prepared here will be
 	 * the same as the one seen by the bpf program with
 	 * bpf_map_lookup_elem().
@@ -2249,7 +2245,7 @@ static long bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_
 				pptr = htab_elem_get_ptr(elem, map->key_size);
 				val = this_cpu_ptr(pptr);
 			} else {
-				val = elem->key + roundup_key_size;
+				val = htab_elem_value(elem, map->key_size);
 			}
 			num_elems++;
 			ret = callback_fn((u64)(long)map, (u64)(long)key,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 314/877] bpf: Register dtor for freeing special fields
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (312 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 313/877] bpf: Factor out htab_elem_value helper() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 315/877] bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk Greg Kroah-Hartman
                   ` (570 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Alexei Starovoitov, syzbot,
	Kumar Kartikeya Dwivedi, Sasha Levin

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

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

From: Kumar Kartikeya Dwivedi <memxor@gmail.com>

[ Upstream commit 1df97a7453eec80c1912c2d0360290a3970a7671 ]

There is a race window where BPF hash map elements can leak special
fields if the program with access to the map value recreates these
special fields between the check_and_free_fields done on the map value
and its eventual return to the memory allocator.

Several ways were explored prior to this patch, most notably [0] tried
to use a poison value to reject attempts to recreate special fields for
map values that have been logically deleted but still accessible to BPF
programs (either while sitting in the free list or when reused). While
this approach works well for task work, timers, wq, etc., it is harder
to apply the idea to kptrs, which have a similar race and failure mode.

Instead, we change bpf_mem_alloc to allow registering destructor for
allocated elements, such that when they are returned to the allocator,
any special fields created while they were accessible to programs in the
mean time will be freed. If these values get reused, we do not free the
fields again before handing the element back. The special fields thus
may remain initialized while the map value sits in a free list.

When bpf_mem_alloc is retired in the future, a similar concept can be
introduced to kmalloc_nolock-backed kmem_cache, paired with the existing
idea of a constructor.

Note that the destructor registration happens in map_check_btf, after
the BTF record is populated and (at that point) avaiable for inspection
and duplication. Duplication is necessary since the freeing of embedded
bpf_mem_alloc can be decoupled from actual map lifetime due to logic
introduced to reduce the cost of rcu_barrier()s in mem alloc free path in
9f2c6e96c65e ("bpf: Optimize rcu_barrier usage between hash map and bpf_mem_alloc.").

As such, once all callbacks are done, we must also free the duplicated
record. To remove dependency on the bpf_map itself, also stash the key
size of the map to obtain value from htab_elem long after the map is
gone.

  [0]: https://lore.kernel.org/bpf/20260216131341.1285427-1-mykyta.yatsenko5@gmail.com

Fixes: 14a324f6a67e ("bpf: Wire up freeing of referenced kptr")
Fixes: 1bfbc267ec91 ("bpf: Enable bpf_timer and bpf_wq in any context")
Reported-by: Alexei Starovoitov <ast@kernel.org>
Tested-by: syzbot@syzkaller.appspotmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260227224806.646888-2-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Stable-dep-of: 1c21452d02ee ("bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/linux/bpf_mem_alloc.h |  6 +++
 kernel/bpf/hashtab.c          | 87 +++++++++++++++++++++++++++++++++++
 kernel/bpf/memalloc.c         | 58 ++++++++++++++++++-----
 3 files changed, 140 insertions(+), 11 deletions(-)

diff --git a/include/linux/bpf_mem_alloc.h b/include/linux/bpf_mem_alloc.h
index e45162ef59bb1..4ce0d27f8ea26 100644
--- a/include/linux/bpf_mem_alloc.h
+++ b/include/linux/bpf_mem_alloc.h
@@ -14,6 +14,8 @@ struct bpf_mem_alloc {
 	struct obj_cgroup *objcg;
 	bool percpu;
 	struct work_struct work;
+	void (*dtor_ctx_free)(void *ctx);
+	void *dtor_ctx;
 };
 
 /* 'size != 0' is for bpf_mem_alloc which manages fixed-size objects.
@@ -32,6 +34,10 @@ int bpf_mem_alloc_percpu_init(struct bpf_mem_alloc *ma, struct obj_cgroup *objcg
 /* The percpu allocation with a specific unit size. */
 int bpf_mem_alloc_percpu_unit_init(struct bpf_mem_alloc *ma, int size);
 void bpf_mem_alloc_destroy(struct bpf_mem_alloc *ma);
+void bpf_mem_alloc_set_dtor(struct bpf_mem_alloc *ma,
+			    void (*dtor)(void *obj, void *ctx),
+			    void (*dtor_ctx_free)(void *ctx),
+			    void *ctx);
 
 /* Check the allocation size for kmalloc equivalent allocator */
 int bpf_mem_alloc_check_size(bool percpu, size_t size);
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 0d1aeafe5eb14..ab41c24c68388 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -129,6 +129,11 @@ struct htab_elem {
 	char key[] __aligned(8);
 };
 
+struct htab_btf_record {
+	struct btf_record *record;
+	u32 key_size;
+};
+
 static inline bool htab_is_prealloc(const struct bpf_htab *htab)
 {
 	return !(htab->map.map_flags & BPF_F_NO_PREALLOC);
@@ -475,6 +480,84 @@ static int htab_map_alloc_check(union bpf_attr *attr)
 	return 0;
 }
 
+static void htab_mem_dtor(void *obj, void *ctx)
+{
+	struct htab_btf_record *hrec = ctx;
+	struct htab_elem *elem = obj;
+	void *map_value;
+
+	if (IS_ERR_OR_NULL(hrec->record))
+		return;
+
+	map_value = htab_elem_value(elem, hrec->key_size);
+	bpf_obj_free_fields(hrec->record, map_value);
+}
+
+static void htab_pcpu_mem_dtor(void *obj, void *ctx)
+{
+	void __percpu *pptr = *(void __percpu **)obj;
+	struct htab_btf_record *hrec = ctx;
+	int cpu;
+
+	if (IS_ERR_OR_NULL(hrec->record))
+		return;
+
+	for_each_possible_cpu(cpu)
+		bpf_obj_free_fields(hrec->record, per_cpu_ptr(pptr, cpu));
+}
+
+static void htab_dtor_ctx_free(void *ctx)
+{
+	struct htab_btf_record *hrec = ctx;
+
+	btf_record_free(hrec->record);
+	kfree(ctx);
+}
+
+static int htab_set_dtor(const struct bpf_htab *htab, void (*dtor)(void *, void *))
+{
+	u32 key_size = htab->map.key_size;
+	const struct bpf_mem_alloc *ma;
+	struct htab_btf_record *hrec;
+	int err;
+
+	/* No need for dtors. */
+	if (IS_ERR_OR_NULL(htab->map.record))
+		return 0;
+
+	hrec = kzalloc(sizeof(*hrec), GFP_KERNEL);
+	if (!hrec)
+		return -ENOMEM;
+	hrec->key_size = key_size;
+	hrec->record = btf_record_dup(htab->map.record);
+	if (IS_ERR(hrec->record)) {
+		err = PTR_ERR(hrec->record);
+		kfree(hrec);
+		return err;
+	}
+	ma = htab_is_percpu(htab) ? &htab->pcpu_ma : &htab->ma;
+	/* Kinda sad, but cast away const-ness since we change ma->dtor. */
+	bpf_mem_alloc_set_dtor((struct bpf_mem_alloc *)ma, dtor, htab_dtor_ctx_free, hrec);
+	return 0;
+}
+
+static int htab_map_check_btf(const struct bpf_map *map, const struct btf *btf,
+			      const struct btf_type *key_type, const struct btf_type *value_type)
+{
+	struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
+
+	if (htab_is_prealloc(htab))
+		return 0;
+	/*
+	 * We must set the dtor using this callback, as map's BTF record is not
+	 * populated in htab_map_alloc(), so it will always appear as NULL.
+	 */
+	if (htab_is_percpu(htab))
+		return htab_set_dtor(htab, htab_pcpu_mem_dtor);
+	else
+		return htab_set_dtor(htab, htab_mem_dtor);
+}
+
 static struct bpf_map *htab_map_alloc(union bpf_attr *attr)
 {
 	bool percpu = (attr->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
@@ -2316,6 +2399,7 @@ const struct bpf_map_ops htab_map_ops = {
 	.map_seq_show_elem = htab_map_seq_show_elem,
 	.map_set_for_each_callback_args = map_set_for_each_callback_args,
 	.map_for_each_callback = bpf_for_each_hash_elem,
+	.map_check_btf = htab_map_check_btf,
 	.map_mem_usage = htab_map_mem_usage,
 	BATCH_OPS(htab),
 	.map_btf_id = &htab_map_btf_ids[0],
@@ -2338,6 +2422,7 @@ const struct bpf_map_ops htab_lru_map_ops = {
 	.map_seq_show_elem = htab_map_seq_show_elem,
 	.map_set_for_each_callback_args = map_set_for_each_callback_args,
 	.map_for_each_callback = bpf_for_each_hash_elem,
+	.map_check_btf = htab_map_check_btf,
 	.map_mem_usage = htab_map_mem_usage,
 	BATCH_OPS(htab_lru),
 	.map_btf_id = &htab_map_btf_ids[0],
@@ -2511,6 +2596,7 @@ const struct bpf_map_ops htab_percpu_map_ops = {
 	.map_seq_show_elem = htab_percpu_map_seq_show_elem,
 	.map_set_for_each_callback_args = map_set_for_each_callback_args,
 	.map_for_each_callback = bpf_for_each_hash_elem,
+	.map_check_btf = htab_map_check_btf,
 	.map_mem_usage = htab_map_mem_usage,
 	BATCH_OPS(htab_percpu),
 	.map_btf_id = &htab_map_btf_ids[0],
@@ -2531,6 +2617,7 @@ const struct bpf_map_ops htab_lru_percpu_map_ops = {
 	.map_seq_show_elem = htab_percpu_map_seq_show_elem,
 	.map_set_for_each_callback_args = map_set_for_each_callback_args,
 	.map_for_each_callback = bpf_for_each_hash_elem,
+	.map_check_btf = htab_map_check_btf,
 	.map_mem_usage = htab_map_mem_usage,
 	BATCH_OPS(htab_lru_percpu),
 	.map_btf_id = &htab_map_btf_ids[0],
diff --git a/kernel/bpf/memalloc.c b/kernel/bpf/memalloc.c
index 146f5b57cfb1c..e89a6f5baf5ba 100644
--- a/kernel/bpf/memalloc.c
+++ b/kernel/bpf/memalloc.c
@@ -102,6 +102,8 @@ struct bpf_mem_cache {
 	int percpu_size;
 	bool draining;
 	struct bpf_mem_cache *tgt;
+	void (*dtor)(void *obj, void *ctx);
+	void *dtor_ctx;
 
 	/* list of objects to be freed after RCU GP */
 	struct llist_head free_by_rcu;
@@ -263,12 +265,14 @@ static void free_one(void *obj, bool percpu)
 	kfree(obj);
 }
 
-static int free_all(struct llist_node *llnode, bool percpu)
+static int free_all(struct bpf_mem_cache *c, struct llist_node *llnode, bool percpu)
 {
 	struct llist_node *pos, *t;
 	int cnt = 0;
 
 	llist_for_each_safe(pos, t, llnode) {
+		if (c->dtor)
+			c->dtor((void *)pos + LLIST_NODE_SZ, c->dtor_ctx);
 		free_one(pos, percpu);
 		cnt++;
 	}
@@ -279,7 +283,7 @@ static void __free_rcu(struct rcu_head *head)
 {
 	struct bpf_mem_cache *c = container_of(head, struct bpf_mem_cache, rcu_ttrace);
 
-	free_all(llist_del_all(&c->waiting_for_gp_ttrace), !!c->percpu_size);
+	free_all(c, llist_del_all(&c->waiting_for_gp_ttrace), !!c->percpu_size);
 	atomic_set(&c->call_rcu_ttrace_in_progress, 0);
 }
 
@@ -311,7 +315,7 @@ static void do_call_rcu_ttrace(struct bpf_mem_cache *c)
 	if (atomic_xchg(&c->call_rcu_ttrace_in_progress, 1)) {
 		if (unlikely(READ_ONCE(c->draining))) {
 			llnode = llist_del_all(&c->free_by_rcu_ttrace);
-			free_all(llnode, !!c->percpu_size);
+			free_all(c, llnode, !!c->percpu_size);
 		}
 		return;
 	}
@@ -420,7 +424,7 @@ static void check_free_by_rcu(struct bpf_mem_cache *c)
 	dec_active(c, &flags);
 
 	if (unlikely(READ_ONCE(c->draining))) {
-		free_all(llist_del_all(&c->waiting_for_gp), !!c->percpu_size);
+		free_all(c, llist_del_all(&c->waiting_for_gp), !!c->percpu_size);
 		atomic_set(&c->call_rcu_in_progress, 0);
 	} else {
 		call_rcu_hurry(&c->rcu, __free_by_rcu);
@@ -638,13 +642,13 @@ static void drain_mem_cache(struct bpf_mem_cache *c)
 	 * Except for waiting_for_gp_ttrace list, there are no concurrent operations
 	 * on these lists, so it is safe to use __llist_del_all().
 	 */
-	free_all(llist_del_all(&c->free_by_rcu_ttrace), percpu);
-	free_all(llist_del_all(&c->waiting_for_gp_ttrace), percpu);
-	free_all(__llist_del_all(&c->free_llist), percpu);
-	free_all(__llist_del_all(&c->free_llist_extra), percpu);
-	free_all(__llist_del_all(&c->free_by_rcu), percpu);
-	free_all(__llist_del_all(&c->free_llist_extra_rcu), percpu);
-	free_all(llist_del_all(&c->waiting_for_gp), percpu);
+	free_all(c, llist_del_all(&c->free_by_rcu_ttrace), percpu);
+	free_all(c, llist_del_all(&c->waiting_for_gp_ttrace), percpu);
+	free_all(c, __llist_del_all(&c->free_llist), percpu);
+	free_all(c, __llist_del_all(&c->free_llist_extra), percpu);
+	free_all(c, __llist_del_all(&c->free_by_rcu), percpu);
+	free_all(c, __llist_del_all(&c->free_llist_extra_rcu), percpu);
+	free_all(c, llist_del_all(&c->waiting_for_gp), percpu);
 }
 
 static void check_mem_cache(struct bpf_mem_cache *c)
@@ -683,6 +687,9 @@ static void check_leaked_objs(struct bpf_mem_alloc *ma)
 
 static void free_mem_alloc_no_barrier(struct bpf_mem_alloc *ma)
 {
+	/* We can free dtor ctx only once all callbacks are done using it. */
+	if (ma->dtor_ctx_free)
+		ma->dtor_ctx_free(ma->dtor_ctx);
 	check_leaked_objs(ma);
 	free_percpu(ma->cache);
 	free_percpu(ma->caches);
@@ -1017,3 +1024,32 @@ int bpf_mem_alloc_check_size(bool percpu, size_t size)
 
 	return 0;
 }
+
+void bpf_mem_alloc_set_dtor(struct bpf_mem_alloc *ma, void (*dtor)(void *obj, void *ctx),
+			    void (*dtor_ctx_free)(void *ctx), void *ctx)
+{
+	struct bpf_mem_caches *cc;
+	struct bpf_mem_cache *c;
+	int cpu, i;
+
+	ma->dtor_ctx_free = dtor_ctx_free;
+	ma->dtor_ctx = ctx;
+
+	if (ma->cache) {
+		for_each_possible_cpu(cpu) {
+			c = per_cpu_ptr(ma->cache, cpu);
+			c->dtor = dtor;
+			c->dtor_ctx = ctx;
+		}
+	}
+	if (ma->caches) {
+		for_each_possible_cpu(cpu) {
+			cc = per_cpu_ptr(ma->caches, cpu);
+			for (i = 0; i < NUM_CACHES; i++) {
+				c = &cc->cache[i];
+				c->dtor = dtor;
+				c->dtor_ctx = ctx;
+			}
+		}
+	}
+}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 315/877] bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (313 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 314/877] bpf: Register dtor for freeing special fields Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 316/877] bpf, sockmap: Fix self-redirect copied_seq double-counting Greg Kroah-Hartman
                   ` (569 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Alexei Starovoitov, Hou Tao,
	Pu Lehui, Sasha Levin

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

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

From: Pu Lehui <pulehui@huawei.com>

[ Upstream commit 1c21452d02eec2f008e2c5535820f85adbd7587a ]

Syzkaller repeatedly triggered UAF splats related to nodes in
waiting_for_gp_ttrace within the bpf memalloc:

BUG: KASAN: slab-use-after-free in llist_del_first+0x85/0x110 lib/llist.c:61
Read of size 8 at addr ffff8881572cd080 by task syz.4.470/5112
 ...
 llist_del_first+0x85/0x110 lib/llist.c:61
 alloc_bulk+0x193/0x460 kernel/bpf/memalloc.c:229
 bpf_mem_refill+0x386/0x560 kernel/bpf/memalloc.c:436

Freed by task 14:
 ...
 __free_rcu kernel/bpf/memalloc.c:281 [inline]
 __free_rcu_tasks_trace+0x48/0xd0 kernel/bpf/memalloc.c:291
 rcu_tasks_invoke_cbs+0x1ec/0x3e0 kernel/rcu/tasks.h:571
 rcu_tasks_one_gp+0x13d/0x220 kernel/rcu/tasks.h:621
 rcu_tasks_kthread+0xf3/0x120 kernel/rcu/tasks.h:651

The reason is that the UAF occurs after the RCU Tasks Trace GP expires:
when the __free_rcu() callback runs, there is no synchronization
protecting llist_del_all() against concurrent alloc_bulk() operating on
waiting_for_gp_ttrace, leading to the race condition below:

CPU0                                           CPU1
                                               __free_rcu (RCU Tasks Trace callback)
alloc_bulk
  llist_del_first(&c->waiting_for_gp_ttrace)
    entry = smp_load_acquire(&head->first);
    do {
      if (entry == NULL)
        return NULL;
                                               free_all(llist_del_all(&c->waiting_for_gp_ttrace))
                                                 llist_for_each_safe(pos, t, llnode)
                                                   free_one(pos);
      next = READ_ONCE(entry->next); <-- trigger UAF
    } while (!try_cmpxchg(&head->first, &entry, next));

In addition, there is also a theoretical race condition on the
free_by_rcu_ttrace list. This race requires two preconditions: an
in-flight Tasks Trace GP keeping c->call_rcu_ttrace_in_progress == 1,
and concurrent cross-CPU frees repopulating c->free_by_rcu_ttrace with
new nodes. Under these conditions, the following scenario triggers UAF:

// CPU0
// irq work is still busy (on PREEMPT_RT)
alloc_bulk()
  llist_del_first(&c->free_by_rcu_ttrace)
    entry = smp_load_acquire(&head->first);
    do {
      if (entry == NULL)
        return NULL;

        // CPU1
        bpf_mem_alloc_destroy()
          WRITE_ONCE(c->draining, true)
          // wait for CPU0
          irq_work_sync()

                // CPU2
                do_call_rcu_ttrace(tgt(CPU0))
                  if (c->draining) {
                    llist_del_all(&c->free_by_rcu_ttrace)
                    free_all()
                  }

// CPU0 continue
      next = READ_ONCE(entry->next); <-- trigger UAF
    while (!try_cmpxchg(&head->first, &entry, next));

Fix this by introducing a raw spinlock to synchronize the concurrent
consumption on waiting_for_gp_ttrace and free_by_rcu_ttrace.

Fixes: 04fabf00b4d3 ("bpf: Allow reuse from waiting_for_gp_ttrace list.")
Suggested-by: Alexei Starovoitov <ast@kernel.org>
Suggested-by: Hou Tao <houtao1@huawei.com>
Signed-off-by: Pu Lehui <pulehui@huawei.com>
Acked-by: Hou Tao <houtao1@huawei.com>
Link: https://lore.kernel.org/r/20260905021139.4116529-1-pulehui@huaweicloud.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/memalloc.c | 50 ++++++++++++++++++++++++-------------------
 1 file changed, 28 insertions(+), 22 deletions(-)

diff --git a/kernel/bpf/memalloc.c b/kernel/bpf/memalloc.c
index e89a6f5baf5ba..bbc08b869aae1 100644
--- a/kernel/bpf/memalloc.c
+++ b/kernel/bpf/memalloc.c
@@ -119,6 +119,7 @@ struct bpf_mem_cache {
 	struct llist_head waiting_for_gp_ttrace;
 	struct rcu_head rcu_ttrace;
 	atomic_t call_rcu_ttrace_in_progress;
+	raw_spinlock_t lock;
 };
 
 struct bpf_mem_caches {
@@ -214,25 +215,24 @@ static void alloc_bulk(struct bpf_mem_cache *c, int cnt, int node, bool atomic)
 	gfp = __GFP_NOWARN | __GFP_ACCOUNT;
 	gfp |= atomic ? GFP_NOWAIT : GFP_KERNEL;
 
-	for (i = 0; i < cnt; i++) {
-		/*
-		 * For every 'c' llist_del_first(&c->free_by_rcu_ttrace); is
-		 * done only by one CPU == current CPU. Other CPUs might
-		 * llist_add() and llist_del_all() in parallel.
-		 */
-		obj = llist_del_first(&c->free_by_rcu_ttrace);
-		if (!obj)
-			break;
-		add_obj_to_free_list(c, obj);
-	}
-	if (i >= cnt)
-		return;
+	/*
+	 * c->lock serializes concurrent llist_del_first() against
+	 * llist_del_all() in __free_rcu() and do_call_rcu_ttrace().
+	 */
+	scoped_guard(raw_spinlock_irqsave, &c->lock) {
+		for (i = 0; i < cnt; i++) {
+			obj = llist_del_first(&c->free_by_rcu_ttrace);
+			if (!obj)
+				break;
+			add_obj_to_free_list(c, obj);
+		}
 
-	for (; i < cnt; i++) {
-		obj = llist_del_first(&c->waiting_for_gp_ttrace);
-		if (!obj)
-			break;
-		add_obj_to_free_list(c, obj);
+		for (; i < cnt; i++) {
+			obj = llist_del_first(&c->waiting_for_gp_ttrace);
+			if (!obj)
+				break;
+			add_obj_to_free_list(c, obj);
+		}
 	}
 	if (i >= cnt)
 		return;
@@ -282,8 +282,12 @@ static int free_all(struct bpf_mem_cache *c, struct llist_node *llnode, bool per
 static void __free_rcu(struct rcu_head *head)
 {
 	struct bpf_mem_cache *c = container_of(head, struct bpf_mem_cache, rcu_ttrace);
+	struct llist_node *llnode;
+
+	scoped_guard(raw_spinlock_irqsave, &c->lock)
+		llnode = llist_del_all(&c->waiting_for_gp_ttrace);
 
-	free_all(c, llist_del_all(&c->waiting_for_gp_ttrace), !!c->percpu_size);
+	free_all(c, llnode, !!c->percpu_size);
 	atomic_set(&c->call_rcu_ttrace_in_progress, 0);
 }
 
@@ -314,7 +318,8 @@ static void do_call_rcu_ttrace(struct bpf_mem_cache *c)
 
 	if (atomic_xchg(&c->call_rcu_ttrace_in_progress, 1)) {
 		if (unlikely(READ_ONCE(c->draining))) {
-			llnode = llist_del_all(&c->free_by_rcu_ttrace);
+			scoped_guard(raw_spinlock_irqsave, &c->lock)
+				llnode = llist_del_all(&c->free_by_rcu_ttrace);
 			free_all(c, llnode, !!c->percpu_size);
 		}
 		return;
@@ -549,6 +554,7 @@ int bpf_mem_alloc_init(struct bpf_mem_alloc *ma, int size, bool percpu)
 			c->objcg = objcg;
 			c->percpu_size = percpu_size;
 			c->tgt = c;
+			raw_spin_lock_init(&c->lock);
 			init_refill_work(c);
 			prefill_mem_cache(c, cpu);
 		}
@@ -571,7 +577,7 @@ int bpf_mem_alloc_init(struct bpf_mem_alloc *ma, int size, bool percpu)
 			c->objcg = objcg;
 			c->percpu_size = percpu_size;
 			c->tgt = c;
-
+			raw_spin_lock_init(&c->lock);
 			init_refill_work(c);
 			prefill_mem_cache(c, cpu);
 		}
@@ -623,7 +629,7 @@ int bpf_mem_alloc_percpu_unit_init(struct bpf_mem_alloc *ma, int size)
 		c->objcg = objcg;
 		c->percpu_size = percpu_size;
 		c->tgt = c;
-
+		raw_spin_lock_init(&c->lock);
 		init_refill_work(c);
 		prefill_mem_cache(c, cpu);
 	}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 316/877] bpf, sockmap: Fix self-redirect copied_seq double-counting
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (314 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 315/877] bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 317/877] bpf, arm64: set up the frame pointer for the exception callback Greg Kroah-Hartman
                   ` (568 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jakub Sitnicki, Jiayuan Chen,
	Geliang Tang, Emil Tsalapatis, Alexei Starovoitov, Sasha Levin

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

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

From: Geliang Tang <tanggeliang@kylinos.cn>

[ Upstream commit 490a83d6386eec1d29f470c8d7331677fb46c3b7 ]

When a BPF stream_verdict program redirects an skb back to the same
socket (self-redirect with BPF_F_INGRESS), sk_psock_verdict_apply()
calls tcp_eat_skb() which advances tcp_sk->copied_seq. However, the
skb is then delivered to the socket's psock ingress queue and later
read by tcp_bpf_recvmsg_parser(), which also advances copied_seq via
the copied_from_self accounting path. This double-counting causes
copied_seq to advance by 2x the actual data length, triggering:

  TCP recvmsg seq # bug 2: copied BF2E806, seq BF2E7FD, \
			   rcvnxt BF2E806, fl 0
  WARNING: net/ipv4/tcp.c:2745 at tcp_recvmsg_locked+0x72b/0x2640
  Call Trace:
   tcp_recvmsg+0x10a/0x500
   sock_recvmsg+0x168/0x1d0
   __sys_recvfrom+0x19a/0x2a0
   __x64_sys_recvfrom+0xe4/0x1f0
   do_syscall_64+0xf7/0x530
   entry_SYSCALL_64_after_hwframe+0x77/0x7f

  cleanup rbuf bug: copied BF2E806 seq BF2E806 rcvnxt BF2E806
  WARNING: net/ipv4/tcp.c:1609 at tcp_cleanup_rbuf+0xf2/0x1c0
  Call Trace:
   tcp_recvmsg_locked+0x8d1/0x2640
   tcp_recvmsg+0x10a/0x500
   sock_recvmsg+0x168/0x1d0
   __sys_recvfrom+0x19a/0x2a0
   __x64_sys_recvfrom+0xe4/0x1f0
   do_syscall_64+0xf7/0x530
   entry_SYSCALL_64_after_hwframe+0x77/0x7f

Fix this by converting self-redirect verdict to __SK_PASS at the
beginning of sk_psock_verdict_apply(). This bypasses the
__SK_REDIRECT case entirely (which calls sk_psock_eat_skb), letting
the __SK_PASS path queue the skb to the psock ingress queue. The
data is then read via tcp_bpf_recvmsg_parser(), which advances
copied_seq exactly once through copied_from_self. Cross-socket
redirects continue through __SK_REDIRECT with sk_psock_eat_skb()
unchanged.

Fixes: e5c6de5fa025 ("bpf, sockmap: Incorrectly handling copied_seq")
Suggested-by: Jakub Sitnicki <jakub@cloudflare.com>
Suggested-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://lore.kernel.org/r/1a8e797a1b26e2f695aaac22ac644c2862f63466.1788858299.git.tanggeliang@kylinos.cn
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/skmsg.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/net/core/skmsg.c b/net/core/skmsg.c
index 7e68b4fdbfce0..6eca57da3cff6 100644
--- a/net/core/skmsg.c
+++ b/net/core/skmsg.c
@@ -1035,6 +1035,10 @@ static int sk_psock_verdict_apply(struct sk_psock *psock, struct sk_buff *skb,
 	int err = 0;
 	u32 len, off;
 
+	if (verdict == __SK_REDIRECT && skb_bpf_ingress(skb) &&
+	    skb_bpf_redirect_fetch(skb) == psock->sk)
+		verdict = __SK_PASS;
+
 	switch (verdict) {
 	case __SK_PASS:
 		err = -EIO;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 317/877] bpf, arm64: set up the frame pointer for the exception callback
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (315 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 316/877] bpf, sockmap: Fix self-redirect copied_seq double-counting Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 318/877] pinctrl: meson: Fix typo in s4 group name Greg Kroah-Hartman
                   ` (567 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Xu Kuohai, Donggeun Yoo,
	Alexei Starovoitov, Sasha Levin

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

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

From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>

[ Upstream commit ef1fb82f12186dd26153b14d9fbcf4ec98db81b3 ]

A program acting as exception boundary saves all callee-saved registers,
so build_prologue() takes the exception_cb path and never calls
push_callee_regs(). That is the only place find_used_callee_regs() runs,
and with it the only place ctx->fp_used is set, so the callback prologue
does not emit the

  mov x25, sp

that points BPF_REG_FP at the frame the callback runs on. x25 keeps
whatever it held when bpf_throw() was called. If the throw came from a
subprogram that uses its own BPF stack, that is the subprogram's frame
pointer, and since the subprogram never returns it never restores x25
either.

Stack accesses through BPF_REG_FP are rewritten to be stack pointer
relative, so those still land in the callback's own frame. Materializing
the register does not: a callback that passes the address of a local
variable to a helper hands over an address in the dead subprogram's
frame. That address is below the callback's stack pointer by then, and
the helper's own call chain covers it, so the helper can write over its
own return address. 0x1234 below is the value the helper was asked to
store:

  pc : 0x1234
  lr : 0x1234
  Call trace:
   0x1234 (P)
   bpf_test_run+0x188/0x3e0
   bpf_prog_test_run_skb+0x47c/0x998
   __sys_bpf+0xbdc/0xdd8
  Kernel panic - not syncing: Oops: Fatal exception in interrupt

Set ctx->fp_used on the exception callback path so that the existing code
further down sets x25 from the stack pointer. The epilogue restores it
from the main program's save area along with the other callee-saved
registers, as it already does. x86 sets the frame pointer for the
callback from the argument it is passed, and powerpc computes it from
the stack pointer.

Fixes: 5d4fa9ec5643 ("bpf, arm64: Avoid blindly saving/restoring all callee-saved registers")
Acked-by: Xu Kuohai <xukuohai@huawei.com>
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Link: https://lore.kernel.org/r/20260907130624.611942-2-donggeunyoo.kernel@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/arm64/net/bpf_jit_comp.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c
index 27d27848db52d..9c28bb7b69ae6 100644
--- a/arch/arm64/net/bpf_jit_comp.c
+++ b/arch/arm64/net/bpf_jit_comp.c
@@ -537,6 +537,8 @@ static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
 		 * 12 registers are on the stack
 		 */
 		emit(A64_SUB_I(1, A64_SP, A64_FP, 96), ctx);
+		/* The callback may use its own BPF stack, set up fp for it. */
+		ctx->fp_used = true;
 	}
 
 	if (ctx->fp_used)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 318/877] pinctrl: meson: Fix typo in s4 group name
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (316 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 317/877] bpf, arm64: set up the frame pointer for the exception callback Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 319/877] HID: amd_sfh: Validate PCI BAR size before mapping Greg Kroah-Hartman
                   ` (566 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sean Anderson, Neil Armstrong,
	Linus Walleij, Sasha Levin

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

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

From: Sean Anderson <sanderson@brivo.com>

[ Upstream commit 692f32609a30f75ca3401e25b504bfd06bd5662a ]

One of the i2c pin groups has some junk at the end. The name should be
i2c2_scl_h1, and indeed that's the name used by i2c2_pins3 in
meson-s4.dtsi.

Fixes: 775214d389c25 ("pinctrl: meson: add pinctrl driver support for Meson-S4 Soc")
Signed-off-by: Sean Anderson <sanderson@brivo.com>
Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Signed-off-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/pinctrl/meson/pinctrl-meson-s4.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/meson/pinctrl-meson-s4.c b/drivers/pinctrl/meson/pinctrl-meson-s4.c
index 872948699e9fe..365dafe457a9f 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-s4.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-s4.c
@@ -854,7 +854,7 @@ static const char * const i2c1_groups[] = {
 static const char * const i2c2_groups[] = {
 	"i2c2_sda_d", "i2c2_scl_d",
 	"i2c2_sda_h8", "i2c2_scl_h9",
-	"i2c2_sda_h0", "i2c2_scl_h1l,"
+	"i2c2_sda_h0", "i2c2_scl_h1",
 };
 
 static const char * const i2c3_groups[] = {
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 319/877] HID: amd_sfh: Validate PCI BAR size before mapping
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (317 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 318/877] pinctrl: meson: Fix typo in s4 group name Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 320/877] HID: bpf: fix __hid_bpf_hw_check_params report length Greg Kroah-Hartman
                   ` (565 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+4eadd4dfe9e66522bae8,
	Slawomir Stepien, Basavaraj Natikar, Jiri Kosina, Sasha Levin

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

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

From: Slawomir Stepien <sst@poczta.fm>

[ Upstream commit 65bcc5f89704efe5b9d69d4ea2c1002d90c31382 ]

The amd_sfh driver maps PCI BAR 2 using pcim_iomap_regions() and
subsequently accesses MMIO registers at offsets up to 0x10958 (e.g.,
AMD_P2C_MSG3 at 0x1068C). However, the driver never validates that the BAR
size is large enough to cover these accesses. If the driver is bound to a
device with a smaller BAR 2, this leads to an out-of-bounds memory access
and a page fault during the probe function.

For example, a page fault can occur when reading from privdata->mmio +
AMD_P2C_MSG3 in mp2_select_ops():

  BUG: unable to handle page fault for address: ffffc9000390368c
  PGD 100000067 P4D 100000067 PUD 1012c1067 PMD 105b64067 PTE 0
  Oops: Oops: 0000 [#1] SMP KASAN NOPTI
  RIP: 0010:readl arch/x86/include/asm/io.h:59 [inline]
  RIP: 0010:mp2_select_ops drivers/hid/amd-sfh-hid/amd_sfh_pcie.c:282
  [inline]
  RIP: 0010:amd_mp2_pci_probe+0x337/0x5f0
  drivers/hid/amd-sfh-hid/amd_sfh_pcie.c:487
  Call Trace:
   <TASK>
   local_pci_probe drivers/pci/pci-driver.c:332 [inline]
   pci_call_probe drivers/pci/pci-driver.c:394 [inline]
   __pci_device_probe drivers/pci/pci-driver.c:455 [inline]
   pci_device_probe+0x431/0xc90 drivers/pci/pci-driver.c:489

Fix this by verifying that the length of BAR 2 is at least 128KB before
attempting to map it. Since the maximum accessed offset is 0x10958, and PCI
BAR sizes are powers of 2, any legitimate hardware will have a BAR size of
at least 128KB.

Fixes: 4f567b9f8141 ("SFH: PCIe driver to add support of AMD sensor fusion hub")
Assisted-by: Gemini:gemini-3.7-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: syzbot+4eadd4dfe9e66522bae8@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=4eadd4dfe9e66522bae8
Link: https://syzkaller.appspot.com/ai_job?id=3bc1c45c-548f-4ab5-8243-d2c8ec321d6c
Signed-off-by: Slawomir Stepien <sst@poczta.fm>
Acked-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
Link: https://syzkaller.appspot.com/bug?extid=4eadd4dfe9e66522bae8
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/hid/amd-sfh-hid/amd_sfh_common.h |  4 ++++
 drivers/hid/amd-sfh-hid/amd_sfh_pcie.c   | 10 ++++++++++
 2 files changed, 14 insertions(+)

diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_common.h b/drivers/hid/amd-sfh-hid/amd_sfh_common.h
index 00308d8998d4d..f05078f93b138 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_common.h
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_common.h
@@ -12,11 +12,15 @@
 
 #include <linux/mutex.h>
 #include <linux/pci.h>
+#include <linux/sizes.h>
 #include "amd_sfh_hid.h"
 
 #define PCI_DEVICE_ID_AMD_MP2		0x15E4
 #define PCI_DEVICE_ID_AMD_MP2_1_1	0x164A
 
+/* The BAR 2 size must cover the highest register offset (0x10958) */
+#define AMD_SFH_MIN_BAR_SIZE		SZ_128K
+
 #define AMD_C2P_MSG(regno) (0x10500 + ((regno) * 4))
 #define AMD_P2C_MSG(regno) (0x10680 + ((regno) * 4))
 
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
index 33ba9af1a249f..b29f8ea39c4c1 100644
--- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
+++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
@@ -390,6 +390,16 @@ static int amd_mp2_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
 	if (rc)
 		return rc;
 
+	if (!(pci_resource_flags(pdev, 2) & IORESOURCE_MEM)) {
+		dev_err(&pdev->dev, "BAR 2 is not IORESOURCE_MEM\n");
+		return -ENODEV;
+	}
+
+	if (pci_resource_len(pdev, 2) < AMD_SFH_MIN_BAR_SIZE) {
+		dev_err(&pdev->dev, "BAR 2 is too small\n");
+		return -EINVAL;
+	}
+
 	rc = pcim_iomap_regions(pdev, BIT(2), DRIVER_NAME);
 	if (rc)
 		return rc;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 320/877] HID: bpf: fix __hid_bpf_hw_check_params report length
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (318 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 319/877] HID: amd_sfh: Validate PCI BAR size before mapping Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 321/877] RISC-V: KVM: Preserve firmware counter value across stop/start Greg Kroah-Hartman
                   ` (564 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Benjamin Tissoires, Sasha Levin

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

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

From: Benjamin Tissoires <bentiss@kernel.org>

[ Upstream commit c4afa4862b878d56e0cc1021298794ac1b45bc49 ]

Turns out that USB, I2C and other transport drivers (except uhid which
just passes the data) still need to have the report ID in the first
byte.

Because they expect the first byte to be the report ID or 0, when the
report ID is 0, they strip that first byte before forwarding to the
device. This means that the transport layer forwards a buffer of size
N-1 to the device, which gets rejected.

Fixes: 5599f8019661 ("HID: bpf: export hid_hw_output_report as a BPF kfunc")
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/hid/bpf/hid_bpf_dispatch.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c
index 1de6a7e0af7b4..a421fecce9dd1 100644
--- a/drivers/hid/bpf/hid_bpf_dispatch.c
+++ b/drivers/hid/bpf/hid_bpf_dispatch.c
@@ -359,7 +359,7 @@ hid_bpf_release_context(struct hid_bpf_ctx *ctx)
 
 static int
 __hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8 *buf, size_t *buf__sz,
-			  enum hid_report_type rtype)
+			  enum hid_report_type rtype, bool hw_request)
 {
 	struct hid_report_enum *report_enum;
 	struct hid_report *report;
@@ -391,6 +391,10 @@ __hid_bpf_hw_check_params(struct hid_bpf_ctx *ctx, __u8 *buf, size_t *buf__sz,
 
 	report_len = hid_report_len(report);
 
+	/* unnumbered reports need to have a report ID reserved in the first byte */
+	if (hw_request && report_enum->numbered == 0)
+		report_len += 1;
+
 	if (*buf__sz > report_len)
 		*buf__sz = report_len;
 
@@ -424,7 +428,7 @@ hid_bpf_hw_request(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz,
 		return -EDEADLOCK;
 
 	/* check arguments */
-	ret = __hid_bpf_hw_check_params(ctx, buf, &size, rtype);
+	ret = __hid_bpf_hw_check_params(ctx, buf, &size, rtype, true);
 	if (ret)
 		return ret;
 
@@ -487,7 +491,7 @@ hid_bpf_hw_output_report(struct hid_bpf_ctx *ctx, __u8 *buf, size_t buf__sz)
 		return -EDEADLOCK;
 
 	/* check arguments */
-	ret = __hid_bpf_hw_check_params(ctx, buf, &size, HID_OUTPUT_REPORT);
+	ret = __hid_bpf_hw_check_params(ctx, buf, &size, HID_OUTPUT_REPORT, true);
 	if (ret)
 		return ret;
 
@@ -515,7 +519,7 @@ __hid_bpf_input_report(struct hid_bpf_ctx *ctx, enum hid_report_type type, u8 *b
 		return -EDEADLOCK;
 
 	/* check arguments */
-	ret = __hid_bpf_hw_check_params(ctx, buf, &size, type);
+	ret = __hid_bpf_hw_check_params(ctx, buf, &size, type, false);
 	if (ret)
 		return ret;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 321/877] RISC-V: KVM: Preserve firmware counter value across stop/start
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (319 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 320/877] HID: bpf: fix __hid_bpf_hw_check_params report length Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 322/877] RISC-V: KVM: Report snapshot write failure to the guest Greg Kroah-Hartman
                   ` (563 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, SeungJu Cheon, Anup Patel,
	Sasha Levin

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

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

From: SeungJu Cheon <suunj1331@gmail.com>

[ Upstream commit 8b3fd1a8b305321171602bfa7c41212441cf69e4 ]

Firmware events accumulate in kvpmu->fw_event[].value while running,
but counter stop only clears fw_event[].started without saving the
value back to pmc->counter_val. A subsequent counter start without
SBI_PMU_START_FLAG_SET_INIT_VALUE reloads the stale counter_val into
fw_event[].value, losing all events counted so far.

Save fw_event[].value into counter_val when actually stopping a
running counter, and remove the now redundant synchronization from
the snapshot path.

Fixes: badc386869e2c ("RISC-V: KVM: Support firmware events")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260825083719.643970-2-suunj1331@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/riscv/kvm/vcpu_pmu.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
index 9ec3280db91d9..4073adf4f91a3 100644
--- a/arch/riscv/kvm/vcpu_pmu.c
+++ b/arch/riscv/kvm/vcpu_pmu.c
@@ -590,10 +590,12 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
 				goto out;
 			}
 
-			if (!kvpmu->fw_event[fevent_code].started)
+			if (!kvpmu->fw_event[fevent_code].started) {
 				sbiret = SBI_ERR_ALREADY_STOPPED;
-
-			kvpmu->fw_event[fevent_code].started = false;
+			} else {
+				kvpmu->fw_event[fevent_code].started = false;
+				pmc->counter_val = kvpmu->fw_event[fevent_code].value;
+			}
 		} else if (pmc->perf_event) {
 			if (pmc->started) {
 				/* Stop counting the counter */
@@ -611,9 +613,7 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
 		}
 
 		if (snap_flag_set && !sbiret) {
-			if (pmc->cinfo.type == SBI_PMU_CTR_TYPE_FW)
-				pmc->counter_val = kvpmu->fw_event[fevent_code].value;
-			else if (pmc->perf_event)
+			if (pmc->perf_event)
 				pmc->counter_val += perf_event_read_value(pmc->perf_event,
 									  &enabled, &running);
 			/*
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 322/877] RISC-V: KVM: Report snapshot write failure to the guest
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (320 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 321/877] RISC-V: KVM: Preserve firmware counter value across stop/start Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 323/877] RISC-V: KVM: Fix perf-backed counter accounting across stop and read Greg Kroah-Hartman
                   ` (562 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, SeungJu Cheon, Anup Patel,
	Sasha Levin

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

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

From: SeungJu Cheon <suunj1331@gmail.com>

[ Upstream commit 057dd2639ceae79adced5d8fe52c32d562edcb3a ]

If kvm_vcpu_write_guest() fails while updating the PMU snapshot area
on counter stop, the guest may receive SBI_SUCCESS without the
snapshot being updated, leaving stale data in shared memory.

Return SBI_ERR_FAILURE when the snapshot write fails.

Fixes: c2f41ddbcdd7 ("RISC-V: KVM: Implement SBI PMU Snapshot feature")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260825083719.643970-3-suunj1331@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/riscv/kvm/vcpu_pmu.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
index 4073adf4f91a3..468e58f152153 100644
--- a/arch/riscv/kvm/vcpu_pmu.c
+++ b/arch/riscv/kvm/vcpu_pmu.c
@@ -642,9 +642,10 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
 		}
 	}
 
-	if (shmem_needs_update)
-		kvm_vcpu_write_guest(vcpu, kvpmu->snapshot_addr, kvpmu->sdata,
-					     sizeof(struct riscv_pmu_snapshot_data));
+	if (shmem_needs_update &&
+	    kvm_vcpu_write_guest(vcpu, kvpmu->snapshot_addr, kvpmu->sdata,
+				 sizeof(struct riscv_pmu_snapshot_data)))
+		sbiret = SBI_ERR_FAILURE;
 
 out:
 	retdata->err_val = sbiret;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 323/877] RISC-V: KVM: Fix perf-backed counter accounting across stop and read
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (321 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 322/877] RISC-V: KVM: Report snapshot write failure to the guest Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 324/877] KVM: arm64: vgic-its: Free the caches when GITS_BASER changes Greg Kroah-Hartman
                   ` (561 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, SeungJu Cheon, Anup Patel,
	Sasha Levin

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

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

From: SeungJu Cheon <suunj1331@gmail.com>

[ Upstream commit c7e2cc38c56142cdab25e6f73602a8222bf9479b ]

pmu_ctr_read() adds the event count returned by perf_event_read_value()
to counter_val, which can accumulate the same count repeatedly across
reads. kvm_riscv_vcpu_pmu_ctr_stop() also leaves counter_val stale by
not folding the current event count into it.

Make reads of perf-backed counters side-effect free, and use
perf_event_pause() when stopping a counter to fold the current event
count into counter_val while resetting it. This preserves the counter
value across stop/start and lets the snapshot path use counter_val
directly.

Fixes: 0cb74b65d2e5 ("RISC-V: KVM: Implement perf support without sampling")
Signed-off-by: SeungJu Cheon <suunj1331@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260825083719.643970-4-suunj1331@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/riscv/kvm/vcpu_pmu.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
index 468e58f152153..147fc0d107ca9 100644
--- a/arch/riscv/kvm/vcpu_pmu.c
+++ b/arch/riscv/kvm/vcpu_pmu.c
@@ -245,12 +245,13 @@ static int pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx,
 	if (pmc->cinfo.type == SBI_PMU_CTR_TYPE_FW) {
 		fevent_code = get_event_code(pmc->event_idx);
 		pmc->counter_val = kvpmu->fw_event[fevent_code].value;
+		*out_val = pmc->counter_val;
 	} else if (pmc->perf_event) {
-		pmc->counter_val += perf_event_read_value(pmc->perf_event, &enabled, &running);
+		*out_val = pmc->counter_val +
+			   perf_event_read_value(pmc->perf_event, &enabled, &running);
 	} else {
 		return -EINVAL;
 	}
-	*out_val = pmc->counter_val;
 
 	return 0;
 }
@@ -561,7 +562,6 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
 {
 	struct kvm_pmu *kvpmu = vcpu_to_pmu(vcpu);
 	int i, pmc_index, sbiret = 0;
-	u64 enabled, running;
 	struct kvm_pmc *pmc;
 	int fevent_code;
 	bool snap_flag_set = flags & SBI_PMU_STOP_FLAG_TAKE_SNAPSHOT;
@@ -598,8 +598,11 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
 			}
 		} else if (pmc->perf_event) {
 			if (pmc->started) {
-				/* Stop counting the counter */
-				perf_event_disable(pmc->perf_event);
+				/*
+				 * Stop the counter and fold the live count into counter_val.
+				 * Reset the event value to avoid redundant accumulation.
+				 */
+				pmc->counter_val += perf_event_pause(pmc->perf_event, true);
 				pmc->started = false;
 			} else {
 				sbiret = SBI_ERR_ALREADY_STOPPED;
@@ -613,9 +616,6 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
 		}
 
 		if (snap_flag_set && !sbiret) {
-			if (pmc->perf_event)
-				pmc->counter_val += perf_event_read_value(pmc->perf_event,
-									  &enabled, &running);
 			/*
 			 * The counter and overflow indicies in the snapshot region are w.r.to
 			 * cbase. Modify the set bit in the counter mask instead of the pmc_index
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 324/877] KVM: arm64: vgic-its: Free the caches when GITS_BASER changes
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (322 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 323/877] RISC-V: KVM: Fix perf-backed counter accounting across stop and read Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 325/877] KVM: arm64: vgic-its: Add stronger type-checking to the ITS entry sizes Greg Kroah-Hartman
                   ` (560 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Marc Zyngier, Fuad Tabba,
	Oliver Upton, Sasha Levin

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

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

From: Fuad Tabba <fuad.tabba@linux.dev>

[ Upstream commit 8cd92f77ae4f5371a7d581f8324c24919670b304 ]

A guest that disables the ITS and re-points or shrinks GITS_BASER<n>
with VALID still set keeps the devices and collections it mapped
against the old table, as KVM frees them only when VALID is cleared.
The contents of the table are IMPLEMENTATION DEFINED, so a write that
gives GITS_BASER<n> a different address or size may lose whatever the
old value described. Free the list whenever the stored value changes,
and drop the translation cache with it.

The cache is not empty just because the ITS is disabled: its->enabled
is written under the cmd_lock, while vgic_its_resolve_lpi() tests it
under the its_lock, so an injection can still cache an entry after the
ITS was disabled. Hence the invalidation inside the its_lock section.

Test for a change rather than a write: its_restore_enable() rewrites
GITS_BASER<n> from its probe-time cache on resume, and KVM reports
GITS_TYPER.HCC as 0, so nothing re-maps the boot CPU's collection
afterwards.

Fixes: 36d6961c2b481 ("KVM: arm/arm64: vgic-its: Free caches when GITS_BASER Valid bit is cleared")
Suggested-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/all/87ecg9owwa.wl-maz@kernel.org/
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://patch.msgid.link/20260821064445.615838-2-fuad.tabba@linux.dev
Signed-off-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/arm64/kvm/vgic/vgic-its.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index 7282305de3471..6737db1fb922f 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -1637,7 +1637,7 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
 				      unsigned long val)
 {
 	const struct vgic_its_abi *abi = vgic_its_get_abi(its);
-	u64 entry_size, table_type;
+	u64 old, entry_size, table_type;
 	u64 reg, *regptr, clearbits = 0;
 
 	/* When GITS_CTLR.Enable is 1, we ignore write accesses. */
@@ -1660,7 +1660,9 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
 		return;
 	}
 
-	reg = update_64bit_reg(*regptr, addr & 7, len, val);
+	old = *regptr;
+
+	reg = update_64bit_reg(old, addr & 7, len, val);
 	reg &= ~GITS_BASER_RO_MASK;
 	reg &= ~clearbits;
 
@@ -1670,7 +1672,8 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
 
 	*regptr = reg;
 
-	if (!(reg & GITS_BASER_VALID)) {
+	/* The ITS driver rewrites an unchanged GITS_BASER<n> on resume. */
+	if (reg != old) {
 		/* Take the its_lock to prevent a race with a save/restore */
 		mutex_lock(&its->its_lock);
 		switch (table_type) {
@@ -1681,6 +1684,8 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
 			vgic_its_free_collection_list(kvm, its);
 			break;
 		}
+		/* A concurrent injection may have cached a translation. */
+		vgic_its_invalidate_cache(its);
 		mutex_unlock(&its->its_lock);
 	}
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 325/877] KVM: arm64: vgic-its: Add stronger type-checking to the ITS entry sizes
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (323 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 324/877] KVM: arm64: vgic-its: Free the caches when GITS_BASER changes Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 326/877] KVM: arm64: vgic-its: Skip unreachable devices instead of failing the save Greg Kroah-Hartman
                   ` (559 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Marc Zyngier, Oliver Upton,
	Sasha Levin

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

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

From: Marc Zyngier <maz@kernel.org>

[ Upstream commit 3b2c81d5feb250dfdcb0ef5825319f36c29f8336 ]

The ITS ABI infrastructure allows for some pretty lax code, where
the size of the data doesn't have to match the size of the entry,
potentially leading to a collection of interesting bugs.

Commit 7fe28d7e68f9 ("KVM: arm64: vgic-its: Add a data length check
in vgic_its_save_*") added some checks, but starts by implicitly
casting all writes to a 64bit value, hiding some of the issues.

Instead, introduce macros that will check the data type actually used
for dealing with the table entries. The macros are taking a symbolic
entry type that is used to fetch the size of the entry type for the
current ABI. This immediately catches a couple of low-impact gotchas
(zero values that are implicitly 32bit), easy enough to fix.

Given that we currently only have a single ABI, hardcode a couple of
BUILD_BUG_ON()s that will fire if we use anything but a 64bit quantity,
and some (currently unreachable) fallback code that may become useful
one day.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20241117165757.247686-5-maz@kernel.org
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Stable-dep-of: cc5d96036e01 ("KVM: arm64: vgic-its: Skip unreachable devices instead of failing the save")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/arm64/kvm/vgic/vgic-its.c | 69 ++++++++++++++++++++++++----------
 arch/arm64/kvm/vgic/vgic.h     | 23 ------------
 2 files changed, 50 insertions(+), 42 deletions(-)

diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index 6737db1fb922f..8842e53734a1d 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -31,6 +31,41 @@ static int vgic_its_commit_v0(struct vgic_its *its);
 static int update_lpi_config(struct kvm *kvm, struct vgic_irq *irq,
 			     struct kvm_vcpu *filter_vcpu, bool needs_inv);
 
+#define vgic_its_read_entry_lock(i, g, valp, t)				\
+	({								\
+		int __sz = vgic_its_get_abi(i)->t##_esz;		\
+		struct kvm *__k = (i)->dev->kvm;			\
+		int __ret;						\
+									\
+		BUILD_BUG_ON(NR_ITS_ABIS == 1 &&			\
+			     sizeof(*(valp)) != ABI_0_ESZ);		\
+		if (NR_ITS_ABIS > 1 &&					\
+		    KVM_BUG_ON(__sz != sizeof(*(valp)), __k))		\
+			__ret = -EINVAL;				\
+		else							\
+			__ret = kvm_read_guest_lock(__k, (g),		\
+						    valp, __sz);	\
+		__ret;							\
+	})
+
+#define vgic_its_write_entry_lock(i, g, val, t)				\
+	({								\
+		int __sz = vgic_its_get_abi(i)->t##_esz;		\
+		struct kvm *__k = (i)->dev->kvm;			\
+		typeof(val) __v = (val);				\
+		int __ret;						\
+									\
+		BUILD_BUG_ON(NR_ITS_ABIS == 1 &&			\
+			     sizeof(__v) != ABI_0_ESZ);			\
+		if (NR_ITS_ABIS > 1 &&					\
+		    KVM_BUG_ON(__sz != sizeof(__v), __k))		\
+			__ret = -EINVAL;				\
+		else							\
+			__ret = vgic_write_guest_lock(__k, (g),		\
+						      &__v, __sz);	\
+		__ret;							\
+	})
+
 /*
  * Creates a new (reference to a) struct vgic_irq for a given LPI.
  * If this LPI is already mapped on another ITS, we increase its refcount
@@ -798,7 +833,7 @@ static int vgic_its_cmd_handle_discard(struct kvm *kvm, struct vgic_its *its,
 
 		its_free_ite(kvm, ite);
 
-		return vgic_its_write_entry_lock(its, gpa, 0, ite_esz);
+		return vgic_its_write_entry_lock(its, gpa, 0ULL, ite);
 	}
 
 	return E_ITS_DISCARD_UNMAPPED_INTERRUPT;
@@ -1147,7 +1182,6 @@ static int vgic_its_cmd_handle_mapd(struct kvm *kvm, struct vgic_its *its,
 	bool valid = its_cmd_get_validbit(its_cmd);
 	u8 num_eventid_bits = its_cmd_get_size(its_cmd);
 	gpa_t itt_addr = its_cmd_get_ittaddr(its_cmd);
-	int dte_esz = vgic_its_get_abi(its)->dte_esz;
 	struct its_device *device;
 	gpa_t gpa;
 
@@ -1172,7 +1206,7 @@ static int vgic_its_cmd_handle_mapd(struct kvm *kvm, struct vgic_its *its,
 	 * is an error, so we are done in any case.
 	 */
 	if (!valid)
-		return vgic_its_write_entry_lock(its, gpa, 0, dte_esz);
+		return vgic_its_write_entry_lock(its, gpa, 0ULL, dte);
 
 	device = vgic_its_alloc_device(its, device_id, itt_addr,
 				       num_eventid_bits);
@@ -2099,7 +2133,7 @@ static int scan_its_table(struct vgic_its *its, gpa_t base, int size, u32 esz,
  * vgic_its_save_ite - Save an interrupt translation entry at @gpa
  */
 static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev,
-			      struct its_ite *ite, gpa_t gpa, int ite_esz)
+			      struct its_ite *ite, gpa_t gpa)
 {
 	u32 next_offset;
 	u64 val;
@@ -2110,7 +2144,7 @@ static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev,
 		ite->collection->collection_id;
 	val = cpu_to_le64(val);
 
-	return vgic_its_write_entry_lock(its, gpa, val, ite_esz);
+	return vgic_its_write_entry_lock(its, gpa, val, ite);
 }
 
 /**
@@ -2210,7 +2244,7 @@ static int vgic_its_save_itt(struct vgic_its *its, struct its_device *device)
 		if (ite->irq->hw && !kvm_vgic_global_state.has_gicv4_1)
 			return -EACCES;
 
-		ret = vgic_its_save_ite(its, device, ite, gpa, ite_esz);
+		ret = vgic_its_save_ite(its, device, ite, gpa);
 		if (ret)
 			return ret;
 	}
@@ -2249,10 +2283,9 @@ static int vgic_its_restore_itt(struct vgic_its *its, struct its_device *dev)
  * @its: ITS handle
  * @dev: ITS device
  * @ptr: GPA
- * @dte_esz: device table entry size
  */
 static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev,
-			     gpa_t ptr, int dte_esz)
+			     gpa_t ptr)
 {
 	u64 val, itt_addr_field;
 	u32 next_offset;
@@ -2265,7 +2298,7 @@ static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev,
 		(dev->num_eventid_bits - 1));
 	val = cpu_to_le64(val);
 
-	return vgic_its_write_entry_lock(its, ptr, val, dte_esz);
+	return vgic_its_write_entry_lock(its, ptr, val, dte);
 }
 
 /**
@@ -2345,10 +2378,8 @@ static int vgic_its_device_cmp(void *priv, const struct list_head *a,
  */
 static int vgic_its_save_device_tables(struct vgic_its *its)
 {
-	const struct vgic_its_abi *abi = vgic_its_get_abi(its);
 	u64 baser = its->baser_device_table;
 	struct its_device *dev;
-	int dte_esz = abi->dte_esz;
 
 	if (!(baser & GITS_BASER_VALID))
 		return 0;
@@ -2367,7 +2398,7 @@ static int vgic_its_save_device_tables(struct vgic_its *its)
 		if (ret)
 			return ret;
 
-		ret = vgic_its_save_dte(its, dev, eaddr, dte_esz);
+		ret = vgic_its_save_dte(its, dev, eaddr);
 		if (ret)
 			return ret;
 	}
@@ -2448,7 +2479,7 @@ static int vgic_its_restore_device_tables(struct vgic_its *its)
 
 static int vgic_its_save_cte(struct vgic_its *its,
 			     struct its_collection *collection,
-			     gpa_t gpa, int esz)
+			     gpa_t gpa)
 {
 	u64 val;
 
@@ -2457,7 +2488,7 @@ static int vgic_its_save_cte(struct vgic_its *its,
 	       collection->collection_id);
 	val = cpu_to_le64(val);
 
-	return vgic_its_write_entry_lock(its, gpa, val, esz);
+	return vgic_its_write_entry_lock(its, gpa, val, cte);
 }
 
 /*
@@ -2465,7 +2496,7 @@ static int vgic_its_save_cte(struct vgic_its *its,
  * Return +1 on success, 0 if the entry was invalid (which should be
  * interpreted as end-of-table), and a negative error value for generic errors.
  */
-static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz)
+static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa)
 {
 	struct its_collection *collection;
 	struct kvm *kvm = its->dev->kvm;
@@ -2473,7 +2504,7 @@ static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz)
 	u64 val;
 	int ret;
 
-	ret = vgic_its_read_entry_lock(its, gpa, &val, esz);
+	ret = vgic_its_read_entry_lock(its, gpa, &val, cte);
 	if (ret)
 		return ret;
 	val = le64_to_cpu(val);
@@ -2520,7 +2551,7 @@ static int vgic_its_save_collection_table(struct vgic_its *its)
 	max_size = GITS_BASER_NR_PAGES(baser) * SZ_64K;
 
 	list_for_each_entry(collection, &its->collection_list, coll_list) {
-		ret = vgic_its_save_cte(its, collection, gpa, cte_esz);
+		ret = vgic_its_save_cte(its, collection, gpa);
 		if (ret)
 			return ret;
 		gpa += cte_esz;
@@ -2534,7 +2565,7 @@ static int vgic_its_save_collection_table(struct vgic_its *its)
 	 * table is not fully filled, add a last dummy element
 	 * with valid bit unset
 	 */
-	return vgic_its_write_entry_lock(its, gpa, 0, cte_esz);
+	return vgic_its_write_entry_lock(its, gpa, 0ULL, cte);
 }
 
 /*
@@ -2559,7 +2590,7 @@ static int vgic_its_restore_collection_table(struct vgic_its *its)
 	max_size = GITS_BASER_NR_PAGES(baser) * SZ_64K;
 
 	while (read < max_size) {
-		ret = vgic_its_restore_cte(its, gpa, cte_esz);
+		ret = vgic_its_restore_cte(its, gpa);
 		if (ret <= 0)
 			break;
 		gpa += cte_esz;
diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h
index 309295f5e1b07..f2486b4d9f956 100644
--- a/arch/arm64/kvm/vgic/vgic.h
+++ b/arch/arm64/kvm/vgic/vgic.h
@@ -146,29 +146,6 @@ static inline int vgic_write_guest_lock(struct kvm *kvm, gpa_t gpa,
 	return ret;
 }
 
-static inline int vgic_its_read_entry_lock(struct vgic_its *its, gpa_t eaddr,
-					   u64 *eval, unsigned long esize)
-{
-	struct kvm *kvm = its->dev->kvm;
-
-	if (KVM_BUG_ON(esize != sizeof(*eval), kvm))
-		return -EINVAL;
-
-	return kvm_read_guest_lock(kvm, eaddr, eval, esize);
-
-}
-
-static inline int vgic_its_write_entry_lock(struct vgic_its *its, gpa_t eaddr,
-					    u64 eval, unsigned long esize)
-{
-	struct kvm *kvm = its->dev->kvm;
-
-	if (KVM_BUG_ON(esize != sizeof(eval), kvm))
-		return -EINVAL;
-
-	return vgic_write_guest_lock(kvm, eaddr, &eval, esize);
-}
-
 /*
  * This struct provides an intermediate representation of the fields contained
  * in the GICH_VMCR and ICH_VMCR registers, such that code exporting the GIC
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 326/877] KVM: arm64: vgic-its: Skip unreachable devices instead of failing the save
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (324 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 325/877] KVM: arm64: vgic-its: Add stronger type-checking to the ITS entry sizes Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 327/877] KVM: arm64: Return -EINVAL for an empty SMCCC filter range at base 0 Greg Kroah-Hartman
                   ` (558 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Marc Zyngier, Fuad Tabba,
	Oliver Upton, Sasha Levin

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

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

From: Fuad Tabba <fuad.tabba@linux.dev>

[ Upstream commit cc5d96036e01ac330d24b2f0c336d60f82ab4930 ]

vgic_its_save_device_tables() aborts with -EINVAL when a device's entry
falls outside the device table, which a guest can arrange on its own: an
indirect table lets it clear an L1 entry's valid bit without touching
GITS_BASER. That fails a save userspace should be able to issue
reliably.

Skip the device instead, and point the saved DTE chain past it, as
commit ad1e686e2378d ("KVM: arm64: vgic-its: Point saved ITEs at the
next valid entry") does for ITEs. compute_next_devid_offset() takes the
next device off the list whether or not it was saved, so the predecessor
would otherwise point at an entry the save never wrote. Restore follows
that offset while it stays inside the table being scanned: within an L2
block, or anywhere in a flat table. Both need userspace to remove a
memslot under the table, since dropping an L1 entry takes the whole
block with it and scan_its_table() stops at the block boundary.

Fixes: 57a9a117154c9 ("KVM: arm64: vgic-its: Device table save/restore")
Suggested-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/all/86bjaz5s6v.wl-maz@kernel.org/
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://patch.msgid.link/20260821064445.615838-4-fuad.tabba@linux.dev
Signed-off-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/arm64/kvm/vgic/vgic-its.c | 32 +++++++++++++++++++-------------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c
index 8842e53734a1d..4b56de3352053 100644
--- a/arch/arm64/kvm/vgic/vgic-its.c
+++ b/arch/arm64/kvm/vgic/vgic-its.c
@@ -2038,18 +2038,22 @@ static int vgic_its_attr_regs_access(struct kvm_device *dev,
 	return ret;
 }
 
-static u32 compute_next_devid_offset(struct list_head *h,
+static u32 compute_next_devid_offset(struct vgic_its *its, u64 baser,
 				     struct its_device *dev)
 {
-	struct its_device *next;
-	u32 next_offset;
+	struct its_device *next = dev;
 
-	if (list_is_last(&dev->dev_list, h))
-		return 0;
-	next = list_next_entry(dev, dev_list);
-	next_offset = next->device_id - dev->device_id;
+	/*
+	 * Point at the next device vgic_its_save_device_tables() saves. It
+	 * sorts device_list first, so the subtraction cannot underflow.
+	 */
+	list_for_each_entry_continue(next, &its->device_list, dev_list) {
+		if (vgic_its_check_id(its, baser, next->device_id, NULL))
+			return min_t(u32, next->device_id - dev->device_id,
+				     VITS_DTE_MAX_DEVID_OFFSET);
+	}
 
-	return min_t(u32, next_offset, VITS_DTE_MAX_DEVID_OFFSET);
+	return 0;
 }
 
 static u32 compute_next_eventid_offset(struct list_head *h, struct its_ite *ite)
@@ -2281,17 +2285,18 @@ static int vgic_its_restore_itt(struct vgic_its *its, struct its_device *dev)
  * vgic_its_save_dte - Save a device table entry at a given GPA
  *
  * @its: ITS handle
+ * @baser: GITS_BASER<dev> the caller is saving against
  * @dev: ITS device
  * @ptr: GPA
  */
-static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev,
-			     gpa_t ptr)
+static int vgic_its_save_dte(struct vgic_its *its, u64 baser,
+			     struct its_device *dev, gpa_t ptr)
 {
 	u64 val, itt_addr_field;
 	u32 next_offset;
 
 	itt_addr_field = dev->itt_addr >> 8;
-	next_offset = compute_next_devid_offset(&its->device_list, dev);
+	next_offset = compute_next_devid_offset(its, baser, dev);
 	val = (1ULL << KVM_ITS_DTE_VALID_SHIFT |
 	       ((u64)next_offset << KVM_ITS_DTE_NEXT_SHIFT) |
 	       (itt_addr_field << KVM_ITS_DTE_ITTADDR_SHIFT) |
@@ -2390,15 +2395,16 @@ static int vgic_its_save_device_tables(struct vgic_its *its)
 		int ret;
 		gpa_t eaddr;
 
+		/* Don't fail a save that userspace must be able to issue. */
 		if (!vgic_its_check_id(its, baser,
 				       dev->device_id, &eaddr))
-			return -EINVAL;
+			continue;
 
 		ret = vgic_its_save_itt(its, dev);
 		if (ret)
 			return ret;
 
-		ret = vgic_its_save_dte(its, dev, eaddr);
+		ret = vgic_its_save_dte(its, baser, dev, eaddr);
 		if (ret)
 			return ret;
 	}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 327/877] KVM: arm64: Return -EINVAL for an empty SMCCC filter range at base 0
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (325 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 326/877] KVM: arm64: vgic-its: Skip unreachable devices instead of failing the save Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 328/877] KVM: arm64: Fix FGT mapping for HFGITR_EL2.nGCSEPP Greg Kroah-Hartman
                   ` (557 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Steffen Eiden,
	Fuad Tabba, Oliver Upton, Sasha Levin

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

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

From: Karl Mehltretter <kmehltretter@gmail.com>

[ Upstream commit 64dc6f1db7e620f2e9337bb181f305fb0561da79 ]

kvm_smccc_set_filter() only rejects a range if its inclusive end,
base + nr_functions - 1, is below base. That catches an empty range
(nr_functions == 0) at every nonzero base, but at base 0 the end wraps
to U32_MAX and KVM tries to insert [0, U32_MAX], which overlaps the
reserved Arm Architecture Calls ranges. KVM_ARM_VM_SMCCC_FILTER then
returns -EEXIST instead of the -EINVAL that the smccc_filter selftest
expects for an empty range.

Reject a zero function count explicitly.

Tested with a userspace reproducer on an arm64 VHE host under QEMU TCG:
EEXIST before, EINVAL after.

Fixes: 821d935c87bc ("KVM: arm64: Introduce support for userspace SMCCC filtering")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Steffen Eiden <seiden@linux.ibm.com>
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
Link: https://patch.msgid.link/20260829054856.70549-2-kmehltretter@gmail.com
Signed-off-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/arm64/kvm/hypercalls.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hypercalls.c b/arch/arm64/kvm/hypercalls.c
index ee6573befb813..82af201d60285 100644
--- a/arch/arm64/kvm/hypercalls.c
+++ b/arch/arm64/kvm/hypercalls.c
@@ -183,7 +183,8 @@ static int kvm_smccc_set_filter(struct kvm *kvm, struct kvm_smccc_filter __user
 	start = filter.base;
 	end = start + filter.nr_functions - 1;
 
-	if (end < start || filter.action >= NR_SMCCC_FILTER_ACTIONS)
+	if (!filter.nr_functions || end < start ||
+	    filter.action >= NR_SMCCC_FILTER_ACTIONS)
 		return -EINVAL;
 
 	mutex_lock(&kvm->arch.config_lock);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 328/877] KVM: arm64: Fix FGT mapping for HFGITR_EL2.nGCSEPP
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (326 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 327/877] KVM: arm64: Return -EINVAL for an empty SMCCC filter range at base 0 Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 329/877] squashfs: Add dictionary size range check to prevent shift-out-of-bounds Greg Kroah-Hartman
                   ` (556 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Leonardo Bras, Mark Brown,
	Lorenzo Stoakes (ARM), Oliver Upton, Sasha Levin

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

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

From: Mark Brown <broonie@kernel.org>

[ Upstream commit 089e4f3c4862ba3f29dff2361caa8084879194fd ]

The encoding to trap mapping currently maps a FGT on OP_GCSPOPX to
HFGITR_EL2.nGCSEPP but as per DDI0601 2026-06 this FGT controls trapping
of GCSPUSHX and GCSPOPCX, and not the separate GCSPOPX instruction.
Update the mapping to reflect the architecture.

Fixes: 863ac38984a82 ("KVM: arm64: Add missing HFGITR_EL2 FGT entries to nested virt")
Reviewed-by: Leonardo Bras <leo.bras@arm.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Link: https://patch.msgid.link/20260901-arm64-gcs-v20-2-f31750bdfadb@kernel.org
Signed-off-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/arm64/kvm/emulate-nested.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
index 05b6435d02a97..364beb6f27a1d 100644
--- a/arch/arm64/kvm/emulate-nested.c
+++ b/arch/arm64/kvm/emulate-nested.c
@@ -1287,7 +1287,7 @@ static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = {
 	SR_FGT(OP_AT_S1E1A, 		HFGITR, ATS1E1A, 1),
 	SR_FGT(OP_COSP_RCTX, 		HFGITR, COSPRCTX, 1),
 	SR_FGT(OP_GCSPUSHX, 		HFGITR, nGCSEPP, 0),
-	SR_FGT(OP_GCSPOPX, 		HFGITR, nGCSEPP, 0),
+	SR_FGT(OP_GCSPOPCX, 		HFGITR, nGCSEPP, 0),
 	SR_FGT(OP_GCSPUSHM, 		HFGITR, nGCSPUSHM_EL1, 0),
 	SR_FGT(OP_BRB_IALL, 		HFGITR, nBRBIALL, 0),
 	SR_FGT(OP_BRB_INJ, 		HFGITR, nBRBINJ, 0),
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 329/877] squashfs: Add dictionary size range check to prevent shift-out-of-bounds
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (327 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 328/877] KVM: arm64: Fix FGT mapping for HFGITR_EL2.nGCSEPP Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 330/877] scsi: sd_zbc: Reject disks with too many zones Greg Kroah-Hartman
                   ` (555 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ran Hongyun, Phillip Lougher,
	Zhihao Cheng, Christian Brauner (Amutable), Sasha Levin

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

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

From: Ran Hongyun <ranhongyun1@huawei.com>

[ Upstream commit 1f7745fb3580152ca902ef181b605f33cabfb1d0 ]

When an abnormal SquashFS image (COMP_OPTS flag is 1 but dictionary size
is 0) is mounted, and performs shift operations using dictionarysize, the
shift exponent is -1, causing a shift-out-of-bounds.

Detail as below:
squashfs_comp_opts(msblk, buffer, length)
  squashfs_xz_comp_opts()
    if (comp_opts)
      n = ffs(opts->dict_size) - 1;<----opts->dict_size=0, n=-1
      if (opts->dict_size != (1 << n) && opts->dict_size !=
	  	(1 << n) + (1 << (n + 1))) <----shift-out-of-bounds

Fix it by adding a dictionary size range check before the shift operation.

Fixes: ff750311d30a ("Squashfs: add compression options support to xz decompressor")
Signed-off-by: Ran Hongyun <ranhongyun1@huawei.com>
Link: https://patch.msgid.link/20260713115525.2661734-1-ranhongyun1@huawei.com
Reviewed-by: Phillip Lougher <phillip@squashfs.org.uk>
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/squashfs/xz_wrapper.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/fs/squashfs/xz_wrapper.c b/fs/squashfs/xz_wrapper.c
index 6c49481a2f8c4..7d54cd524d6d9 100644
--- a/fs/squashfs/xz_wrapper.c
+++ b/fs/squashfs/xz_wrapper.c
@@ -57,10 +57,10 @@ static void *squashfs_xz_comp_opts(struct squashfs_sb_info *msblk,
 
 		opts->dict_size = le32_to_cpu(comp_opts->dictionary_size);
 
-		/* the dictionary size should be 2^n or 2^n+2^(n+1) */
+		/* the dictionary size should be positive and 2^n or 2^n+2^(n+1) */
 		n = ffs(opts->dict_size) - 1;
-		if (opts->dict_size != (1 << n) && opts->dict_size != (1 << n) +
-						(1 << (n + 1))) {
+		if (opts->dict_size <= 0 || (opts->dict_size != (1 << n) &&
+			opts->dict_size != (1 << n) + (1 << (n + 1)))) {
 			err = -EIO;
 			goto out;
 		}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 330/877] scsi: sd_zbc: Reject disks with too many zones
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (328 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 329/877] squashfs: Add dictionary size range check to prevent shift-out-of-bounds Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 331/877] Bluetooth: SMP: reject Security Request over BR/EDR Greg Kroah-Hartman
                   ` (554 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, ZHOU Jiaxiang, Damien Le Moal,
	Martin K. Petersen (Oracle), Sasha Levin

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

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

From: ZHOU Jiaxiang <me@fxti.xyz>

[ Upstream commit b6ec0f79745967c751c85df373062c8d15e45fc4 ]

sd_zbc_read_zones() computes the number of zones with 64-bit arithmetic and
stores the result in the unsigned int nr_zones field of struct
zoned_disk_info, silently truncating counts that exceed 32 bits. The
truncated count is later used to size per-zone resources, while the device
may still report more zones than fit.

Moreover, sd_zbc_report_zones() counts the reported zones with a signed int
zone_idx, which overflows past INT_MAX. Reject devices reporting more than
INT_MAX zones at scan time; such a device is not realistic for any medium
that exists today, and accepting it produces inconsistent zone bookkeeping.

Fixes: 89d947561077 ("sd: Implement support for ZBC devices")
Signed-off-by: ZHOU Jiaxiang <me@fxti.xyz>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Link: https://patch.msgid.link/C41798AB5AA6BF2B+20260916135822.32584-3-me@fxti.xyz
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/scsi/sd_zbc.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c
index b8d42098f0b68..b96b49763322a 100644
--- a/drivers/scsi/sd_zbc.c
+++ b/drivers/scsi/sd_zbc.c
@@ -595,7 +595,7 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp)
 int sd_zbc_read_zones(struct scsi_disk *sdkp, struct queue_limits *lim,
 		u8 buf[SD_BUF_SIZE])
 {
-	unsigned int nr_zones;
+	u64 nr_zones;
 	u32 zone_blocks = 0;
 	int ret;
 
@@ -627,6 +627,12 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, struct queue_limits *lim,
 		goto err;
 
 	nr_zones = round_up(sdkp->capacity, zone_blocks) >> ilog2(zone_blocks);
+	if (nr_zones > INT_MAX) {
+		sd_printk(KERN_ERR, sdkp, "Too many zones (%llu)\n",
+			  nr_zones);
+		ret = -EINVAL;
+		goto err;
+	}
 	sdkp->early_zone_info.nr_zones = nr_zones;
 	sdkp->early_zone_info.zone_blocks = zone_blocks;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 331/877] Bluetooth: SMP: reject Security Request over BR/EDR
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (329 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 330/877] scsi: sd_zbc: Reject disks with too many zones Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 332/877] Bluetooth: mgmt: Dequeue pending mesh_send_sync entries on cancel Greg Kroah-Hartman
                   ` (553 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Christiano Amora,
	Luiz Augusto von Dentz, Sasha Levin

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

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

From: Christiano Amora <christiano.amora@gmail.com>

[ Upstream commit f033482d76a9f18080c7a40c5f9c678bd7adc8f3 ]

Bose QC Ultra Headphones (dual-mode, same public address on both
transports) occasionally send an SMP Security Request on the BR/EDR
SMP fixed channel right after the ACL link is encrypted. The kernel
handles it as if it were an LE link: smp_cmd_security_req() has no
transport check, smp_ltk_encrypt() looks up an LTK with the ACL
connection's dst_type, and hci_find_ltk() matches the peer's LE LTK
because the LE public address type is stored as ADDR_LE_DEV_PUBLIC (0),
the same value as BDADDR_BREDR. HCI_OP_LE_START_ENC is then issued on
the ACL handle, the controller rejects it with Invalid HCI Command
Parameters, and hci_cs_le_start_enc() disconnects the link with
HCI_ERROR_AUTH_FAILURE. The headphones drop within a second of
connecting, before any profile is up; a manual reconnect works.

btmon (MediaTek MT7922, kernel 7.0.12):

  > HCI Event: Encryption Change (0x08) plen 4
        Status: Success (0x00)
        Handle: 50 Address: BC:87:FA:47:73:5E (Bose Corporation)
        Encryption: Enabled with AES-CCM (0x02)
  > ACL Data RX: Handle 50 flags 0x02 dlen 6
        BR/EDR SMP: Security Request (0x0b) len 1
        Authentication requirement: No bonding, No MITM, SC (0x08)
  < HCI Command: LE Start Encryption (0x08|0x0019) plen 28
        Handle: 50 Address: BC:87:FA:47:73:5E (Bose Corporation)
  > HCI Event: Command Status (0x0f) plen 4
        LE Start Encryption (0x08|0x0019) ncmd 1
        Status: Invalid HCI Command Parameters (0x12)
  < HCI Command: Disconnect (0x01|0x0006) plen 3
        Handle: 50 Address: BC:87:FA:47:73:5E (Bose Corporation)
        Reason: Authentication Failure (0x05)

SMP over BR/EDR is limited to cross-transport key derivation; the
Security Request procedure (Core Specification Vol 3, Part H, Section
2.4.6, PDU in Section 3.6.7) has no BR/EDR counterpart. Reply with
Pairing Failed / Command Not Supported on a non-LE link, before the PDU
is parsed, and keep the connection. The reply is sent directly rather
than through smp_failure(): rejecting a command on the wrong transport
is not an authentication failure, and MGMT_EV_AUTH_FAILED would make
bluetoothd disconnect the device.

Tested on the affected host (kernel 7.0.12, MediaTek MT7922, Bose QC
Ultra) with the patched module built out of tree: 7 days and 49
reconnects without a drop, against 2 drops in the 3 days before the
patch. Every disconnect in that week had a userspace or remote reason.

Fixes: b5ae344d4c0f ("Bluetooth: Add full SMP BR/EDR support")
Assisted-by: LLM
Signed-off-by: Christiano Amora <christiano.amora@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/bluetooth/smp.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 9e9e9e2933096..078d5a19a846e 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -2301,6 +2301,23 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
 
 	bt_dev_dbg(hdev, "conn %p", conn);
 
+	/* SMP over BR/EDR only covers cross-transport key derivation; the
+	 * Security Request procedure has no BR/EDR counterpart. Reject it
+	 * here, otherwise smp_ltk_encrypt() finds the peer's LE LTK
+	 * (ADDR_LE_DEV_PUBLIC and BDADDR_BREDR are both 0) and issues
+	 * HCI_OP_LE_START_ENC on the ACL handle, which the controller
+	 * rejects and hci_cs_le_start_enc() turns into a disconnect. Reply
+	 * without smp_failure(): this is not an authentication failure, and
+	 * MGMT_EV_AUTH_FAILED would make bluetoothd drop the device.
+	 */
+	if (hcon->type != LE_LINK) {
+		u8 reason = SMP_CMD_NOTSUPP;
+
+		smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
+			     &reason);
+		return 0;
+	}
+
 	if (skb->len < sizeof(*rp))
 		return SMP_INVALID_PARAMS;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 332/877] Bluetooth: mgmt: Dequeue pending mesh_send_sync entries on cancel
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (330 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 331/877] Bluetooth: SMP: reject Security Request over BR/EDR Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 333/877] cgroup: selftests: Move memcontrol specific helpers out of common cgroup_util.c Greg Kroah-Hartman
                   ` (552 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Lee Jones, Luiz Augusto von Dentz,
	Sasha Levin

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

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

From: Lee Jones <lee@kernel.org>

[ Upstream commit 71af682ba4692c2ed9ace4c3d4ca462ae368c029 ]

In send_cancel(), pending mesh_tx objects are removed from the
hdev->mesh_pending list and freed via mesh_send_complete().  However, if
a mesh transmission was already queued onto hdev->cmd_sync_work_list via
mesh_next(), the queued entry retains a raw pointer to mesh_tx.

When hci_cmd_sync_work later processes the entry, it attempts to execute
mesh_send_sync and its destroy callback mesh_send_start_complete using
the already freed mesh_tx pointer, leading to a use-after-free.

Fix this by invoking hci_cmd_sync_dequeue() for mesh_send_sync on the
target mesh_tx before completing it.  If the entry is found and dequeued,
its destroy callback will complete and free the object; otherwise,
mesh_send_complete() is called directly.

Additionally, ensure the transmission queue advances after cancellation
or errors.  In mesh_send_start_complete(), call mesh_next() on error
unless err is -ECANCELED, because hci_cmd_sync_dequeue() holds
hdev->cmd_sync_work_lock and calling mesh_next() synchronously would
deadlock.  Instead, advance the queue in send_cancel() once the lock is
released and if no transmission is in progress.

Fixes: b338d91703fa ("Bluetooth: Implement support for Mesh")
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/bluetooth/mgmt.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index cdb2425a16a2c..1dc94c1518131 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2290,6 +2290,8 @@ static void mesh_send_start_complete(struct hci_dev *hdev, void *data, int err)
 		hci_dev_clear_flag(hdev, HCI_MESH_SENDING);
 		/* Send Complete Error Code for handle */
 		mesh_send_complete(hdev, mesh_tx, false);
+		if (err != -ECANCELED)
+			mesh_next(hdev, NULL, 0);
 		return;
 	}
 
@@ -2399,19 +2401,28 @@ static int send_cancel(struct hci_dev *hdev, void *data)
 		do {
 			mesh_tx = mgmt_mesh_next(hdev, cmd->sk);
 
-			if (mesh_tx)
-				mesh_send_complete(hdev, mesh_tx, false);
+			if (mesh_tx) {
+				if (!hci_cmd_sync_dequeue(hdev, mesh_send_sync,
+							  mesh_tx, NULL))
+					mesh_send_complete(hdev, mesh_tx, false);
+			}
 		} while (mesh_tx);
 	} else {
 		mesh_tx = mgmt_mesh_find(hdev, cancel->handle);
 
-		if (mesh_tx && mesh_tx->sk == cmd->sk)
-			mesh_send_complete(hdev, mesh_tx, false);
+		if (mesh_tx && mesh_tx->sk == cmd->sk) {
+			if (!hci_cmd_sync_dequeue(hdev, mesh_send_sync,
+						  mesh_tx, NULL))
+				mesh_send_complete(hdev, mesh_tx, false);
+		}
 	}
 
 	mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_MESH_SEND_CANCEL,
 			  0, NULL, 0);
 
+	if (!hci_dev_test_flag(hdev, HCI_MESH_SENDING))
+		mesh_next(hdev, NULL, 0);
+
 	return 0;
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 333/877] cgroup: selftests: Move memcontrol specific helpers out of common cgroup_util.c
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (331 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 332/877] Bluetooth: mgmt: Dequeue pending mesh_send_sync entries on cancel Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 334/877] selftests: cgroup: give the O_TMPFILE open in get_temp_fd() a mode Greg Kroah-Hartman
                   ` (551 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, James Houghton, Michal Koutný,
	Sean Christopherson, Sasha Levin

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

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

From: Sean Christopherson <seanjc@google.com>

[ Upstream commit 3a7f9e518c6a83d54c84c101e23ffc8aa12df139 ]

Move a handful of helpers out of cgroup_util.c and into test_memcontrol.c
that have nothing to with cgroups in general, in anticipation of making
cgroup_util.c a generic library that can be used by other selftests.

Make read_text() and write_text() non-static so test_memcontrol.c can
use them.

Signed-off-by: James Houghton <jthoughton@google.com>
Acked-by: Michal Koutný <mkoutny@suse.com>
Link: https://lore.kernel.org/r/20250508184649.2576210-4-jthoughton@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Stable-dep-of: c774ec8f0a5d ("selftests: cgroup: give the O_TMPFILE open in get_temp_fd() a mode")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 tools/testing/selftests/cgroup/cgroup_util.c  | 82 +------------------
 tools/testing/selftests/cgroup/cgroup_util.h  |  8 +-
 .../selftests/cgroup/test_memcontrol.c        | 78 ++++++++++++++++++
 3 files changed, 83 insertions(+), 85 deletions(-)

diff --git a/tools/testing/selftests/cgroup/cgroup_util.c b/tools/testing/selftests/cgroup/cgroup_util.c
index 1e2d46636a0ca..0ef3b8b8d7f74 100644
--- a/tools/testing/selftests/cgroup/cgroup_util.c
+++ b/tools/testing/selftests/cgroup/cgroup_util.c
@@ -20,7 +20,7 @@
 #include "../clone3/clone3_selftests.h"
 
 /* Returns read len on success, or -errno on failure. */
-static ssize_t read_text(const char *path, char *buf, size_t max_len)
+ssize_t read_text(const char *path, char *buf, size_t max_len)
 {
 	ssize_t len;
 	int fd;
@@ -39,7 +39,7 @@ static ssize_t read_text(const char *path, char *buf, size_t max_len)
 }
 
 /* Returns written len on success, or -errno on failure. */
-static ssize_t write_text(const char *path, char *buf, ssize_t len)
+ssize_t write_text(const char *path, char *buf, ssize_t len)
 {
 	int fd;
 
@@ -488,84 +488,6 @@ int cg_run_nowait(const char *cgroup,
 	return pid;
 }
 
-int get_temp_fd(void)
-{
-	return open(".", O_TMPFILE | O_RDWR | O_EXCL);
-}
-
-int alloc_pagecache(int fd, size_t size)
-{
-	char buf[PAGE_SIZE];
-	struct stat st;
-	int i;
-
-	if (fstat(fd, &st))
-		goto cleanup;
-
-	size += st.st_size;
-
-	if (ftruncate(fd, size))
-		goto cleanup;
-
-	for (i = 0; i < size; i += sizeof(buf))
-		read(fd, buf, sizeof(buf));
-
-	return 0;
-
-cleanup:
-	return -1;
-}
-
-int alloc_anon(const char *cgroup, void *arg)
-{
-	size_t size = (unsigned long)arg;
-	char *buf, *ptr;
-
-	buf = malloc(size);
-	for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
-		*ptr = 0;
-
-	free(buf);
-	return 0;
-}
-
-int is_swap_enabled(void)
-{
-	char buf[PAGE_SIZE];
-	const char delim[] = "\n";
-	int cnt = 0;
-	char *line;
-
-	if (read_text("/proc/swaps", buf, sizeof(buf)) <= 0)
-		return -1;
-
-	for (line = strtok(buf, delim); line; line = strtok(NULL, delim))
-		cnt++;
-
-	return cnt > 1;
-}
-
-int set_oom_adj_score(int pid, int score)
-{
-	char path[PATH_MAX];
-	int fd, len;
-
-	sprintf(path, "/proc/%d/oom_score_adj", pid);
-
-	fd = open(path, O_WRONLY | O_APPEND);
-	if (fd < 0)
-		return fd;
-
-	len = dprintf(fd, "%d", score);
-	if (len < 0) {
-		close(fd);
-		return len;
-	}
-
-	close(fd);
-	return 0;
-}
-
 int proc_mount_contains(const char *option)
 {
 	char buf[4 * PAGE_SIZE];
diff --git a/tools/testing/selftests/cgroup/cgroup_util.h b/tools/testing/selftests/cgroup/cgroup_util.h
index 19b131ee77072..139c870ecc285 100644
--- a/tools/testing/selftests/cgroup/cgroup_util.h
+++ b/tools/testing/selftests/cgroup/cgroup_util.h
@@ -21,6 +21,9 @@ static inline int values_close(long a, long b, int err)
 	return labs(a - b) <= (a + b) / 100 * err;
 }
 
+extern ssize_t read_text(const char *path, char *buf, size_t max_len);
+extern ssize_t write_text(const char *path, char *buf, ssize_t len);
+
 extern int cg_find_unified_root(char *root, size_t len, bool *nsdelegate);
 extern char *cg_name(const char *root, const char *name);
 extern char *cg_name_indexed(const char *root, const char *name, int index);
@@ -49,11 +52,6 @@ extern int cg_enter_current_thread(const char *cgroup);
 extern int cg_run_nowait(const char *cgroup,
 			 int (*fn)(const char *cgroup, void *arg),
 			 void *arg);
-extern int get_temp_fd(void);
-extern int alloc_pagecache(int fd, size_t size);
-extern int alloc_anon(const char *cgroup, void *arg);
-extern int is_swap_enabled(void);
-extern int set_oom_adj_score(int pid, int score);
 extern int cg_wait_for_proc_count(const char *cgroup, int count);
 extern int cg_killall(const char *cgroup);
 int proc_mount_contains(const char *option);
diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c
index 7a44d221b8c4b..44baef99fdb0e 100644
--- a/tools/testing/selftests/cgroup/test_memcontrol.c
+++ b/tools/testing/selftests/cgroup/test_memcontrol.c
@@ -24,6 +24,84 @@
 static bool has_localevents;
 static bool has_recursiveprot;
 
+int get_temp_fd(void)
+{
+	return open(".", O_TMPFILE | O_RDWR | O_EXCL);
+}
+
+int alloc_pagecache(int fd, size_t size)
+{
+	char buf[PAGE_SIZE];
+	struct stat st;
+	int i;
+
+	if (fstat(fd, &st))
+		goto cleanup;
+
+	size += st.st_size;
+
+	if (ftruncate(fd, size))
+		goto cleanup;
+
+	for (i = 0; i < size; i += sizeof(buf))
+		read(fd, buf, sizeof(buf));
+
+	return 0;
+
+cleanup:
+	return -1;
+}
+
+int alloc_anon(const char *cgroup, void *arg)
+{
+	size_t size = (unsigned long)arg;
+	char *buf, *ptr;
+
+	buf = malloc(size);
+	for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
+		*ptr = 0;
+
+	free(buf);
+	return 0;
+}
+
+int is_swap_enabled(void)
+{
+	char buf[PAGE_SIZE];
+	const char delim[] = "\n";
+	int cnt = 0;
+	char *line;
+
+	if (read_text("/proc/swaps", buf, sizeof(buf)) <= 0)
+		return -1;
+
+	for (line = strtok(buf, delim); line; line = strtok(NULL, delim))
+		cnt++;
+
+	return cnt > 1;
+}
+
+int set_oom_adj_score(int pid, int score)
+{
+	char path[PATH_MAX];
+	int fd, len;
+
+	sprintf(path, "/proc/%d/oom_score_adj", pid);
+
+	fd = open(path, O_WRONLY | O_APPEND);
+	if (fd < 0)
+		return fd;
+
+	len = dprintf(fd, "%d", score);
+	if (len < 0) {
+		close(fd);
+		return len;
+	}
+
+	close(fd);
+	return 0;
+}
+
 /*
  * This test creates two nested cgroups with and without enabling
  * the memory controller.
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 334/877] selftests: cgroup: give the O_TMPFILE open in get_temp_fd() a mode
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (332 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 333/877] cgroup: selftests: Move memcontrol specific helpers out of common cgroup_util.c Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 335/877] scsi: megaraid_sas: Protect megasas_get_ctrl_info() in megasas_resume() Greg Kroah-Hartman
                   ` (550 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Eva Kurchatova, Tejun Heo,
	Sasha Levin

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

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

From: Eva Kurchatova <eva.kurchatova@virtuozzo.com>

[ Upstream commit c774ec8f0a5d02a06d34c27f5a7de7e333b91265 ]

O_TMPFILE, like O_CREAT, needs the third argument. Without it glibc
refuses the call at compile time as soon as fortification is on:

  In function 'open',
      inlined from 'get_temp_fd' at test_memcontrol.c:33:9:
  /usr/include/bits/fcntl2.h:52:11: error: call to '__open_missing_mode'
    declared with attribute error: open with O_CREAT or O_TMPFILE in
    second argument needs 3 arguments

The fortify checks take effect only once the compiler optimises, and
cgroup/Makefile builds with "-Wall -pthread" alone, so this goes
unnoticed in a plain build. Building the tests with the flags
distributions commonly use, -O2 -D_FORTIFY_SOURCE=3, loses
test_memcontrol entirely.

Fixes: 84092dbcf901 ("selftests: cgroup: add memory controller self-tests")
Signed-off-by: Eva Kurchatova <eva.kurchatova@virtuozzo.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 tools/testing/selftests/cgroup/test_memcontrol.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c
index 44baef99fdb0e..d817aec949fe4 100644
--- a/tools/testing/selftests/cgroup/test_memcontrol.c
+++ b/tools/testing/selftests/cgroup/test_memcontrol.c
@@ -26,7 +26,7 @@ static bool has_recursiveprot;
 
 int get_temp_fd(void)
 {
-	return open(".", O_TMPFILE | O_RDWR | O_EXCL);
+	return open(".", O_TMPFILE | O_RDWR | O_EXCL, 0600);
 }
 
 int alloc_pagecache(int fd, size_t size)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 335/877] scsi: megaraid_sas: Protect megasas_get_ctrl_info() in megasas_resume()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (333 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 334/877] selftests: cgroup: give the O_TMPFILE open in get_temp_fd() a mode Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 336/877] docs: s390/pci: Improve and update PCI documentation Greg Kroah-Hartman
                   ` (549 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kashyap Desai, Sumit Saxena,
	Shivasharan S, Chandrakanth patil, Bart Van Assche,
	Martin K. Petersen (Oracle), Sasha Levin

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

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

From: Bart Van Assche <bvanassche@acm.org>

[ Upstream commit 42d1221d321e55afc7bba9109a77aaf5a817c8a3 ]

Protect the megasas_get_ctrl_info() call in megasas_resume() with
instance->reset_mutex using scoped_guard().

megasas_get_ctrl_info() may release and reacquire instance->reset_mutex.
Hence, calling this function without holding instance->reset_mutex is not
safe.

Fixes: c3b10a55abc9 ("scsi: megaraid_sas: Update controller info during resume")
Cc: Kashyap Desai <kashyap.desai@broadcom.com>
Cc: Sumit Saxena <sumit.saxena@broadcom.com>
Cc: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
Cc: Chandrakanth patil <chandrakanth.patil@broadcom.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/f06b5ee432b21cf293f0663e15b64f75a84b9fd5.1788204406.git.bvanassche@acm.org
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/scsi/megaraid/megaraid_sas_base.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 8a44e01ebf9b6..04f892832c1d9 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -7873,7 +7873,9 @@ megasas_resume(struct device *dev)
 			goto fail_init_mfi;
 	}
 
-	if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS)
+	scoped_guard(mutex, &instance->reset_mutex)
+		rval = megasas_get_ctrl_info(instance);
+	if (rval != DCMD_SUCCESS)
 		goto fail_init_mfi;
 
 	tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 336/877] docs: s390/pci: Improve and update PCI documentation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (334 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 335/877] scsi: megaraid_sas: Protect megasas_get_ctrl_info() in megasas_resume() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 337/877] s390/pci/docs: Fix sriov_numvfs attribute name Greg Kroah-Hartman
                   ` (548 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Farhan Ali, Randy Dunlap,
	Matthew Rosato, Niklas Schnelle, Gerd Bayer, Vasily Gorbik,
	Sasha Levin

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

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

From: Niklas Schnelle <schnelle@linux.ibm.com>

[ Upstream commit 737c4f4a241ca85c597ca2ef1a6f8446bf681ab5 ]

Update the s390 specific PCI documentation to better reflect current
behavior and terms such as the handling of Isolated VFs via commit
25f39d3dcb48 ("s390/pci: Ignore RID for isolated VFs").

Add a descriptions for /sys/firmware/clp/uid_checking which was added
in commit b043a81ce3ee ("s390/pci: Expose firmware provided UID Checking
state in sysfs") but missed documentation.

Similarly add documentation for the fidparm attribute added by commit
99ad39306a62 ("s390/pci: Expose FIDPARM attribute in sysfs") and
add a list of pft values and their names.

Finally improve formatting of the different attribute descriptions by
adding a separating colon.

Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
Acked-by: Randy Dunlap <rdunlap@infradead.org>
Tested-by: Randy Dunlap <rdunlap@infradead.org>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Gerd Bayer <gbayer@linux.ibm.com>
Link: https://lore.kernel.org/r/20260407-uid_slot-v8-1-15ae4409d2ce@linux.ibm.com
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Stable-dep-of: 4525a9110495 ("s390/pci/docs: Fix sriov_numvfs attribute name")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 Documentation/arch/s390/pci.rst | 152 +++++++++++++++++++++-----------
 1 file changed, 101 insertions(+), 51 deletions(-)

diff --git a/Documentation/arch/s390/pci.rst b/Documentation/arch/s390/pci.rst
index d5755484d8e75..c3476de4f0327 100644
--- a/Documentation/arch/s390/pci.rst
+++ b/Documentation/arch/s390/pci.rst
@@ -6,6 +6,7 @@ S/390 PCI
 
 Authors:
         - Pierre Morel
+        - Niklas Schnelle
 
 Copyright, IBM Corp. 2020
 
@@ -27,14 +28,16 @@ Command line parameters
 debugfs entries
 ---------------
 
-The S/390 debug feature (s390dbf) generates views to hold various debug results in sysfs directories of the form:
+The S/390 debug feature (s390dbf) generates views to hold various debug results
+in sysfs directories of the form:
 
  * /sys/kernel/debug/s390dbf/pci_*/
 
 For example:
 
   - /sys/kernel/debug/s390dbf/pci_msg/sprintf
-    Holds messages from the processing of PCI events, like machine check handling
+
+    holds messages from the processing of PCI events, like machine check handling
     and setting of global functionality, like UID checking.
 
   Change the level of logging to be more or less verbose by piping
@@ -47,87 +50,134 @@ Sysfs entries
 
 Entries specific to zPCI functions and entries that hold zPCI information.
 
-* /sys/bus/pci/slots/XXXXXXXX
+* /sys/bus/pci/slots/XXXXXXXX:
 
-  The slot entries are set up using the function identifier (FID) of the
-  PCI function. The format depicted as XXXXXXXX above is 8 hexadecimal digits
-  with 0 padding and lower case hexadecimal digits.
+  The slot entries are set up using the function identifier (FID) of the PCI
+  function as slot name. The format depicted as XXXXXXXX above is 8 hexadecimal
+  digits with 0 padding and lower case hexadecimal digits.
 
   - /sys/bus/pci/slots/XXXXXXXX/power
 
   A physical function that currently supports a virtual function cannot be
   powered off until all virtual functions are removed with:
-  echo 0 > /sys/bus/pci/devices/XXXX:XX:XX.X/sriov_numvf
+  echo 0 > /sys/bus/pci/devices/DDDD:BB:dd.f/sriov_numvf
 
-* /sys/bus/pci/devices/XXXX:XX:XX.X/
+* /sys/bus/pci/devices/DDDD:BB:dd.f/:
 
-  - function_id
-    A zPCI function identifier that uniquely identifies the function in the Z server.
+  - function_id:
+    The zPCI function identifier (FID) is a 32-bit hexadecimal value that
+    uniquely identifies the PCI function. Unless the hypervisor provides
+    a virtual FID e.g. on KVM this identifier is unique across the machine even
+    between different partitions.
 
-  - function_handle
-    Low-level identifier used for a configured PCI function.
-    It might be useful for debugging.
+  - function_handle:
+    This 32-bit hexadecimal value is a low-level identifier used for a PCI
+    function. Note that the function handle may be changed and become invalid
+    on PCI events and when enabling/disabling the PCI function.
 
-  - pchid
-    Model-dependent location of the I/O adapter.
+  - pchid:
+    This 16-bit hexadecimal value encodes a model-dependent location for
+    the PCI function.
 
-  - pfgid
-    PCI function group ID, functions that share identical functionality
+  - pfgid:
+    PCI function group ID; functions that share identical functionality
     use a common identifier.
     A PCI group defines interrupts, IOMMU, IOTLB, and DMA specifics.
 
-  - vfn
+  - vfn:
     The virtual function number, from 1 to N for virtual functions,
     0 for physical functions.
 
-  - pft
-    The PCI function type
-
-  - port
-    The port corresponds to the physical port the function is attached to.
-    It also gives an indication of the physical function a virtual function
-    is attached to.
-
-  - uid
-    The user identifier (UID) may be defined as part of the machine
-    configuration or the z/VM or KVM guest configuration. If the accompanying
-    uid_is_unique attribute is 1 the platform guarantees that the UID is unique
-    within that instance and no devices with the same UID can be attached
-    during the lifetime of the system.
-
-  - uid_is_unique
-    Indicates whether the user identifier (UID) is guaranteed to be and remain
-    unique within this Linux instance.
-
-  - pfip/segmentX
+  - pft:
+    The PCI function type is an s390-specific type attribute. It indicates
+    a more general, usage oriented, type than PCI Specification
+    class/vendor/device identifiers. That is PCI functions with the same pft
+    value may be backed by different hardware implementations. At the same time
+    apart from unclassified functions (pft is 0x00) the same pft value
+    generally implies a similar usage model. At the same time the same
+    PCI hardware device may appear with different pft values when in a
+    different usage model. For example NETD and NETH VFs may be implemented
+    by the same PCI hardware device but in NETD the parent Physical Function
+    is user managed while with NETH it is platform managed.
+
+    Currently the following PFT values are defined:
+
+    - 0x00 (UNC): Unclassified
+    - 0x02 (ROCE): RoCE Express
+    - 0x05 (ISM): Internal Shared Memory
+    - 0x0a (ROC2): RoCE Express 2
+    - 0x0b (NVMe): NVMe
+    - 0x0c (NETH): Network Express hybrid
+    - 0x0d (CNW): Cloud Network Adapter
+    - 0x0f (NETD): Network Express direct
+
+  - port:
+    The port is a decimal value corresponding to the physical port the function
+    is attached to. Virtual Functions (VFs) share the port with their parent
+    Physical Function (PF). A value of 0 indicates that the port attribute is
+    not applicable for that PCI function type.
+
+  - uid:
+    The user-defined identifier (UID) for a PCI function is a 32-bit
+    hexadecimal value. It is defined on a per instance basis as part of the
+    partition, KVM guest, or z/VM guest configuration. If UID Checking is
+    enabled the platform ensures that the UID is unique within that instance
+    and no two PCI functions with the same UID will be visible to the instance.
+
+    Independent of this guarantee and unlike the function ID (FID) the UID may
+    be the same in different partitions within the same machine. This allows to
+    create PCI configurations in multiple partitions to be identical in the
+    UID-namespace.
+
+  - uid_is_unique:
+    A 0 or 1 flag indicating whether the user-defined identifier (UID) is
+    guaranteed to be and remain unique within this Linux instance. This
+    platform feature is called UID Checking.
+
+  - pfip/segmentX:
     The segments determine the isolation of a function.
     They correspond to the physical path to the function.
     The more the segments are different, the more the functions are isolated.
 
+  - fidparm:
+    Contains an 8-bit-per-PCI function parameter field in hexadecimal provided
+    by the platform. The meaning of this field is PCI function type specific.
+    For NETH VFs a value of 0x01 indicates that the function supports
+    promiscuous mode.
+
+* /sys/firmware/clp/uid_checking:
+
+  In addition to the per-device uid_is_unique attribute this presents a
+  global indication of whether UID Checking is enabled. This allows users
+  to check for UID Checking even when no PCI functions are configured.
+
 Enumeration and hotplug
 =======================
 
 The PCI address consists of four parts: domain, bus, device and function,
-and is of this form: DDDD:BB:dd.f
+and is of this form: DDDD:BB:dd.f.
 
-* When not using multi-functions (norid is set, or the firmware does not
-  support multi-functions):
+* For a PCI function for which the platform does not expose the RID, the
+  pci=norid kernel parameter is used, or a so-called isolated Virtual Function
+  which does have RID information but is used without its parent Physical
+  Function being part of the same PCI configuration:
 
   - There is only one function per domain.
 
-  - The domain is set from the zPCI function's UID as defined during the
-    LPAR creation.
+  - The domain is set from the zPCI function's UID if UID Checking is on;
+    otherwise the domain ID is generated dynamically and is not stable
+    across reboots or hot plug.
 
-* When using multi-functions (norid parameter is not set),
-  zPCI functions are addressed differently:
+* For a PCI function for which the platform exposes the RID and which
+  is not an Isolated Virtual Function:
 
   - There is still only one bus per domain.
 
-  - There can be up to 256 functions per bus.
+  - There can be up to 256 PCI functions per bus.
 
-  - The domain part of the address of all functions for
-    a multi-Function device is set from the zPCI function's UID as defined
-    in the LPAR creation for the function zero.
+  - The domain part of the address of all functions within the same topology is
+    that of the configured PCI function with the lowest devfn within that
+    topology.
 
-  - New functions will only be ready for use after the function zero
-    (the function with devfn 0) has been enumerated.
+  - Virtual Functions generated by an SR-IOV capable Physical Function only
+    become visible once SR-IOV is enabled.
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 337/877] s390/pci/docs: Fix sriov_numvfs attribute name
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (335 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 336/877] docs: s390/pci: Improve and update PCI documentation Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 338/877] s390/cio: Fix cio_update_schib() to not cache invalid schib Greg Kroah-Hartman
                   ` (547 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Randy Dunlap,
	Heiko Carstens, Sasha Levin

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

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

From: Karl Mehltretter <kmehltretter@gmail.com>

[ Upstream commit 4525a911049543c23885a540a788d13be318a486 ]

The attribute is sriov_numvfs (drivers/pci/iov.c); the document names it
sriov_numvf, which does not exist.

Use sriov_numvfs.

Fixes: de267a7c71ba ("s390/pci: Documentation for zPCI")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 Documentation/arch/s390/pci.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/arch/s390/pci.rst b/Documentation/arch/s390/pci.rst
index c3476de4f0327..8dc09634163ba 100644
--- a/Documentation/arch/s390/pci.rst
+++ b/Documentation/arch/s390/pci.rst
@@ -60,7 +60,7 @@ Entries specific to zPCI functions and entries that hold zPCI information.
 
   A physical function that currently supports a virtual function cannot be
   powered off until all virtual functions are removed with:
-  echo 0 > /sys/bus/pci/devices/DDDD:BB:dd.f/sriov_numvf
+  echo 0 > /sys/bus/pci/devices/DDDD:BB:dd.f/sriov_numvfs
 
 * /sys/bus/pci/devices/DDDD:BB:dd.f/:
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 338/877] s390/cio: Fix cio_update_schib() to not cache invalid schib
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (336 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 337/877] s390/pci/docs: Fix sriov_numvfs attribute name Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 339/877] s390/cio: Check pmcw.dnv before pmcw.ena in I/O entry points Greg Kroah-Hartman
                   ` (546 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, William Bezenah, Vineeth Vijayan,
	Peter Oberparleiter, Heiko Carstens, Sasha Levin

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

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

From: Vineeth Vijayan <vneethv@linux.ibm.com>

[ Upstream commit 29d9e5835d89223aa913dcf7b942cc1c148bdd25 ]

When pmcw.dnv is 0, the contents of all SCHIB fields are unpredictable.
Zero sch->schib in that case to prevent subsequent code from making
decisions based on unpredictable data.

Reported-by: William Bezenah <wbezenah@linux.ibm.com>
Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Fixes: 8c58a229688c ("s390/cio: Do not unregister the subchannel based on DNV")
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/s390/cio/cio.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index ad17ab0a93149..700d8d4ba9da8 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -453,7 +453,8 @@ EXPORT_SYMBOL_GPL(cio_commit_config);
 /**
  * cio_update_schib - Perform stsch and update schib if subchannel is valid.
  * @sch: subchannel on which to perform stsch
- * Return zero on success, -ENODEV otherwise.
+ * Return zero on success, -ENODEV if the subchannel is not operational,
+ * -EACCES if the subchannel has no valid device.
  */
 int cio_update_schib(struct subchannel *sch)
 {
@@ -462,10 +463,12 @@ int cio_update_schib(struct subchannel *sch)
 	if (stsch(sch->schid, &schib))
 		return -ENODEV;
 
-	memcpy(&sch->schib, &schib, sizeof(schib));
-
-	if (!css_sch_is_valid(&schib))
+	if (!css_sch_is_valid(&schib)) {
+		memset(&sch->schib, 0, sizeof(sch->schib));
 		return -EACCES;
+	}
+
+	memcpy(&sch->schib, &schib, sizeof(schib));
 
 	return 0;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 339/877] s390/cio: Check pmcw.dnv before pmcw.ena in I/O entry points
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (337 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 338/877] s390/cio: Fix cio_update_schib() to not cache invalid schib Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 340/877] s390/cio: Guard PMCW field accesses with dnv check Greg Kroah-Hartman
                   ` (545 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, William Bezenah, Vineeth Vijayan,
	Peter Oberparleiter, Heiko Carstens, Sasha Levin

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

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

From: Vineeth Vijayan <vneethv@linux.ibm.com>

[ Upstream commit f6f2985eabdb2bfdc82ce90a1ea3ec53ba795f34 ]

The device number valid (dnv) bit in the PMCW must be checked before
acting on any other PMCW fields for IO-type subchannels. A subchannel
with dnv=0 has no valid device number associated, making it meaningless
to evaluate the enabled (ena) state or issue any I/O instruction against
it.

Reported-by: William Bezenah <wbezenah@linux.ibm.com>
Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Fixes: 8c58a229688c ("s390/cio: Do not unregister the subchannel based on DNV")
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/s390/cio/device_ops.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index acd6790dba4dd..c0289b81a0d71 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -142,6 +142,8 @@ int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
 	if (!cdev || !cdev->dev.parent)
 		return -ENODEV;
 	sch = to_subchannel(cdev->dev.parent);
+	if (!sch->schib.pmcw.dnv)
+		return -ENODEV;
 	if (!sch->schib.pmcw.ena)
 		return -EINVAL;
 	if (cdev->private->state == DEV_STATE_NOT_OPER)
@@ -198,6 +200,8 @@ int ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa,
 	if (!cdev || !cdev->dev.parent)
 		return -ENODEV;
 	sch = to_subchannel(cdev->dev.parent);
+	if (!sch->schib.pmcw.dnv)
+		return -ENODEV;
 	if (!sch->schib.pmcw.ena)
 		return -EINVAL;
 	if (cdev->private->state == DEV_STATE_NOT_OPER)
@@ -379,6 +383,8 @@ int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)
 	if (!cdev || !cdev->dev.parent)
 		return -ENODEV;
 	sch = to_subchannel(cdev->dev.parent);
+	if (!sch->schib.pmcw.dnv)
+		return -ENODEV;
 	if (!sch->schib.pmcw.ena)
 		return -EINVAL;
 	if (cdev->private->state == DEV_STATE_NOT_OPER)
@@ -413,6 +419,8 @@ int ccw_device_resume(struct ccw_device *cdev)
 	if (!cdev || !cdev->dev.parent)
 		return -ENODEV;
 	sch = to_subchannel(cdev->dev.parent);
+	if (!sch->schib.pmcw.dnv)
+		return -ENODEV;
 	if (!sch->schib.pmcw.ena)
 		return -EINVAL;
 	if (cdev->private->state == DEV_STATE_NOT_OPER)
@@ -548,6 +556,8 @@ int ccw_device_tm_start_timeout_key(struct ccw_device *cdev, struct tcw *tcw,
 	int rc;
 
 	sch = to_subchannel(cdev->dev.parent);
+	if (!sch->schib.pmcw.dnv)
+		return -ENODEV;
 	if (!sch->schib.pmcw.ena)
 		return -EINVAL;
 	if (cdev->private->state == DEV_STATE_VERIFY) {
@@ -694,6 +704,8 @@ int ccw_device_tm_intrg(struct ccw_device *cdev)
 {
 	struct subchannel *sch = to_subchannel(cdev->dev.parent);
 
+	if (!sch->schib.pmcw.dnv)
+		return -ENODEV;
 	if (!sch->schib.pmcw.ena)
 		return -EINVAL;
 	if (cdev->private->state != DEV_STATE_ONLINE)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 340/877] s390/cio: Guard PMCW field accesses with dnv check
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (338 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 339/877] s390/cio: Check pmcw.dnv before pmcw.ena in I/O entry points Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes() Greg Kroah-Hartman
                   ` (544 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, William Bezenah, Vineeth Vijayan,
	Peter Oberparleiter, Heiko Carstens, Sasha Levin

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

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

From: Vineeth Vijayan <vneethv@linux.ibm.com>

[ Upstream commit 9590f4d83880dfb5a81906e48e72779248fbe8f0 ]

When PMCW.DNV is 0, no I/O device is associated with the subchannel.
However, several code paths access PMCW fields directly from the cached
sch->schib without first invoking the update helper. Add explicit DNV
validation before accessing PMCW fields from the cached SCHIB to avoid
using invalid data.

Reported-by: William Bezenah <wbezenah@linux.ibm.com>
Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Fixes: 8c58a229688c ("s390/cio: Do not unregister the subchannel based on DNV")
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/s390/cio/chp.c          | 3 +++
 drivers/s390/cio/device.c       | 9 +++++----
 drivers/s390/cio/device_fsm.c   | 3 +++
 drivers/s390/cio/device_ops.c   | 9 +++++++++
 drivers/s390/cio/vfio_ccw_fsm.c | 2 +-
 5 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 0c5bda060249e..b6ef882f98607 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -78,6 +78,9 @@ u8 chp_get_sch_opm(struct subchannel *sch)
 	int opm;
 	int i;
 
+	if (!sch->schib.pmcw.dnv)
+		return 0;
+
 	opm = 0;
 	chp_id_init(&chpid);
 	for (i = 0; i < 8; i++) {
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 7e309ea2e177c..b6e2839dfeb37 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -925,7 +925,7 @@ static int ccw_device_move_to_sch(struct ccw_device *cdev,
 
 	if (!sch_is_pseudo_sch(old_sch)) {
 		spin_lock_irq(&old_sch->lock);
-		old_enabled = old_sch->schib.pmcw.ena;
+		old_enabled = old_sch->schib.pmcw.dnv && old_sch->schib.pmcw.ena;
 		rc = 0;
 		if (old_enabled)
 			rc = cio_disable_subchannel(old_sch);
@@ -944,7 +944,7 @@ static int ccw_device_move_to_sch(struct ccw_device *cdev,
 		CIO_MSG_EVENT(0, "device_move(0.%x.%04x,0.%x.%04x)=%d\n",
 			      cdev->private->dev_id.ssid,
 			      cdev->private->dev_id.devno, sch->schid.ssid,
-			      sch->schib.pmcw.dev, rc);
+			      sch->schid.sch_no, rc);
 		if (old_enabled) {
 			/* Try to re-enable the old subchannel. */
 			spin_lock_irq(&old_sch->lock);
@@ -1210,7 +1210,7 @@ static void io_subchannel_quiesce(struct subchannel *sch)
 	cdev = sch_get_cdev(sch);
 	if (cio_is_console(sch->schid))
 		goto out_unlock;
-	if (!sch->schib.pmcw.ena)
+	if (!sch->schib.pmcw.dnv || !sch->schib.pmcw.ena)
 		goto out_unlock;
 	ret = cio_disable_subchannel(sch);
 	if (ret != -EBUSY)
@@ -1257,7 +1257,8 @@ static int recovery_check(struct device *dev, void *data)
 	switch (cdev->private->state) {
 	case DEV_STATE_ONLINE:
 		sch = to_subchannel(cdev->dev.parent);
-		if ((sch->schib.pmcw.pam & sch->opm) == sch->vpm)
+		if (sch->schib.pmcw.dnv &&
+		    (sch->schib.pmcw.pam & sch->opm) == sch->vpm)
 			break;
 		fallthrough;
 	case DEV_STATE_DISCONNECTED:
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 42791fa0b80e2..96bab4cde37a2 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -169,6 +169,9 @@ __recover_lost_chpids(struct subchannel *sch, int old_lpm)
 	int mask, i;
 	struct chp_id chpid;
 
+	if (!sch->schib.pmcw.dnv)
+		return;
+
 	chp_id_init(&chpid);
 	for (i = 0; i<8; i++) {
 		mask = 0x80 >> i;
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index c0289b81a0d71..8fe3ff4f0855d 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -490,6 +490,8 @@ struct channel_path_desc_fmt0 *ccw_device_get_chp_desc(struct ccw_device *cdev,
 	struct chp_id chpid;
 
 	sch = to_subchannel(cdev->dev.parent);
+	if (!sch->schib.pmcw.dnv)
+		return NULL;
 	chp_id_init(&chpid);
 	chpid.id = sch->schib.pmcw.chpid[chp_idx];
 	return chp_get_chp_desc(chpid);
@@ -510,6 +512,8 @@ u8 *ccw_device_get_util_str(struct ccw_device *cdev, int chp_idx)
 	struct chp_id chpid;
 	u8 *util_str;
 
+	if (!sch->schib.pmcw.dnv)
+		return NULL;
 	chp_id_init(&chpid);
 	chpid.id = sch->schib.pmcw.chpid[chp_idx];
 	chp = chpid_to_chp(chpid);
@@ -662,6 +666,9 @@ int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask)
 	struct chp_id chpid;
 	int mdc = 0, i;
 
+	if (!sch->schib.pmcw.dnv)
+		return 0;
+
 	/* Adjust requested path mask to excluded varied off paths. */
 	if (mask)
 		mask &= sch->lpm;
@@ -798,6 +805,8 @@ int ccw_device_get_chpid(struct ccw_device *cdev, int chp_idx, u8 *chpid)
 
 	if ((chp_idx < 0) || (chp_idx > 7))
 		return -EINVAL;
+	if (!sch->schib.pmcw.dnv)
+		return -ENODEV;
 	mask = 0x80 >> chp_idx;
 	if (!(sch->schib.pmcw.pim & mask))
 		return -ENODEV;
diff --git a/drivers/s390/cio/vfio_ccw_fsm.c b/drivers/s390/cio/vfio_ccw_fsm.c
index 5fd94e9d5c618..9a000b0231d60 100644
--- a/drivers/s390/cio/vfio_ccw_fsm.c
+++ b/drivers/s390/cio/vfio_ccw_fsm.c
@@ -399,7 +399,7 @@ static void fsm_close(struct vfio_ccw_private *private,
 
 	spin_lock_irq(&sch->lock);
 
-	if (!sch->schib.pmcw.ena)
+	if (!sch->schib.pmcw.dnv || !sch->schib.pmcw.ena)
 		goto err_unlock;
 
 	ret = cio_disable_subchannel(sch);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (339 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 340/877] s390/cio: Guard PMCW field accesses with dnv check Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-10-01 19:58   ` Harshit Mogalapalli
  2026-09-30 15:20 ` [PATCH 6.12 342/877] xsk: Use a 32-bit compare in xsk_map_gen_lookup Greg Kroah-Hartman
                   ` (543 subsequent siblings)
  884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Julian Sun, Jan Kara,
	Christian Brauner (Amutable), Sasha Levin

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

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

From: Julian Sun <sunjunchao@bytedance.com>

[ Upstream commit 7459c021874246c196f397686e100702f059b9e7 ]

We observed hung tasks when users attempted to unmount a filesystem
after its disk had been removed while still in use. During device
removal, fs_bdev_mark_dead() calls evict_inodes() while holding s_umount.

Each time evict_inodes() drops s_inode_list_lock to reschedule, it
restarts the walk from the head of s_inodes. With many referenced inodes
at the head of the list, these restarts repeatedly scan the same inodes
without reclaiming them. This can keep s_umount held for a long time,
blocking concurrent umount attempts and triggering hung-task reports.

Keep the current inode, already marked I_FREEING, out of the disposal
batch until s_inode_list_lock is reacquired. Resume the walk from this
inode and dispose of it in a later batch or at the end of the walk.

The zero-refcount and state checks under i_lock allow this walker to
claim the inode by setting I_FREEING and removing it from the LRU.
Other reclaimers skip the inode, leaving this walker responsible for
eviction. Only evict() removes it from s_inodes, so keeping it out of
the disposal batch ensures that it remains on the list while the lock
is dropped. After reacquiring the lock, reading its current next pointer
accounts for concurrent removal of following inodes.

The existing inode lifetime rules prohibit acquiring a reference to an
inode marked I_FREEING or I_WILL_FREE. __iget() requires its caller to
hold i_lock and establish that taking a reference is valid. Inode lookup
and igrab() check these flags under i_lock when acquiring a reference
from zero. ihold() requires an existing reference, which would keep
i_count nonzero and prevent this walker from claiming the inode. These
rules already allow iput_final() and the inode shrinker to release
i_lock after setting I_FREEING and before eviction completes.

A temporary __iget() reference would also keep the inode on the list,
but its release must preserve last-reference handling. Another user can
acquire a reference, update lazy timestamps and drop its reference while
the pin is held. If the pin becomes the last reference, dropping it with
atomic_dec_and_test() and evicting directly bypasses iput()'s lazytime
handling and can lose those timestamp updates.

Releasing the pin with iput() preserves that handling, but does not
guarantee eviction. fs_bdev_mark_dead() runs with SB_ACTIVE set, so iput()
may retain the inode in cache, whereas evict_inodes() must evict eligible
zero-reference inodes. The inode may also have been freed when iput()
returns, so the walker cannot then use it to force eviction. Using
I_FREEING preserves the existing eviction behavior without introducing
an additional last-reference transition.

The xfstests auto group passed on ext4 and XFS with known unrelated
failures excluded. No new issues were observed, and the previously
reproducible hung task no longer occurs with this patch.

Fixes: ac05fbb40062 ("inode: don't softlockup when evicting inodes")
Signed-off-by: Julian Sun <sunjunchao@bytedance.com>
Link: https://patch.msgid.link/20260915044912.3183440-1-sunjunchao@bytedance.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/inode.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/fs/inode.c b/fs/inode.c
index 8dabb224f941c..8592fd1a18526 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -790,7 +790,6 @@ void evict_inodes(struct super_block *sb)
 	struct inode *inode, *next;
 	LIST_HEAD(dispose);
 
-again:
 	spin_lock(&sb->s_inode_list_lock);
 	list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
 		if (atomic_read(&inode->i_count))
@@ -809,19 +808,19 @@ void evict_inodes(struct super_block *sb)
 		inode->i_state |= I_FREEING;
 		inode_lru_list_del(inode);
 		spin_unlock(&inode->i_lock);
-		list_add(&inode->i_lru, &dispose);
 
 		/*
-		 * We can have a ton of inodes to evict at unmount time given
-		 * enough memory, check to see if we need to go to sleep for a
-		 * bit so we don't livelock.
+		 * Keep this inode out of dispose so it stays on s_inodes while
+		 * the list lock is dropped. I_FREEING prevents new references
+		 * and leaves eviction to us, so we can resume the walk from it.
 		 */
 		if (need_resched()) {
 			spin_unlock(&sb->s_inode_list_lock);
 			cond_resched();
 			dispose_list(&dispose);
-			goto again;
+			spin_lock(&sb->s_inode_list_lock);
 		}
+		list_add(&inode->i_lru, &dispose);
 	}
 	spin_unlock(&sb->s_inode_list_lock);
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 342/877] xsk: Use a 32-bit compare in xsk_map_gen_lookup
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (340 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes() Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 343/877] bpf: Skip unsettled links in link iterator Greg Kroah-Hartman
                   ` (542 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Zhiling Zou,
	Alexei Starovoitov, Emil Tsalapatis, Eduard Zingerman,
	Sasha Levin

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

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

From: Zhiling Zou <zhilinz@nebusec.ai>

[ Upstream commit 70504de0bb627848667207bec7ccfd647deb8814 ]

xsk_map_gen_lookup() loads a u32 key and compares it with max_entries
using BPF_JMP_IMM. BPF immediates are sign-extended to 64 bits, so a
max_entries value of 0x80000000 or higher becomes a threshold larger
than every zero-extended 32-bit key. An out-of-range index then skips
the bounds check and the generated lookup reads past xsk_map[].

Compare with BPF_JMP32_IMM so the check stays in 32-bit unsigned range.

Fixes: e65650f291ee ("bpf: Implement map_gen_lookup() callback for XSKMAP")
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Link: https://patch.msgid.link/7d2cb8e8dfaa9eb8fdff85156987a60960787dc3.1789056660.git.zhilinz@nebusec.ai
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/xdp/xskmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/xdp/xskmap.c b/net/xdp/xskmap.c
index afa457506274c..607f8b7e16d96 100644
--- a/net/xdp/xskmap.c
+++ b/net/xdp/xskmap.c
@@ -124,7 +124,7 @@ static int xsk_map_gen_lookup(struct bpf_map *map, struct bpf_insn *insn_buf)
 	struct bpf_insn *insn = insn_buf;
 
 	*insn++ = BPF_LDX_MEM(BPF_W, ret, index, 0);
-	*insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 5);
+	*insn++ = BPF_JMP32_IMM(BPF_JGE, ret, map->max_entries, 5);
 	*insn++ = BPF_ALU64_IMM(BPF_LSH, ret, ilog2(sizeof(struct xsk_sock *)));
 	*insn++ = BPF_ALU64_IMM(BPF_ADD, mp, offsetof(struct xsk_map, xsk_map));
 	*insn++ = BPF_ALU64_REG(BPF_ADD, ret, mp);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 343/877] bpf: Skip unsettled links in link iterator
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (341 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 342/877] xsk: Use a 32-bit compare in xsk_map_gen_lookup Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 344/877] net/sched: cls_u32: fix manual hash table handle IDR aliasing Greg Kroah-Hartman
                   ` (541 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Xiang Mei, Weiming Shi,
	Andrii Nakryiko, Sasha Levin

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

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

From: Weiming Shi <bestswngs@gmail.com>

[ Upstream commit 50e80e2bb5e2be8515205b9c496b9640ddefa434 ]

bpf_link_prime() inserts a link into link_idr before anon_inode_getfile()
succeeds and before bpf_link_settle() publishes the ID in link->id.
bpf_link_by_id() treats such an ID-zero link as unsettled, but the link
iterator takes a reference without this check.

If anon_inode_getfile() then fails, the creator removes the ID and frees
its still-private link directly.  The iterator is left with a dangling
reference and its next bpf_link_put() accesses freed memory.

Treat ID-zero entries as transient in bpf_link_get_curr_or_next(), just as
bpf_link_by_id() does.

  BUG: KASAN: slab-use-after-free in bpf_link_put
  Write of size 8 by task exp/384
  Call Trace:
  bpf_link_put                    kernel/bpf/syscall.c:3372
  bpf_link_seq_next               kernel/bpf/link_iter.c:33
  bpf_seq_read                    kernel/bpf/bpf_iter.c:158
  vfs_read                        fs/read_write.c:572
  ksys_read                       fs/read_write.c:716
  do_syscall_64                   arch/x86/entry/syscall_64.c:84
  entry_SYSCALL_64_after_hwframe  arch/x86/entry/entry_64.S:121
  Kernel panic - not syncing: KASAN: panic_on_warn set ...

Fixes: 9f8836127308 ("bpf: Add bpf_link iterator")
Reported-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20260914170206.170723-2-bestswngs@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/syscall.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 954b299f241b6..857285a48d433 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -5472,7 +5472,10 @@ struct bpf_link *bpf_link_get_curr_or_next(u32 *id)
 again:
 	link = idr_get_next(&link_idr, id);
 	if (link) {
-		link = bpf_link_inc_not_zero(link);
+		if (link->id)
+			link = bpf_link_inc_not_zero(link);
+		else
+			link = ERR_PTR(-EAGAIN);
 		if (IS_ERR(link)) {
 			(*id)++;
 			goto again;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 344/877] net/sched: cls_u32: fix manual hash table handle IDR aliasing
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (342 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 343/877] bpf: Skip unsettled links in link iterator Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 345/877] net/mlx5: devcom, Base component size on linked devices Greg Kroah-Hartman
                   ` (540 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko (gemini + nipa),
	Victor Nogueira, hybris, Jamal Hadi Salim, Simon Horman,
	Jakub Kicinski, Sasha Levin

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

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

From: Jamal Hadi Salim <jhs@mojatatu.com>

[ Upstream commit 0a5f5d9e94dead312d32c366b917c64e552b72f7 ]

A u32 hash table created with an explicit handle ('tc filter add ...
handle 801: u32 divisor N') keys its IDR entry on the raw handle, while
the destroy paths free it under handle2id(handle). The two key domains
disagree for handles in the 0x800..0xFFF htid range:
handle2id() folds them back into the auto-allocated id space (1..0x7FF).

A manual table therefore leaves its raw-keyed IDR entry unreachable on
delete (a permanent leak), and its delete can drop the idr entry of an
unrelated live auto table. A later auto allocation can then hand out a
handle that aliases the live manual table; u32_lookup_ht() first-match
routes lookups and TCA_U32_LINK for that htid to the wrong table.

Key the divisor-path alloc on handle2id(handle) so allocation and
removal share one key domain. A manual handle that maps onto an id
already in use is rejected with -ENOSPC, and auto allocation skips ids
held by live manual tables.

Conditions to recreate:
  ip link add test0 type dummy
  tc qdisc add dev test0 clsact
  tc filter add dev test0 ingress protocol ip pref 1 \
          handle 801: u32 divisor 16
  tc filter add dev test0 ingress protocol ip pref 2 u32 divisor 16
  tc -d filter show dev test0 ingress | grep 'fh 801:'
  # unpatched: two live tables with handle 0x80100000 (the pref 2 root
  # hnode is auto-allocated id 1); patched: the auto hnode takes id 2.

Also tested with a poc with a live u32 table on the block, add/delete a manual
table 'handle 901: u32 divisor 1' twice; unpatched, the re-add fails with
-ENOSPC because the raw key leaked on the first delete.

Fixes: 73af53d82076 ("net: sched: cls_u32: Fix u32's systematic failure to free IDR entries for hnodes.")
Reported-by: Sashiko (gemini + nipa) <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260822222049.114526-1-jhs@mojatatu.com
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Tested-by: hybris <hybris@mojatatu.ai>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/QDISC-LQFE.v1.20260911041746.1@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/sched/cls_u32.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 83a60698cc009..e5e5533f866dc 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -1000,8 +1000,16 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
 				return -ENOMEM;
 			}
 		} else {
-			err = idr_alloc_u32(&tp_c->handle_idr, ht, &handle,
-					    handle, GFP_KERNEL);
+			/* The IDR is keyed on the mapped id, and that is
+			 * what the destroy paths remove. Ask for it here,
+			 * so a manual handle colliding with the
+			 * auto-allocated id space is rejected (-ENOSPC)
+			 * instead of aliasing a future auto id.
+			 */
+			u32 id = handle2id(handle);
+
+			err = idr_alloc_u32(&tp_c->handle_idr, ht, &id, id,
+					    GFP_KERNEL);
 			if (err) {
 				kfree(ht);
 				return err;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 345/877] net/mlx5: devcom, Base component size on linked devices
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (343 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 344/877] net/sched: cls_u32: fix manual hash table handle IDR aliasing Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 346/877] bpf: Restrict CO-RE poisoning to relocatable instructions Greg Kroah-Hartman
                   ` (539 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Shay Drory, Akiva Goldberger,
	Tariq Toukan, Jakub Kicinski, Sasha Levin

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

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

From: Shay Drory <shayd@nvidia.com>

[ Upstream commit d09e8f64653c93da5793c16be19330968f2a32e6 ]

mlx5_devcom_comp_get_size() returns the component's kref count. That
kref is bumped in mlx5_devcom_register_component() under comp_list_lock,
before the comp_dev is linked onto comp_dev_list_head under comp->sem.
The event broadcast (mlx5_devcom_locked_send_event()) walks that list.

Hence, a caller can read the expected size, but send_event won't be sent
to all peers. In the SD group registration path, this lets a member
broadcast its role-election event over an incomplete list, electing a
primary that never completes the group, is never marked ready, and
leaves the group with a stale primary.

Track the number of linked comp_devs in a dedicated counter, maintained
under comp->sem together with the list add/remove, and return it from
mlx5_devcom_comp_get_size().

Fixes: 9bb1ac80738a ("net/mlx5: devcom, Add component size getter")
Signed-off-by: Shay Drory <shayd@nvidia.com>
Reviewed-by: Akiva Goldberger <agoldberger@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260915113459.3934760-2-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
index 7b0766c89f4cf..cd8ce2abcf189 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c
@@ -29,6 +29,7 @@ struct mlx5_devcom_comp {
 	struct list_head comp_dev_list_head;
 	mlx5_devcom_event_handler_t handler;
 	struct kref ref;
+	int nr_devs;
 	bool ready;
 	struct rw_semaphore sem;
 	struct lock_class_key lock_key;
@@ -158,6 +159,7 @@ devcom_alloc_comp_dev(struct mlx5_devcom_dev *devc,
 
 	down_write(&comp->sem);
 	list_add_tail(&devcom->list, &comp->comp_dev_list_head);
+	WRITE_ONCE(comp->nr_devs, comp->nr_devs + 1);
 	up_write(&comp->sem);
 
 	return devcom;
@@ -170,6 +172,7 @@ devcom_free_comp_dev(struct mlx5_devcom_comp_dev *devcom)
 
 	down_write(&comp->sem);
 	list_del(&devcom->list);
+	WRITE_ONCE(comp->nr_devs, comp->nr_devs - 1);
 	up_write(&comp->sem);
 
 	kref_put(&devcom->devc->ref, mlx5_devcom_dev_release);
@@ -260,7 +263,7 @@ int mlx5_devcom_comp_get_size(struct mlx5_devcom_comp_dev *devcom)
 {
 	struct mlx5_devcom_comp *comp = devcom->comp;
 
-	return kref_read(&comp->ref);
+	return READ_ONCE(comp->nr_devs);
 }
 
 int mlx5_devcom_send_event(struct mlx5_devcom_comp_dev *devcom,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 346/877] bpf: Restrict CO-RE poisoning to relocatable instructions
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (344 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 345/877] net/mlx5: devcom, Base component size on linked devices Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 347/877] libbpf: Reject truncated ldimm64 CO-RE relocations Greg Kroah-Hartman
                   ` (538 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nicholas Carlini,
	Kumar Kartikeya Dwivedi, Eduard Zingerman, Sasha Levin

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

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

From: Kumar Kartikeya Dwivedi <memxor@gmail.com>

[ Upstream commit 394ae398337c5f87e567f6cd63b937fc2b2f6ddc ]

CO-RE relocation records can name any instruction offset. When a
relocation cannot be resolved, bpf_core_patch_insn() currently poisons its
target before checking whether that instruction is a valid relocation
target. Malformed metadata can therefore replace jumps, calls, exits,
register-source arithmetic, or non-immediate loads instead of failing at
the relocation step.

Handle poisoning only after the instruction has passed the same class and
operand-form checks used for a resolved relocation. Route invalid forms
through the existing diagnostic and return a hard error. Keep poisoning
supported instructions, including both halves of a plain ldimm64, so an
unresolved relocation in dead code remains valid.

Extend bpf_core_poison_insn() to poison both halves of ldimm64, and return
its status directly from each validated instruction case. This avoids
routing the success path through a common label and leaves the helper free
to report errors.

The shared relocation code applies this restriction to both libbpf and
in-kernel CO-RE.

Fixes: d7a252708dbc ("libbpf: Improve handling of failed CO-RE relocations")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://patch.msgid.link/20260917233222.2542500-7-memxor@gmail.com
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 tools/lib/bpf/relo_core.c | 58 +++++++++++++++++++++------------------
 1 file changed, 31 insertions(+), 27 deletions(-)

diff --git a/tools/lib/bpf/relo_core.c b/tools/lib/bpf/relo_core.c
index 04c8febfc0aa7..4367378d272b3 100644
--- a/tools/lib/bpf/relo_core.c
+++ b/tools/lib/bpf/relo_core.c
@@ -965,23 +965,30 @@ static int bpf_core_calc_relo(const char *prog_name,
 }
 
 /*
- * Turn instruction for which CO_RE relocation failed into invalid one with
+ * Turn instruction for which CO-RE relocation failed into invalid one with
  * distinct signature.
  */
-static void bpf_core_poison_insn(const char *prog_name, int relo_idx,
-				 int insn_idx, struct bpf_insn *insn)
+static int bpf_core_poison_insn(const char *prog_name, int relo_idx,
+				struct bpf_insn *insn, int insn_idx)
 {
-	pr_debug("prog '%s': relo #%d: substituting insn #%d w/ invalid insn\n",
-		 prog_name, relo_idx, insn_idx);
-	insn->code = BPF_JMP | BPF_CALL;
-	insn->dst_reg = 0;
-	insn->src_reg = 0;
-	insn->off = 0;
-	/* if this instruction is reachable (not a dead code),
-	 * verifier will complain with the following message:
-	 * invalid func unknown#195896080
-	 */
-	insn->imm = 195896080; /* => 0xbad2310 => "bad relo" */
+	int insn_cnt = is_ldimm64_insn(insn) ? 2 : 1;
+	int i;
+
+	for (i = 0; i < insn_cnt; i++) {
+		pr_debug("prog '%s': relo #%d: substituting insn #%d w/ invalid insn\n",
+			 prog_name, relo_idx, insn_idx + i);
+		insn[i].code = BPF_JMP | BPF_CALL;
+		insn[i].dst_reg = 0;
+		insn[i].src_reg = 0;
+		insn[i].off = 0;
+		/*
+		 * If this instruction is reachable (not dead code), the verifier
+		 * will complain with "invalid func unknown#195896080".
+		 */
+		insn[i].imm = 195896080; /* => 0xbad2310 => "bad relo" */
+	}
+
+	return 0;
 }
 
 static int insn_bpf_size_to_bytes(struct bpf_insn *insn)
@@ -1032,17 +1039,6 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,
 
 	class = BPF_CLASS(insn->code);
 
-	if (res->poison) {
-poison:
-		/* poison second part of ldimm64 to avoid confusing error from
-		 * verifier about "unknown opcode 00"
-		 */
-		if (is_ldimm64_insn(insn))
-			bpf_core_poison_insn(prog_name, relo_idx, insn_idx + 1, insn + 1);
-		bpf_core_poison_insn(prog_name, relo_idx, insn_idx, insn);
-		return 0;
-	}
-
 	orig_val = res->orig_val;
 	new_val = res->new_val;
 
@@ -1050,7 +1046,9 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,
 	case BPF_ALU:
 	case BPF_ALU64:
 		if (BPF_SRC(insn->code) != BPF_K)
-			return -EINVAL;
+			goto bad_insn;
+		if (res->poison)
+			return bpf_core_poison_insn(prog_name, relo_idx, insn, insn_idx);
 		if (res->validate && insn->imm != orig_val) {
 			pr_warn("prog '%s': relo #%d: unexpected insn #%d (ALU/ALU64) value: got %u, exp %llu -> %llu\n",
 				prog_name, relo_idx,
@@ -1067,6 +1065,8 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,
 	case BPF_LDX:
 	case BPF_ST:
 	case BPF_STX:
+		if (res->poison)
+			return bpf_core_poison_insn(prog_name, relo_idx, insn, insn_idx);
 		if (res->validate && insn->off != orig_val) {
 			pr_warn("prog '%s': relo #%d: unexpected insn #%d (LDX/ST/STX) value: got %u, exp %llu -> %llu\n",
 				prog_name, relo_idx, insn_idx, insn->off, (unsigned long long)orig_val,
@@ -1082,7 +1082,7 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,
 			pr_warn("prog '%s': relo #%d: insn #%d (LDX/ST/STX) accesses field incorrectly. "
 				"Make sure you are accessing pointers, unsigned integers, or fields of matching type and size.\n",
 				prog_name, relo_idx, insn_idx);
-			goto poison;
+			return bpf_core_poison_insn(prog_name, relo_idx, insn, insn_idx);
 		}
 
 		orig_val = insn->off;
@@ -1125,6 +1125,9 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,
 			return -EINVAL;
 		}
 
+		if (res->poison)
+			return bpf_core_poison_insn(prog_name, relo_idx, insn, insn_idx);
+
 		imm = (__u32)insn[0].imm | ((__u64)insn[1].imm << 32);
 		if (res->validate && imm != orig_val) {
 			pr_warn("prog '%s': relo #%d: unexpected insn #%d (LDIMM64) value: got %llu, exp %llu -> %llu\n",
@@ -1142,6 +1145,7 @@ int bpf_core_patch_insn(const char *prog_name, struct bpf_insn *insn,
 		break;
 	}
 	default:
+bad_insn:
 		pr_warn("prog '%s': relo #%d: trying to relocate unrecognized insn #%d, code:0x%x, src:0x%x, dst:0x%x, off:0x%x, imm:0x%x\n",
 			prog_name, relo_idx, insn_idx, insn->code,
 			insn->src_reg, insn->dst_reg, insn->off, insn->imm);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 347/877] libbpf: Reject truncated ldimm64 CO-RE relocations
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (345 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 346/877] bpf: Restrict CO-RE poisoning to relocatable instructions Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:20 ` [PATCH 6.12 348/877] netfilter: flowtable: publish HW_DEAD after worker is done Greg Kroah-Hartman
                   ` (537 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Kumar Kartikeya Dwivedi,
	Eduard Zingerman, Sasha Levin

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

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

From: Kumar Kartikeya Dwivedi <memxor@gmail.com>

[ Upstream commit b4e875d397da451fb4e9c573ff4b86db53caba05 ]

CO-RE relocation of an ldimm64 instruction operates on two instruction
slots. A malformed BPF ELF can end a function after the first slot and
attach a CO-RE relocation to it. libbpf allocates the instruction array
according to the function symbol size, so the shared relocation code would
then access beyond the allocation.

Reject a terminal ldimm64 in libbpf's relocation loop, where the program
length is available, before resolving or applying the relocation. Both
resolved and unresolved relocations validate the absent second slot, and
unresolved relocation poisoning would additionally write past the array.

The in-kernel caller is protected by the verifier's early instruction-stream
check before it applies CO-RE relocations.

Fixes: eacaaed784e2 ("libbpf: Implement enum value-based CO-RE relocations")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/20260914140852.03DA21F0089B@smtp.kernel.org
Link: https://patch.msgid.link/20260917233222.2542500-11-memxor@gmail.com
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 tools/lib/bpf/libbpf.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index ffb0d1f7e9a08..214f8b48c1ea3 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -5983,6 +5983,13 @@ bpf_object__relocate_core(struct bpf_object *obj, const char *targ_btf_path)
 				return -EINVAL;
 			insn = &prog->insns[insn_idx];
 
+			if (is_ldimm64_insn(insn) && (size_t)insn_idx + 1 >= prog->insns_cnt) {
+				pr_warn("prog '%s': relo #%d: insn #%d (LDIMM64) is truncated\n",
+					prog->name, i, insn_idx);
+				err = -EINVAL;
+				goto out;
+			}
+
 			err = record_relo_core(prog, rec, insn_idx);
 			if (err) {
 				pr_warn("prog '%s': relo #%d: failed to record relocation: %d\n",
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 348/877] netfilter: flowtable: publish HW_DEAD after worker is done
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (346 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 347/877] libbpf: Reject truncated ldimm64 CO-RE relocations Greg Kroah-Hartman
@ 2026-09-30 15:20 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 349/877] netfilter: nfnetlink_queue: hold nfnl mutex in event notifier Greg Kroah-Hartman
                   ` (536 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:20 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jérémy Jean,
	Pablo Neira Ayuso, Sasha Levin

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

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

From: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>

[ Upstream commit d644b23afe1ef509c9961a6d84a093c2587edf02 ]

flow_offload_work_del() sets NF_FLOW_HW_DEAD before the work handler
clears NF_FLOW_HW_PENDING. Once a flow is both HW_DYING and HW_DEAD, a
concurrent garbage collection pass can remove it and schedule it for RCU
freeing.

The offload worker holds neither an RCU read lock nor a reference to the
flow. If it is preempted after publishing HW_DEAD, the RCU callback can
free the flow before the worker resumes and clears HW_PENDING, resulting
in a use-after-free.

Move HW_DEAD publication to the common worker epilogue after the pending
bit is cleared, making it the final flow access by destroy work. Order all
preceding flow accesses before publishing the bit that allows garbage
collection to free the object.

Fixes: 2c8897953f3b ("netfilter: flowtable: Add pending bit for offload work")
Assisted-by: Codex:gpt-5
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/netfilter/nf_flow_table_offload.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c
index 4f346f51d7d74..8e3edc7c37b38 100644
--- a/net/netfilter/nf_flow_table_offload.c
+++ b/net/netfilter/nf_flow_table_offload.c
@@ -993,7 +993,6 @@ static void flow_offload_work_del(struct flow_offload_work *offload)
 	flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_ORIGINAL);
 	if (test_bit(NF_FLOW_HW_BIDIRECTIONAL, &offload->flow->flags))
 		flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_REPLY);
-	set_bit(NF_FLOW_HW_DEAD, &offload->flow->flags);
 }
 
 static void flow_offload_tuple_stats(struct flow_offload_work *offload,
@@ -1057,6 +1056,12 @@ static void flow_offload_work_handler(struct work_struct *work)
 	}
 
 	clear_bit(NF_FLOW_HW_PENDING, &offload->flow->flags);
+	if (offload->cmd == FLOW_CLS_DESTROY) {
+		/* Publish after the worker's last flow access. */
+		smp_mb__before_atomic();
+		set_bit(NF_FLOW_HW_DEAD, &offload->flow->flags);
+	}
+
 	kfree(offload);
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 349/877] netfilter: nfnetlink_queue: hold nfnl mutex in event notifier
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (347 preceding siblings ...)
  2026-09-30 15:20 ` [PATCH 6.12 348/877] netfilter: flowtable: publish HW_DEAD after worker is done Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 350/877] netfilter: nft_synproxy: use the family-aware checksum helper Greg Kroah-Hartman
                   ` (535 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Florian Westphal, Pablo Neira Ayuso,
	Sasha Levin

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

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

From: Florian Westphal <fw@strlen.de>

[ Upstream commit 9461613afc59acef44a0071b0dd5075f6e993ffe ]

We must serialize the release notifier and the config netlink function.
A concurrent thread can issue close() which can call the release function
while unrelated socket processes UNBIND request for same portid:

Oops: general protection fault, [..]
RIP: 0010:__instance_destroy+0x60/0x210 [nfnetlink_queue]
Call Trace:
 nfqnl_recv_config+0x9b0/0xdc0 [nfnetlink_queue]
 nfnetlink_rcv_msg+0x7c2/0xeb0
 ? __pfx_nfnetlink_rcv_msg+0x10/0x10

After this, parallel UNBIND and URELEASE events are impossible.

This change isn't nice, but its the shortest fix given instances
are not refcounted and the nfnetlink config callback drops the
rcu read lock early due to need for sleeping allocations.

Fixes: 7af4cc3fa158 ("[NETFILTER]: Add "nfnetlink_queue" netfilter queue handler over nfnetlink")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/netfilter/nfnetlink_queue.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index 2e00a07eb545d..797c99c626d23 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -1338,6 +1338,7 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
 	if (event == NETLINK_URELEASE && n->protocol == NETLINK_NETFILTER) {
 		int i;
 
+		nfnl_lock(NFNL_SUBSYS_QUEUE);
 		/* destroy all instances for this portid */
 		spin_lock(&q->instances_lock);
 		for (i = 0; i < INSTANCE_BUCKETS; i++) {
@@ -1351,6 +1352,7 @@ nfqnl_rcv_nl_event(struct notifier_block *this,
 			}
 		}
 		spin_unlock(&q->instances_lock);
+		nfnl_unlock(NFNL_SUBSYS_QUEUE);
 	}
 	return NOTIFY_DONE;
 }
@@ -1672,9 +1674,9 @@ static int nfqnl_recv_config(struct sk_buff *skb, const struct nfnl_info *info,
 
 	/* Lookup queue under RCU. After peer_portid check (or for new queue
 	 * in BIND case), the queue is owned by the socket sending this message.
-	 * A socket cannot simultaneously send a message and close, so while
-	 * processing this CONFIG message, nfqnl_rcv_nl_event() (triggered by
-	 * socket close) cannot destroy this queue. Safe to use without RCU.
+	 * nfqnl_rcv_nl_event() will block on the nfnl subsys mutex that is
+	 * held by the caller, so the queue cannot be destroyed in parallel,
+	 * even after we drop the RCU read lock.
 	 */
 	rcu_read_lock();
 	queue = instance_lookup(q, queue_num);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 350/877] netfilter: nft_synproxy: use the family-aware checksum helper
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (348 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 349/877] netfilter: nfnetlink_queue: hold nfnl mutex in event notifier Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 351/877] ipvs: revalidate ihl before icmp_send Greg Kroah-Hartman
                   ` (534 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Pablo Neira Ayuso,
	Sasha Levin

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

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

From: Karl Mehltretter <kmehltretter@gmail.com>

[ Upstream commit a311a898172743558b82f6035ef2aa8c310a4223 ]

nft_synproxy_do_eval() verifies the TCP checksum before it switches on
skb->protocol.  It uses nf_ip_checksum(), which constructs an IPv4
pseudo header and relies on the IPv4 header checksum when folding the
whole skb.  Neither operation is valid for an IPv6 packet.

A correctly checksummed IPv6 segment can therefore fail verification
when it reaches the hook as CHECKSUM_NONE or, at NF_INET_LOCAL_IN,
CHECKSUM_COMPLETE.  nft_synproxy_do_eval() returns NF_DROP before
nft_synproxy_eval_v6() can send a SYN-ACK.

nft_synproxy_validate() deliberately admits NFPROTO_IPV6 and
NFPROTO_INET, and the xtables counterpart ip6t_SYNPROXY.c already calls
nf_ip6_checksum().

Use nf_checksum() with nft_pf() so the checksum helper dispatches to the
packet family's implementation.

Fixes: ad49d86e07a4 ("netfilter: nf_tables: Add synproxy support")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/netfilter/nft_synproxy.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nft_synproxy.c b/net/netfilter/nft_synproxy.c
index a80bdce38546f..a6253595a1676 100644
--- a/net/netfilter/nft_synproxy.c
+++ b/net/netfilter/nft_synproxy.c
@@ -117,7 +117,8 @@ static void nft_synproxy_do_eval(const struct nft_synproxy *priv,
 		return;
 	}
 
-	if (nf_ip_checksum(skb, nft_hook(pkt), thoff, IPPROTO_TCP)) {
+	if (nf_checksum(skb, nft_hook(pkt), thoff, IPPROTO_TCP,
+			nft_pf(pkt))) {
 		regs->verdict.code = NF_DROP;
 		return;
 	}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 351/877] ipvs: revalidate ihl before icmp_send
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (349 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 350/877] netfilter: nft_synproxy: use the family-aware checksum helper Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 352/877] netfilter: ctnetlink: fix suspicious RCU usage in expect_iter_name Greg Kroah-Hartman
                   ` (533 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Julian Anastasov, Pablo Neira Ayuso,
	Sasha Levin

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

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

From: Julian Anastasov <ja@ssi.bg>

[ Upstream commit e290145564886d6a3038810c621f738c1fe9fa51 ]

While the outer IP header is already pulled into the skb head, we must
be careful and revalidate the embedded headers after reading them from
the skb frags to prevent possible out-of-bounds access.

One such place reported by Sashiko is ip_vs_in_icmp() where local
process can change the ihl field and after pskb_may_pull() we can see
larger value. Even if icmp_send() has checks to prevent out-of-bounds
access, play safe and add check to drop the packet if the ihl field is
changed.  As the outer headers are pulled, make sure the transport
header is updated too, it was used before commit 7fcc2fe39fed ("net:
icmp: avoid invalid transport header access in icmp_send tracepoint")

Fixes: f2edb9f7706d ("ipvs: implement passive PMTUD for IPIP packets")
Link: https://sashiko.dev/#/patchset/20260806105211.34622-1-ja%40ssi.bg
Signed-off-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/netfilter/ipvs/ip_vs_core.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 1f62ca2f73309..4e30a903f4bdc 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -1776,6 +1776,12 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,
 		/* Ensure the IP header is present in headroom */
 		if (!pskb_may_pull(skb, hlen_orig))
 			goto ignore_tunnel;
+		skb_set_transport_header(skb, hlen_orig);
+		/* Before now we may used ihl from skb frag, revalidate it after
+		 * copying it into skb head to prevent out-of-bounds access
+		 */
+		if (ip_hdr(skb)->ihl * 4 != hlen_orig)
+			goto ignore_tunnel;
 		IP_VS_DBG(12, "Sending ICMP for %pI4->%pI4: t=%u, c=%u, i=%u\n",
 			&ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr,
 			type, code, ntohl(info));
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 352/877] netfilter: ctnetlink: fix suspicious RCU usage in expect_iter_name
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (350 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 351/877] ipvs: revalidate ihl before icmp_send Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 353/877] arm64: io: Reject non-user protection in ioremap_prot() Greg Kroah-Hartman
                   ` (532 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+4bd730aede2791e40bdf,
	Naman Gulati, Pablo Neira Ayuso, Sasha Levin

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

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

From: Naman Gulati <namangulati@google.com>

[ Upstream commit 207d591c353201f3bd3e0c89bb7d44a849c8fd59 ]

expect_iter_name() is invoked by nf_ct_expect_iterate_net() under
spin_lock_bh(&nf_conntrack_expect_lock). It does not hold
rcu_read_lock().

When accessing exp->helper with rcu_dereference() in syzbot's report,
lockdep warns:

  =============================
  WARNING: suspicious RCU usage
  syzkaller #0 Not tainted
  -----------------------------
  net/netfilter/nf_conntrack_netlink.c:3393 suspicious rcu_dereference_check() usage!

  locks held by syz-executor381/5628: 2, last CPU#1:
   #0: ffffffff9aee42a0 (nfnl_subsys_ctnetlink_exp){+.+.}-{4:4},
       at: nfnetlink_rcv_msg+0xa69/0x12b0
   #1: ffffffff8ea74d58 (nf_conntrack_expect_lock){+...}-{3:3},
       at: nf_ct_expect_iterate_net+0x38/0x180

  Call Trace:
   <TASK>
   dump_stack_lvl+0xe8/0x150
   lockdep_rcu_suspicious+0x140/0x1d0
   expect_iter_name+0xfb/0x100
   nf_ct_expect_iterate_net+0xf2/0x180
   ctnetlink_del_expect+0x45d/0x640
   nfnetlink_rcv_msg+0xcc2/0x12b0
   netlink_rcv_skb+0x226/0x4a0
   nfnetlink_rcv+0x2b9/0x28c0
   netlink_unicast+0x7bd/0x940
   netlink_sendmsg+0x813/0xb40
   ____sys_sendmsg+0x54e/0x850
   ___sys_sendmsg+0x2a5/0x360
   __sys_sendmsg+0x2a5/0x360
   do_syscall_64+0x166/0x520
   entry_SYSCALL_64_after_hwframe+0x77/0x7f

Use rcu_dereference_protected() with lockdep_is_held() on
nf_conntrack_expect_lock instead, similar to expect_iter_me() in
nf_conntrack_helper.c.

Fixes: f01794106042 ("netfilter: nf_conntrack_expect: use expect->helper")
Reported-by: syzbot+4bd730aede2791e40bdf@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6aa4a377.f81106d8.2ab401.0024.GAE@google.com/T/#u
Signed-off-by: Naman Gulati <namangulati@google.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/netfilter/nf_conntrack_netlink.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index a081d38702f5d..8bb32965edb83 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -3390,7 +3390,8 @@ static bool expect_iter_name(struct nf_conntrack_expect *exp, void *data)
 	struct nf_conntrack_helper *helper;
 	const char *name = data;
 
-	helper = rcu_dereference(exp->helper);
+	helper = rcu_dereference_protected(exp->helper,
+					   lockdep_is_held(&nf_conntrack_expect_lock));
 	if (!helper)
 		return false;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 353/877] arm64: io: Reject non-user protection in ioremap_prot()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (351 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 352/877] netfilter: ctnetlink: fix suspicious RCU usage in expect_iter_name Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 354/877] ocfs2: make ocfs2_calc_xattr_init() return void Greg Kroah-Hartman
                   ` (531 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Zeng Heng, Catalin Marinas,
	Will Deacon, Sasha Levin

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

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

From: Zeng Heng <zengheng4@huawei.com>

[ Upstream commit bb756b11ad63832ebee58caf9e8f9381eaecff9f ]

Mapping a stack-top page via /dev/mem with PROT_NONE and then
reading that process's /proc/<pid>/cmdline triggers a spurious WARN
in ioremap_prot() through generic_access_phys():

  WARNING: ./arch/arm64/include/asm/io.h:275 at generic_access_phys
  Call trace:
    generic_access_phys+0x1c8/0x228 (P)
    __access_remote_vm+0x2b4/0x398
    access_remote_vm+0x14/0x30
    get_mm_cmdline+0xf8/0x2a0
    proc_pid_cmdline_read+0x68/0x120

generic_access_phys() passes the protection derived from the user PTE
to ioremap_prot(). On arm64, a PROT_NONE mapping is represented by a
present-invalid PTE, so pte_present() still returns true and the
protection reaches ioremap_prot().

A PROT_NONE mapping does not have PTE_USER, causing the existing
WARN_ON_ONCE() in ioremap_prot() to fire even though this is a valid
user mapping. Execute-only mappings have the same issue and must not
be readable through this path either.

ioremap_prot() should therefore reject protection values without
PTE_USER without warning. This makes the access fail cleanly for
PROT_NONE and execute-only mappings while retaining the existing
user-protection contract.

Fixes: 8f098037139b ("arm64: io: Extract user memory type in ioremap_prot()")
Signed-off-by: Zeng Heng <zengheng4@huawei.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/arm64/include/asm/io.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 46bd37707e080..16a423101bdcd 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -282,7 +282,8 @@ static inline void __iomem *ioremap_prot(phys_addr_t phys, size_t size,
 	pgprot_t prot;
 	pteval_t user_prot_val = pgprot_val(__pgprot(user_prot));
 
-	if (WARN_ON_ONCE(!(user_prot_val & PTE_USER)))
+	/* Reject PROT_NONE and exec-only */
+	if (!(user_prot_val & PTE_USER))
 		return NULL;
 
 	prot = __pgprot_modify(PAGE_KERNEL, PTE_ATTRINDX_MASK,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 354/877] ocfs2: make ocfs2_calc_xattr_init() return void
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (352 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 353/877] arm64: io: Reject non-user protection in ioremap_prot() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 355/877] drm/nouveau/clk: fix list cursor use after loop in nvkm_clk_ustate_update Greg Kroah-Hartman
                   ` (530 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Joseph Qi, Andrew Morton,
	kernel test robot, Mark Fasheh, Joel Becker, Junxiao Bi,
	Changwei Ge, Jun Piao, Heming Zhao, Sasha Levin

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

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

From: Joseph Qi <joseph.qi@linux.alibaba.com>

[ Upstream commit 525c0edc032b3297d0c1056cf1fa20cf1f9e6184 ]

ocfs2_calc_xattr_init() used to read the default ACL off the parent inode
itself, so it could return an error from ocfs2_xattr_get_nolock().  Commit
bd7c05fb4a47 ("ocfs2: fix circular locking dependency in
ocfs2_init_acl()") moved that lookup before the transaction starts and
deleted the error path, but left the now vestigial 'int ret = 0'
declaration and both 'return ret' statements behind, along with an
unreachable error branch in ocfs2_mknod().

Drop the leftover variable and convert the return type to void, so the
callee states that it always succeeds and the caller no longer carries a
check that can never trigger.

No functional change.

Link: https://lore.kernel.org/20260904023751.3703334-1-joseph.qi@linux.alibaba.com
Fixes: bd7c05fb4a47 ("ocfs2: fix circular locking dependency in ocfs2_init_acl()")
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202609040247.8B3lmoqX-lkp@intel.com/
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Heming Zhao <heming.zhao@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/ocfs2/namei.c |  9 ++-------
 fs/ocfs2/xattr.c | 13 +++++--------
 fs/ocfs2/xattr.h |  8 ++++----
 3 files changed, 11 insertions(+), 19 deletions(-)

diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index 1dcd420878dcb..5ce71207bc9dd 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -332,13 +332,8 @@ static int ocfs2_mknod(struct mnt_idmap *idmap,
 		goto leave;
 
 	/* calculate meta data/clusters for setting security and acl xattr */
-	status = ocfs2_calc_xattr_init(dir, mode, &si, &want_clusters,
-				       &xattr_credits, &want_meta,
-				       &acl_state);
-	if (status < 0) {
-		mlog_errno(status);
-		goto leave;
-	}
+	ocfs2_calc_xattr_init(dir, mode, &si, &want_clusters, &xattr_credits,
+			      &want_meta, &acl_state);
 
 	/* Reserve a cluster if creating an extent based directory. */
 	if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) {
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 52156e8495432..3cc679e5f1a1a 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -607,12 +607,11 @@ int ocfs2_calc_security_init(struct inode *dir,
 	return ret;
 }
 
-int ocfs2_calc_xattr_init(struct inode *dir, umode_t mode,
-			  struct ocfs2_security_xattr_info *si,
-			  int *want_clusters, int *xattr_credits,
-			  int *want_meta, struct ocfs2_acl_state *acl_state)
+void ocfs2_calc_xattr_init(struct inode *dir, umode_t mode,
+			   struct ocfs2_security_xattr_info *si,
+			   int *want_clusters, int *xattr_credits,
+			   int *want_meta, struct ocfs2_acl_state *acl_state)
 {
-	int ret = 0;
 	struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
 	int s_size = 0, a_size = 0, acl_len = 0, new_clusters;
 
@@ -634,7 +633,7 @@ int ocfs2_calc_xattr_init(struct inode *dir, umode_t mode,
 	}
 
 	if (!(s_size + a_size))
-		return ret;
+		return;
 
 	/*
 	 * The max space of security xattr taken inline is
@@ -700,8 +699,6 @@ int ocfs2_calc_xattr_init(struct inode *dir, umode_t mode,
 			}
 		}
 	}
-
-	return ret;
 }
 
 static int ocfs2_xattr_extend_allocation(struct inode *inode,
diff --git a/fs/ocfs2/xattr.h b/fs/ocfs2/xattr.h
index 5cdd6c6b40064..aeba323e14b3c 100644
--- a/fs/ocfs2/xattr.h
+++ b/fs/ocfs2/xattr.h
@@ -57,10 +57,10 @@ int ocfs2_calc_security_init(struct inode *,
 			     int *, int *, struct ocfs2_alloc_context **);
 
 struct ocfs2_acl_state;
-int ocfs2_calc_xattr_init(struct inode *dir, umode_t mode,
-			  struct ocfs2_security_xattr_info *si,
-			  int *want_clusters, int *xattr_credits,
-			  int *want_meta, struct ocfs2_acl_state *acl_state);
+void ocfs2_calc_xattr_init(struct inode *dir, umode_t mode,
+			   struct ocfs2_security_xattr_info *si,
+			   int *want_clusters, int *xattr_credits,
+			   int *want_meta, struct ocfs2_acl_state *acl_state);
 
 /*
  * xattrs can live inside an inode, as part of an external xattr block,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 355/877] drm/nouveau/clk: fix list cursor use after loop in nvkm_clk_ustate_update
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (353 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 354/877] ocfs2: make ocfs2_calc_xattr_init() return void Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 356/877] drm/nouveau/clk: dont clobber reclock status when restoring volt/fan Greg Kroah-Hartman
                   ` (529 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Dan Carpenter, Francesco Magazzu,
	Lyude Paul, Sasha Levin

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

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

From: Dan Carpenter <dan.carpenter@oracle.com>

[ Upstream commit aff09d9e37e02dc60bde79035ac15b136d602259 ]

If list_for_each_entry() exits without hitting a break then "pstate" is
not a valid pstate pointer.  Introduce a "found" variable instead.

The check is reachable from userspace: nvkm_clk_ustate_update() takes the
pstate id straight from the 'pstate' debugfs file, so requesting an id
that is not in clk->states - or any id at all when the perf tables are
broken and the list is empty - makes the pstate->pstate != req test
dereference the list head cast to a struct nvkm_pstate, which is an
out-of-bounds read.

Fixes: 7c8565220697 ("drm/nouveau/clk: implement power state and engine clock control in core")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
[Francesco: rebased on drm-misc-next, expanded the commit message]
Signed-off-by: Francesco Magazzu <postadelmaga@gmail.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260918131620.405133-2-postadelmaga@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
index 178dc56909c27..5f4cd122415fa 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
@@ -473,6 +473,7 @@ static int
 nvkm_clk_ustate_update(struct nvkm_clk *clk, int req)
 {
 	struct nvkm_pstate *pstate;
+	bool found = false;
 	int i = 0;
 
 	if (!clk->allow_reclock)
@@ -480,12 +481,14 @@ nvkm_clk_ustate_update(struct nvkm_clk *clk, int req)
 
 	if (req != -1 && req != -2) {
 		list_for_each_entry(pstate, &clk->states, head) {
-			if (pstate->pstate == req)
+			if (pstate->pstate == req) {
+				found = true;
 				break;
+			}
 			i++;
 		}
 
-		if (pstate->pstate != req)
+		if (!found)
 			return -EINVAL;
 		req = i;
 	}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 356/877] drm/nouveau/clk: dont clobber reclock status when restoring volt/fan
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (354 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 355/877] drm/nouveau/clk: fix list cursor use after loop in nvkm_clk_ustate_update Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 357/877] drm/nouveau/disp: dont reject HDMI config on cards without SCDC Greg Kroah-Hartman
                   ` (528 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Francesco Magazzu, Lyude Paul,
	Sasha Levin

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

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

From: Francesco Magazzu <postadelmaga@gmail.com>

[ Upstream commit e5cccdafc855cd5f96f4b51d38114a0360b075d7 ]

nvkm_cstate_prog() reuses 'ret' for the voltage and fan-speed restore
calls it makes after reprogramming the clocks.  Those calls almost always
succeed, so the status of the reclock itself is overwritten and the
function reports success even when clk->func->calc() or clk->func->prog()
failed.  The converse is also true: a successful reclock is reported as an
error if the final restore call fails, even though that failure is only
logged and otherwise ignored.

The only consumer of the return value is the error message in
nvkm_pstate_work(), so in practice a failing reclock is simply never
reported.  Nothing else changes, but a function that returns success on
failure is a trap for the next caller.

Keep the calc/prog status in 'ret' and use a separate local for the
restore calls.

Fixes: 3eca809b3c05 ("drm/nouveau/clk: cosmetic changes")
Signed-off-by: Francesco Magazzu <postadelmaga@gmail.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260918131620.405133-5-postadelmaga@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
index 5f4cd122415fa..e6539931a7596 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c
@@ -199,16 +199,18 @@ nvkm_cstate_prog(struct nvkm_clk *clk, struct nvkm_pstate *pstate, int cstatei)
 	}
 
 	if (volt) {
-		ret = nvkm_volt_set_id(volt, cstate->voltage,
-				       pstate->base.voltage, clk->temp, -1);
-		if (ret && ret != -ENODEV)
-			nvkm_error(subdev, "failed to lower voltage: %d\n", ret);
+		int err = nvkm_volt_set_id(volt, cstate->voltage,
+					   pstate->base.voltage, clk->temp, -1);
+
+		if (err && err != -ENODEV)
+			nvkm_error(subdev, "failed to lower voltage: %d\n", err);
 	}
 
 	if (therm) {
-		ret = nvkm_therm_cstate(therm, pstate->fanspeed, -1);
-		if (ret && ret != -ENODEV)
-			nvkm_error(subdev, "failed to lower fan speed: %d\n", ret);
+		int err = nvkm_therm_cstate(therm, pstate->fanspeed, -1);
+
+		if (err && err != -ENODEV)
+			nvkm_error(subdev, "failed to lower fan speed: %d\n", err);
 	}
 
 	return ret;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 357/877] drm/nouveau/disp: dont reject HDMI config on cards without SCDC
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (355 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 356/877] drm/nouveau/clk: dont clobber reclock status when restoring volt/fan Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 358/877] net/sched: act_ct: dont WARN on benign flow_offload_alloc() failure Greg Kroah-Hartman
                   ` (527 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Giuseppe Ranieri, Tano Dzhinski,
	Lyude Paul, Sasha Levin

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

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

From: Giuseppe Ranieri <giuseppe@ranieri.dev>

[ Upstream commit 1717fcc5be575d4768279148ae9465a8b13d4339 ]

nv50_hdmi_enable() passes the sink's SCDC capability from its EDID
straight through to nvif_outp_hdmi(). On pre-Maxwell-2 cards there is no
hdmi->scdc callback, so nvkm_uoutp_mthd_hdmi() rejects the whole
configuration with -EINVAL, and nv50_hdmi_enable() returns before
hdmi->ctrl() runs and before the AVI and VSI infoframes are sent.

The result on such a card driving an SCDC-capable HDMI 2.0 sink is that
HDMI audio silently stops working. Video is unaffected, and nothing is
logged, which makes the failure hard to attribute.

SCDC is optional, and the hdmi->scdc() call further down is already
guarded against a missing callback. Requesting it on a card that cannot
do it need not invalidate the rest of the HDMI configuration, so drop
that term from the condition and let the existing guard skip SCDC alone.

Fixes: 6c6abab20b99 ("drm/nouveau/disp: add output hdmi config method")
Signed-off-by: Giuseppe Ranieri <giuseppe@ranieri.dev>
Co-Authored-By: Tano Dzhinski <tano.dzhinski@gmail.com>
Signed-off-by: Tano Dzhinski <tano.dzhinski@gmail.com>
Tested-by: Tano Dzhinski <tano.dzhinski@gmail.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260917215114.1136715-1-tano.dzhinski@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
index 377d0e0cef848..9887b3898505b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uoutp.c
@@ -253,8 +253,7 @@ nvkm_uoutp_mthd_hdmi(struct nvkm_outp *outp, void *argv, u32 argc)
 
 	if (!ior->func->hdmi ||
 	    args->v0.max_ac_packet > 0x1f ||
-	    args->v0.rekey > 0x7f ||
-	    (args->v0.scdc && !ior->func->hdmi->scdc))
+	    args->v0.rekey > 0x7f)
 		return -EINVAL;
 
 	if (!args->v0.enable) {
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 358/877] net/sched: act_ct: dont WARN on benign flow_offload_alloc() failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (356 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 357/877] drm/nouveau/disp: dont reject HDMI config on cards without SCDC Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 359/877] net: gue: reject invalid REMCSUM offsets Greg Kroah-Hartman
                   ` (526 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+6cc37aba98dac721c415,
	Nguyen Ngoc Thang, Simon Horman, Jakub Kicinski, Sasha Levin

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

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

From: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>

[ Upstream commit 47abe7a5c4eb53269aca3506446f851572a059a3 ]

flow_offload_alloc() returns NULL when the conntrack entry is dying
(e.g. raced with a conntrack flush) or when the GFP_ATOMIC allocation
fails; both are expected under load and neither is a kernel bug. This
path runs from softirq on every committed packet, so with
panic_on_warn=1 an unprivileged user can panic the box just by racing
a conntrack flush against a `tc ... action ct commit` classifier.

Reproduced with a custom repro under QEMU: a small, fixed set of UDP
flows through `tc filter ... action ct commit` on lo, raced against
threads flooding bare ctnetlink CT_DELETE (flush) requests. Hits
WARNING: net/sched/act_ct.c:437 (tcf_ct_flow_table_add(), inlined
into tcf_ct_act() in this build) within ~15s on the unpatched kernel;
same setup is clean on the patched kernel. The fix itself is
behavior-preserving: both branches already did `goto err_alloc`
before and after, only the WARN is removed.

Fixes: 64ff70b80fd4 ("net/sched: act_ct: Offload established connections to flow table")
Reported-by: syzbot+6cc37aba98dac721c415@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=6cc37aba98dac721c415
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260915150816.36487-1-ngocthang2710.1999@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/sched/act_ct.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c
index 8aed25cad9eef..46564bfc13251 100644
--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -430,11 +430,10 @@ static void tcf_ct_flow_table_add(struct tcf_ct_flow_table *ct_ft,
 	if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status))
 		return;
 
+	/* NULL if ct is dying (raced flush) or the atomic alloc failed. */
 	entry = flow_offload_alloc(ct);
-	if (!entry) {
-		WARN_ON_ONCE(1);
+	if (!entry)
 		goto err_alloc;
-	}
 
 	if (tcp) {
 		ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 359/877] net: gue: reject invalid REMCSUM offsets
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (357 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 358/877] net/sched: act_ct: dont WARN on benign flow_offload_alloc() failure Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 360/877] net: ethernet: mtk_eth_soc: unregister net_devices in case of probe failure Greg Kroah-Hartman
                   ` (525 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jérémy Jean,
	Jakub Kicinski, Sasha Levin

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

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

From: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>

[ Upstream commit 2566866fc30965d915d0b52b5c3323b362619f0e ]

The REMCSUM option carries an absolute checksum start and checksum field
offset. gue_remcsum() passes them to skb_remcsum_process(), whose
partial path stores offset - start in the u16 skb->csum_offset variable.
If offset is less than start, this underflows.

A forwarded packet can retain CHECKSUM_PARTIAL and reach a NETIF_F_HW_CSUM
driver which trusts the metadata, leading skb_copy_and_csum_dev() to write
two bytes about 64 KiB beyond the destination buffer.

Reject reversed tuples in validate_gue_flags(), after the existing length
validation, so all GUE parsers enforce the ordering in one place.

Fixes: fe881ef11cf0 ("gue: Use checksum partial with remote checksum offload")
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Link: https://patch.msgid.link/20260915124806.2852293-2-Jeremy.Jean@oss.cyber.gouv.fr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/net/gue.h | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/include/net/gue.h b/include/net/gue.h
index caefd6da86939..d377155fd0b31 100644
--- a/include/net/gue.h
+++ b/include/net/gue.h
@@ -84,8 +84,9 @@ static inline size_t guehdr_priv_flags_len(__be32 flags)
 }
 
 /* Validate standard and private flags. Returns non-zero (meaning invalid)
- * if there is an unknown standard or private flags, or the options length for
- * the flags exceeds the options length specific in hlen of the GUE header.
+ * if there is an unknown standard or private flags, if the options length for
+ * the flags exceeds the options length specified in hlen of the GUE header, or
+ * if a private option contains invalid data.
  */
 static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
 {
@@ -103,8 +104,8 @@ static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
 		/* Private flags are last four bytes accounted in
 		 * guehdr_flags_len
 		 */
-		__be32 pflags = *(__be32 *)((void *)&guehdr[1] +
-					    len - GUE_LEN_PRIV);
+		void *data = (void *)&guehdr[1] + len;
+		__be32 pflags = *(__be32 *)(data - GUE_LEN_PRIV);
 
 		if (pflags & ~GUE_PFLAGS_ALL)
 			return 1;
@@ -112,6 +113,16 @@ static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
 		len += guehdr_priv_flags_len(pflags);
 		if (len > optlen)
 			return 1;
+
+		if (pflags & GUE_PFLAG_REMCSUM) {
+			__be16 *pd = data;
+
+			/* The field offset pd[1] must not be less
+			 * than the start pd[0].
+			 */
+			if (ntohs(pd[1]) < ntohs(pd[0]))
+				return 1;
+		}
 	}
 
 	return 0;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 360/877] net: ethernet: mtk_eth_soc: unregister net_devices in case of probe failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (358 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 359/877] net: gue: reject invalid REMCSUM offsets Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 361/877] ip6_gre: Call ip6erspan_tunnel_unlink_md() in ip6erspan_changelink() Greg Kroah-Hartman
                   ` (524 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Lorenzo Bianconi, Jakub Kicinski,
	Sasha Levin

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

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

From: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>

[ Upstream commit 310d1ac61a4d5a2ca8356a3a48d263acf54503ce ]

If register_netdev() fails for one of the MTK_MAX_DEVS devices in
mtk_probe(), the error path jumps to err_deinit_ppe, skipping
mtk_unreg_dev(). The previously registered net_devices are then freed by
mtk_free_dev() while still in NETREG_REGISTERED state, hitting the
BUG_ON(dev->reg_state != NETREG_UNREGISTERED).

Route the register_netdev() failure to err_unreg_netdev so the net_devices
registered so far are properly unregistered before being freed.

Fixes: 8a8a9e89f801 ("net: ethernet: mediatek: cleanup error path inside mtk_hw_init")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Link: https://patch.msgid.link/20260916-mtk_eth_soc-netdev-fix-v1-1-5dac50eb65b1@oss.qualcomm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 42a4f52ecdc2d..4c9ebbb1b4f18 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4347,6 +4347,10 @@ static int mtk_unreg_dev(struct mtk_eth *eth)
 		mac = netdev_priv(eth->netdev[i]);
 		if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
 			unregister_netdevice_notifier(&mac->device_notifier);
+
+		if (eth->netdev[i]->reg_state != NETREG_REGISTERED)
+			continue;
+
 		unregister_netdev(eth->netdev[i]);
 	}
 
@@ -5128,7 +5132,7 @@ static int mtk_probe(struct platform_device *pdev)
 		err = register_netdev(eth->netdev[i]);
 		if (err) {
 			dev_err(eth->dev, "error bringing up device\n");
-			goto err_deinit_ppe;
+			goto err_unreg_netdev;
 		} else
 			netif_info(eth, probe, eth->netdev[i],
 				   "mediatek frame engine at 0x%08lx, irq %d\n",
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 361/877] ip6_gre: Call ip6erspan_tunnel_unlink_md() in ip6erspan_changelink().
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (359 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 360/877] net: ethernet: mtk_eth_soc: unregister net_devices in case of probe failure Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 362/877] eth: fbnic: Handle maximum standalone channels Greg Kroah-Hartman
                   ` (523 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Xuanqiang Luo,
	Ido Schimmel, Jakub Kicinski, Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit dd47bcf279f1083f09bf5266890b26263361022b ]

The cited commit accidentally added ip6gre_tunnel_unlink_md()
in ip6erspan_changelink().

Let's correct it to ip6erspan_tunnel_unlink_md().

Fixes: b80d0b93b991 ("net: ip6_gre: fix tunnel metadata device sharing.")
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260916230927.378957-1-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv6/ip6_gre.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 4b0c166fe7e24..ce1ba9d2af405 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -2314,7 +2314,7 @@ static int ip6erspan_changelink(struct net_device *dev, struct nlattr *tb[],
 		return PTR_ERR(t);
 
 	ip6erspan_set_version(data, &p);
-	ip6gre_tunnel_unlink_md(ign, t);
+	ip6erspan_tunnel_unlink_md(ign, t);
 	ip6gre_tunnel_unlink(ign, t);
 	ip6erspan_tnl_change(t, &p, !tb[IFLA_MTU]);
 	ip6erspan_tunnel_link_md(ign, t);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 362/877] eth: fbnic: Handle maximum standalone channels
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (360 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 361/877] ip6_gre: Call ip6erspan_tunnel_unlink_md() in ip6erspan_changelink() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 363/877] eth: fbnic: Set AW_FLUSH_MODE alongside AW_FLUSH when flushing the mailbox Greg Kroah-Hartman
                   ` (522 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Björn Töpel, Simon Horman,
	Jakub Kicinski, Sasha Levin

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

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

From: Björn Töpel <bjorn@kernel.org>

[ Upstream commit 1f4c73064a50f53d596c6f1d06d2d700f43c4b32 ]

Standalone channels use one NAPI vector for each Tx and Rx queue.
fbnic's allocation path excludes FBNIC_MAX_TXQS from that layout. A
64-Tx/64-Rx configuration therefore records 128 vectors but allocates
only 64, leaving NULL entries that resource setup dereferences.

Include the maximum vector count in standalone allocation.

Fixes: bc6107771bb4 ("eth: fbnic: Allocate a netdevice and napi vectors with queues")
Signed-off-by: Björn Töpel <bjorn@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/178942020457.7700.13129750616387075931.stgit@ahduyck-xeon-server.home.arpa
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/meta/fbnic/fbnic_txrx.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
index 16a0e30f8aaa5..38e96b003ea05 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
@@ -1162,7 +1162,7 @@ int fbnic_alloc_napi_vectors(struct fbnic_net *fbn)
 	int err;
 
 	/* Allocate 1 Tx queue per napi vector */
-	if (num_napi < FBNIC_MAX_TXQS && num_napi == num_tx + num_rx) {
+	if (num_napi <= FBNIC_MAX_TXQS && num_napi == num_tx + num_rx) {
 		while (num_tx) {
 			err = fbnic_alloc_napi_vector(fbd, fbn,
 						      num_napi, v_idx,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 363/877] eth: fbnic: Set AW_FLUSH_MODE alongside AW_FLUSH when flushing the mailbox
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (361 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 362/877] eth: fbnic: Handle maximum standalone channels Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 364/877] sctp: avoid livelock while updating retransmit path Greg Kroah-Hartman
                   ` (521 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Alexander Duyck, Simon Horman,
	Jakub Kicinski, Sasha Levin

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

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

From: Alexander Duyck <alexanderduyck@fb.com>

[ Upstream commit 8947f13e436a4ff5eed9f8f019b2865a07af4bb2 ]

When tearing down the FW mailbox Rx ring, fbnic_mbx_reset_desc_ring()
writes AW_CFG with FLUSH set and everything else, BME included, cleared.
Clearing BME halts the device's writes to the host but leaves the staged
requests parked in the PUL write pipeline rather than draining them, so
on the write path FLUSH alone never terminates the outstanding requests
and the flush the firmware waits on never completes.

Add the FLUSH_MODE definition and set both bits so the staged writes
drain out of the pipeline on their own. BME stays cleared, so nothing
lands on the host; it is restored later in fbnic_mbx_init_desc_ring()
when the ring is rebuilt, once the outstanding writes are gone.

The read path is unaffected. AR_CFG has no equivalent mode bit and
AR_FLUSH terminates the outstanding reads by itself, so it is left as
is.

Both writes remain plain stores rather than read-modify-writes. That is
deliberate: the matching write in fbnic_mbx_init_desc_ring() restores
BME and the TLP attributes, and clears both flush bits as a side effect.

Fixes: 3b12f00ddd08 ("fbnic: Gate AXI read/write enabling on FW mailbox")
Signed-off-by: Alexander Duyck <alexanderduyck@fb.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/178942022583.7700.11050671998277309744.stgit@ahduyck-xeon-server.home.arpa
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/meta/fbnic/fbnic_csr.h | 1 +
 drivers/net/ethernet/meta/fbnic/fbnic_fw.c  | 9 ++++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
index e91b4432fddd7..2da0f5f8882bc 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
@@ -700,6 +700,7 @@ enum {
 /* PUL User Registers */
 #define FBNIC_CSR_START_PUL_USER	0x31000	/* CSR section delimiter */
 #define FBNIC_PUL_OB_TLP_HDR_AW_CFG	0x3103d		/* 0xc40f4 */
+#define FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH_MODE	CSR_BIT(20)
 #define FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH	CSR_BIT(19)
 #define FBNIC_PUL_OB_TLP_HDR_AW_CFG_BME		CSR_BIT(18)
 #define FBNIC_PUL_OB_TLP_HDR_AR_CFG	0x3103e		/* 0xc40f8 */
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
index 6f606bdfd2296..175ad17bd47b5 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw.c
@@ -60,8 +60,15 @@ static void fbnic_mbx_reset_desc_ring(struct fbnic_dev *fbd, int mbx_idx)
 	 */
 	switch (mbx_idx) {
 	case FBNIC_IPC_MBX_RX_IDX:
+		/* Clearing BME blocks the device from writing to the host
+		 * but leaves the requests parked in the write pipeline. The
+		 * write path only clears outstanding requests when both FLUSH
+		 * and FLUSH_MODE are set; FLUSH_MODE lets them drain without
+		 * landing on the host.
+		 */
 		wr32(fbd, FBNIC_PUL_OB_TLP_HDR_AW_CFG,
-		     FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH);
+		     FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH |
+		     FBNIC_PUL_OB_TLP_HDR_AW_CFG_FLUSH_MODE);
 		break;
 	case FBNIC_IPC_MBX_TX_IDX:
 		wr32(fbd, FBNIC_PUL_OB_TLP_HDR_AR_CFG,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 364/877] sctp: avoid livelock while updating retransmit path
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (362 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 363/877] eth: fbnic: Set AW_FLUSH_MODE alongside AW_FLUSH when flushing the mailbox Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 365/877] bpf: Bound ownership depth through local kptrs and graph roots Greg Kroah-Hartman
                   ` (520 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yiqi Sun, Xin Long, Jakub Kicinski,
	Sasha Levin

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

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

From: Yiqi Sun <sunyiqixm@gmail.com>

[ Upstream commit d2c31b837406395e576afeb25958c98e9938f3f6 ]

sctp_assoc_update_retran_path() can loop forever when every remaining
transport, including retran_path, is SCTP_UNCONFIRMED: the state check
runs before the wraparound test, so the loop cannot observe that it has
completed a full pass.

Fix this by considering a transport only when it is not UNCONFIRMED,
then checking whether the walk has returned to retran_path. This makes
the full-pass termination independent of the transport state while
preserving the existing fallback selection semantics.

Also restore the NULL guard around the retran_path assignment. In the
all-UNCONFIRMED case there is no eligible replacement transport, and
installing NULL would leave later retransmit-path users and the debug
print with a NULL path.

Fixes: 4c47af4d5eb2 ("net: sctp: rework multihoming retransmission path selection to rfc4960")
Signed-off-by: Yiqi Sun <sunyiqixm@gmail.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20260915095017.942213-1-sunyiqixm@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/sctp/associola.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index f409b9f6b228f..0a19aea3b5246 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1303,18 +1303,19 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
 		/* Manually skip the head element. */
 		if (&trans->transports == &asoc->peer.transport_addr_list)
 			continue;
-		if (trans->state == SCTP_UNCONFIRMED)
-			continue;
-		trans_next = sctp_trans_elect_best(trans, trans_next);
-		/* Active is good enough for immediate return. */
-		if (trans_next->state == SCTP_ACTIVE)
-			break;
+		if (trans->state != SCTP_UNCONFIRMED) {
+			trans_next = sctp_trans_elect_best(trans, trans_next);
+			/* Active is good enough for immediate return. */
+			if (trans_next->state == SCTP_ACTIVE)
+				break;
+		}
 		/* We've reached the end, time to update path. */
 		if (trans == asoc->peer.retran_path)
 			break;
 	}
 
-	asoc->peer.retran_path = trans_next;
+	if (trans_next)
+		asoc->peer.retran_path = trans_next;
 
 	pr_debug("%s: association:%p updated new path to addr:%pISpc\n",
 		 __func__, asoc, &asoc->peer.retran_path->ipaddr.sa);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 365/877] bpf: Bound ownership depth through local kptrs and graph roots
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (363 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 364/877] sctp: avoid livelock while updating retransmit path Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 366/877] net: usb: catc: bound the RX packet length in catc_rx_done() Greg Kroah-Hartman
                   ` (519 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nicholas Carlini,
	Kumar Kartikeya Dwivedi, Alexei Starovoitov, Sasha Levin

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

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

From: Kumar Kartikeya Dwivedi <memxor@gmail.com>

[ Upstream commit bfc888f04588f591851e95c974954cfca58e6c19 ]

Program-allocated objects can own other local objects through referenced
kptrs. bpf_obj_free_fields() follows those pointers through
__bpf_obj_drop_impl() synchronously, before the object storage is freed
through RCU. A self-referential local kptr type therefore permits arbitrarily
deep object chains, and dropping the head can exhaust the kernel stack.
Long acyclic type chains have the same problem.

btf_check_and_fixup_fields() still assumes referenced kptrs only point to
kernel types and checks ownership through list and rbtree roots only. Its
existing rule is sufficient for graph-only cycles: the target of each graph
edge must contain a node, so every type in a cycle has both a root and a
node. The rule rejects such a type owning another root, breaking every
cycle. It also limits graph-only chains to three types, or two if the first
type contains a node, and conservatively rejects longer acyclic chains.
The missing local-kptr edges, rather than a missed graph-only cycle, are the
bug introduced by support for bpf_kptr_xchg() into local kptrs.

Replace that restriction with one bounded ownership walk covering graph
roots and local referenced kptrs. Run it after all BTF records have been
fixed up, reject cycles and paths deeper than eight record-bearing types,
and cache each type's suffix depth while checking it against the remaining
budget. This also permits the longer acyclic graph-only layouts rejected
by the old rule; update their existing BTF tests accordingly.

Keep the bound independent of MAX_CALL_FRAMES because recursive destruction
can run below a BPF call chain. A plain local pointee without special-field
metadata adds only a final non-recursing drop. Non-owning kptrs and
kernel-BTF kptrs do not recurse through local records and remain outside the
walk. Include local percpu-kptr edges too, although allocation of percpu
objects with special fields is currently forbidden, so that relaxing that
restriction cannot bypass the ownership bound.

btf_check_and_fixup_fields() continues to initialize graph_root.value_rec,
including for separately allocated map records. The ownership relationships
belong to immutable program BTF and only need validation at BTF load time.

Fixes: b0966c724584 ("bpf: Support bpf_kptr_xchg into local kptr")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20260914132444.2564218-2-memxor@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/btf.c                              | 134 +++++++++++-------
 .../selftests/bpf/prog_tests/linked_list.c    |   4 +-
 2 files changed, 88 insertions(+), 50 deletions(-)

diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 0c040c2e8c4f5..5f3b1162208b5 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -4062,13 +4062,10 @@ int btf_check_and_fixup_fields(const struct btf *btf, struct btf_record *rec)
 {
 	int i;
 
-	/* There are three types that signify ownership of some other type:
-	 *  kptr_ref, bpf_list_head, bpf_rb_root.
-	 * kptr_ref only supports storing kernel types, which can't store
-	 * references to program allocated local types.
-	 *
-	 * Hence we only need to ensure that bpf_{list_head,rb_root} ownership
-	 * does not form cycles.
+	/*
+	 * Check fields which require the complete BTF and initialize runtime
+	 * metadata. Ownership relationships are validated after every record has
+	 * been fixed up.
 	 */
 	if (IS_ERR_OR_NULL(rec) || !(rec->field_mask & BPF_GRAPH_ROOT))
 		return 0;
@@ -4083,51 +4080,88 @@ int btf_check_and_fixup_fields(const struct btf *btf, struct btf_record *rec)
 		if (!meta)
 			return -EFAULT;
 		rec->fields[i].graph_root.value_rec = meta->record;
+	}
+	return 0;
+}
 
-		/* We need to set value_rec for all root types, but no need
-		 * to check ownership cycle for a type unless it's also a
-		 * node type.
-		 */
-		if (!(rec->field_mask & BPF_GRAPH_NODE))
+static int btf_owned_type_idx(const struct btf *btf, struct btf_struct_metas *tab,
+			      const struct btf_field *field)
+{
+	struct btf_struct_meta *meta;
+	u32 btf_id;
+
+	if (field->type & BPF_GRAPH_ROOT) {
+		btf_id = field->graph_root.value_btf_id;
+	} else if (field->type == BPF_KPTR_REF || field->type == BPF_KPTR_PERCPU) {
+		if (btf_is_kernel(field->kptr.btf))
+			return -ENOENT;
+		btf_id = field->kptr.btf_id;
+	} else {
+		return -ENOENT;
+	}
+
+	meta = btf_find_struct_meta(btf, btf_id);
+	if (!meta)
+		return field->type & BPF_GRAPH_ROOT ? -EFAULT : -ENOENT;
+	return meta - tab->types;
+}
+
+/*
+ * Each ownership edge adds kernel frames through bpf_obj_free_fields() and
+ * __bpf_obj_drop_impl(). Keep the bound deliberately small because object
+ * destruction can itself run below a BPF call chain. A final pointee without
+ * special fields is not present in the struct metadata table and adds only a
+ * non-recursing drop.
+ */
+#define BTF_MAX_OWNERSHIP_DEPTH 8
+
+static int btf_ownership_depth(const struct btf *btf,
+			       struct btf_struct_metas *tab, u8 *depth,
+			       int idx, int depth_left)
+{
+	const struct btf_record *rec = tab->types[idx].record;
+	int i, ret, max_depth = 0;
+
+	if (!depth_left)
+		return -ELOOP;
+	if (depth[idx])
+		goto done;
+
+	for (i = 0; i < rec->cnt; i++) {
+		ret = btf_owned_type_idx(btf, tab, &rec->fields[i]);
+		if (ret == -ENOENT)
 			continue;
+		if (ret < 0)
+			return ret;
+		ret = btf_ownership_depth(btf, tab, depth, ret, depth_left - 1);
+		if (ret < 0)
+			return ret;
+		max_depth = max(max_depth, ret);
+	}
+	depth[idx] = max_depth + 1;
+done:
+	return depth[idx] > depth_left ? -ELOOP : depth[idx];
+}
 
-		/* We need to ensure ownership acyclicity among all types. The
-		 * proper way to do it would be to topologically sort all BTF
-		 * IDs based on the ownership edges, since there can be multiple
-		 * bpf_{list_head,rb_node} in a type. Instead, we use the
-		 * following resaoning:
-		 *
-		 * - A type can only be owned by another type in user BTF if it
-		 *   has a bpf_{list,rb}_node. Let's call these node types.
-		 * - A type can only _own_ another type in user BTF if it has a
-		 *   bpf_{list_head,rb_root}. Let's call these root types.
-		 *
-		 * We ensure that if a type is both a root and node, its
-		 * element types cannot be root types.
-		 *
-		 * To ensure acyclicity:
-		 *
-		 * When A is an root type but not a node, its ownership
-		 * chain can be:
-		 *	A -> B -> C
-		 * Where:
-		 * - A is an root, e.g. has bpf_rb_root.
-		 * - B is both a root and node, e.g. has bpf_rb_node and
-		 *   bpf_list_head.
-		 * - C is only an root, e.g. has bpf_list_node
-		 *
-		 * When A is both a root and node, some other type already
-		 * owns it in the BTF domain, hence it can not own
-		 * another root type through any of the ownership edges.
-		 *	A -> B
-		 * Where:
-		 * - A is both an root and node.
-		 * - B is only an node.
-		 */
-		if (meta->record->field_mask & BPF_GRAPH_ROOT)
-			return -ELOOP;
+static int btf_check_ownership_depth(const struct btf *btf,
+				     struct btf_struct_metas *tab)
+{
+	u8 *depth;
+	int i, ret = 0;
+
+	depth = kvcalloc(tab->cnt, sizeof(*depth), GFP_KERNEL | __GFP_NOWARN);
+	if (!depth)
+		return -ENOMEM;
+
+	for (i = 0; i < tab->cnt; i++) {
+		ret = btf_ownership_depth(btf, tab, depth, i,
+					  BTF_MAX_OWNERSHIP_DEPTH);
+		if (ret < 0)
+			break;
+		ret = 0;
 	}
-	return 0;
+	kvfree(depth);
+	return ret;
 }
 
 static void __btf_struct_show(const struct btf *btf, const struct btf_type *t,
@@ -5811,6 +5845,10 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uat
 			if (err < 0)
 				goto errout_meta;
 		}
+
+		err = btf_check_ownership_depth(btf, struct_meta_tab);
+		if (err < 0)
+			goto errout_meta;
 	}
 
 	err = finalize_log(&env->log, uattr, uattr_size);
diff --git a/tools/testing/selftests/bpf/prog_tests/linked_list.c b/tools/testing/selftests/bpf/prog_tests/linked_list.c
index 77d07e0a4a55c..5744909a561b2 100644
--- a/tools/testing/selftests/bpf/prog_tests/linked_list.c
+++ b/tools/testing/selftests/bpf/prog_tests/linked_list.c
@@ -711,7 +711,7 @@ static void test_btf(void)
 			break;
 
 		err = btf__load_into_kernel(btf);
-		ASSERT_EQ(err, -ELOOP, "check btf");
+		ASSERT_EQ(err, 0, "check btf");
 		btf__free(btf);
 		break;
 	}
@@ -770,7 +770,7 @@ static void test_btf(void)
 			break;
 
 		err = btf__load_into_kernel(btf);
-		ASSERT_EQ(err, -ELOOP, "check btf");
+		ASSERT_EQ(err, 0, "check btf");
 		btf__free(btf);
 		break;
 	}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 366/877] net: usb: catc: bound the RX packet length in catc_rx_done()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (364 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 365/877] bpf: Bound ownership depth through local kptrs and graph roots Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 367/877] bpf: Check params size before reading reserved fields Greg Kroah-Hartman
                   ` (518 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Aamir Ahmed, Simon Horman,
	Jakub Kicinski, Sasha Levin

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

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

From: Aamir Ahmed <elb12345@hotmail.co.uk>

[ Upstream commit 9d565b6b72fe3f41fd43636e143072848105189f ]

catc_rx_done() walks a multi-packet URB, reading a two-byte length from
each packet header. Its bound, pkt_len > urb->actual_length, ignores the
header offset and compares against the whole transfer rather than the
bytes left from pkt_start, so a crafted packet header makes
skb_copy_to_linear_data() read past the buffer.

A length below ETH_HLEN is also accepted, including zero, and
eth_type_trans() then reads a MAC header from the uninitialised tailroom
of a shorter skb. The is_f5u011 branch takes its length straight from
the transfer, so a zero-length URB reaches the same path.

Track the bytes remaining from the current packet, and reject a header
that does not fit, a length past what is left, and a length below an
Ethernet header.

A transfer shorter than an Ethernet header, including a zero-length one,
previously became a runt skb passed to netif_rx() and counted as
received; it is now counted in rx_length_errors and ends the walk.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Aamir Ahmed <elb12345@hotmail.co.uk>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/AS8P251MB00015FD7716F38C345619B56C8BB2@AS8P251MB0001.EURP251.PROD.OUTLOOK.COM
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/usb/catc.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index 98346cb4ece01..dd1e29add0609 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -239,17 +239,26 @@ static void catc_rx_done(struct urb *urb)
 	}
 
 	do {
-		if(!catc->is_f5u011) {
-			pkt_len = le16_to_cpup((__le16*)pkt_start);
-			if (pkt_len > urb->actual_length) {
+		int remaining = urb->actual_length -
+				(pkt_start - (u8 *)urb->transfer_buffer);
+
+		if (!catc->is_f5u011) {
+			if (remaining < pkt_offset) {
 				catc->netdev->stats.rx_length_errors++;
 				catc->netdev->stats.rx_errors++;
 				break;
 			}
+			pkt_len = le16_to_cpup((__le16 *)pkt_start);
 		} else {
 			pkt_len = urb->actual_length;
 		}
 
+		if (pkt_len < ETH_HLEN || pkt_len + pkt_offset > remaining) {
+			catc->netdev->stats.rx_length_errors++;
+			catc->netdev->stats.rx_errors++;
+			break;
+		}
+
 		if (!(skb = dev_alloc_skb(pkt_len)))
 			return;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 367/877] bpf: Check params size before reading reserved fields
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (365 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 366/877] net: usb: catc: bound the RX packet length in catc_rx_done() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 368/877] net/sched: sch_hfsc: bound the classify inner-filter walk with a drift budget Greg Kroah-Hartman
                   ` (517 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Yuqi Xu, Alexei Starovoitov,
	Ren Wei, Sasha Levin

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

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

From: Yuqi Xu <xuyuqiabc@gmail.com>

[ Upstream commit a11212910cf09b2fe8db9afa41ef60c4f81879c5 ]

bpf_crypto_ctx_create() is a kfunc whose second argument is declared
with the __sz annotation, so the verifier only guarantees that
params__sz bytes of params are valid.  The function nevertheless reads
params->reserved[0] and params->reserved[1] (offsets 14 and 15) before
comparing params__sz against the size of struct bpf_crypto_params, so a
BPF program can pass a shorter buffer and have the kernel read past the
region that was validated for it.

Move the size check in front of the reserved field reads.

Fixes: 3e1c6f35409f ("bpf: make common crypto API for TC/XDP programs")
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Ren Wei <weir@nebusec.ai>
Link: https://patch.msgid.link/4f3ab4b03e79017e215521743996555439bf0bb3.1789802413.git.xuyuqiabc@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/crypto.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/kernel/bpf/crypto.c b/kernel/bpf/crypto.c
index 1d024fe7248ac..3837d4dcf48d5 100644
--- a/kernel/bpf/crypto.c
+++ b/kernel/bpf/crypto.c
@@ -149,8 +149,9 @@ bpf_crypto_ctx_create(const struct bpf_crypto_params *params, u32 params__sz,
 	const struct bpf_crypto_type *type;
 	struct bpf_crypto_ctx *ctx;
 
-	if (!params || params->reserved[0] || params->reserved[1] ||
-	    params__sz != sizeof(struct bpf_crypto_params)) {
+	if (!params ||
+	    params__sz != sizeof(struct bpf_crypto_params) ||
+	    params->reserved[0] || params->reserved[1]) {
 		*err = -EINVAL;
 		return NULL;
 	}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 368/877] net/sched: sch_hfsc: bound the classify inner-filter walk with a drift budget
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (366 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 367/877] bpf: Check params size before reading reserved fields Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 369/877] drm/virtio: fix object leak when drm_gem_handle_create() fails Greg Kroah-Hartman
                   ` (516 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko (gemini + nipa),
	Victor Nogueira, hybris, Jamal Hadi Salim, Jakub Kicinski,
	Sasha Levin

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

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

From: Jamal Hadi Salim <jhs@mojatatu.com>

[ Upstream commit 8a60ade2277e1f0e0d0578d565354e52292fa46d ]

hfsc_classify() applies the "filter may only point downwards" level check
only when the filter result carries no bound class. A filter created with
a flowid gets res.class set once at bind time, so the check never runs for
it during classification. hfsc_adjust_levels() can later raise a class's
level without revalidating existing bindings, leaving two binds that were
each legal at bind time pointing at each other; the classify walk then
bounces between two interior classes forever with the qdisc lock held and
BH disabled — a soft lockup from a single packet. The stuck walk trips
the watchdog:

  watchdog: BUG: soft lockup - CPU#3 stuck for 13s! [ping:444]
  RIP: 0010:u32_classify+0x542/0x17f0
  ...
  tcf_classify+0x66/0xa0
  hfsc_enqueue+0x166/0xdf0

Bound the traversal with a budget of non-descending hops, the only way a
configured walk can move without descending the class tree once levels
drift after bind time. The budget is cumulative over the whole walk and
is deliberately not reset on a descending hop: a chain that alternates a
descent with a lateral hop would return the budget every lap and never
trip. Descending hops never decrement it, so legitimately deep trees are
unaffected and a terminating lateral chain still classifies normally.
Drop the packet with a rate-limited warning once the budget is exhausted,
mirroring the merged HTB fix.

This is a follow-up to commit 729c4896ab82 ("net/sched: sch_htb: limit
htb_classify inner-class filter hops"), which bounded the same classify
loop on the HTB side but left the HFSC walk unbounded.

Conditions to recreate the bug:
- CONFIG_NET_SCHED, CONFIG_NET_SCH_HFSC, CONFIG_NET_CLS_U32,
  CONFIG_LOCKUP_DETECTOR.
- Build a cycle with two legal-at-bind-time flowid binds and a level
  drift: class X 1:1 (child of root) with leaf child 1:10; class Y 1:2
  (sibling of X) with children 1:20 and 1:200; root u32 filter flowid
  1:1; filter on X flowid 1:2 (legal when Y is a leaf); after Y's level
  rises to 2, filter on Y flowid 1:1 (legal then). Send one packet (ping
  on the device). Unfixed kernel: classify spins with the qdisc lock
  held; with softlockup_panic=1 it panics.
- Reachable from unprivileged user via unshare -Urn (CAP_NET_ADMIN).

Fixes: a2f79227138c ("net_sched: sch_hfsc: fix classification loops")
Reported-by: Sashiko (gemini + nipa) <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/netdev/QDISC-CTUU.v2.20260913192614@mojatatu.com/
Link: https://sashiko.dev/#/patchset/QDISC-CTUU.v2.20260913192614@mojatatu.com
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/QDISC-CTUU.v2.20260913192614%40mojatatu.com
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Tested-by: hybris <hybris@mojatatu.ai>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-CTUU.v3.20260916184908@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/sched/sch_hfsc.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 601f99dd989ae..df3501dfe01a8 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -386,6 +386,15 @@ cftree_update(struct hfsc_class *cl)
 #define	SM_MASK		((1ULL << SM_SHIFT) - 1)
 #define	ISM_MASK	((1ULL << ISM_SHIFT) - 1)
 
+/*
+ * Cap on the non-descending hops a classify walk may take before its
+ * filter chain is treated as misconfigured. A flowid binding that was
+ * legal at bind time can become lateral once hfsc_adjust_levels()
+ * raises a class level; a few such hops are legitimate, an unbounded
+ * run means the chain cycles.
+ */
+#define	HFSC_CLASSIFY_MAX_DRIFT	8
+
 static inline u64
 seg_x2y(u64 x, u64 sm)
 {
@@ -1133,6 +1142,7 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
 	struct hfsc_class *head, *cl;
 	struct tcf_result res;
 	struct tcf_proto *tcf;
+	unsigned int drift;
 	int result;
 
 	if (TC_H_MAJ(skb->priority ^ sch->handle) == 0 &&
@@ -1142,6 +1152,7 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
 
 	*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
 	head = &q->root;
+	drift = HFSC_CLASSIFY_MAX_DRIFT;
 	tcf = rcu_dereference_bh(q->root.filter_list);
 	while (tcf && (result = tcf_classify(skb, NULL, tcf, &res, false)) >= 0) {
 #ifdef CONFIG_NET_CLS_ACT
@@ -1167,6 +1178,17 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
 		if (cl->level == 0)
 			return cl; /* hit leaf class */
 
+		/*
+		 * flowid binds skip the level check above (res.class is set
+		 * at bind time and levels drift after), so a walk can follow
+		 * lateral hops without descending; a bounded number of them
+		 * is legal, more means the chain cycles.
+		 */
+		if (cl->level >= head->level && drift-- == 0) {
+			pr_warn_ratelimited("hfsc: classify hop budget exhausted, dropping packet\n");
+			return NULL;
+		}
+
 		/* apply inner filter chain */
 		tcf = rcu_dereference_bh(cl->filter_list);
 		head = cl;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 369/877] drm/virtio: fix object leak when drm_gem_handle_create() fails
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (367 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 368/877] net/sched: sch_hfsc: bound the classify inner-filter walk with a drift budget Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 370/877] drm/virtio: fix object leak in virtio_gpu_resource_create_ioctl() Greg Kroah-Hartman
                   ` (515 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yuhao Jiang, Junrui Luo,
	Dmitry Osipenko, Sasha Levin

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

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

From: Junrui Luo <moonafterrain@outlook.com>

[ Upstream commit 36570ef2244cc4d7563b1f0157bc0f032498638c ]

virtio_gpu_gem_create() owns the reference taken by
virtio_gpu_object_create(). On the drm_gem_handle_create() error path it
calls drm_gem_object_release() instead of dropping that reference.

drm_gem_object_release() is the inverse of drm_gem_object_init() and does
not touch the reference count or call obj->funcs->free(), so it is only
correct as the last step of a destructor, as in
virtio_gpu_cleanup_object(). Using it here leaves the bo at refcount 1
with no remaining reference, so virtio_gpu_free_object() never runs and
the shmem pages, sg table and virtio_gpu_object are leaked. Since
virtio_gpu_object_create() has already set bo->created,
VIRTIO_GPU_CMD_RESOURCE_UNREF is not queued either, leaking the host-side
resource and the resource id.

drm_gem_handle_create_tail() drops the handle reference on all of its
internal error paths, so the caller only has to drop its own. Use
drm_gem_object_put(), matching the success path below.

Fixes: dc5698e80cf7 ("Add virtio gpu driver.")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Assisted-by: Claude:claude-opus-5
Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/20260915-fixes-v2-1-a0d799e4db66@outlook.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/virtio/virtgpu_gem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c
index 2e75cdeb49b3d..0233a1c3181c5 100644
--- a/drivers/gpu/drm/virtio/virtgpu_gem.c
+++ b/drivers/gpu/drm/virtio/virtgpu_gem.c
@@ -45,7 +45,7 @@ static int virtio_gpu_gem_create(struct drm_file *file,
 
 	ret = drm_gem_handle_create(file, &obj->base.base, &handle);
 	if (ret) {
-		drm_gem_object_release(&obj->base.base);
+		drm_gem_object_put(&obj->base.base);
 		return ret;
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 370/877] drm/virtio: fix object leak in virtio_gpu_resource_create_ioctl()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (368 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 369/877] drm/virtio: fix object leak when drm_gem_handle_create() fails Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 371/877] drm/virtio: fix object leaks in virtio_gpu_resource_create_blob_ioctl() Greg Kroah-Hartman
                   ` (514 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Junrui Luo, Dmitry Osipenko,
	Sasha Levin

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

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

From: Junrui Luo <moonafterrain@outlook.com>

[ Upstream commit 477bc3068fc3777b9d8ffd79e265b0dfdf2d3a6b ]

virtio_gpu_resource_create_ioctl() calls drm_gem_object_release() on the
drm_gem_handle_create() error path instead of dropping the reference it
owns, so obj->funcs->free() never runs and the virtio_gpu_object, its
pages and sg table, the resource id and the host-side resource are
leaked.

Use drm_gem_object_put() instead.

Fixes: 62fb7a5e1096 ("virtio-gpu: add 3d/virgl support")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/20260915-fixes-v2-2-a0d799e4db66@outlook.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index e4f76f3155504..60e5146ddefec 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -180,7 +180,7 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
 
 	ret = drm_gem_handle_create(file, obj, &handle);
 	if (ret) {
-		drm_gem_object_release(obj);
+		drm_gem_object_put(obj);
 		return ret;
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 371/877] drm/virtio: fix object leaks in virtio_gpu_resource_create_blob_ioctl()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (369 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 370/877] drm/virtio: fix object leak in virtio_gpu_resource_create_ioctl() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 372/877] drm/virtio: release the GEM object on virtio_gpu_vram_create() errors Greg Kroah-Hartman
                   ` (513 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Junrui Luo, Dmitry Osipenko,
	Sasha Levin

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

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

From: Junrui Luo <moonafterrain@outlook.com>

[ Upstream commit 24b6d5c7641412c9ebef0d4c8b888d49a0e6b880 ]

virtio_gpu_resource_create_blob_ioctl() calls drm_gem_object_release() on
both the virtio_gpu_resource_assign_uuid() and drm_gem_handle_create()
error paths instead of dropping the reference it owns, so
obj->funcs->free() never runs and the virtio_gpu_object, the resource id
and the host-side resource are leaked.

Use drm_gem_object_put() instead.

Fixes: 897b4d1acaf5 ("drm/virtio: implement blob resources: resource create blob ioctl")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/20260915-fixes-v2-3-a0d799e4db66@outlook.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/virtio/virtgpu_ioctl.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_ioctl.c b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
index 60e5146ddefec..d8aec5112b326 100644
--- a/drivers/gpu/drm/virtio/virtgpu_ioctl.c
+++ b/drivers/gpu/drm/virtio/virtgpu_ioctl.c
@@ -546,14 +546,14 @@ static int virtio_gpu_resource_create_blob_ioctl(struct drm_device *dev,
 	if (params.blob_flags & VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE) {
 		ret = virtio_gpu_resource_assign_uuid(vgdev, bo);
 		if (ret) {
-			drm_gem_object_release(obj);
+			drm_gem_object_put(obj);
 			return ret;
 		}
 	}
 
 	ret = drm_gem_handle_create(file, obj, &handle);
 	if (ret) {
-		drm_gem_object_release(obj);
+		drm_gem_object_put(obj);
 		return ret;
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 372/877] drm/virtio: release the GEM object on virtio_gpu_vram_create() errors
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (370 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 371/877] drm/virtio: fix object leaks in virtio_gpu_resource_create_blob_ioctl() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 373/877] drm/bridge: samsung-dsim: fix TE GPIO lifetime for host attach Greg Kroah-Hartman
                   ` (512 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Junrui Luo, Dmitry Osipenko,
	Sasha Levin

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

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

From: Junrui Luo <moonafterrain@outlook.com>

[ Upstream commit 036d28db1818af2f9d80db771f5405da84d7732d ]

virtio_gpu_vram_create() frees the object with a bare kfree(vram) on
both error paths after drm_gem_private_object_init() has run, and on the
second one after drm_gem_create_mmap_offset() has linked obj->vma_node
into the device's VMA offset manager. The freed object stays in that
interval tree, so a later lookup or insertion walks freed memory, and
the dma_resv and gpuva lock are never destroyed.

Call drm_gem_object_release() before kfree() on both paths.

Fixes: 16845c5d5409 ("drm/virtio: implement blob resources: implement vram object")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/20260915-fixes-v2-4-a0d799e4db66@outlook.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/virtio/virtgpu_vram.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_vram.c b/drivers/gpu/drm/virtio/virtgpu_vram.c
index 25df81c027837..47a886824cd71 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vram.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vram.c
@@ -202,16 +202,12 @@ int virtio_gpu_vram_create(struct virtio_gpu_device *vgdev,
 
 	/* Create fake offset */
 	ret = drm_gem_create_mmap_offset(obj);
-	if (ret) {
-		kfree(vram);
-		return ret;
-	}
+	if (ret)
+		goto err_release_obj;
 
 	ret = virtio_gpu_resource_id_get(vgdev, &vram->base.hw_res_handle);
-	if (ret) {
-		kfree(vram);
-		return ret;
-	}
+	if (ret)
+		goto err_release_obj;
 
 	virtio_gpu_cmd_resource_create_blob(vgdev, &vram->base, params, NULL,
 					    0);
@@ -225,4 +221,9 @@ int virtio_gpu_vram_create(struct virtio_gpu_device *vgdev,
 
 	*bo_ptr = &vram->base;
 	return 0;
+
+err_release_obj:
+	drm_gem_object_release(obj);
+	kfree(vram);
+	return ret;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 373/877] drm/bridge: samsung-dsim: fix TE GPIO lifetime for host attach
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (371 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 372/877] drm/virtio: release the GEM object on virtio_gpu_vram_create() errors Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 374/877] Bluetooth: bnep: fix out-of-bounds reads on short RX/TX frames and control fallthrough Greg Kroah-Hartman
                   ` (511 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Luca Ceresoli, Li Youhong,
	Sasha Levin

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

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

From: Li Youhong <liyouhong@kylinos.cn>

[ Upstream commit ada667890773e033d2f40dc94176e3beb930b516 ]

When the Exynos DSI driver was generalized into samsung-dsim, the TE
GPIO acquisition was switched from gpiod_get_optional() to
devm_gpiod_get_optional() while keeping the matching gpiod_put() calls.
That combination is wrong for a managed descriptor.

However, dropping the puts and keeping the managed get is also wrong:
samsung_dsim_register_te_irq() runs from the DSI host attach callback,
and host detach/reattach can happen without destroying the device that
owns the managed action. A second attach would then request the GPIO
again without having released it.

Switch back to a non-managed gpiod_get_optional() and keep the explicit
gpiod_put() on the request_irq() error path and in
samsung_dsim_unregister_te_irq().

Fixes: e7447128ca4a ("drm: bridge: Generalize Exynos-DSI driver into a Samsung DSIM bridge")
Suggested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Li Youhong <liyouhong@kylinos.cn>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Link: https://patch.msgid.link/20260904014958.1572918-1-dayou5941@163.com
[Luca: remove unnecessary comment]
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/bridge/samsung-dsim.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c
index f3f836da6c2a7..b13c68cf725c8 100644
--- a/drivers/gpu/drm/bridge/samsung-dsim.c
+++ b/drivers/gpu/drm/bridge/samsung-dsim.c
@@ -1678,7 +1678,7 @@ static int samsung_dsim_register_te_irq(struct samsung_dsim *dsi, struct device
 	int te_gpio_irq;
 	int ret;
 
-	dsi->te_gpio = devm_gpiod_get_optional(dev, "te", GPIOD_IN);
+	dsi->te_gpio = gpiod_get_optional(dev, "te", GPIOD_IN);
 	if (!dsi->te_gpio)
 		return 0;
 	else if (IS_ERR(dsi->te_gpio))
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 374/877] Bluetooth: bnep: fix out-of-bounds reads on short RX/TX frames and control fallthrough
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (372 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 373/877] drm/bridge: samsung-dsim: fix TE GPIO lifetime for host attach Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 375/877] Bluetooth: btintel_pcie: validate device-supplied DMA indices Greg Kroah-Hartman
                   ` (510 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Hui Peng, Luiz Augusto von Dentz,
	Sasha Levin

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

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

From: Hui Peng <benquike@gmail.com>

[ Upstream commit f0ca020cbb9bb7f3f4ea8ba1dfcf30a282aec91e ]

Fix multiple out-of-bounds reads in Bluetooth BNEP frame processing:

1. In bnep_rx_frame() and bnep_ctrl_frame() (net/bluetooth/bnep/core.c),
   use pskb_may_pull() to verify the BNEP header, control type byte,
   filter count, and extension headers exist before reading them, and
   return 0 after handling BNEP_CONTROL instead of falling through to
   Ethernet frame submission when no extension headers follow.
2. In bnep_net_xmit() (net/bluetooth/bnep/netdev.c), verify skb->len >=
   ETH_HLEN with pskb_may_pull() before reading the 14-byte Ethernet
   header to prevent an out-of-bounds heap read and infoleak on short
   AF_PACKET TX frames.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/bluetooth/bnep/core.c   | 17 ++++++++++++++++-
 net/bluetooth/bnep/netdev.c |  8 +++++++-
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index ed3ca38d8a6e1..e93c79982abcc 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -273,9 +273,14 @@ static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
 
 		BT_DBG("type 0x%x len %u", h->type, h->len);
 
+		if (skb->len < h->len) {
+			err = -EILSEQ;
+			break;
+		}
+
 		switch (h->type & BNEP_TYPE_MASK) {
 		case BNEP_EXT_CONTROL:
-			bnep_rx_control(s, skb->data, skb->len);
+			bnep_rx_control(s, skb->data, h->len);
 			break;
 
 		default:
@@ -376,6 +381,11 @@ static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
 			goto badframe;
 	}
 
+	if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
+		kfree_skb(skb);
+		return 0;
+	}
+
 	/* Strip 802.1p header */
 	if (ntohs(s->eh.h_proto) == ETH_P_8021Q) {
 		if (!skb_pull(skb, 4))
@@ -454,6 +464,11 @@ static int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb)
 		goto send;
 	}
 
+	if (skb->len < ETH_HLEN) {
+		kfree_skb(skb);
+		return 0;
+	}
+
 	iv[il++] = (struct kvec) { &type, 1 };
 	len++;
 
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c
index cc1cff63194f0..5d9d851db926f 100644
--- a/net/bluetooth/bnep/netdev.c
+++ b/net/bluetooth/bnep/netdev.c
@@ -169,6 +169,12 @@ static netdev_tx_t bnep_net_xmit(struct sk_buff *skb,
 
 	BT_DBG("skb %p, dev %p", skb, dev);
 
+	if (!pskb_may_pull(skb, ETH_HLEN)) {
+		dev->stats.tx_dropped++;
+		kfree_skb(skb);
+		return NETDEV_TX_OK;
+	}
+
 #ifdef CONFIG_BT_BNEP_MC_FILTER
 	if (bnep_net_mc_filter(skb, s)) {
 		kfree_skb(skb);
@@ -221,7 +227,7 @@ void bnep_net_setup(struct net_device *dev)
 	dev->addr_len = ETH_ALEN;
 
 	ether_setup(dev);
-	dev->min_mtu = 0;
+	dev->min_mtu = ETH_MIN_MTU;
 	dev->max_mtu = ETH_MAX_MTU;
 	dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 	dev->netdev_ops = &bnep_netdev_ops;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 375/877] Bluetooth: btintel_pcie: validate device-supplied DMA indices
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (373 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 374/877] Bluetooth: bnep: fix out-of-bounds reads on short RX/TX frames and control fallthrough Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 376/877] Bluetooth: RFCOMM: Reject short EA=0 frames in rfcomm_recv_frame() Greg Kroah-Hartman
                   ` (509 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ravindra, Luiz Augusto von Dentz,
	Sasha Levin

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

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

From: Ravindra <ravindra@intel.com>

[ Upstream commit 37a11129345337efd6eef8e62b03b6348cd0dd8b ]

In btintel_pcie_msix_rx_handle(), the driver processes RX completion
descriptors (urbd1) written by the PCIe device into DMA-coherent memory.
urbd1->frbd_tag (a 16-bit field fully controlled by the device firmware
via DMA) is used directly as an array index into rxq->bufs[] without any
bounds check. rxq->bufs[] has only BTINTEL_PCIE_RX_DESCS_COUNT (64)
entries, while frbd_tag can be any value 0-65535. A malicious or
malfunctioning device can write an out-of-range frbd_tag, causing the
driver to dereference an out-of-bounds data_buf pointer.

Additionally, cr_hia is read from a DMA-shared index array also writable
by the device; if the device sets cr_hia >= rxq->count, the while-loop
never terminates because cr_tia is wrapped via modulo rxq->count and can
never equal an out-of-range cr_hia.

Add bounds validation for cr_hia and frbd_tag in the RX path, and cr_hia
in the TX path. Log invalid values with bt_dev_err before returning.

Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
Signed-off-by: Ravindra <ravindra@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/bluetooth/btintel_pcie.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index bc87ebc46f4db..9facd47ff89b9 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -513,6 +513,11 @@ static void btintel_pcie_msix_tx_handle(struct btintel_pcie_data *data)
 
 	txq = &data->txq;
 
+	if (cr_hia >= txq->count) {
+		bt_dev_err(data->hdev, "TXQ: invalid cr_hia %u", cr_hia);
+		return;
+	}
+
 	while (cr_tia != cr_hia) {
 		data->tx_wait_done = true;
 		wake_up(&data->tx_wait_q);
@@ -786,6 +791,11 @@ static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data)
 
 	rxq = &data->rxq;
 
+	if (cr_hia >= rxq->count) {
+		bt_dev_err(hdev, "RXQ: invalid cr_hia %u", cr_hia);
+		return;
+	}
+
 	/* The firmware sends multiple CD in a single MSI-X and it needs to
 	 * process all received CDs in this interrupt.
 	 */
@@ -793,6 +803,12 @@ static void btintel_pcie_msix_rx_handle(struct btintel_pcie_data *data)
 		urbd1 = &rxq->urbd1s[cr_tia];
 		ipc_print_urbd1(data->hdev, urbd1, cr_tia);
 
+		if (urbd1->frbd_tag >= rxq->count) {
+			bt_dev_err(hdev, "RXQ: invalid frbd_tag %u",
+				   urbd1->frbd_tag);
+			return;
+		}
+
 		buf = &rxq->bufs[urbd1->frbd_tag];
 		if (!buf) {
 			bt_dev_err(hdev, "RXQ: failed to get the DMA buffer for %d",
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 376/877] Bluetooth: RFCOMM: Reject short EA=0 frames in rfcomm_recv_frame()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (374 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 375/877] Bluetooth: btintel_pcie: validate device-supplied DMA indices Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 377/877] octeontx2-af: Fix memory scaling limitation in SR-IOV mode Greg Kroah-Hartman
                   ` (508 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Hui Peng, Luiz Augusto von Dentz,
	Sasha Levin

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

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

From: Hui Peng <benquike@gmail.com>

[ Upstream commit 6d91041bb38b97e2feb625123cc0529d7b83a0e1 ]

While rfcomm_recv_frame() verifies that skb->len is at least
sizeof(*hdr) + 1 (4 bytes: 3-byte header + 1-byte FCS), an RFCOMM frame
with an extended 2-byte length field (!__test_ea(hdr->len)) has a 4-byte
header plus a 1-byte FCS (5 bytes minimum, sizeof(*hdr) + 2).

When a 4-byte RFCOMM frame with EA == 0 arrives:
1. The initial skb->len < sizeof(*hdr) + 1 check passes (4 < 4 is false).
2. Trimming the FCS byte decrements skb->len to 3.
3. If __check_fcs() succeeds, skb_pull(skb, 4) fails (4 > 3) and returns
   NULL without advancing skb->data.
4. Because the return value of skb_pull() is ignored, the un-pulled
   3-byte struct rfcomm_hdr remains at skb->data and is either queued as
   application payload via rfcomm_recv_data() or parsed as a multiplexer
   control command via rfcomm_recv_mcc() on DLCI 0.

Fix this by extending the length check in rfcomm_recv_frame() to also
require skb->len >= sizeof(*hdr) + 2 when !__test_ea(hdr->len).

Fixes: b230e5bf501c ("Bluetooth: RFCOMM: validate skb length in rfcomm_recv_frame")
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/bluetooth/rfcomm/core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 5dc575833371a..6c57f5a766c17 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1817,7 +1817,8 @@ static struct rfcomm_session *rfcomm_recv_frame(struct rfcomm_session *s,
 		return s;
 	}
 
-	if (skb->len < sizeof(*hdr) + 1) {
+	if (skb->len < sizeof(*hdr) + 1 ||
+	    (!__test_ea(hdr->len) && skb->len < sizeof(*hdr) + 2)) {
 		kfree_skb(skb);
 		return s;
 	}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 377/877] octeontx2-af: Fix memory scaling limitation in SR-IOV mode
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (375 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 376/877] Bluetooth: RFCOMM: Reject short EA=0 frames in rfcomm_recv_frame() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 378/877] dpll: use exact lookup for reference sync pin id Greg Kroah-Hartman
                   ` (507 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Leon Romanovsky, Ratheesh Kannoth,
	Jakub Kicinski, Sasha Levin

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

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

From: Ratheesh Kannoth <rkannoth@marvell.com>

[ Upstream commit d06f2ebf67ff2962fe00d687e4f0d4703eb41a12 ]

The original code used DMA_ATTR_FORCE_CONTIGUOUS, which could exhaust
the CMA pool when a large number of VFs were requested.

Fix this by switching to the DMA streaming API. This is equivalent on
Octeon platforms, which provide full I/O coherency via the SMMU.

Cc: Leon Romanovsky <leon@kernel.org>
Fixes: 73d33dbc0723 ("octeontx2-af: Use DMA_ATTR_FORCE_CONTIGUOUS attribute in DMA alloc")
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
Reviewed-by: Leon Romanovsky <leon@kernel.org>
Link: https://patch.msgid.link/20260916022111.1083017-1-rkannoth@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 .../ethernet/marvell/octeontx2/af/common.h    | 45 ++++++++++++++++---
 1 file changed, 39 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/marvell/octeontx2/af/common.h b/drivers/net/ethernet/marvell/octeontx2/af/common.h
index 2436c1ff9ba4c..680cbee17ca6f 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/common.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/common.h
@@ -7,6 +7,10 @@
 #ifndef COMMON_H
 #define COMMON_H
 
+#include <linux/dma-mapping.h>
+#include <linux/gfp.h>
+#include <linux/mm.h>
+
 #include "rvu_struct.h"
 
 #define OTX2_ALIGN			128  /* Align to cacheline */
@@ -44,6 +48,33 @@ struct qmem {
 	u32		qsize;
 };
 
+static inline void *otx2_dma_alloc_coherent(struct device *dev, size_t size,
+					    dma_addr_t *dma_handle)
+{
+	dma_addr_t dma_addr;
+	void *vaddr;
+
+	vaddr = kzalloc(size, GFP_KERNEL);
+	if (!vaddr)
+		return NULL;
+
+	dma_addr = dma_map_single(dev, vaddr, size, DMA_BIDIRECTIONAL);
+	if (dma_mapping_error(dev, dma_addr)) {
+		kfree(vaddr);
+		return NULL;
+	}
+
+	*dma_handle = dma_addr;
+	return vaddr;
+}
+
+static inline void otx2_dma_free_coherent(struct device *dev, size_t size,
+					  void *vaddr, dma_addr_t dma_handle)
+{
+	dma_unmap_single(dev, dma_handle, size, DMA_BIDIRECTIONAL);
+	kfree(vaddr);
+}
+
 static inline int qmem_alloc(struct device *dev, struct qmem **q,
 			     int qsize, int entry_sz)
 {
@@ -60,8 +91,11 @@ static inline int qmem_alloc(struct device *dev, struct qmem **q,
 
 	qmem->entry_sz = entry_sz;
 	qmem->alloc_sz = (qsize * entry_sz) + OTX2_ALIGN;
-	qmem->base = dma_alloc_attrs(dev, qmem->alloc_sz, &qmem->iova,
-				     GFP_KERNEL, DMA_ATTR_FORCE_CONTIGUOUS);
+
+	if (get_order(PAGE_ALIGN(qmem->alloc_sz)) > MAX_PAGE_ORDER)
+		return -ENOMEM;
+
+	qmem->base = otx2_dma_alloc_coherent(dev, qmem->alloc_sz, &qmem->iova);
 	if (!qmem->base)
 		return -ENOMEM;
 
@@ -80,10 +114,9 @@ static inline void qmem_free(struct device *dev, struct qmem *qmem)
 		return;
 
 	if (qmem->base)
-		dma_free_attrs(dev, qmem->alloc_sz,
-			       qmem->base - qmem->align,
-			       qmem->iova - qmem->align,
-			       DMA_ATTR_FORCE_CONTIGUOUS);
+		otx2_dma_free_coherent(dev, qmem->alloc_sz,
+				       qmem->base - qmem->align,
+				       qmem->iova - qmem->align);
 	devm_kfree(dev, qmem);
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 378/877] dpll: use exact lookup for reference sync pin id
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (376 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 377/877] octeontx2-af: Fix memory scaling limitation in SR-IOV mode Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 379/877] net: usb: sr9700: include receive overhead in the length check Greg Kroah-Hartman
                   ` (506 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ivan Vecera, Jakub Kicinski,
	Sasha Levin

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

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

From: Ivan Vecera <ivecera@redhat.com>

[ Upstream commit 7cce782d8327b7291334c4a304cf3fd909a74d9d ]

dpll_pin_ref_sync_state_set() looks up the reference sync pin in the
pin->ref_sync_pins xarray, which is keyed by the sync pin's id (see
dpll_pin_ref_sync_pair_add() using xa_insert() with ref_sync_pin->id).
The pin id to operate on is supplied by userspace via DPLL_A_PIN_ID.

The lookup however used xa_find() with a ULONG_MAX limit, which returns
the first present entry with an index greater than or equal to the
requested id, not the entry stored exactly at that id. If userspace
passes an id that is not paired as a reference sync pin, but another
pin with a higher id is present in the xarray, xa_find() silently
returns that wrong pin and the subsequent ref_sync_set() operates on
it. The request only fails when the given id is larger than every
present key.

Use xa_load() for an exact-key lookup instead, mirroring the deletion
path in dpll_pin_ref_sync_pair_del().

Fixes: 58256a26bfb3 ("dpll: add reference sync get/set")
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
Link: https://patch.msgid.link/20260917143736.526221-1-ivecera@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/dpll/dpll_netlink.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
index d6281bc46988a..270ea8f7248a4 100644
--- a/drivers/dpll/dpll_netlink.c
+++ b/drivers/dpll/dpll_netlink.c
@@ -956,8 +956,7 @@ dpll_pin_ref_sync_state_set(struct dpll_pin *pin,
 	unsigned long i;
 	int ret;
 
-	ref_sync_pin = xa_find(&pin->ref_sync_pins, &ref_sync_pin_idx,
-			       ULONG_MAX, XA_PRESENT);
+	ref_sync_pin = xa_load(&pin->ref_sync_pins, ref_sync_pin_idx);
 	if (!ref_sync_pin) {
 		NL_SET_ERR_MSG(extack, "reference sync pin not found");
 		return -EINVAL;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 379/877] net: usb: sr9700: include receive overhead in the length check
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (377 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 378/877] dpll: use exact lookup for reference sync pin id Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 380/877] ipv6: Fix dst leak for uncached routes Greg Kroah-Hartman
                   ` (505 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ethan Nelson-Moore, Pengpeng Hou,
	Jakub Kicinski, Sasha Levin

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

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

From: Pengpeng Hou <hppiscas@163.com>

[ Upstream commit c06bde80ae7a7b595732f7cabcb92cf08db9d56a ]

The receive fixup subtracts the Ethernet CRC from the reported packet
length, but compares that payload length against the whole remaining
receive buffer. The following copy starts after the three-byte header,
and the cursor advance consumes both that header and the four-byte CRC.

Require the payload to fit after SR_RX_OVERHEAD before copying it or
advancing to the next packet. The loop already ensures that the
remaining buffer is larger than the overhead, so the subtraction is
safe.

The issue was found by our static-analysis tool.

Fixes: c9b37458e956 ("USB2NET : SR9700 : One chip USB 1.1 USB2NET SR9700Device Driver Support")
Reviewed-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Tested-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Signed-off-by: Pengpeng Hou <hppiscas@163.com>
Link: https://patch.msgid.link/20260920034745.18468-1-hppiscas@163.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/usb/sr9700.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c
index e4d7bcd0d99c2..202bb55e811f4 100644
--- a/drivers/net/usb/sr9700.c
+++ b/drivers/net/usb/sr9700.c
@@ -403,7 +403,8 @@ static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 		/* ignore the CRC length */
 		len = (skb->data[1] | (skb->data[2] << 8)) - 4;
 
-		if (len > ETH_FRAME_LEN || len > skb->len || len < 0)
+		if (len > ETH_FRAME_LEN || len < 0 ||
+		    len > skb->len - SR_RX_OVERHEAD)
 			return 0;
 
 		/* the last packet of current skb */
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 380/877] ipv6: Fix dst leak for uncached routes.
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (378 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 379/877] net: usb: sr9700: include receive overhead in the length check Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 381/877] tg3: clean up PHYLIB resources on probe failure Greg Kroah-Hartman
                   ` (504 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima, Hangbin Liu,
	Xuanqiang Luo, Ido Schimmel, Eric Dumazet, Jakub Kicinski,
	Sasha Levin

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

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

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit be31fe6333f534155e6b408f1ef6d77974bb41aa ]

ip6_route_output_flags(), ip6_rt_put_flags(), and ip6_dst_check()
detect an uncached route by list_empty(&rt->dst.rt_uncached),
which replaced the static DST_NOCACHE flag check in commit
a4c2fd7f7891 ("net: remove DST_NOCACHE flag").

When a device is unregistered, rt6_uncached_list_flush_dev()
unlinks uncached routes tied to the device from rt6_uncached_list.

Previously, they were moved to another list with list_move()
(__list_del_entry() + list_add()), and since commit 98aa546af5e4
("inet: remove (struct uncached_list)->quarantine"), the routes
are just unlinked with list_del_init().

If list_del_init() runs concurrently, list_empty() evaluates to
true; ip6_route_output_flags() calls dst_hold_safe() incorrectly
and ip6_rt_put_flags() skips ip6_rt_put(), leaking dst, and thus
dev tied via rt->from as well.

The same race is partially fixed by commit 9a6f0c4d5796 ("dst:
fix races in rt6_uncached_list_del() and rt_del_uncached_list()").

Let's check rt6->dst.rt_uncached_list instead.

Note that IPv4 does not have the same issue.

Fixes: 98aa546af5e4 ("inet: remove (struct uncached_list)->quarantine")
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Reviewed-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260920191558.2990636-1-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/net/ip6_route.h | 4 ++--
 net/ipv6/route.c        | 7 ++++---
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index eaa2f6770ce77..1de182615a07a 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -94,12 +94,12 @@ static inline struct dst_entry *ip6_route_output(struct net *net,
 }
 
 /* Only conditionally release dst if flags indicates
- * !RT6_LOOKUP_F_DST_NOREF or dst is in uncached_list.
+ * !RT6_LOOKUP_F_DST_NOREF or dst is uncached.
  */
 static inline void ip6_rt_put_flags(struct rt6_info *rt, int flags)
 {
 	if (!(flags & RT6_LOOKUP_F_DST_NOREF) ||
-	    !list_empty(&rt->dst.rt_uncached))
+	    rt->dst.rt_uncached_list)
 		ip6_rt_put(rt);
 }
 
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 15f02882be040..692b44975af31 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -139,6 +139,7 @@ void rt6_uncached_list_add(struct rt6_info *rt)
 {
 	struct uncached_list *ul = raw_cpu_ptr(&rt6_uncached_list);
 
+	/* Set once and never cleared: non-NULL marks an uncached route. */
 	rt->dst.rt_uncached_list = ul;
 
 	spin_lock_bh(&ul->lock);
@@ -2706,8 +2707,8 @@ struct dst_entry *ip6_route_output_flags(struct net *net,
 	rcu_read_lock();
 	dst = ip6_route_output_flags_noref(net, sk, fl6, flags);
 	rt6 = dst_rt6_info(dst);
-	/* For dst cached in uncached_list, refcnt is already taken. */
-	if (list_empty(&rt6->dst.rt_uncached) && !dst_hold_safe(dst)) {
+	/* For an uncached dst, refcnt is already taken. */
+	if (!rt6->dst.rt_uncached_list && !dst_hold_safe(dst)) {
 		dst = &net->ipv6.ip6_null_entry->dst;
 		dst_hold(dst);
 	}
@@ -2817,7 +2818,7 @@ INDIRECT_CALLABLE_SCOPE struct dst_entry *ip6_dst_check(struct dst_entry *dst,
 	from = rcu_dereference(rt->from);
 
 	if (from && (rt->rt6i_flags & RTF_PCPU ||
-	    unlikely(!list_empty(&rt->dst.rt_uncached))))
+	    unlikely(rt->dst.rt_uncached_list)))
 		dst_ret = rt6_dst_from_check(rt, from, cookie);
 	else
 		dst_ret = rt6_check(rt, from, cookie);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 381/877] tg3: clean up PHYLIB resources on probe failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (379 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 380/877] ipv6: Fix dst leak for uncached routes Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 382/877] drm/i915/psr: Add new SU area calculation helper to apply workarounds Greg Kroah-Hartman
                   ` (503 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak, Paolo Abeni,
	Sasha Levin

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

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

From: Myeonghun Pak <mhun512@gmail.com>

[ Upstream commit a92e1a412c53dc0d9ad639e7abf8b3fc70a5b6ad ]

tg3_get_invariants() can register an MDIO bus and connect a PHY for
USE_PHYLIB devices. If tg3_init_one() later fails, its common error path
releases the mappings and netdev without undoing those PHYLIB resources.

Disconnect the PHY and unregister the MDIO bus before the remaining
teardown. Guard PHY cleanup with USE_PHYLIB to match tg3_phy_init(), and
call tg3_mdio_fini() unconditionally to match tg3_mdio_init(). The existing
IS_CONNECTED and MDIOBUS_INITED flags make both helpers safe when
initialization only completed partially.

This issue was identified during our ongoing static-analysis research while
reviewing kernel code.

Fixes: 158d7abdae85 ("tg3: Add mdio bus registration")
Assisted-by: OpenAI:GPT-5.6
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Link: https://patch.msgid.link/20260917183336.36239-1-mhun512@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/broadcom/tg3.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 752f33ae98383..1df77bf9428b1 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -18031,6 +18031,10 @@ static int tg3_init_one(struct pci_dev *pdev,
 	return 0;
 
 err_out_apeunmap:
+	if (tg3_flag(tp, USE_PHYLIB))
+		tg3_phy_fini(tp);
+	tg3_mdio_fini(tp);
+
 	if (tp->aperegs) {
 		iounmap(tp->aperegs);
 		tp->aperegs = NULL;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 382/877] drm/i915/psr: Add new SU area calculation helper to apply workarounds
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (380 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 381/877] tg3: clean up PHYLIB resources on probe failure Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 383/877] drm/i915/psr: Clear stale sel fetch enable bits on sel fetch disable Greg Kroah-Hartman
                   ` (502 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jouni Högander, Mika Kahola,
	Sasha Levin

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

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

From: Jouni Högander <jouni.hogander@intel.com>

[ Upstream commit f3c25031bb321d8cef15ecd4df27d0f644a95193 ]

intel_psr2_sel_fetch_update is already quite long function. Now we are
about to add one more HW workaround. Let's split applying workarounds to
selective update area into a separate function.

Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240926064759.1313335-2-jouni.hogander@intel.com
Stable-dep-of: 2777ec985227 ("drm/i915/psr: Clear stale sel fetch enable bits on sel fetch disable")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/i915/display/intel_psr.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 5173f5759ce88..af4548d1f724c 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2529,11 +2529,24 @@ static bool psr2_sel_fetch_pipe_state_supported(const struct intel_crtc_state *c
 	return true;
 }
 
+static void
+intel_psr_apply_su_area_workarounds(struct intel_crtc_state *crtc_state)
+{
+	struct intel_display *display = to_intel_display(crtc_state);
+	struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
+
+	/* Wa_14014971492 */
+	if (!crtc_state->has_panel_replay &&
+	    ((IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_A0, STEP_B0) ||
+	      IS_ALDERLAKE_P(i915) || IS_TIGERLAKE(i915))) &&
+	    crtc_state->splitter.enable)
+		crtc_state->psr2_su_area.y1 = 0;
+}
+
 int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
 				struct intel_crtc *crtc)
 {
 	struct intel_display *display = to_intel_display(state);
-	struct drm_i915_private *dev_priv = to_i915(state->base.dev);
 	struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
 	struct intel_plane_state *new_plane_state, *old_plane_state;
 	struct intel_plane *plane;
@@ -2644,12 +2657,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
 	if (full_update)
 		goto skip_sel_fetch_set_loop;
 
-	/* Wa_14014971492 */
-	if (!crtc_state->has_panel_replay &&
-	    ((IS_DISPLAY_VER_STEP(display, IP_VER(14, 0), STEP_A0, STEP_B0) ||
-	      IS_ALDERLAKE_P(dev_priv) || IS_TIGERLAKE(dev_priv))) &&
-	    crtc_state->splitter.enable)
-		crtc_state->psr2_su_area.y1 = 0;
+	intel_psr_apply_su_area_workarounds(crtc_state);
 
 	ret = drm_atomic_add_affected_planes(&state->base, &crtc->base);
 	if (ret)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 383/877] drm/i915/psr: Clear stale sel fetch enable bits on sel fetch disable
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (381 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 382/877] drm/i915/psr: Add new SU area calculation helper to apply workarounds Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 384/877] s390/debug: Do not register views for failed static debug areas Greg Kroah-Hartman
                   ` (501 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nemesa Garg, Jouni Högander,
	Suraj Kandpal, Jani Nikula, Sasha Levin

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

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

From: Nemesa Garg <nemesa.garg@intel.com>

[ Upstream commit 2777ec9852277a06ae68fee0c4f1a32783e4a999 ]

Selective fetch is dropped while pipe CRC is active, and the planes keep
their SEL_FETCH_PLANE_CTL / SEL_FETCH_CUR_CTL enable bit set in hardware
over that. A plane disabled while selective fetch is off never gets the
bit cleared, as the disable path is guarded by enable_psr2_sel_fetch.
Once selective fetch comes back the hardware resumes fetching for a
plane that is no longer enabled and keeps its DDB range reserved.

Clear the bits as selective fetch is turned off instead. Atomic check
has both the old and the new crtc state, so record the transition there
and let the plane and cursor arm paths write the registers to 0 for that
commit.

v2: Drop the old_crtc_state->hw.active check. [Jouni]

Fixes: b1f5279b5981 ("drm/i915/psr: Move plane sel fetch configuration into plane source files")
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/8739
Assisted-by: Copilot:Claude-Opus-5
Signed-off-by: Nemesa Garg <nemesa.garg@intel.com>
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com>
Link: https://patch.msgid.link/20260909110332.3528029-3-nemesa.garg@intel.com
(cherry picked from commit a4c0e7f80429eda6990960971aebd4e4b9533cc6)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/i915/display/intel_cursor.c       |  7 +++++--
 .../gpu/drm/i915/display/intel_display_types.h    |  2 ++
 drivers/gpu/drm/i915/display/intel_psr.c          | 15 +++++++++++++++
 .../gpu/drm/i915/display/skl_universal_plane.c    |  9 ++++-----
 4 files changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
index aeadb834d3328..2a70b2f7b39c8 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -536,7 +536,8 @@ static void i9xx_cursor_disable_sel_fetch_arm(struct intel_dsb *dsb,
 	struct intel_display *display = to_intel_display(plane->base.dev);
 	enum pipe pipe = plane->pipe;
 
-	if (!crtc_state->enable_psr2_sel_fetch)
+	if (!crtc_state->enable_psr2_sel_fetch &&
+	    !crtc_state->clear_psr2_sel_fetch)
 		return;
 
 	intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), 0);
@@ -571,8 +572,10 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_dsb *dsb,
 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
 	enum pipe pipe = plane->pipe;
 
-	if (!crtc_state->enable_psr2_sel_fetch)
+	if (!crtc_state->enable_psr2_sel_fetch) {
+		i9xx_cursor_disable_sel_fetch_arm(dsb, plane, crtc_state);
 		return;
+	}
 
 	if (drm_rect_height(&plane_state->psr2_sel_fetch_area) > 0) {
 		if (crtc_state->enable_psr2_su_region_et) {
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 992945b37190e..92be2cf1cf3b0 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1213,6 +1213,8 @@ struct intel_crtc_state {
 	bool has_sel_update;
 	bool enable_psr2_sel_fetch;
 	bool enable_psr2_su_region_et;
+	/* Drop the stale selective fetch enable bits as selective fetch is turned off */
+	bool clear_psr2_sel_fetch;
 	bool req_psr2_sdp_prior_scanline;
 	bool has_panel_replay;
 	bool wm_level_disabled;
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index af4548d1f724c..596b82b736b62 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2547,6 +2547,8 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
 				struct intel_crtc *crtc)
 {
 	struct intel_display *display = to_intel_display(state);
+	const struct intel_crtc_state *old_crtc_state =
+		intel_atomic_get_old_crtc_state(state, crtc);
 	struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
 	struct intel_plane_state *new_plane_state, *old_plane_state;
 	struct intel_plane *plane;
@@ -2559,6 +2561,19 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
 	bool full_update = false, su_area_changed;
 	int i, ret;
 
+	/*
+	 * Selective fetch is not always usable, for instance it is dropped
+	 * while pipe CRC is active. The planes keep their selective fetch
+	 * enable bit set in hardware over that, and a plane disabled while
+	 * selective fetch is off never gets the bit cleared. Once selective
+	 * fetch comes back the hardware would resume fetching for a plane that
+	 * is no longer enabled and keep its DDB range reserved, so have the
+	 * plane update drop the bit for every plane of the pipe as selective
+	 * fetch is turned off.
+	 */
+	crtc_state->clear_psr2_sel_fetch = old_crtc_state->enable_psr2_sel_fetch &&
+		!crtc_state->enable_psr2_sel_fetch;
+
 	if (!crtc_state->enable_psr2_sel_fetch)
 		return 0;
 
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 7f77a76309bd5..42b3bd848162f 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -776,7 +776,8 @@ static void icl_plane_disable_sel_fetch_arm(struct intel_dsb *dsb,
 	struct intel_display *display = to_intel_display(plane->base.dev);
 	enum pipe pipe = plane->pipe;
 
-	if (!crtc_state->enable_psr2_sel_fetch)
+	if (!crtc_state->enable_psr2_sel_fetch &&
+	    !crtc_state->clear_psr2_sel_fetch)
 		return;
 
 	intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_CTL(pipe, plane->id), 0);
@@ -1505,10 +1506,8 @@ static void icl_plane_update_sel_fetch_arm(struct intel_dsb *dsb,
 	struct intel_display *display = to_intel_display(plane->base.dev);
 	enum pipe pipe = plane->pipe;
 
-	if (!crtc_state->enable_psr2_sel_fetch)
-		return;
-
-	if (drm_rect_height(&plane_state->psr2_sel_fetch_area) > 0)
+	if (crtc_state->enable_psr2_sel_fetch &&
+	    drm_rect_height(&plane_state->psr2_sel_fetch_area) > 0)
 		intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_CTL(pipe, plane->id),
 				   SEL_FETCH_PLANE_CTL_ENABLE);
 	else
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 384/877] s390/debug: Do not register views for failed static debug areas
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (382 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 383/877] drm/i915/psr: Clear stale sel fetch enable bits on sel fetch disable Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 385/877] s390/debug: Fix NULL pointer dereference in debug_info_copy() Greg Kroah-Hartman
                   ` (500 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mikhail Zaslonko, Heiko Carstens,
	Sasha Levin

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

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

From: Mikhail Zaslonko <zaslonko@linux.ibm.com>

[ Upstream commit 28e29992b034acffc9342df216c06097825ce610 ]

__REGISTER_STATIC_DEBUG_INFO() calls debug_register_view()
unconditionally, even when debug_register_static() has failed. In that
case _debug_register() was never reached and id->debugfs_root_entry is
still NULL, so debugfs_create_file() places the view file in the debugfs
root directory. For sclp_err this leaves a /sys/kernel/debug/hex_ascii
file with nothing to indicate which debug log it belongs to.

debug_register_static() is not exported and the macro is its only
caller, so let it return an error code and skip the view registration
when it fails. No debugfs files are created for such an area then.

Reproduce by booting with s390dbf=sclp_err::100000000. The sclp_err
registration fails, no s390dbf/sclp_err/ directory is created, and a
hex_ascii file appears in the debugfs root instead.

Fixes: d72541f94512 ("s390/debug: add early tracing support")
Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/s390/include/asm/debug.h |  8 ++++++--
 arch/s390/kernel/debug.c      | 12 +++++++++---
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h
index ccd4e148b5ed4..7c3b058495d9d 100644
--- a/arch/s390/include/asm/debug.h
+++ b/arch/s390/include/asm/debug.h
@@ -451,7 +451,11 @@ static int VNAME(var, active_entries)[EARLY_AREAS] __initdata
 #define __REGISTER_STATIC_DEBUG_INFO(var, name, pages, areas, view)	\
 static int __init VNAME(var, reg)(void)					\
 {									\
-	debug_register_static(&var, (pages), (areas));			\
+	int rc;								\
+									\
+	rc = debug_register_static(&var, (pages), (areas));		\
+	if (rc)								\
+		return rc;						\
 	debug_register_view(&var, (view));				\
 	return 0;							\
 }									\
@@ -483,7 +487,7 @@ static debug_info_t __refdata var =					\
 	__DEBUG_INFO_INIT(var, (name), (buf_size));			\
 __REGISTER_STATIC_DEBUG_INFO(var, name, pages, nr_areas, view)
 
-void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas);
+int debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas);
 
 #endif /* MODULE */
 
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index f275fa8b3873f..9becc37529447 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -702,8 +702,12 @@ EXPORT_SYMBOL(debug_register);
  *
  * Note: This function is called automatically via an initcall generated by
  *	 DEFINE_STATIC_DEBUG_INFO.
+ *
+ * Return:
+ * - 0 on success
+ * - negative error code on failure
  */
-void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas)
+int debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas)
 {
 	unsigned long flags;
 	debug_info_t *copy;
@@ -711,7 +715,7 @@ void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas)
 	if (!initialized) {
 		pr_err("Tried to register debug feature %s too early\n",
 		       id->name);
-		return;
+		return -EINVAL;
 	}
 
 	copy = debug_info_alloc("", pages_per_area, nr_areas, id->buf_size,
@@ -726,7 +730,7 @@ void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas)
 		id->active_entries = NULL;
 		spin_unlock_irqrestore(&id->lock, flags);
 
-		return;
+		return -ENOMEM;
 	}
 
 	/* Replace static trace area with dynamic copy. */
@@ -744,6 +748,8 @@ void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas)
 	mutex_lock(&debug_mutex);
 	_debug_register(id);
 	mutex_unlock(&debug_mutex);
+
+	return 0;
 }
 
 /* Remove debugfs entries. */
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 385/877] s390/debug: Fix NULL pointer dereference in debug_info_copy()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (383 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 384/877] s390/debug: Do not register views for failed static debug areas Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 386/877] net: ethernet: ti: netcp: fix pm_runtime usage counter leak on error Greg Kroah-Hartman
                   ` (499 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mikhail Zaslonko,
	Peter Oberparleiter, Heiko Carstens, Sasha Levin

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

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

From: Mikhail Zaslonko <zaslonko@linux.ibm.com>

[ Upstream commit 012bfcd5a51082d5a65f096dfb9ca652b5267965 ]

When debug_register_static() fails, it clears areas, active_pages and
active_entries but leaves the area bounds unchanged. Copying such an
area, either by opening its view file or via debug_dump(), makes
debug_info_copy() dereference the NULL pointers.

Skip the copy loop when the source has no areas.

Closes: https://lore.kernel.org/r/20260903132123.12F271F00A3F@smtp.kernel.org
Fixes: d72541f94512 ("s390/debug: add early tracing support")
Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/s390/kernel/debug.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index 9becc37529447..3aaab76f43d9b 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -344,7 +344,8 @@ static debug_info_t *debug_info_copy(debug_info_t *in, int mode)
 		debug_info_free(rc);
 	} while (1);
 
-	if (mode == NO_AREAS)
+	/* debug_register_static() failure leaves areas NULL, bounds intact */
+	if (mode == NO_AREAS || !in->areas)
 		goto out;
 
 	for (i = 0; i < in->nr_areas; i++) {
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 386/877] net: ethernet: ti: netcp: fix pm_runtime usage counter leak on error
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (384 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 385/877] s390/debug: Fix NULL pointer dereference in debug_info_copy() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 387/877] genetlink: report the real command id for dump-only ops in policy dumps Greg Kroah-Hartman
                   ` (498 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, bui duc phuc, Simon Horman,
	Paolo Abeni, Sasha Levin

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

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

From: bui duc phuc <phucduc.bui@gmail.com>

[ Upstream commit ac4334522e4ba4a3b6710dd5d4cc98092824b8ca ]

pm_runtime_get_sync() leaves the runtime PM usage counter incremented even
when it fails, but the error path in netcp_probe() does not call
pm_runtime_put_noidle() to balance it, leaking a reference each time
resume fails.

Use pm_runtime_resume_and_get() instead, which automatically drops the
usage counter on failure, fixing the leak.

Fixes: 84640e27f230 ("net: netcp: Add Keystone NetCP core ethernet driver")
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260918042804.13101-1-phucduc.bui@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/ti/netcp_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/ti/netcp_core.c b/drivers/net/ethernet/ti/netcp_core.c
index d07dcffc2517e..15c2a6dffb8c1 100644
--- a/drivers/net/ethernet/ti/netcp_core.c
+++ b/drivers/net/ethernet/ti/netcp_core.c
@@ -2167,7 +2167,7 @@ static int netcp_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	pm_runtime_enable(&pdev->dev);
-	ret = pm_runtime_get_sync(&pdev->dev);
+	ret = pm_runtime_resume_and_get(&pdev->dev);
 	if (ret < 0) {
 		dev_err(dev, "Failed to enable NETCP power-domain\n");
 		pm_runtime_disable(&pdev->dev);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 387/877] genetlink: report the real command id for dump-only ops in policy dumps
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (385 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 386/877] net: ethernet: ti: netcp: fix pm_runtime usage counter leak on error Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 388/877] net: pcs: xpcs: fix clock reference leak on xpcs_init_clks failure Greg Kroah-Hartman
                   ` (497 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jakub Kicinski, Paolo Abeni,
	Sasha Levin

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

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

From: Jakub Kicinski <kuba@kernel.org>

[ Upstream commit 261e8a37ecbaf462cdf9c336d2b2f5056088401a ]

The op-to-policy map a CTRL_CMD_GETPOLICY dump returns is the only way
for userspace to find out which policy index belongs to which command.
ctrl_dumppolicy_put_op() tags the nest with doit->cmd, but an op which
only has a dumpit has no doit and every path which fills the split ops
in zeroes it out, so those entries all claim to be command 0.  nlctrl's
own CTRL_CMD_GETPOLICY and NETDEV_CMD_QSTATS_GET are both in that group:

  [{'family-id': 16, 'op-policy': {'do': 0, 'dump': 0, 'op-id': 3}},
   {'family-id': 16, 'op-policy': {'dump': 1, 'op-id': 0}},

ctrl_fill_info() gets this right - it uses the iterator's cmd for
CTRL_ATTR_OP_ID - so the two introspection interfaces of the same family
contradict each other today.

Pass the command in rather than reconstructing it from
doit->cmd | dumpit->cmd inside the helper, both callers already have it.

Fixes: 26588edbef60 ("genetlink: support split policies in ctrl_dumppolicy_put_op()")
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Link: https://patch.msgid.link/20260918222949.4190284-1-kuba@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/netlink/genetlink.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 3327d84518141..ecd5a0fd482a6 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1647,7 +1647,7 @@ static void *ctrl_dumppolicy_prep(struct sk_buff *skb,
 }
 
 static int ctrl_dumppolicy_put_op(struct sk_buff *skb,
-				  struct netlink_callback *cb,
+				  struct netlink_callback *cb, u32 cmd,
 				  struct genl_split_ops *doit,
 				  struct genl_split_ops *dumpit)
 {
@@ -1668,7 +1668,7 @@ static int ctrl_dumppolicy_put_op(struct sk_buff *skb,
 	if (!nest_pol)
 		goto err;
 
-	nest_op = nla_nest_start(skb, doit->cmd);
+	nest_op = nla_nest_start(skb, cmd);
 	if (!nest_op)
 		goto err;
 
@@ -1712,7 +1712,8 @@ static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
 						      &doit, &dumpit)))
 				return -ENOENT;
 
-			if (ctrl_dumppolicy_put_op(skb, cb, &doit, &dumpit))
+			if (ctrl_dumppolicy_put_op(skb, cb, ctx->op,
+						   &doit, &dumpit))
 				return skb->len;
 
 			/* done with the per-op policy index list */
@@ -1721,6 +1722,7 @@ static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
 
 		while (ctx->dump_map) {
 			if (ctrl_dumppolicy_put_op(skb, cb,
+						   ctx->op_iter->cmd,
 						   &ctx->op_iter->doit,
 						   &ctx->op_iter->dumpit))
 				return skb->len;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 388/877] net: pcs: xpcs: fix clock reference leak on xpcs_init_clks failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (386 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 387/877] genetlink: report the real command id for dump-only ops in policy dumps Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 389/877] thermal: gov_step_wise: Fix stale mitigation vote with non-zero lower bounds Greg Kroah-Hartman
                   ` (496 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Coia Prant, Simon Horman,
	Paolo Abeni, Sasha Levin

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

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

From: Coia Prant <coiaprant@gmail.com>

[ Upstream commit 9892d71cf0ce3ff3d4fed2d9a3968fd4feb1c918 ]

xpcs_init_clks() takes references with clk_bulk_get_optional() and then
enables them with clk_bulk_prepare_enable(). If the enable step fails,
the function returns without dropping the references.

xpcs_create() handles the failure through out_free_data, which calls
xpcs_free_data() but never xpcs_clear_clks(), so the clk references are
leaked.

Add the missing clk_bulk_put() on the enable failure path. The
prepare/enable side is already rolled back by
clk_bulk_prepare_enable() itself.

Fixes: f6bb3e9d98c2 ("net: pcs: xpcs: Add Synopsys DW xPCS platform device driver")
Signed-off-by: Coia Prant <coiaprant@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260919172021.2336748-1-coiaprant@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/pcs/pcs-xpcs.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index 0152f820c1bbe..1a6576a116672 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -1393,8 +1393,10 @@ static int xpcs_init_clks(struct dw_xpcs *xpcs)
 		return dev_err_probe(dev, ret, "Failed to get clocks\n");
 
 	ret = clk_bulk_prepare_enable(DW_XPCS_NUM_CLKS, xpcs->clks);
-	if (ret)
+	if (ret) {
+		clk_bulk_put(DW_XPCS_NUM_CLKS, xpcs->clks);
 		return dev_err_probe(dev, ret, "Failed to enable clocks\n");
+	}
 
 	return 0;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 389/877] thermal: gov_step_wise: Fix stale mitigation vote with non-zero lower bounds
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (387 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 388/877] net: pcs: xpcs: fix clock reference leak on xpcs_init_clks failure Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 390/877] bpf: Fix bounds check for skb-backed dynptrs Greg Kroah-Hartman
                   ` (495 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Manaf Meethalavalappu Pallikunhi,
	Rafael J. Wysocki, Sasha Levin

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

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

From: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>

[ Upstream commit ec0d89150a9381d591344a9f6f5428655c227a7f ]

When two or more thermal zones bind to a common cooling device and one zone
uses a non-zero instance->lower value, there is a bug where the instance
holds a stale mitigation vote even after its trip is cleared.

Problem scenario:
- thermal-zone1: Trip at 50°C, cooling-map with lower=0
- thermal-zone2: Trip at 55°C, cooling-map with lower=2
- Both zones share the same cooling device (e.g., CPU)

Issue flow:
1. Both trips trigger, zone1 requests state 5, zone2 also mitigates
2. Zone2 trip clears (temp < 53°C due to hysteresis)
3. When throttle=false and trend=THERMAL_TREND_DROPPING:
   - Current code checks: if (cur_state <= instance->lower)
     return THERMAL_NO_TARGET
   - Since cur_state (5) > instance->lower (2),
     it returns instance->lower (2)
   - This is the BUG where it returns instance->lower even though
     trip is cleared
4. Zone2's passive polling stops (tz->passive reaches 0) - no more updates
   for zone2
5. Zone2's stale vote of 2 persists indefinitely
6. Even when zone1 wants to reduce cooling to state, the cooling device
   cannot go below state 2 due to zone2's stale vote

When a trip is cleared (throttle == false), always return THERMAL_NO_TARGET
instead of instance->lower. Remove the unnecessary check comparing
cur_state with instance->lower. Since passive polling is already
deactivated when the trip is cleared, the instance should always be
deactivated regardless of its current cooling state. This ensures that
instances with non-zero lower bounds do not retain stale mitigation votes
after their trips are cleared.

Fixes: 042a3d80f118 ("thermal: core: Move passive polling management to the core")
Signed-off-by: Manaf Meethalavalappu Pallikunhi <manaf.pallikunhi@oss.qualcomm.com>
Link: https://patch.msgid.link/20260922-step_wise_multi_zone_stale_vote_fix-v1-1-789f68dab229@oss.qualcomm.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/thermal/gov_step_wise.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/thermal/gov_step_wise.c b/drivers/thermal/gov_step_wise.c
index b038f042ed74e..b191e11e553b5 100644
--- a/drivers/thermal/gov_step_wise.c
+++ b/drivers/thermal/gov_step_wise.c
@@ -65,14 +65,12 @@ static unsigned long get_target_state(struct thermal_instance *instance,
 				     min(instance->lower + 1, instance->upper),
 				     instance->upper);
 	} else if (trend == THERMAL_TREND_DROPPING) {
-		if (cur_state <= instance->lower)
-			return THERMAL_NO_TARGET;
-
 		/*
-		 * If 'throttle' is false, no mitigation is necessary, so
-		 * request the lower state for this instance.
+		 * If 'throttle' is false, no mitigation is necessary and
+		 * passive polling is already deactivated, so clear this
+		 * instance state by returning THERMAL_NO_TARGET.
 		 */
-		return instance->lower;
+		return THERMAL_NO_TARGET;
 	}
 
 	return instance->target;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 390/877] bpf: Fix bounds check for skb-backed dynptrs
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (388 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 389/877] thermal: gov_step_wise: Fix stale mitigation vote with non-zero lower bounds Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 391/877] bpf: Fix bpf_sock context code generation Greg Kroah-Hartman
                   ` (494 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Emil Tsalapatis,
	Alexei Starovoitov, Jiayuan Chen, Sasha Levin

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

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

From: Emil Tsalapatis <emil@etsalapatis.com>

[ Upstream commit ed6eec97b534979dcf28b40c389cee57bd6561d4 ]

The skb_pointer_if_linear() function checks whether a
memory region of length len starting at offset off into
the skb is in the linear area, and returns a pointer to
the region if so. The check currently subtracts between
skb_headlen and offset of the check, and since skb_headlen
is unsigned the subtraction can underflow. This causes the
bounds check to spuriously pass and generate an arbitrary
pointer of the form *(skb->data + off).

The only user of this helper is currently skb-backed BPF
dynptr code. Returning the wrong pointer leads to the
dynptr erroneously being backed with invalid memory.

Ensure the subtraction cannot underflow, and fail the check if
it would. Use u64 arithmetic to also prevent overflow when
calculating (skb_headlen(skb) - off) since off is unsigned.

Fixes: 6f5a630d7c57 ("bpf, net: Introduce skb_pointer_if_linear().")
Reported-by: Nicholas Carlini <nicholas@carlini.com>
Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://patch.msgid.link/20260922172028.6269-2-emil@etsalapatis.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/linux/skbuff.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 1bfdc03e0d94e..1e6b8871c432f 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -4280,7 +4280,10 @@ skb_header_pointer_careful(const struct sk_buff *skb, int offset,
 static inline void * __must_check
 skb_pointer_if_linear(const struct sk_buff *skb, int offset, int len)
 {
-	if (likely(skb_headlen(skb) - offset >= len))
+	unsigned int uoffset = (unsigned int)offset;
+
+	if (likely(uoffset <= skb_headlen(skb) &&
+		   (unsigned int)len <= skb_headlen(skb) - uoffset))
 		return skb->data + offset;
 	return NULL;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 391/877] bpf: Fix bpf_sock context code generation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (389 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 390/877] bpf: Fix bounds check for skb-backed dynptrs Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 392/877] bpf, sockmap: Reject max_entries > INT_MAX in sock_map_alloc Greg Kroah-Hartman
                   ` (493 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Emil Tsalapatis,
	Alexei Starovoitov, Jiayuan Chen, Sasha Levin

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

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

From: Emil Tsalapatis <emil@etsalapatis.com>

[ Upstream commit 4a4852376e3a2727ea40e61143d6d7c22bb6dfad ]

Currently, the ctx access code reads the rx_queue_mapping
field with either a 4-byte or 2-byte load. The rest of the bits
in the register are marked known zero by the verifier. However,
the emitted ctx access code places in the register on certain
the special value (-1) using BPF_MOV_IMM64, which gets sign-extended
to turn on all the bits in the register. By shifting this value right,
the program ends up with a value at runtime above what the verifier
assumes is possible.

Fix this by ensuring the read value is as wide as the assumed size.
Use MOV32 instructions instead of MOV64 instructions to keep
the upper bits zero as assumed by the verifier. Also properly report
the size of the destination variable (the bpf_sock field, 4 bytes) instead
of the source (the socket field, 2 bytes).

Fixes: c3c16f2ea6d2 ("bpf: Add rx_queue_mapping to bpf_sock")
Reported-by: Nicholas Carlini <nicholas@carlini.com>
Suggested-by: Nicholas Carlini <nicholas@carlini.com>
Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://patch.msgid.link/20260922172028.6269-4-emil@etsalapatis.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/filter.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/net/core/filter.c b/net/core/filter.c
index 7114a64e1898e..a680cf27ad820 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -10187,11 +10187,12 @@ u32 bpf_sock_convert_ctx_access(enum bpf_access_type type,
 				       target_size));
 		*insn++ = BPF_JMP_IMM(BPF_JNE, si->dst_reg, NO_QUEUE_MAPPING,
 				      1);
-		*insn++ = BPF_MOV64_IMM(si->dst_reg, -1);
+		*insn++ = BPF_MOV32_IMM(si->dst_reg, -1);
 #else
-		*insn++ = BPF_MOV64_IMM(si->dst_reg, -1);
-		*target_size = 2;
+		*insn++ = BPF_MOV32_IMM(si->dst_reg, -1);
 #endif
+		*target_size = sizeof_field(struct bpf_sock, rx_queue_mapping);
+
 		break;
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 392/877] bpf, sockmap: Reject max_entries > INT_MAX in sock_map_alloc
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (390 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 391/877] bpf: Fix bpf_sock context code generation Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 393/877] net/mlx5: Bridge, dont fail switchdev events of sibling eswitch ports Greg Kroah-Hartman
                   ` (492 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Zhao Gongyi, Alexei Starovoitov,
	Sasha Levin

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

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

From: Zhao Gongyi <zhaogongyi@BYTEDANCE.COM>

[ Upstream commit 814a81c842bd88f6bd8a4ce550d560df071a5d03 ]

sock_map_alloc() only rejects max_entries == 0 and otherwise allows any
u32 value.  sock_map_free() then walks the sks[] array with a signed int
iterator:

	int i;
	for (i = 0; i < stab->map.max_entries; i++)
		struct sock **psk = &stab->sks[i];

When a SOCKMAP is created with max_entries = 0xffffffff (UINT_MAX), the
allocation of 32 GiB can succeed on large-memory hosts.  During free the
counter reaches 0x80000000, wraps to INT_MIN, is sign-extended by movslq
and turned into a ~16 GiB negative offset from stab->sks, pointing far
below the allocation.

The faulting access is an xchg() write in sock_map_free().  Without
KASAN, the same out-of-bounds write can fault on an unmapped vmalloc page
or corrupt an unrelated allocation if that vmalloc address is populated.
On a KASAN kernel with CONFIG_KASAN_VMALLOC=y, the shadow check for that
address hits an unmapped shadow page and oopses first:

  BUG: unable to handle page fault for address: fffff521b59c5a00
  RIP: 0010:kasan_check_range+0x107/0x190
  Call Trace:
   sock_map_free+0x93/0x190
   map_create+0x68d/0xb30
   __sys_bpf+0x21e/0x2e70

Vmcore confirmed stab->map.max_entries == 0xffffffff, stab->sks ==
0xffffc911ace2d000, and the faulting address sks + (s64)INT_MIN * 8
exactly at 0xffffc90dace2d000.  The same buggy path is reached on the
normal close()/bpf_map_free_deferred() path whenever such a map is
destroyed.

sock_map_alloc() used to bound its allocation size through
bpf_map_charge_init(), but the bound was dropped when rlimit-based memory
accounting was removed.  Reject max_entries > INT_MAX at creation time so
the signed iterator in sock_map_free() never sees a value that would
overflow.

Triggered by syzkaller and reproduced on both a 6.6-based KASAN kernel
and the upstream v7.3-rc2 kernel.

Fixes: 0d2c4f964050 ("bpf: Eliminate rlimit-based memory accounting for sockmap and sockhash maps")
Signed-off-by: Zhao Gongyi <zhaogongyi@BYTEDANCE.COM>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20260917121016.48171-1-zhaogongyi@bytedance.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/sock_map.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/core/sock_map.c b/net/core/sock_map.c
index 6440ce16fc621..be4a4f8f346cb 100644
--- a/net/core/sock_map.c
+++ b/net/core/sock_map.c
@@ -41,6 +41,7 @@ static struct bpf_map *sock_map_alloc(union bpf_attr *attr)
 	struct bpf_stab *stab;
 
 	if (attr->max_entries == 0 ||
+	    attr->max_entries > INT_MAX ||
 	    attr->key_size    != 4 ||
 	    (attr->value_size != sizeof(u32) &&
 	     attr->value_size != sizeof(u64)) ||
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 393/877] net/mlx5: Bridge, dont fail switchdev events of sibling eswitch ports
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (391 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 392/877] bpf, sockmap: Reject max_entries > INT_MAX in sock_map_alloc Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 394/877] net/mlx5: Bridge, dont fail unlink of untracked/unsupported peer ports Greg Kroah-Hartman
                   ` (491 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bernardo Soares, Vlad Buslov,
	Saeed Mahameed, Mark Bloch, Jakub Kicinski, Sasha Levin

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

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

From: Bernardo Soares <bsoares.it@gmail.com>

[ Upstream commit 35e6f970f553954d92ba20afa885139a8e7dd0d7 ]

mlx5 registers the bridge offload switchdev notifiers once per eswitch
instance, but the notifier chains are global, so every instance sees
every event and must filter out the ones that aren't its own. The
existing filter, mlx5_esw_bridge_dev_same_hw(), only checks that the
event netdevice sits on the same HCA - intentional for merged eswitch,
where one bridge can span representors of several eswitches on one
HCA - but same-HCA doesn't mean the instance actually has that port:
peer ports are only created reactively from NETDEV_CHANGEUPPER, so an
instance brought up after a sibling PF's port was already enslaved has
none. The port object and attribute handlers claim the event anyway
once same-HW passes, then fail the port lookup and return -EINVAL,
which gets reported to user space even though the owning instance
already handled it (e.g. "bridge vlan add ... RTNETLINK answers:
Invalid argument"). Fix by filtering on the tracked port instead.

The same gap exists in the generic recursive lower-device walk used by
attribute changes on a bridge with more than one representor enslaved
directly: mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get() is entered
with the bridge master netdevice, falls through to its generic
netdev_for_each_lower_dev() loop, and returns as soon as the recursion
into any one lower device yields a non-NULL rep - the underlying base
case, mlx5_esw_bridge_rep_vport_num_vhca_id_get(), only checks
mlx5_esw_bridge_dev_same_hw(), not ownership by the calling instance's
br_offloads. mlx5_esw_bridge_lag_rep_get(), used for the LAG-master
case, already filters on mlx5_esw_bridge_dev_same_esw() per candidate
and so cannot select a sibling's rep; it is not the source of this bug.
On a merged-eswitch HCA with a bridge spanning representors of more
than one eswitch instance directly, the walk can return a sibling's rep
instead of continuing to the one the calling instance actually owns, so
the attribute change fails the same way as above. Fix by checking
mlx5_esw_bridge_port_exists() at the point each rep is picked, same as
the previous fix did for the notifier filter.

Fixes: c358ea1741bc ("net/mlx5: Bridge, allow merged eswitch connectivity")
Signed-off-by: Bernardo Soares <bsoares.it@gmail.com>
Cc: Vlad Buslov <vladbu@nvidia.com>
Cc: Saeed Mahameed <saeedm@nvidia.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Link: https://patch.msgid.link/20260918095931.29792-2-bsoares.it@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 .../mellanox/mlx5/core/en/rep/bridge.c        | 45 +++++++++++++++----
 .../ethernet/mellanox/mlx5/core/esw/bridge.c  |  6 +++
 .../ethernet/mellanox/mlx5/core/esw/bridge.h  |  2 +
 3 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
index 0f5d7ea8956f7..d8658fa517e70 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
@@ -89,9 +89,16 @@ mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(struct net_device *dev, struct m
 	struct net_device *lower_dev;
 	struct list_head *iter;
 
-	if (netif_is_lag_master(dev) || mlx5e_eswitch_rep(dev))
-		return mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, esw, vport_num,
-								 esw_owner_vhca_id);
+	if (netif_is_lag_master(dev) || mlx5e_eswitch_rep(dev)) {
+		struct net_device *rep;
+
+		rep = mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, esw, vport_num,
+								esw_owner_vhca_id);
+		if (rep && !mlx5_esw_bridge_port_exists(*vport_num, *esw_owner_vhca_id,
+							esw->br_offloads))
+			return NULL;
+		return rep;
+	}
 
 	netdev_for_each_lower_dev(dev, lower_dev, iter) {
 		struct net_device *rep;
@@ -108,6 +115,28 @@ mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(struct net_device *dev, struct m
 	return NULL;
 }
 
+static bool mlx5_esw_bridge_rep_port_lookup(struct net_device *dev,
+					    struct mlx5_esw_bridge_offloads *br_offloads,
+					    u16 *vport_num, u16 *esw_owner_vhca_id)
+{
+	if (!mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, br_offloads->esw, vport_num,
+						       esw_owner_vhca_id))
+		return false;
+
+	return mlx5_esw_bridge_port_exists(*vport_num, *esw_owner_vhca_id, br_offloads);
+}
+
+static bool mlx5_esw_bridge_lower_rep_port_lookup(struct net_device *dev,
+						  struct mlx5_esw_bridge_offloads *br_offloads,
+						  u16 *vport_num, u16 *esw_owner_vhca_id)
+{
+	if (!mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(dev, br_offloads->esw, vport_num,
+							     esw_owner_vhca_id))
+		return false;
+
+	return mlx5_esw_bridge_port_exists(*vport_num, *esw_owner_vhca_id, br_offloads);
+}
+
 static bool mlx5_esw_bridge_is_local(struct net_device *dev, struct net_device *rep,
 				     struct mlx5_eswitch *esw)
 {
@@ -222,8 +251,7 @@ mlx5_esw_bridge_port_obj_add(struct net_device *dev,
 	u16 vport_num, esw_owner_vhca_id;
 	int err;
 
-	if (!mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, br_offloads->esw, &vport_num,
-						       &esw_owner_vhca_id))
+	if (!mlx5_esw_bridge_rep_port_lookup(dev, br_offloads, &vport_num, &esw_owner_vhca_id))
 		return 0;
 
 	port_obj_info->handled = true;
@@ -255,8 +283,7 @@ mlx5_esw_bridge_port_obj_del(struct net_device *dev,
 	const struct switchdev_obj_port_mdb *mdb;
 	u16 vport_num, esw_owner_vhca_id;
 
-	if (!mlx5_esw_bridge_rep_vport_num_vhca_id_get(dev, br_offloads->esw, &vport_num,
-						       &esw_owner_vhca_id))
+	if (!mlx5_esw_bridge_rep_port_lookup(dev, br_offloads, &vport_num, &esw_owner_vhca_id))
 		return 0;
 
 	port_obj_info->handled = true;
@@ -287,8 +314,8 @@ mlx5_esw_bridge_port_obj_attr_set(struct net_device *dev,
 	u16 vport_num, esw_owner_vhca_id;
 	int err = 0;
 
-	if (!mlx5_esw_bridge_lower_rep_vport_num_vhca_id_get(dev, br_offloads->esw, &vport_num,
-							     &esw_owner_vhca_id))
+	if (!mlx5_esw_bridge_lower_rep_port_lookup(dev, br_offloads, &vport_num,
+						   &esw_owner_vhca_id))
 		return 0;
 
 	port_attr_info->handled = true;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
index 282cef59e6173..6104ae8e72410 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
@@ -1683,6 +1683,12 @@ int mlx5_esw_bridge_vport_peer_unlink(struct net_device *br_netdev, u16 vport_nu
 					    extack);
 }
 
+bool mlx5_esw_bridge_port_exists(u16 vport_num, u16 esw_owner_vhca_id,
+				 struct mlx5_esw_bridge_offloads *br_offloads)
+{
+	return mlx5_esw_bridge_port_lookup(vport_num, esw_owner_vhca_id, br_offloads);
+}
+
 int mlx5_esw_bridge_port_vlan_add(u16 vport_num, u16 esw_owner_vhca_id, u16 vid, u16 flags,
 				  struct mlx5_esw_bridge_offloads *br_offloads,
 				  struct netlink_ext_ack *extack)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.h b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.h
index d6f5391619930..a4e59cc210894 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.h
@@ -80,6 +80,8 @@ int mlx5_esw_bridge_vlan_proto_set(u16 vport_num, u16 esw_owner_vhca_id, u16 pro
 				   struct mlx5_esw_bridge_offloads *br_offloads);
 int mlx5_esw_bridge_mcast_set(u16 vport_num, u16 esw_owner_vhca_id, bool enable,
 			      struct mlx5_esw_bridge_offloads *br_offloads);
+bool mlx5_esw_bridge_port_exists(u16 vport_num, u16 esw_owner_vhca_id,
+				 struct mlx5_esw_bridge_offloads *br_offloads);
 int mlx5_esw_bridge_port_vlan_add(u16 vport_num, u16 esw_owner_vhca_id, u16 vid, u16 flags,
 				  struct mlx5_esw_bridge_offloads *br_offloads,
 				  struct netlink_ext_ack *extack);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 394/877] net/mlx5: Bridge, dont fail unlink of untracked/unsupported peer ports
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (392 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 393/877] net/mlx5: Bridge, dont fail switchdev events of sibling eswitch ports Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 395/877] sctp: hold asoc or transport before mod_timer() in timer handlers Greg Kroah-Hartman
                   ` (490 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bernardo Soares, Mark Bloch,
	Jakub Kicinski, Sasha Levin

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

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

From: Bernardo Soares <bsoares.it@gmail.com>

[ Upstream commit 2e51097c982b7b22382fda3202ba29f0ea33e8c0 ]

mlx5_esw_bridge_vport_unlink() returns -EINVAL when the port isn't
tracked by this instance's br_offloads. This is reachable on a sibling
instance that registered its notifier after the port was already
enslaved: it never saw the NETDEV_CHANGEUPPER link event, so
peer_link() never created a peer port for it, but it does see the
later unlink event and fails. Return 0 instead, and give
mlx5_esw_bridge_vport_peer_unlink() the same merged_eswitch capability
guard peer_link() already has, since without it peer_link() likewise
never creates a port to unlink.

This also matters beyond the -EINVAL itself:
mlx5_esw_bridge_switchdev_port_event() runs on the per-netns
netdev_chain, and notifier_from_errno(-EINVAL) sets NOTIFY_STOP_MASK,
which call_netdevice_notifiers_info() checks to stop calling further
listeners on that chain - so the old -EINVAL silently dropped the
event for any listener registered later on the same chain, even
though none of it was visible to user space since
__netdev_upper_dev_unlink() discards the return value.

Fixes: c358ea1741bc ("net/mlx5: Bridge, allow merged eswitch connectivity")
Signed-off-by: Bernardo Soares <bsoares.it@gmail.com>
Reviewed-by: Mark Bloch <mbloch@nvidia.com>
Link: https://patch.msgid.link/20260918095931.29792-3-bsoares.it@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
index 6104ae8e72410..684154914cf83 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c
@@ -1646,10 +1646,8 @@ int mlx5_esw_bridge_vport_unlink(struct net_device *br_netdev, u16 vport_num,
 	int err;
 
 	port = mlx5_esw_bridge_port_lookup(vport_num, esw_owner_vhca_id, br_offloads);
-	if (!port) {
-		NL_SET_ERR_MSG_MOD(extack, "Port is not attached to any bridge");
-		return -EINVAL;
-	}
+	if (!port)
+		return 0;
 	if (port->bridge->ifindex != br_netdev->ifindex) {
 		NL_SET_ERR_MSG_MOD(extack, "Port is attached to another bridge");
 		return -EINVAL;
@@ -1679,6 +1677,9 @@ int mlx5_esw_bridge_vport_peer_unlink(struct net_device *br_netdev, u16 vport_nu
 				      struct mlx5_esw_bridge_offloads *br_offloads,
 				      struct netlink_ext_ack *extack)
 {
+	if (!MLX5_CAP_ESW(br_offloads->esw->dev, merged_eswitch))
+		return 0;
+
 	return mlx5_esw_bridge_vport_unlink(br_netdev, vport_num, esw_owner_vhca_id, br_offloads,
 					    extack);
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 395/877] sctp: hold asoc or transport before mod_timer() in timer handlers
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (393 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 394/877] net/mlx5: Bridge, dont fail unlink of untracked/unsupported peer ports Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 396/877] net: stmmac: selftests: Support running selftests on DSA conduits Greg Kroah-Hartman
                   ` (489 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Tangxin Xie, Xin Long,
	Jakub Kicinski, Sasha Levin

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

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

From: Xin Long <lucien.xin@gmail.com>

[ Upstream commit cae23ae3f7887a1cf8a75da38edcebeef695040f ]

Take the association or transport reference before rearming a timer in the
timer handlers.

The existing code calls mod_timer() before taking the reference needed by
the rearmed timer without holding the sock lock. This creates a race with
timer cleanup: if the timer is deleted after mod_timer() returns but before
the reference is taken, the cleanup path can drop the timer's reference and
destroy the transport or association. The timer handler then takes a
reference on the already freed object and eventually drops it, causing a
refcount underflow.

Hold the object before mod_timer() and drop the reference if mod_timer()
reports that the timer was already pending in timer handlers. Apply the
same ordering to the proto-unreachable path, which can rearm a transport
timer outside the timer handlers without holding the sock lock.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Tangxin Xie <xietangxin@h-partners.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/c31b5e3ee2b7274e804f5eba2f21e2412e7eef7a.1790013825.git.lucien.xin@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/sctp/input.c         |  7 ++++---
 net/sctp/sm_sideeffect.c | 37 ++++++++++++++++++++++---------------
 2 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/net/sctp/input.c b/net/sctp/input.c
index df5b2187b8fad..e946c1b4abfea 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -436,9 +436,10 @@ void sctp_icmp_proto_unreachable(struct sock *sk,
 		if (timer_pending(&t->proto_unreach_timer))
 			return;
 		else {
-			if (!mod_timer(&t->proto_unreach_timer,
-						jiffies + (HZ/20)))
-				sctp_transport_hold(t);
+			sctp_transport_hold(t);
+			if (mod_timer(&t->proto_unreach_timer,
+				      jiffies + (HZ / 20)))
+				sctp_transport_put(t);
 		}
 	} else {
 		struct net *net = sock_net(sk);
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index c05f1b0736960..7d451e6c5d277 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -244,8 +244,9 @@ void sctp_generate_t3_rtx_event(struct timer_list *t)
 		pr_debug("%s: sock is busy\n", __func__);
 
 		/* Try again later.  */
-		if (!mod_timer(&transport->T3_rtx_timer, jiffies + (HZ/20)))
-			sctp_transport_hold(transport);
+		sctp_transport_hold(transport);
+		if (mod_timer(&transport->T3_rtx_timer, jiffies + (HZ / 20)))
+			sctp_transport_put(transport);
 		goto out_unlock;
 	}
 
@@ -280,8 +281,9 @@ static void sctp_generate_timeout_event(struct sctp_association *asoc,
 			 timeout_type);
 
 		/* Try again later.  */
-		if (!mod_timer(&asoc->timers[timeout_type], jiffies + (HZ/20)))
-			sctp_association_hold(asoc);
+		sctp_association_hold(asoc);
+		if (mod_timer(&asoc->timers[timeout_type], jiffies + (HZ / 20)))
+			sctp_association_put(asoc);
 		goto out_unlock;
 	}
 
@@ -373,8 +375,9 @@ void sctp_generate_heartbeat_event(struct timer_list *t)
 		pr_debug("%s: sock is busy\n", __func__);
 
 		/* Try again later.  */
-		if (!mod_timer(&transport->hb_timer, jiffies + (HZ/20)))
-			sctp_transport_hold(transport);
+		sctp_transport_hold(transport);
+		if (mod_timer(&transport->hb_timer, jiffies + (HZ / 20)))
+			sctp_transport_put(transport);
 		goto out_unlock;
 	}
 
@@ -383,8 +386,9 @@ void sctp_generate_heartbeat_event(struct timer_list *t)
 	timeout = sctp_transport_timeout(transport);
 	if (elapsed < timeout) {
 		elapsed = timeout - elapsed;
-		if (!mod_timer(&transport->hb_timer, jiffies + elapsed))
-			sctp_transport_hold(transport);
+		sctp_transport_hold(transport);
+		if (mod_timer(&transport->hb_timer, jiffies + elapsed))
+			sctp_transport_put(transport);
 		goto out_unlock;
 	}
 
@@ -417,9 +421,10 @@ void sctp_generate_proto_unreach_event(struct timer_list *t)
 		pr_debug("%s: sock is busy\n", __func__);
 
 		/* Try again later.  */
-		if (!mod_timer(&transport->proto_unreach_timer,
-				jiffies + (HZ/20)))
-			sctp_transport_hold(transport);
+		sctp_transport_hold(transport);
+		if (mod_timer(&transport->proto_unreach_timer,
+			      jiffies + (HZ / 20)))
+			sctp_transport_put(transport);
 		goto out_unlock;
 	}
 
@@ -453,8 +458,9 @@ void sctp_generate_reconf_event(struct timer_list *t)
 		pr_debug("%s: sock is busy\n", __func__);
 
 		/* Try again later.  */
-		if (!mod_timer(&transport->reconf_timer, jiffies + (HZ / 20)))
-			sctp_transport_hold(transport);
+		sctp_transport_hold(transport);
+		if (mod_timer(&transport->reconf_timer, jiffies + (HZ / 20)))
+			sctp_transport_put(transport);
 		goto out_unlock;
 	}
 
@@ -489,8 +495,9 @@ void sctp_generate_probe_event(struct timer_list *t)
 		pr_debug("%s: sock is busy\n", __func__);
 
 		/* Try again later.  */
-		if (!mod_timer(&transport->probe_timer, jiffies + (HZ / 20)))
-			sctp_transport_hold(transport);
+		sctp_transport_hold(transport);
+		if (mod_timer(&transport->probe_timer, jiffies + (HZ / 20)))
+			sctp_transport_put(transport);
 		goto out_unlock;
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 396/877] net: stmmac: selftests: Support running selftests on DSA conduits
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (394 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 395/877] sctp: hold asoc or transport before mod_timer() in timer handlers Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 397/877] net: stmmac: selftests: Check the dev->features for S-TAG offload testing Greg Kroah-Hartman
                   ` (488 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Maxime Chevallier,
	Jakub Kicinski, Sasha Levin

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

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

From: Maxime Chevallier <maxime.chevallier@bootlin.com>

[ Upstream commit d68acbf93531abdb5b02b21994cd4c15a3c95b42 ]

Most stmmac selftests rely on dev_add_pack() to add custom handlers,
that validate the packets sent to ourselves through MAC loopback.

However, when the stmmac-driven interface is a DSA CPU conduit, all
frames that are received have ETH_P_XDSA as a protocol, even though they
don't actually contain any tag as they come from the loopback and not
the switch.

This will prevent any incoming packet to match our packet handlers.

Let's register a ETH_P_ALL packet handler when we detect that we're a
DSA conduit, and use a proxy packet handler to filter the h_proto.

As this allows external frames to be received through our .func(), the
packet handler is added after the dev->addr field is populated in our
selftest attributes.

Note that we may still receive incoming packets from the switch, but
these frames shouldn't interfere with the very specific frames used for
selftests, and stmmac selftests in general aren't safe against external
traffic interferences.

This was validated on a WPQ864 devkit for IPQ8064, that has the SoC
connected to a QCA8k switch.

The ARP offload's packet handler is left alone, this feature is just not
implemented in stmmac and due for removal.

Fixes: 091810dbded9 ("net: stmmac: Introduce selftests support")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20260917215339.2022523-2-maxime.chevallier@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 .../stmicro/stmmac/stmmac_selftests.c         | 89 +++++++++++++++----
 1 file changed, 71 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
index 266211a401392..e1a5a0316d8d9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
@@ -13,6 +13,7 @@
 #include <linux/ip.h>
 #include <linux/phy.h>
 #include <linux/udp.h>
+#include <net/dsa.h>
 #include <net/pkt_cls.h>
 #include <net/pkt_sched.h>
 #include <net/tcp.h>
@@ -238,6 +239,9 @@ struct stmmac_test_priv {
 	struct stmmac_packet_attrs *packet;
 	struct packet_type pt;
 	struct completion comp;
+	__be16 packet_type;
+	int (*func)(struct sk_buff *skb, struct net_device *ndev,
+		    struct packet_type *pt, struct net_device *orig_ndev);
 	int double_vlan;
 	int vlan_id;
 	int ok;
@@ -317,6 +321,50 @@ static int stmmac_test_loopback_validate(struct sk_buff *skb,
 	return 0;
 }
 
+static int stmmac_sft_filter(struct sk_buff *skb, struct net_device *ndev,
+			     struct packet_type *pt,
+			     struct net_device *orig_ndev)
+{
+	struct stmmac_test_priv *tpriv = pt->af_packet_priv;
+	struct ethhdr *hdr = eth_hdr(skb);
+	int ret = 0;
+
+	if (hdr->h_proto == tpriv->packet_type) {
+		struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
+
+		if (nskb)
+			ret = tpriv->func(nskb, ndev, pt, orig_ndev);
+	}
+
+	kfree_skb(skb);
+	return ret;
+}
+
+static void stmmac_sft_add_pack(struct packet_type *pt)
+{
+	struct stmmac_test_priv *tpriv = pt->af_packet_priv;
+
+	if (netdev_uses_dsa(tpriv->pt.dev)) {
+		tpriv->packet_type = tpriv->pt.type;
+		tpriv->func = tpriv->pt.func;
+
+		/* DSA conduit will report ETH_P_XDSA, so our packet handler
+		 * won't match. Let's register a ETH_P_ALL match and filter
+		 * manually in stmmac_sft_filter.
+		 */
+		tpriv->pt.type = htons(ETH_P_ALL);
+		tpriv->pt.func = stmmac_sft_filter;
+		tpriv->pt.ignore_outgoing = true;
+	}
+
+	dev_add_pack(pt);
+}
+
+static void stmmac_sft_remove_pack(struct packet_type *pt)
+{
+	dev_remove_pack(pt);
+}
+
 static int __stmmac_test_loopback(struct stmmac_priv *priv,
 				  struct stmmac_packet_attrs *attr)
 {
@@ -338,7 +386,7 @@ static int __stmmac_test_loopback(struct stmmac_priv *priv,
 	tpriv->packet = attr;
 
 	if (!attr->dont_wait)
-		dev_add_pack(&tpriv->pt);
+		stmmac_sft_add_pack(&tpriv->pt);
 
 	skb = stmmac_test_get_udp_skb(priv, attr);
 	if (!skb) {
@@ -361,7 +409,7 @@ static int __stmmac_test_loopback(struct stmmac_priv *priv,
 
 cleanup:
 	if (!attr->dont_wait)
-		dev_remove_pack(&tpriv->pt);
+		stmmac_sft_remove_pack(&tpriv->pt);
 	kfree(tpriv);
 	return ret;
 }
@@ -775,7 +823,7 @@ static int stmmac_test_flowctrl(struct stmmac_priv *priv)
 	tpriv->pt.func = stmmac_test_flowctrl_validate;
 	tpriv->pt.dev = priv->dev;
 	tpriv->pt.af_packet_priv = tpriv;
-	dev_add_pack(&tpriv->pt);
+	stmmac_sft_add_pack(&tpriv->pt);
 
 	/* Compute minimum number of packets to make FIFO full */
 	pkt_count = priv->plat->rx_fifo_size;
@@ -833,7 +881,7 @@ static int stmmac_test_flowctrl(struct stmmac_priv *priv)
 cleanup:
 	dev_mc_del(priv->dev, paddr);
 	dev_set_promiscuity(priv->dev, -1);
-	dev_remove_pack(&tpriv->pt);
+	stmmac_sft_remove_pack(&tpriv->pt);
 	kfree(tpriv);
 	return ret;
 }
@@ -938,18 +986,20 @@ static int __stmmac_test_vlanfilt(struct stmmac_priv *priv)
 	 * HASH values.
 	 */
 	tpriv->vlan_id = 0x123;
-	dev_add_pack(&tpriv->pt);
 
 	ret = vlan_vid_add(priv->dev, htons(ETH_P_8021Q), tpriv->vlan_id);
 	if (ret)
 		goto cleanup;
 
+	attr.vlan = 1;
+	attr.dst = priv->dev->dev_addr;
+	attr.sport = 9;
+	attr.dport = 9;
+
+	stmmac_sft_add_pack(&tpriv->pt);
+
 	for (i = 0; i < 4; i++) {
-		attr.vlan = 1;
 		attr.vlan_id_out = tpriv->vlan_id + i;
-		attr.dst = priv->dev->dev_addr;
-		attr.sport = 9;
-		attr.dport = 9;
 
 		skb = stmmac_test_get_udp_skb(priv, &attr);
 		if (!skb) {
@@ -976,9 +1026,9 @@ static int __stmmac_test_vlanfilt(struct stmmac_priv *priv)
 	}
 
 vlan_del:
+	stmmac_sft_remove_pack(&tpriv->pt);
 	vlan_vid_del(priv->dev, htons(ETH_P_8021Q), tpriv->vlan_id);
 cleanup:
-	dev_remove_pack(&tpriv->pt);
 	kfree(tpriv);
 	return ret;
 }
@@ -1032,18 +1082,20 @@ static int __stmmac_test_dvlanfilt(struct stmmac_priv *priv)
 	 * HASH values.
 	 */
 	tpriv->vlan_id = 0x123;
-	dev_add_pack(&tpriv->pt);
 
 	ret = vlan_vid_add(priv->dev, htons(ETH_P_8021AD), tpriv->vlan_id);
 	if (ret)
 		goto cleanup;
 
+	attr.vlan = 2;
+	attr.dst = priv->dev->dev_addr;
+	attr.sport = 9;
+	attr.dport = 9;
+
+	stmmac_sft_add_pack(&tpriv->pt);
+
 	for (i = 0; i < 4; i++) {
-		attr.vlan = 2;
 		attr.vlan_id_out = tpriv->vlan_id + i;
-		attr.dst = priv->dev->dev_addr;
-		attr.sport = 9;
-		attr.dport = 9;
 
 		skb = stmmac_test_get_udp_skb(priv, &attr);
 		if (!skb) {
@@ -1070,9 +1122,9 @@ static int __stmmac_test_dvlanfilt(struct stmmac_priv *priv)
 	}
 
 vlan_del:
+	stmmac_sft_remove_pack(&tpriv->pt);
 	vlan_vid_del(priv->dev, htons(ETH_P_8021AD), tpriv->vlan_id);
 cleanup:
-	dev_remove_pack(&tpriv->pt);
 	kfree(tpriv);
 	return ret;
 }
@@ -1303,7 +1355,6 @@ static int stmmac_test_vlanoff_common(struct stmmac_priv *priv, bool svlan)
 	tpriv->pt.af_packet_priv = tpriv;
 	tpriv->packet = &attr;
 	tpriv->vlan_id = 0x123;
-	dev_add_pack(&tpriv->pt);
 
 	ret = vlan_vid_add(priv->dev, htons(proto), tpriv->vlan_id);
 	if (ret)
@@ -1311,6 +1362,8 @@ static int stmmac_test_vlanoff_common(struct stmmac_priv *priv, bool svlan)
 
 	attr.dst = priv->dev->dev_addr;
 
+	stmmac_sft_add_pack(&tpriv->pt);
+
 	skb = stmmac_test_get_udp_skb(priv, &attr);
 	if (!skb) {
 		ret = -ENOMEM;
@@ -1328,9 +1381,9 @@ static int stmmac_test_vlanoff_common(struct stmmac_priv *priv, bool svlan)
 	ret = tpriv->ok ? 0 : -ETIMEDOUT;
 
 vlan_del:
+	stmmac_sft_remove_pack(&tpriv->pt);
 	vlan_vid_del(priv->dev, htons(proto), tpriv->vlan_id);
 cleanup:
-	dev_remove_pack(&tpriv->pt);
 	kfree(tpriv);
 	return ret;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 397/877] net: stmmac: selftests: Check the dev->features for S-TAG offload testing
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (395 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 396/877] net: stmmac: selftests: Support running selftests on DSA conduits Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 398/877] net: stmmac: selftests: Capture all packets for vlan checks Greg Kroah-Hartman
                   ` (487 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Maxime Chevallier,
	Jakub Kicinski, Sasha Levin

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

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

From: Maxime Chevallier <maxime.chevallier@bootlin.com>

[ Upstream commit ba804b23d76d278ee475b8427fa7c5623ce5e270 ]

The S-TAG offload insertion incorrectly checks the dvlan (double vlan)
DMA cap, which is different than S-TAG support. Use
NETIF_F_HW_VLAN_STAG_TX to check if the feature is supported instead.

Note that this flag isn't set in stmmac yet, but contrary to ARP
offload, this is a feature that has a chance to get there eventually so
let's leave the selftest here for now. It'll report -EOPNOTSUPP in the
meantime.

Fixes: 091810dbded9 ("net: stmmac: Introduce selftests support")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20260917215339.2022523-4-maxime.chevallier@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
index e1a5a0316d8d9..6f2edff624134 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
@@ -1395,7 +1395,7 @@ static int stmmac_test_vlanoff(struct stmmac_priv *priv)
 
 static int stmmac_test_svlanoff(struct stmmac_priv *priv)
 {
-	if (!priv->dma_cap.dvlan)
+	if (!(priv->dev->features & NETIF_F_HW_VLAN_STAG_TX))
 		return -EOPNOTSUPP;
 	return stmmac_test_vlanoff_common(priv, true);
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 398/877] net: stmmac: selftests: Capture all packets for vlan checks
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (396 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 397/877] net: stmmac: selftests: Check the dev->features for S-TAG offload testing Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 399/877] net: stmmac: dwmac4: Use the correct bufzise when the len is exactly 8K Greg Kroah-Hartman
                   ` (486 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Maxime Chevallier,
	Jakub Kicinski, Sasha Levin

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

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

From: Maxime Chevallier <maxime.chevallier@bootlin.com>

[ Upstream commit 960db6f65788c21249ea04a947d5c01e38d19294 ]

While we use vlan_vid_add to trigger the tag filtering machinery
in the driver, there's no netdev associated to the VLAN. This causes the
skb to arrive with empty skb->vlan_tci fields, as the packet is marked
OTHERHOST in __netif_receive_skb_core(), and we fail our validation.

Let's use the proxy mechanism introduced for DSA, that registers a
ETH_P_ALL packet handler that runs earlier, before the vlan netdev
lookup, then filters for the correct ethertype before passing an skb
clone to our validation function.

As we may receive external frames with the right tag from the outside,
let's move the address check in the vlan validation function earlier.

Fixes: 091810dbded9 ("net: stmmac: Introduce selftests support")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20260917215339.2022523-5-maxime.chevallier@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 .../stmicro/stmmac/stmmac_selftests.c         | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
index 6f2edff624134..e39ee3ea0efff 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c
@@ -242,6 +242,7 @@ struct stmmac_test_priv {
 	__be16 packet_type;
 	int (*func)(struct sk_buff *skb, struct net_device *ndev,
 		    struct packet_type *pt, struct net_device *orig_ndev);
+	bool capture_all;
 	int double_vlan;
 	int vlan_id;
 	int ok;
@@ -344,13 +345,15 @@ static void stmmac_sft_add_pack(struct packet_type *pt)
 {
 	struct stmmac_test_priv *tpriv = pt->af_packet_priv;
 
-	if (netdev_uses_dsa(tpriv->pt.dev)) {
+	if (netdev_uses_dsa(tpriv->pt.dev) || tpriv->capture_all) {
 		tpriv->packet_type = tpriv->pt.type;
 		tpriv->func = tpriv->pt.func;
 
 		/* DSA conduit will report ETH_P_XDSA, so our packet handler
 		 * won't match. Let's register a ETH_P_ALL match and filter
-		 * manually in stmmac_sft_filter.
+		 * manually in stmmac_sft_filter. This is also useful for
+		 * VLAN tests, to capture packets otherwise marked as
+		 * OTHERHOST.
 		 */
 		tpriv->pt.type = htons(ETH_P_ALL);
 		tpriv->pt.func = stmmac_sft_filter;
@@ -923,6 +926,11 @@ static int stmmac_test_vlan_validate(struct sk_buff *skb,
 		goto out;
 	if (skb_headlen(skb) < (STMMAC_TEST_PKT_SIZE - ETH_HLEN))
 		goto out;
+
+	ehdr = (struct ethhdr *)skb_mac_header(skb);
+	if (!ether_addr_equal_unaligned(ehdr->h_dest, tpriv->packet->dst))
+		goto out;
+
 	if (tpriv->vlan_id) {
 		if (skb->vlan_proto != htons(proto))
 			goto out;
@@ -934,10 +942,6 @@ static int stmmac_test_vlan_validate(struct sk_buff *skb,
 		}
 	}
 
-	ehdr = (struct ethhdr *)skb_mac_header(skb);
-	if (!ether_addr_equal_unaligned(ehdr->h_dest, tpriv->packet->dst))
-		goto out;
-
 	ihdr = ip_hdr(skb);
 	if (tpriv->double_vlan)
 		ihdr = (struct iphdr *)(skb_network_header(skb) + 4);
@@ -979,6 +983,7 @@ static int __stmmac_test_vlanfilt(struct stmmac_priv *priv)
 	tpriv->pt.dev = priv->dev;
 	tpriv->pt.af_packet_priv = tpriv;
 	tpriv->packet = &attr;
+	tpriv->capture_all = true;
 
 	/*
 	 * As we use HASH filtering, false positives may appear. This is a
@@ -1075,6 +1080,7 @@ static int __stmmac_test_dvlanfilt(struct stmmac_priv *priv)
 	tpriv->pt.dev = priv->dev;
 	tpriv->pt.af_packet_priv = tpriv;
 	tpriv->packet = &attr;
+	tpriv->capture_all = true;
 
 	/*
 	 * As we use HASH filtering, false positives may appear. This is a
@@ -1355,6 +1361,7 @@ static int stmmac_test_vlanoff_common(struct stmmac_priv *priv, bool svlan)
 	tpriv->pt.af_packet_priv = tpriv;
 	tpriv->packet = &attr;
 	tpriv->vlan_id = 0x123;
+	tpriv->capture_all = true;
 
 	ret = vlan_vid_add(priv->dev, htons(proto), tpriv->vlan_id);
 	if (ret)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 399/877] net: stmmac: dwmac4: Use the correct bufzise when the len is exactly 8K
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (397 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 398/877] net: stmmac: selftests: Capture all packets for vlan checks Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices Greg Kroah-Hartman
                   ` (485 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Maxime Chevallier, Nicolai Buchwitz,
	Jakub Kicinski, Sasha Levin

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

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

From: Maxime Chevallier <maxime.chevallier@bootlin.com>

[ Upstream commit b42e7012773a0e81e97a2dda6ef907f5147a6658 ]

DMA bufsize selection isn't made on the MTU but the actual frame length,
so including the L2 header. On DWMAC4, if the len is exactly BUF_SIZE_8KiB,
the next larger size is incorrectly selected.

Lets fix the comparison and while at it, rename the parameter from len
to mtu.

Fixes: c3efed5ad1b0 ("net: stmmac: Enable dwmac4 jumbo frame more than 8KiB").
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Link: https://patch.msgid.link/20260917215339.2022523-6-maxime.chevallier@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 4 ++--
 drivers/net/ethernet/stmicro/stmmac/hwif.h         | 2 +-
 drivers/net/ethernet/stmicro/stmmac/ring_mode.c    | 4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
index e99401bcc1f84..67c886316cbdd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
@@ -490,11 +490,11 @@ static void dwmac4_set_sarc(struct dma_desc *p, u32 sarc_type)
 	p->des3 |= cpu_to_le32(sarc_type & TDES3_SA_INSERT_CTRL_MASK);
 }
 
-static int set_16kib_bfsize(int mtu)
+static int set_16kib_bfsize(int len)
 {
 	int ret = 0;
 
-	if (unlikely(mtu >= BUF_SIZE_8KiB))
+	if (unlikely(len > BUF_SIZE_8KiB))
 		ret = BUF_SIZE_16KiB;
 	return ret;
 }
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index 31d7f9375d747..4376d61db969f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -587,7 +587,7 @@ struct stmmac_mode_ops {
 	unsigned int (*is_jumbo_frm) (int len, int ehn_desc);
 	int (*jumbo_frm)(struct stmmac_tx_queue *tx_q, struct sk_buff *skb,
 			 int csum);
-	int (*set_16kib_bfsize)(int mtu);
+	int (*set_16kib_bfsize)(int len);
 	void (*init_desc3)(struct dma_desc *p);
 	void (*refill_desc3)(struct stmmac_rx_queue *rx_q, struct dma_desc *p);
 	void (*clean_desc3)(struct stmmac_tx_queue *tx_q, struct dma_desc *p);
diff --git a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
index 45c14c1bb0eaa..88a8d22812f5d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
+++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
@@ -128,10 +128,10 @@ static void clean_desc3(struct stmmac_tx_queue *tx_q, struct dma_desc *p)
 		p->des3 = 0;
 }
 
-static int set_16kib_bfsize(int mtu)
+static int set_16kib_bfsize(int len)
 {
 	int ret = 0;
-	if (unlikely(mtu > BUF_SIZE_8KiB))
+	if (unlikely(len > BUF_SIZE_8KiB))
 		ret = BUF_SIZE_16KiB;
 	return ret;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (398 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 399/877] net: stmmac: dwmac4: Use the correct bufzise when the len is exactly 8K Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-10-01 20:09   ` Harshit Mogalapalli
  2026-09-30 15:21 ` [PATCH 6.12 401/877] nfc: nfcmrvl: validate helper command length before pull Greg Kroah-Hartman
                   ` (484 subsequent siblings)
  884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, co+ac0a8c41de69121d, Weiming Shi,
	Alexei Starovoitov, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Weiming Shi <bestswngs@gmail.com>

[ Upstream commit 6db1ce73e9853f533eb7f413f14ba00f8ec6f80d ]

__bpf_offload_dev_match() falls back to comparing offdev pointers after an
exact netdev mismatch. Bound-only programs normally have NULL offdevs, so
unrelated netdevs compare equal. A bound-only program on an
offload-registered netdev can instead inherit a real offdev and match a
sibling port. With CAP_BPF and CAP_NET_ADMIN, a caller can use
bpf(BPF_LINK_CREATE) with a different target ifindex to run metadata kfuncs
specialized for the bound driver on the target driver's xdp_buff. Running a
veth-bound program on tun reads beyond tun's bare stack xdp_buff as a
veth_xdp_buff.

  Oops: general protection fault, probably for non-canonical address
  KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
  RIP: 0010:veth_xdp_rx_timestamp (drivers/net/veth.c:1673)
  Call Trace:
   ...
   tun_build_skb (drivers/net/tun.c:1739)
   tun_get_user (drivers/net/tun.c:1856)
   tun_chr_write_iter (drivers/net/tun.c:2091)
   vfs_write (fs/read_write.c:595 fs/read_write.c:687)
   ksys_write (fs/read_write.c:739)
   do_syscall_64 (arch/x86/entry/syscall_64.c:84)
   entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
  Kernel panic - not syncing: Fatal exception in interrupt

Restrict non-offloaded programs to exact netdev matches and retain the
shared-offdev fallback only for genuinely offloaded multi-port programs.

Fixes: 2b3486bc2d23 ("bpf: Introduce device-bound XDP programs")
Reported-by: <co+ac0a8c41de69121d@bugs.sh>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20260917161335.1020405-2-bestswngs@gmail.com/
Link: https://patch.msgid.link/20260920132303.4109240-3-bestswngs@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 kernel/bpf/offload.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c
index 56115739fcfdd..1b6f9e7175666 100644
--- a/kernel/bpf/offload.c
+++ b/kernel/bpf/offload.c
@@ -703,6 +703,8 @@ static bool __bpf_offload_dev_match(struct bpf_prog *prog,
 		return false;
 	if (offload->netdev == netdev)
 		return true;
+	if (!bpf_prog_is_offloaded(prog->aux))
+		return false;
 
 	ondev1 = bpf_offload_find_netdev(offload->netdev);
 	ondev2 = bpf_offload_find_netdev(netdev);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 401/877] nfc: nfcmrvl: validate helper command length before pull
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (399 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 402/877] nfc: st21nfca: validate received frame size Greg Kroah-Hartman
                   ` (483 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, David Heidelberg,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit 686f942332b1667f13f3b8d6a2f50bcfbf42e277 ]

The firmware download receive path removes the NCI data header and
reads the helper command before validating the remaining packet length.
A short frame can therefore reach the data access before the malformed
packet is rejected.

Validate the complete helper command length before stripping the NCI
data header.

Fixes: 3194c6870158 ("NFC: nfcmrvl: add firmware download support")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260715084325.40276-1-pengpeng@iscas.ac.cn
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/nfc/nfcmrvl/fw_dnld.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/nfc/nfcmrvl/fw_dnld.c b/drivers/nfc/nfcmrvl/fw_dnld.c
index 93094418fd247..9716caddb88e8 100644
--- a/drivers/nfc/nfcmrvl/fw_dnld.c
+++ b/drivers/nfc/nfcmrvl/fw_dnld.c
@@ -262,9 +262,14 @@ static int process_state_fw_dnld(struct nfcmrvl_private *priv,
 		 * B8..N: payload
 		 */
 
-		/* Remove NCI HDR */
-		skb_pull(skb, 3);
-		if (skb->data[0] != HELPER_CMD_PACKET_FORMAT || skb->len != 5) {
+		if (skb->len != NCI_DATA_HDR_SIZE + 5) {
+			nfc_err(priv->dev, "bad command");
+			return -EINVAL;
+		}
+
+		/* Remove NCI header */
+		skb_pull(skb, NCI_DATA_HDR_SIZE);
+		if (skb->data[0] != HELPER_CMD_PACKET_FORMAT) {
 			nfc_err(priv->dev, "bad command");
 			return -EINVAL;
 		}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 402/877] nfc: st21nfca: validate received frame size
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (400 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 401/877] nfc: nfcmrvl: validate helper command length before pull Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 403/877] nfc: llcp: Fix list corruption / refcount desync in nfc_llcp_recv_dm() Greg Kroah-Hartman
                   ` (482 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, David Heidelberg,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit a653c01ce447f10c36b901646888c0330363af4f ]

st21nfca_hci_i2c_repack() trims a received frame at its EOF marker
before removing byte stuffing.  It then assumes the truncated frame
contains the LLC header and two CRC bytes, and it unconditionally reads
the byte after an escape marker.

A malformed frame can place EOF immediately after the start marker or can
end its data portion with an escape marker.  The former leaves too few
bytes for check_crc(), while the latter makes the unstuffing loop read past
the current skb length.

Require the minimum framing bytes both before and after unstuffing.  Use
separate input and output cursors while removing byte stuffing, and reject
an escape marker without its encoded byte.  This keeps malformed frames
within the received frame boundary before CRC processing.

Fixes: 3096e25a3e40 ("NFC: st21nfca: Fix incorrect byte stuffing revocation")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260715084405.41546-1-pengpeng@iscas.ac.cn
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/nfc/st21nfca/i2c.c | 29 +++++++++++++++++++----------
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c
index 02c3d11a19c43..4d95e25d3724f 100644
--- a/drivers/nfc/st21nfca/i2c.c
+++ b/drivers/nfc/st21nfca/i2c.c
@@ -290,27 +290,36 @@ static int check_crc(u8 *buf, int buflen)
  */
 static int st21nfca_hci_i2c_repack(struct sk_buff *skb)
 {
-	int i, j, r, size;
+	int read, write, r, size;
 
-	if (skb->len < 1 || (skb->len > 1 && skb->data[1] != 0))
+	if (skb->len < ST21NFCA_FRAME_HEADROOM ||
+	    !IS_START_OF_FRAME(skb->data))
 		return -EBADMSG;
 
 	size = get_frame_size(skb->data, skb->len);
 	if (size > 0) {
+		if (size < ST21NFCA_FRAME_HEADROOM + 2)
+			return -EBADMSG;
+
 		skb_trim(skb, size);
 		/* remove ST21NFCA byte stuffing for upper layer */
-		for (i = 1, j = 0; i < skb->len; i++) {
-			if (skb->data[i + j] ==
+		for (read = 1, write = 1; read < skb->len;) {
+			if (skb->data[read] ==
 					(u8) ST21NFCA_ESCAPE_BYTE_STUFFING) {
-				skb->data[i] = skb->data[i + j + 1]
-						| ST21NFCA_BYTE_STUFFING_MASK;
-				i++;
-				j++;
+				if (read + 1 == skb->len)
+					return -EBADMSG;
+
+				skb->data[write++] = skb->data[read + 1]
+						     | ST21NFCA_BYTE_STUFFING_MASK;
+				read += 2;
+			} else {
+				skb->data[write++] = skb->data[read++];
 			}
-			skb->data[i] = skb->data[i + j];
 		}
 		/* remove byte stuffing useless byte */
-		skb_trim(skb, i - j);
+		skb_trim(skb, write);
+		if (skb->len < ST21NFCA_FRAME_HEADROOM + 2)
+			return -EBADMSG;
 		/* remove ST21NFCA_SOF_EOF from head */
 		skb_pull(skb, 1);
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 403/877] nfc: llcp: Fix list corruption / refcount desync in nfc_llcp_recv_dm()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (401 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 402/877] nfc: st21nfca: validate received frame size Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 404/877] selftests: nci: Correct pthread_create return value check Greg Kroah-Hartman
                   ` (481 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
	David Heidelberg, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>

[ Upstream commit bf1460acdf8cf5a07c819f59785d40f20d113099 ]

nfc_llcp_recv_dm() handles DM(NOBOUND)/DM(REJ) for a socket that is still
linked on local->connecting_sockets: it looks the socket up with
nfc_llcp_connecting_sock_get(), sets sk->sk_state = LLCP_CLOSED and
returns, without taking the socket lock and without unlinking the socket
from the connecting_sockets list.

llcp_sock_release() selects the list to unlink from by sk_state: a socket
in LLCP_CONNECTING is unlinked from connecting_sockets, otherwise from the
sockets list.  Because recv_dm left the socket physically on
connecting_sockets but in the LLCP_CLOSED state, release() takes the else
branch and calls nfc_llcp_sock_unlink(&local->sockets, sk).  That runs
sk_del_node_init() while holding sockets.lock, i.e. it removes the socket
from the connecting_sockets hlist under the wrong lock.  A concurrent
connect() linking another socket onto connecting_sockets under
connecting_sockets.lock then mutates the same hlist unserialized, which
corrupts the list and desyncs the sk_add_node()/sk_del_node_init()
sock_hold()/__sock_put() pairing.  An unprivileged local process holding
LLCP sockets, with the DM supplied by the remote peer over an established
LLCP link, can drive this to leak kernel sockets without bound (the
mis-decrement goes through the non-freeing __sock_put() path, so the
object is never released), leading to memory exhaustion / DoS.

This is the same class of bug that was fixed in the sibling handler
nfc_llcp_recv_cc() by commit b493ea2765cc ("nfc: llcp: Fix use-after-free
race in nfc_llcp_recv_cc()"); recv_dm did not receive the equivalent fix.

Fix it the same way: take lock_sock(), re-check that the socket is still
hashed (release() may have won the race), and for the NOBOUND/REJ case
unlink it from connecting_sockets before moving it to LLCP_CLOSED.  The
unlink drops the connecting_sockets membership reference via
sk_del_node_init(), leaving the socket unhashed, so the later
nfc_llcp_sock_unlink() in llcp_sock_release() becomes a no-op and no
double put occurs.

Fixes: a69f32af86e3 ("NFC: Socket linked list")
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Link: https://patch.msgid.link/20260716232657.203145-1-qwe.aldo@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/nfc/llcp_core.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
index 7b86faf3f4ce5..9ae9b4fde311e 100644
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -1249,6 +1249,7 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local,
 	struct nfc_llcp_sock *llcp_sock;
 	struct sock *sk;
 	u8 dsap, ssap, reason;
+	bool connecting = false;
 
 	dsap = nfc_llcp_dsap(skb);
 	ssap = nfc_llcp_ssap(skb);
@@ -1260,6 +1261,7 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local,
 	case LLCP_DM_NOBOUND:
 	case LLCP_DM_REJ:
 		llcp_sock = nfc_llcp_connecting_sock_get(local, dsap);
+		connecting = true;
 		break;
 
 	default:
@@ -1274,10 +1276,33 @@ static void nfc_llcp_recv_dm(struct nfc_llcp_local *local,
 
 	sk = &llcp_sock->sk;
 
+	lock_sock(sk);
+
+	/* Check if socket was destroyed whilst waiting for the lock */
+	if (!sk_hashed(sk)) {
+		release_sock(sk);
+		nfc_llcp_sock_put(llcp_sock);
+		return;
+	}
+
+	/*
+	 * For DM(NOBOUND)/DM(REJ) the socket is still linked on the
+	 * connecting_sockets list.  Unlink it here, under the socket lock,
+	 * before moving it to LLCP_CLOSED: llcp_sock_release() selects the
+	 * list to unlink from by sk_state, so leaving a connecting socket
+	 * in the CLOSED state would make it unlink from the wrong list and
+	 * corrupt the connecting_sockets list / desync the socket refcount.
+	 * This mirrors nfc_llcp_recv_cc().
+	 */
+	if (connecting)
+		nfc_llcp_sock_unlink(&local->connecting_sockets, sk);
+
 	sk->sk_err = ENXIO;
 	sk->sk_state = LLCP_CLOSED;
 	sk->sk_state_change(sk);
 
+	release_sock(sk);
+
 	nfc_llcp_sock_put(llcp_sock);
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 404/877] selftests: nci: Correct pthread_create return value check
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (402 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 403/877] nfc: llcp: Fix list corruption / refcount desync in nfc_llcp_recv_dm() Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 405/877] nfc: llcp: Fix race condition in accept_queue lifecycle Greg Kroah-Hartman
                   ` (480 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Lei Zhu, David Heidelberg,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Lei Zhu <zhulei@kylinos.cn>

[ Upstream commit 3d8afc5243ea2ee803d98e69eb4a01748167ac1b ]

The pthread_create() functions returns 0 on success and a positive value on
failure. Modify the return value check to correctly detect failure cases.

Fixes: 72696bd8a09d ("selftests: nci: Extract the start/stop discovery function")
Signed-off-by: Lei Zhu <zhulei@kylinos.cn>
Link: https://patch.msgid.link/20260729072426.303484-1-zhulei_szu@163.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 tools/testing/selftests/nci/nci_dev.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/nci/nci_dev.c b/tools/testing/selftests/nci/nci_dev.c
index 1562aa7d60b0f..2fae9ea352c87 100644
--- a/tools/testing/selftests/nci/nci_dev.c
+++ b/tools/testing/selftests/nci/nci_dev.c
@@ -438,7 +438,7 @@ FIXTURE_SETUP(NCI)
 	else
 		rc = pthread_create(&thread_t, NULL, virtual_dev_open,
 				    (void *)&self->virtual_nci_fd);
-	ASSERT_GT(rc, -1);
+	ASSERT_EQ(rc, 0);
 
 	rc = send_cmd_with_idx(self->sd, self->fid, self->pid,
 			       NFC_CMD_DEV_UP, self->dev_idex);
@@ -509,7 +509,7 @@ FIXTURE_TEARDOWN(NCI)
 			rc = pthread_create(&thread_t, NULL, virtual_deinit,
 					    (void *)&self->virtual_nci_fd);
 
-		ASSERT_GT(rc, -1);
+		ASSERT_EQ(rc, 0);
 		rc = send_cmd_with_idx(self->sd, self->fid, self->pid,
 				       NFC_CMD_DEV_DOWN, self->dev_idex);
 		EXPECT_EQ(rc, 0);
@@ -590,7 +590,7 @@ int start_polling(int dev_idx, int proto, int virtual_fd, int sd, int fid, int p
 
 	rc = pthread_create(&thread_t, NULL, virtual_poll_start,
 			    (void *)&virtual_fd);
-	if (rc < 0)
+	if (rc)
 		return rc;
 
 	rc = send_cmd_mt_nla(sd, fid, pid, NFC_CMD_START_POLL, 2, nla_start_poll_type,
@@ -610,7 +610,7 @@ int stop_polling(int dev_idx, int virtual_fd, int sd, int fid, int pid)
 
 	rc = pthread_create(&thread_t, NULL, virtual_poll_stop,
 			    (void *)&virtual_fd);
-	if (rc < 0)
+	if (rc)
 		return rc;
 
 	rc = send_cmd_with_idx(sd, fid, pid,
@@ -830,6 +830,8 @@ int disconnect_tag(int nfc_sock, int virtual_fd)
 
 	status = pthread_create(&thread_t, NULL, virtual_deactivate_proc,
 				(void *)&virtual_fd);
+	if (status)
+		return status;
 
 	close(nfc_sock);
 	pthread_join(thread_t, (void **)&status);
@@ -874,7 +876,7 @@ TEST_F(NCI, deinit)
 	else
 		rc = pthread_create(&thread_t, NULL, virtual_deinit,
 				    (void *)&self->virtual_nci_fd);
-	ASSERT_GT(rc, -1);
+	ASSERT_EQ(rc, 0);
 
 	rc = send_cmd_with_idx(self->sd, self->fid, self->pid,
 			       NFC_CMD_DEV_DOWN, self->dev_idex);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 405/877] nfc: llcp: Fix race condition in accept_queue lifecycle
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (403 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 404/877] selftests: nci: Correct pthread_create return value check Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 406/877] selftests: nci: Fix uninitialized family ID on missing attribute Greg Kroah-Hartman
                   ` (479 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Lee Jones, David Heidelberg,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Lee Jones <lee@kernel.org>

[ Upstream commit c3eef2f988a3db9690369d7cef9a3344dd9788d3 ]

In nfc_llcp_socket_release(), sockets and listener accept queues are
walked under the local sockets rwlock and bh_lock_sock().  However,
bh_lock_sock() does not synchronise against process-context lock_sock()
held by nfc_llcp_accept_dequeue() during accept().  Because
socket_release() does not check sock_owned_by_user(), both paths can
concurrently unlink and release the same child socket, resulting in
use-after-free or a NULL pointer dereference of child->parent in
nfc_llcp_accept_unlink().

Fix this synchronisation race by having nfc_llcp_socket_release() use
process-context lock_sock() instead of bh_lock_sock():

1. Pop sockets from the local sockets list under the write lock using
   nfc_llcp_sock_list_pop() so lock_sock() can be acquired without
   holding the rwlock.

2. Because lock_sock() can sleep, defer the final release of the
   nfc_llcp_local structure to a workqueue (release_work).  This avoids
   a sleeping-in-atomic bug when the last local reference is dropped
   from softirq context.  Additionally, hold a single device reference
   on local from registration until final destruction.

3. In nfc_llcp_local_get(), use kref_get_unless_zero() to prevent
   resurrecting a local object whose teardown has been scheduled.

4. In llcp_sock_accept(), verify that the listener socket state is still
   LLCP_LISTEN after waking from schedule_timeout() to prevent hangs if
   the listener is closed concurrently.

5. When unlinking unaccepted child sockets during listener release,
   unlink them from local->sockets, call sock_orphan(), and drop their
   initial sk_alloc creation reference via sock_put().

6. Make nfc_llcp_accept_unlink() idempotent by guarding parent access with
   a NULL check.

Fixes: 50b78b2a6500 ("NFC: Fix sleeping in atomic when releasing socket")
Signed-off-by: Lee Jones <lee@kernel.org>
Link: https://patch.msgid.link/20260902123033.1169067-1-lee@kernel.org
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/nfc/llcp.h      |   1 +
 net/nfc/llcp_core.c | 125 +++++++++++++++++++++++++++-----------------
 net/nfc/llcp_sock.c |  49 ++++++++++++-----
 3 files changed, 116 insertions(+), 59 deletions(-)

diff --git a/net/nfc/llcp.h b/net/nfc/llcp.h
index d8345ed57c954..23ae7a0112d37 100644
--- a/net/nfc/llcp.h
+++ b/net/nfc/llcp.h
@@ -91,6 +91,7 @@ struct nfc_llcp_local {
 	struct hlist_head pending_sdreqs;
 	struct timer_list sdreq_timer;
 	struct work_struct sdreq_timeout_work;
+	struct work_struct release_work;
 	u8 sdreq_next_tid;
 
 	/* sockets array */
diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
index 9ae9b4fde311e..a4d7b2eaebd43 100644
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -20,6 +20,8 @@ static LIST_HEAD(llcp_devices);
 /* Protects llcp_devices list */
 static DEFINE_SPINLOCK(llcp_devices_lock);
 
+static struct workqueue_struct *llcp_wq;
+
 static void nfc_llcp_rx_skb(struct nfc_llcp_local *local, struct sk_buff *skb);
 
 void nfc_llcp_sock_link(struct llcp_sock_list *l, struct sock *sk)
@@ -63,21 +65,33 @@ static void nfc_llcp_socket_purge(struct nfc_llcp_sock *sock)
 	}
 }
 
+static struct sock *nfc_llcp_sock_list_pop(struct llcp_sock_list *l)
+{
+	struct sock *sk;
+
+	write_lock(&l->lock);
+	sk = sk_head(&l->head);
+	if (sk) {
+		sock_hold(sk);
+		sk_del_node_init(sk);
+	}
+	write_unlock(&l->lock);
+
+	return sk;
+}
+
 static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device,
 				    int err)
 {
 	struct sock *sk;
-	struct hlist_node *tmp;
 	struct nfc_llcp_sock *llcp_sock;
 
 	skb_queue_purge(&local->tx_queue);
 
-	write_lock(&local->sockets.lock);
-
-	sk_for_each_safe(sk, tmp, &local->sockets.head) {
+	while ((sk = nfc_llcp_sock_list_pop(&local->sockets))) {
 		llcp_sock = nfc_llcp_sock(sk);
 
-		bh_lock_sock(sk);
+		lock_sock(sk);
 
 		nfc_llcp_socket_purge(llcp_sock);
 
@@ -91,17 +105,27 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device,
 			list_for_each_entry_safe(lsk, n,
 						 &llcp_sock->accept_queue,
 						 accept_queue) {
-				accept_sk = &lsk->sk;
-				bh_lock_sock(accept_sk);
-
-				nfc_llcp_accept_unlink(accept_sk);
+				bool put_creation = false;
 
-				if (err)
-					accept_sk->sk_err = err;
-				accept_sk->sk_state = LLCP_CLOSED;
-				accept_sk->sk_state_change(sk);
+				accept_sk = &lsk->sk;
+				lock_sock_nested(accept_sk,
+						 SINGLE_DEPTH_NESTING);
+
+				if (nfc_llcp_sock(accept_sk)->parent == sk) {
+					nfc_llcp_accept_unlink(accept_sk);
+					nfc_llcp_sock_unlink(&local->sockets, accept_sk);
+
+					if (err)
+						accept_sk->sk_err = err;
+					accept_sk->sk_state = LLCP_CLOSED;
+					accept_sk->sk_state_change(accept_sk);
+					sock_orphan(accept_sk);
+					put_creation = true;
+				}
 
-				bh_unlock_sock(accept_sk);
+				release_sock(accept_sk);
+				if (put_creation)
+					sock_put(accept_sk); /* creation ref */
 			}
 		}
 
@@ -110,23 +134,18 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device,
 		sk->sk_state = LLCP_CLOSED;
 		sk->sk_state_change(sk);
 
-		bh_unlock_sock(sk);
-
-		sk_del_node_init(sk);
+		release_sock(sk);
+		sock_put(sk);
 	}
 
-	write_unlock(&local->sockets.lock);
-
 	/* If we still have a device, we keep the RAW sockets alive */
 	if (device == true)
 		return;
 
-	write_lock(&local->raw_sockets.lock);
-
-	sk_for_each_safe(sk, tmp, &local->raw_sockets.head) {
+	while ((sk = nfc_llcp_sock_list_pop(&local->raw_sockets))) {
 		llcp_sock = nfc_llcp_sock(sk);
 
-		bh_lock_sock(sk);
+		lock_sock(sk);
 
 		nfc_llcp_socket_purge(llcp_sock);
 
@@ -135,26 +154,20 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool device,
 		sk->sk_state = LLCP_CLOSED;
 		sk->sk_state_change(sk);
 
-		bh_unlock_sock(sk);
-
-		sk_del_node_init(sk);
+		release_sock(sk);
+		sock_put(sk);
 	}
-
-	write_unlock(&local->raw_sockets.lock);
 }
 
 static struct nfc_llcp_local *nfc_llcp_local_get(struct nfc_llcp_local *local)
 {
-	/* Since using nfc_llcp_local may result in usage of nfc_dev, whenever
-	 * we hold a reference to local, we also need to hold a reference to
-	 * the device to avoid UAF.
-	 */
-	if (!nfc_get_device(local->dev->idx))
+	if (!local)
 		return NULL;
 
-	kref_get(&local->ref);
+	if (kref_get_unless_zero(&local->ref))
+		return local;
 
-	return local;
+	return NULL;
 }
 
 static void local_cleanup(struct nfc_llcp_local *local)
@@ -172,30 +185,34 @@ static void local_cleanup(struct nfc_llcp_local *local)
 	nfc_llcp_free_sdp_tlv_list(&local->pending_sdreqs);
 }
 
-static void local_release(struct kref *ref)
+static void local_release_work(struct work_struct *work)
 {
 	struct nfc_llcp_local *local;
+	struct nfc_dev *dev;
 
-	local = container_of(ref, struct nfc_llcp_local, ref);
+	local = container_of(work, struct nfc_llcp_local, release_work);
+	dev = local->dev;
 
 	local_cleanup(local);
 	kfree(local);
+	nfc_put_device(dev);
 }
 
-int nfc_llcp_local_put(struct nfc_llcp_local *local)
+static void local_release(struct kref *ref)
 {
-	struct nfc_dev *dev;
-	int ret;
+	struct nfc_llcp_local *local;
 
-	if (local == NULL)
-		return 0;
+	local = container_of(ref, struct nfc_llcp_local, ref);
 
-	dev = local->dev;
+	queue_work(llcp_wq, &local->release_work);
+}
 
-	ret = kref_put(&local->ref, local_release);
-	nfc_put_device(dev);
+int nfc_llcp_local_put(struct nfc_llcp_local *local)
+{
+	if (!local)
+		return 0;
 
-	return ret;
+	return kref_put(&local->ref, local_release);
 }
 
 static struct nfc_llcp_sock *nfc_llcp_sock_get(struct nfc_llcp_local *local,
@@ -1703,6 +1720,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev)
 	INIT_WORK(&local->rx_work, nfc_llcp_rx_work);
 
 	INIT_WORK(&local->timeout_work, nfc_llcp_timeout_work);
+	INIT_WORK(&local->release_work, local_release_work);
 
 	rwlock_init(&local->sockets.lock);
 	rwlock_init(&local->connecting_sockets.lock);
@@ -1746,10 +1764,23 @@ void nfc_llcp_unregister_device(struct nfc_dev *dev)
 
 int __init nfc_llcp_init(void)
 {
-	return nfc_llcp_sock_init();
+	int ret;
+
+	llcp_wq = alloc_workqueue("nfc_llcp_wq", WQ_UNBOUND, 0);
+	if (!llcp_wq)
+		return -ENOMEM;
+
+	ret = nfc_llcp_sock_init();
+	if (ret) {
+		destroy_workqueue(llcp_wq);
+		return ret;
+	}
+
+	return 0;
 }
 
 void nfc_llcp_exit(void)
 {
 	nfc_llcp_sock_exit();
+	destroy_workqueue(llcp_wq);
 }
diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
index 507447bbceea4..f9d35711eb9a7 100644
--- a/net/nfc/llcp_sock.c
+++ b/net/nfc/llcp_sock.c
@@ -392,11 +392,12 @@ void nfc_llcp_accept_unlink(struct sock *sk)
 
 	pr_debug("state %d\n", sk->sk_state);
 
-	list_del_init(&llcp_sock->accept_queue);
-	sk_acceptq_removed(llcp_sock->parent);
-	llcp_sock->parent = NULL;
-
-	sock_put(sk);
+	if (llcp_sock->parent) {
+		list_del_init(&llcp_sock->accept_queue);
+		sk_acceptq_removed(llcp_sock->parent);
+		llcp_sock->parent = NULL;
+		sock_put(sk);
+	}
 }
 
 void nfc_llcp_accept_enqueue(struct sock *parent, struct sock *sk)
@@ -423,12 +424,20 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent,
 
 	list_for_each_entry_safe(lsk, n, &llcp_parent->accept_queue,
 				 accept_queue) {
+		struct nfc_llcp_local *local;
+
 		sk = &lsk->sk;
-		lock_sock(sk);
+		lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
 
 		if (sk->sk_state == LLCP_CLOSED) {
-			release_sock(sk);
+			local = nfc_llcp_sock(sk)->local;
+
 			nfc_llcp_accept_unlink(sk);
+			if (local)
+				nfc_llcp_sock_unlink(&local->sockets, sk);
+			sock_orphan(sk);
+			release_sock(sk);
+			sock_put(sk);
 			continue;
 		}
 
@@ -464,7 +473,7 @@ static int llcp_sock_accept(struct socket *sock, struct socket *newsock,
 
 	pr_debug("parent %p\n", sk);
 
-	lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
+	lock_sock(sk);
 
 	if (sk->sk_state != LLCP_LISTEN) {
 		ret = -EBADFD;
@@ -490,7 +499,12 @@ static int llcp_sock_accept(struct socket *sock, struct socket *newsock,
 
 		release_sock(sk);
 		timeo = schedule_timeout(timeo);
-		lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
+		lock_sock(sk);
+
+		if (sk->sk_state != LLCP_LISTEN) {
+			ret = -EBADFD;
+			break;
+		}
 	}
 	__set_current_state(TASK_RUNNING);
 	remove_wait_queue(sk_sleep(sk), &wait);
@@ -629,13 +643,24 @@ static int llcp_sock_release(struct socket *sock)
 
 		list_for_each_entry_safe(lsk, n, &llcp_sock->accept_queue,
 					 accept_queue) {
+			bool put_creation = false;
+
 			accept_sk = &lsk->sk;
-			lock_sock(accept_sk);
+			lock_sock_nested(accept_sk, SINGLE_DEPTH_NESTING);
 
-			nfc_llcp_send_disconnect(lsk);
-			nfc_llcp_accept_unlink(accept_sk);
+			if (nfc_llcp_sock(accept_sk)->parent == sk) {
+				nfc_llcp_send_disconnect(lsk);
+				nfc_llcp_accept_unlink(accept_sk);
+				nfc_llcp_sock_unlink(&local->sockets, accept_sk);
+
+				accept_sk->sk_state = LLCP_CLOSED;
+				sock_orphan(accept_sk);
+				put_creation = true;
+			}
 
 			release_sock(accept_sk);
+			if (put_creation)
+				sock_put(accept_sk); /* creation ref */
 		}
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 406/877] selftests: nci: Fix uninitialized family ID on missing attribute
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (404 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 405/877] nfc: llcp: Fix race condition in accept_queue lifecycle Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 407/877] selftests/nci: Fix out-of-bounds store on thread join Greg Kroah-Hartman
                   ` (478 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Chaithanya Lagisetty, Hangbin Liu,
	David Heidelberg, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Chaithanya Lagisetty <nagachaithanya9911@gmail.com>

[ Upstream commit eda518d2cdb6074a0bcdfa06af291616bcb5c421 ]

get_family_id() walks the generic netlink CTRL_CMD_GETFAMILY reply
looking for the CTRL_ATTR_FAMILY_ID attribute and returns the parsed
value in the local variable "id". If the reply does not carry that
attribute, the parsing loop never assigns "id" and the function returns
an indeterminate stack value, which the caller stores in self->fid and
uses for subsequent netlink requests.

Initialize "id" to 0 so a missing attribute yields a deterministic
(invalid) family ID instead of a garbage value.

Fixes: f595cf1242f3 ("selftests: Add nci suite")
Signed-off-by: Chaithanya Lagisetty <nagachaithanya9911@gmail.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260901070618.3299012-1-nagachaithanya9911@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 tools/testing/selftests/nci/nci_dev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/nci/nci_dev.c b/tools/testing/selftests/nci/nci_dev.c
index 2fae9ea352c87..2a96ca0a9fb1b 100644
--- a/tools/testing/selftests/nci/nci_dev.c
+++ b/tools/testing/selftests/nci/nci_dev.c
@@ -182,7 +182,7 @@ static int get_family_id(int sd, __u32 pid, __u32 *event_group)
 	} ans;
 	struct nlattr *na;
 	int resp_len;
-	__u16 id;
+	__u16 id = 0;
 	int len;
 	int rc;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 407/877] selftests/nci: Fix out-of-bounds store on thread join
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (405 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 406/877] selftests: nci: Fix uninitialized family ID on missing attribute Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:21 ` [PATCH 6.12 408/877] nfc: virtual_ncidev: Add missing ioctl compat handler Greg Kroah-Hartman
                   ` (477 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Chris Gellermann, Simon Horman,
	David Heidelberg, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Chris Gellermann <christian.gellermann@codasip.com>

[ Upstream commit 6be581aeffc215bfc77939cd59902b0dbc4af23e ]

The NCI test collects the exit status of its helper threads by passing
the address of an int to pthread_join():

	int status;
	...
	pthread_join(thread_t, (void **) &status);

pthread_join() stores a void pointer to the memory location. On 64-bit
systems, a void pointer is wider than an int, so the store overruns the
4 bytes of space allocated on the stack for the integer and corrupts the
adjacent stack. On our CHERI system, this caused a fault due to a
capability bounds violation.

Fix this by introducing a helper that joins a thread through a void
pointer and converts the result back to an integer, which is what the
helper threads return.

While here, also fix the logic in disconnect_tag() if the helper thread
creation failed. Previously, it would have joined a thread that was
never created when pthread_create() failed.

Fixes: f595cf1242f3 ("selftests: Add nci suite")
Signed-off-by: Chris Gellermann <christian.gellermann@codasip.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260904095915.3372241-1-christian.gellermann@codasip.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 tools/testing/selftests/nci/nci_dev.c | 31 +++++++++++++++++----------
 1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/tools/testing/selftests/nci/nci_dev.c b/tools/testing/selftests/nci/nci_dev.c
index 2a96ca0a9fb1b..ab34e08c64d60 100644
--- a/tools/testing/selftests/nci/nci_dev.c
+++ b/tools/testing/selftests/nci/nci_dev.c
@@ -8,6 +8,7 @@
 
 #include <stdlib.h>
 #include <errno.h>
+#include <stdint.h>
 #include <string.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
@@ -87,6 +88,16 @@ struct msgtemplate {
 	char buf[MAX_MSG_SIZE];
 };
 
+static int join_thread_status(pthread_t thread)
+{
+	void *thread_ret = NULL;
+
+	if (pthread_join(thread, &thread_ret))
+		return -1;
+
+	return (int)(intptr_t)thread_ret;
+}
+
 static int create_nl_socket(void)
 {
 	int fd;
@@ -444,7 +455,7 @@ FIXTURE_SETUP(NCI)
 			       NFC_CMD_DEV_UP, self->dev_idex);
 	EXPECT_EQ(rc, 0);
 
-	pthread_join(thread_t, (void **)&status);
+	status = join_thread_status(thread_t);
 	ASSERT_EQ(status, 0);
 	self->open_state = true;
 }
@@ -514,7 +525,7 @@ FIXTURE_TEARDOWN(NCI)
 				       NFC_CMD_DEV_DOWN, self->dev_idex);
 		EXPECT_EQ(rc, 0);
 
-		pthread_join(thread_t, (void **)&status);
+		status = join_thread_status(thread_t);
 		ASSERT_EQ(status, 0);
 	}
 
@@ -585,7 +596,6 @@ int start_polling(int dev_idx, int proto, int virtual_fd, int sd, int fid, int p
 	void *nla_start_poll_data[2] = {&dev_idx, &proto};
 	int nla_start_poll_len[2] = {4, 4};
 	pthread_t thread_t;
-	int status;
 	int rc;
 
 	rc = pthread_create(&thread_t, NULL, virtual_poll_start,
@@ -598,14 +608,12 @@ int start_polling(int dev_idx, int proto, int virtual_fd, int sd, int fid, int p
 	if (rc != 0)
 		return rc;
 
-	pthread_join(thread_t, (void **)&status);
-	return status;
+	return join_thread_status(thread_t);
 }
 
 int stop_polling(int dev_idx, int virtual_fd, int sd, int fid, int pid)
 {
 	pthread_t thread_t;
-	int status;
 	int rc;
 
 	rc = pthread_create(&thread_t, NULL, virtual_poll_stop,
@@ -618,8 +626,7 @@ int stop_polling(int dev_idx, int virtual_fd, int sd, int fid, int pid)
 	if (rc != 0)
 		return rc;
 
-	pthread_join(thread_t, (void **)&status);
-	return status;
+	return join_thread_status(thread_t);
 }
 
 TEST_F(NCI, start_poll)
@@ -834,8 +841,10 @@ int disconnect_tag(int nfc_sock, int virtual_fd)
 		return status;
 
 	close(nfc_sock);
-	pthread_join(thread_t, (void **)&status);
-	return status;
+	if (status)
+		return -1;
+
+	return join_thread_status(thread_t);
 }
 
 TEST_F(NCI, t4t_tag_read)
@@ -882,7 +891,7 @@ TEST_F(NCI, deinit)
 			       NFC_CMD_DEV_DOWN, self->dev_idex);
 	EXPECT_EQ(rc, 0);
 
-	pthread_join(thread_t, (void **)&status);
+	status = join_thread_status(thread_t);
 	self->open_state = 0;
 	ASSERT_EQ(status, 0);
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 408/877] nfc: virtual_ncidev: Add missing ioctl compat handler
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (406 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 407/877] selftests/nci: Fix out-of-bounds store on thread join Greg Kroah-Hartman
@ 2026-09-30 15:21 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 409/877] nfc: llcp: fix sdreq TLV list leak on parse/alloc/send failure Greg Kroah-Hartman
                   ` (476 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:21 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Chris Gellermann, Simon Horman,
	David Heidelberg, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Chris Gellermann <christian.gellermann@codasip.com>

[ Upstream commit 51814683e28fc64eceb415962376956c3cfc75a7 ]

The compat handler for ioctls to the virtual nci device is missing. So,
nci-specific ioctls of a compat task return with -1 and errno set to
ENOTTY. Add a handler.

The handling of an ioctl() call of a compat task to get the index of
virtual nci device (IOCTL_GET_NCIDEV_IDX) lands in the default case of
the ioctl compat handler (see fs/ioctl.c):

COMPAT_SYSCALL_DEFINE3(ioctl, ...)
{
	...
	default:
       		error = do_vfs_ioctl(fd_file(f), fd, cmd, ...);
		if (error != -ENOIOCTLCMD)
			break;

		if (fd_file(f)->f_op->compat_ioctl)
			error = fd_file(f)->f_op->compat_ioctl(fd_file(f), cmd, arg);
		if (error == -ENOIOCTLCMD)
			error = -ENOTTY;
	...
}

There, do_vfs_ioctl() returns -ENOIOCTLCMD and compat_ioctl is not
set for virtual_ncidev_fops, i.e. f_op->compat_ioctl == NULL. So, the
ioctl() syscall returns with -1 and errno set to ENOTTY to the compat
task.

To fix this, use the compat_ptr_ioctl helper for compat handling here.
It shall be used for ioctls that "either ignore the argument or pass a
pointer to a compatible data type". The driver's sole ioctl takes a user
void pointer and copies nfc_dev->idx to it, a 4-byte integer across all
ABIs.

This issue has been found by running the nci_dev kernel selftest as
rv64 binary on top of a CHERI kernel, where the ioctl() ends up in
the ioctl compat handler, similar to a 32-bit application on top of a
64-bit kernel.

Fixes: e624e6c3e777 ("nfc: Add a virtual nci device driver")
Signed-off-by: Chris Gellermann <christian.gellermann@codasip.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260904164252.18351-1-christian.gellermann@codasip.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/nfc/virtual_ncidev.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/nfc/virtual_ncidev.c b/drivers/nfc/virtual_ncidev.c
index 590b038e449e5..db15d26692666 100644
--- a/drivers/nfc/virtual_ncidev.c
+++ b/drivers/nfc/virtual_ncidev.c
@@ -195,7 +195,8 @@ static const struct file_operations virtual_ncidev_fops = {
 	.write = virtual_ncidev_write,
 	.open = virtual_ncidev_open,
 	.release = virtual_ncidev_close,
-	.unlocked_ioctl = virtual_ncidev_ioctl
+	.unlocked_ioctl = virtual_ncidev_ioctl,
+	.compat_ioctl = compat_ptr_ioctl,
 };
 
 static struct miscdevice miscdev = {
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 409/877] nfc: llcp: fix sdreq TLV list leak on parse/alloc/send failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (407 preceding siblings ...)
  2026-09-30 15:21 ` [PATCH 6.12 408/877] nfc: virtual_ncidev: Add missing ioctl compat handler Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 410/877] nfc: st21nfca: validate ISO15693 inventory length Greg Kroah-Hartman
                   ` (475 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Cong Nguyen, Simon Horman,
	David Heidelberg, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Cong Nguyen <congnt264@gmail.com>

[ Upstream commit 66f4300206b82b0b143ef0d9be90cd8d29f23a47 ]

nfc_genl_llc_sdreq() builds a list of TLV nodes while walking nested
netlink attrs, but 3 error paths (nested-attr parse failure, TLV alloc
ENOMEM, nfc_llcp_send_snl_sdreq() failure) all skip freeing what was
already queued.

Route them through a new free_list label, mirroring the SDRES path in
the same file which already does this. Harmless on the success path
too -- send_snl_sdreq() drains the list as it moves nodes, so it's
already empty by the time free_list runs.

Fixes: d9b8d8e19b07 ("NFC: llcp: Service Name Lookup netlink interface")
Assisted-by: Claude:claude-opus-4
Signed-off-by: Cong Nguyen <congnt264@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260914121129.2098606-1-congnt264@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/nfc/netlink.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index dd2ce73a24fbe..ce18dda58a832 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -1176,7 +1176,7 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
 
 		if (rc != 0) {
 			rc = -EINVAL;
-			goto put_local;
+			goto free_list;
 		}
 
 		if (!sdp_attrs[NFC_SDP_ATTR_URI])
@@ -1195,7 +1195,7 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
 		sdreq = nfc_llcp_build_sdreq_tlv(tid, uri, uri_len);
 		if (sdreq == NULL) {
 			rc = -ENOMEM;
-			goto put_local;
+			goto free_list;
 		}
 
 		tlvs_len += sdreq->tlv_len;
@@ -1210,6 +1210,9 @@ static int nfc_genl_llc_sdreq(struct sk_buff *skb, struct genl_info *info)
 
 	rc = nfc_llcp_send_snl_sdreq(local, &sdreq_list, tlvs_len);
 
+free_list:
+	nfc_llcp_free_sdp_tlv_list(&sdreq_list);
+
 put_local:
 	nfc_llcp_local_put(local);
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 410/877] nfc: st21nfca: validate ISO15693 inventory length
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (408 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 409/877] nfc: llcp: fix sdreq TLV list leak on parse/alloc/send failure Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 411/877] nfc: llcp: fix -ENOMEM on connect with zero-length service name Greg Kroah-Hartman
                   ` (474 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, David Heidelberg,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pengpeng Hou <pengpeng@iscas.ac.cn>

[ Upstream commit 7f2ea5ed588c03d481f0301e6c3d4240132383fb ]

The ISO15693 inventory helper removes a two-byte prefix without checking
that it exists, then accepts a one-byte remainder before reading data[1] as
the DSFID.

Require the prefix and at least two remaining bytes before copying the UID
data and reading the DSFID.

Fixes: 7974728094d3 ("NFC: st21nfca: Add ISO15693 Reader/Writer support")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260830132958.6397-1-pengpeng@iscas.ac.cn
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/nfc/st21nfca/core.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/nfc/st21nfca/core.c b/drivers/nfc/st21nfca/core.c
index 161caf2675cfc..7eb5e5f0686be 100644
--- a/drivers/nfc/st21nfca/core.c
+++ b/drivers/nfc/st21nfca/core.c
@@ -577,9 +577,7 @@ static int st21nfca_get_iso15693_inventory(struct nfc_hci_dev *hdev,
 	if (r < 0)
 		goto exit;
 
-	skb_pull(inventory_skb, 2);
-
-	if (inventory_skb->len == 0 ||
+	if (!skb_pull(inventory_skb, 2) || inventory_skb->len < 2 ||
 	    inventory_skb->len > NFC_ISO15693_UID_MAXSIZE) {
 		r = -EPROTO;
 		goto exit;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 411/877] nfc: llcp: fix -ENOMEM on connect with zero-length service name
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (409 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 410/877] nfc: st21nfca: validate ISO15693 inventory length Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 412/877] nfc: llcp: fix WKS SAP hijacking via prefix match in nfc_llcp_wks_sap() Greg Kroah-Hartman
                   ` (473 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ömer Mete Kaya,
	David Heidelberg, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ömer Mete Kaya <omermetekaya0@gmail.com>

[ Upstream commit c04981e42d94f39c1dba965cc462a046e946a6c5 ]

When service_name_len is 0, kmemdup() returns ZERO_SIZE_PTR which
passes the NULL check, causing nfc_llcp_send_connect() to attempt
building a zero-length service name TLV and fail with -ENOMEM.

Fix by setting service_name to NULL directly when service_name_len is 0.

Fixes: d646960f7986 ("NFC: Initial LLCP support")
Signed-off-by: Ömer Mete Kaya <omermetekaya0@gmail.com>
Link: https://patch.msgid.link/20260909122029.34081-1-omermetekaya0@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/nfc/llcp_sock.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
index f9d35711eb9a7..0601ddb4304aa 100644
--- a/net/nfc/llcp_sock.c
+++ b/net/nfc/llcp_sock.c
@@ -759,12 +759,16 @@ static int llcp_sock_connect(struct socket *sock, struct sockaddr *_addr,
 	llcp_sock->service_name_len = min_t(unsigned int,
 					    addr->service_name_len,
 					    NFC_LLCP_MAX_SERVICE_NAME);
-	llcp_sock->service_name = kmemdup(addr->service_name,
-					  llcp_sock->service_name_len,
-					  GFP_KERNEL);
-	if (!llcp_sock->service_name) {
-		ret = -ENOMEM;
-		goto sock_llcp_release;
+	if (llcp_sock->service_name_len == 0) {
+		llcp_sock->service_name = NULL;
+	} else {
+		llcp_sock->service_name = kmemdup(addr->service_name,
+						  llcp_sock->service_name_len,
+						  GFP_KERNEL);
+		if (!llcp_sock->service_name) {
+			ret = -ENOMEM;
+			goto sock_llcp_release;
+		}
 	}
 
 	nfc_llcp_sock_link(&local->connecting_sockets, sk);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 412/877] nfc: llcp: fix WKS SAP hijacking via prefix match in nfc_llcp_wks_sap()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (410 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 411/877] nfc: llcp: fix -ENOMEM on connect with zero-length service name Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 413/877] nfc: llcp: fix slab-out-of-bounds reads when logging service names Greg Kroah-Hartman
                   ` (472 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ömer Mete Kaya,
	David Heidelberg, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ömer Mete Kaya <omermetekaya0@gmail.com>

[ Upstream commit 408cff6bd60636df201274d320edfdfde9ed41db ]

nfc_llcp_wks_sap() compares only service_name_len bytes, so a short
service_name like "u" matches longer WKS strings like "urn:nfc:sn:snep".
Fix by requiring exact length match before strncmp().

Fixes: d646960f7986 ("NFC: Initial LLCP support")
Signed-off-by: Ömer Mete Kaya <omermetekaya0@gmail.com>
Link: https://patch.msgid.link/20260909121437.33744-1-omermetekaya0@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/nfc/llcp_core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
index a4d7b2eaebd43..0b1a2755f58ac 100644
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -367,7 +367,8 @@ static int nfc_llcp_wks_sap(const char *service_name, size_t service_name_len)
 		if (wks[sap] == NULL)
 			continue;
 
-		if (strncmp(wks[sap], service_name, service_name_len) == 0)
+		if (strlen(wks[sap]) == service_name_len &&
+		    !strncmp(wks[sap], service_name, service_name_len))
 			return sap;
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 413/877] nfc: llcp: fix slab-out-of-bounds reads when logging service names
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (411 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 412/877] nfc: llcp: fix WKS SAP hijacking via prefix match in nfc_llcp_wks_sap() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 414/877] nfc: pn533: fix OOB read in pn533_acr122_is_rx_frame_valid() Greg Kroah-Hartman
                   ` (471 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+1e3df0852e82c21ca418,
	Ömer Mete Kaya, David Heidelberg, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ömer Mete Kaya <omermetekaya0@gmail.com>

[ Upstream commit 7dcf371a35632f035baf77bcf2c129165f772ce4 ]

nfc_llcp_wks_sap() and nfc_llcp_build_sdreq_tlv() pass non-null-
terminated strings to pr_debug() using the %s format specifier.
The buffers are allocated via kmemdup() or come from netlink
attributes and are not guaranteed to be null-terminated, causing
__dynamic_pr_debug() to read beyond the allocated region:

  KASAN: slab-out-of-bounds Read in __dynamic_pr_debug

Fix both call sites by using %.*s with the explicit length to limit
the output to the actual length of the string.

Fixes: d9b8d8e19b07 ("NFC: llcp: Service Name Lookup netlink interface")
Reported-by: syzbot+1e3df0852e82c21ca418@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1e3df0852e82c21ca418
Signed-off-by: Ömer Mete Kaya <omermetekaya0@gmail.com>
Link: https://patch.msgid.link/20260908161952.731468-1-omermetekaya0@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/nfc/llcp_commands.c | 2 +-
 net/nfc/llcp_core.c     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
index a93bf0b43d504..2d9e0925b1cc7 100644
--- a/net/nfc/llcp_commands.c
+++ b/net/nfc/llcp_commands.c
@@ -135,7 +135,7 @@ struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, const char *uri,
 {
 	struct nfc_llcp_sdp_tlv *sdreq;
 
-	pr_debug("uri: %s, len: %zu\n", uri, uri_len);
+	pr_debug("uri: %.*s, len: %zu\n", (int)uri_len, uri, uri_len);
 
 	/* sdreq->tlv_len is u8, takes uri_len, + 3 for header, + 1 for NULL */
 	if (WARN_ON_ONCE(uri_len > U8_MAX - 4))
diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c
index 0b1a2755f58ac..49f7793ab0312 100644
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -356,7 +356,7 @@ static int nfc_llcp_wks_sap(const char *service_name, size_t service_name_len)
 {
 	int sap, num_wks;
 
-	pr_debug("%s\n", service_name);
+	pr_debug("%.*s\n", (int)service_name_len, service_name);
 
 	if (service_name == NULL)
 		return -EINVAL;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 414/877] nfc: pn533: fix OOB read in pn533_acr122_is_rx_frame_valid()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (412 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 413/877] nfc: llcp: fix slab-out-of-bounds reads when logging service names Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 415/877] net/sched: act_gate: budget the per-entry list in get_fill_size Greg Kroah-Hartman
                   ` (470 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+1853daab1a47603d4678,
	Deepanshu Kartikey, David Heidelberg, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Deepanshu Kartikey <kartikey406@gmail.com>

[ Upstream commit b61732f47316d45f27706db7812950145d3327b5 ]

frame->ccid.datalen is read directly from the USB response frame
and used, unchecked, as an index into frame->data[]. A malicious or
malfunctioning device can set this field to an arbitrary value,
causing the driver to read far outside the received buffer.

Bound ccid.datalen against the maximum possible ACR122 frame size
before using it. This replaces the existing datalen == 0 check,
since datalen < 2 already covers that case and additionally
rejects datalen == 1, which would still underflow the
"datalen - 2" offset used below.

Fixes: 9815c7cf22da ("NFC: pn533: Separate physical layer from the core implementation")
Reported-by: syzbot+1853daab1a47603d4678@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1853daab1a47603d4678
Tested-by: syzbot+1853daab1a47603d4678@syzkaller.appspotmail.com
Assisted-by: LLM
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
Link: https://patch.msgid.link/20260923035627.6210-1-kartikey406@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/nfc/pn533/usb.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c
index 0f12f86ebb023..35f3350cad324 100644
--- a/drivers/nfc/pn533/usb.c
+++ b/drivers/nfc/pn533/usb.c
@@ -319,7 +319,9 @@ static bool pn533_acr122_is_rx_frame_valid(void *_frame, struct pn533 *dev)
 	if (frame->ccid.type != 0x83)
 		return false;
 
-	if (!frame->ccid.datalen)
+	if (frame->ccid.datalen < 2 ||
+	    frame->ccid.datalen > PN533_ACR122_FRAME_MAX_PAYLOAD_LEN +
+	    PN533_ACR122_RX_FRAME_TAIL_LEN)
 		return false;
 
 	if (frame->data[frame->ccid.datalen - 2] == 0x63)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 415/877] net/sched: act_gate: budget the per-entry list in get_fill_size
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (413 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 414/877] nfc: pn533: fix OOB read in pn533_acr122_is_rx_frame_valid() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 416/877] veth: manage XDP program pointers during channel resize Greg Kroah-Hartman
                   ` (469 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, hybris, Jamal Hadi Salim,
	Victor Nogueira, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Victor Nogueira <victor@mojatatu.com>

[ Upstream commit cfa165cbfbed9d0f4bbc22fef4309f595a3ab187 ]

tcf_gate_get_fill_size returns only the TCA_GATE_PARMS size, but
tcf_gate_dump also emits three 64-bit timestamps, the clock id, flags,
priority and the variable-length TCA_GATE_ENTRY_LIST nest. The per-entry
nest is unbounded: parse_gate_list places no cap on the number of
sched-entries, so a gate with many entries can push the real dump well
past the skb that tca_get_fill allocates from this size.

RTM_NEWACTION then fails the add-notify with -EINVAL while the action is
already committed to the IDR, and a subsequent RTM_GETACTION on the
installed gate also returns -EINVAL because its dump no longer fits.

Fix this by accounting for the missing fields in tcf_gate_get_fill_size
along with all elements in the entries list.

Note that sizing the reply from the action lets an oversized gate
install cleanly for the first time: with the input unbounded by
parse_gate_list, the sized skb can now grow well above
NLMSG_GOODSIZE per netlink request (a transient GFP_KERNEL allocation
reachable only with namespace-local CAP_NET_ADMIN). Overload from a
malicious netns admin is hardening material, not net, per the
discussion at
https://lore.kernel.org/netdev/20260914191108.55a1a4f1@kernel.org/;
a follow-up patch for net-next will cap the sched-entry count.

Fixes: 4e76e75d6aba ("net sched actions: calculate add/delete event message size")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260824153903.4143642-1-victor@mojatatu.com
Tested-by: hybris <hybris@mojatatu.ai>
Co-developed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Link: https://patch.msgid.link/QDISC-3BLH.v1.20260914203033@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/sched/act_gate.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/net/sched/act_gate.c b/net/sched/act_gate.c
index 58cae012a4391..d66c07aef95a2 100644
--- a/net/sched/act_gate.c
+++ b/net/sched/act_gate.c
@@ -686,7 +686,35 @@ static void tcf_gate_stats_update(struct tc_action *a, u64 bytes, u64 packets,
 
 static size_t tcf_gate_get_fill_size(const struct tc_action *act)
 {
-	return nla_total_size(sizeof(struct tc_gate));
+	struct tcf_gate *gact = to_gate(act);
+	const struct tcf_gate_params *p;
+	struct tcfg_gate_entry *entry;
+	size_t size = nla_total_size(sizeof(struct tc_gate)) /* TCA_GATE_PARMS */
+		+ 3 * nla_total_size_64bit(sizeof(u64)) /* TCA_GATE_BASE_TIME
+							 * TCA_GATE_CYCLE_TIME
+							 * TCA_GATE_CYCLE_TIME_EXT
+							 */
+		+ nla_total_size(sizeof(s32)) /* TCA_GATE_CLOCKID */
+		+ nla_total_size(sizeof(u32)) /* TCA_GATE_FLAGS */
+		+ nla_total_size(sizeof(s32)) /* TCA_GATE_PRIORITY */
+		+ nla_total_size(0); /* TCA_GATE_ENTRY_LIST */
+	/* TCA_GATE_TM is budgeted by tcf_action_shared_attrs_size() */
+
+	rcu_read_lock();
+	p = rcu_dereference(gact->param);
+	if (p) {
+		list_for_each_entry_rcu(entry, &p->entries, list)
+			/* TCA_GATE_ONE_ENTRY nest and its attributes */
+			size += nla_total_size(0)
+				+ nla_total_size(sizeof(u32)) /* TCA_GATE_ENTRY_INDEX */
+				+ nla_total_size(0) /* TCA_GATE_ENTRY_GATE */
+				+ nla_total_size(sizeof(u32)) /* TCA_GATE_ENTRY_INTERVAL */
+				+ nla_total_size(sizeof(s32)) /* TCA_GATE_ENTRY_MAX_OCTETS */
+				+ nla_total_size(sizeof(s32)); /* TCA_GATE_ENTRY_IPV */
+	}
+	rcu_read_unlock();
+
+	return size;
 }
 
 static void tcf_gate_entry_destructor(void *priv)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 416/877] veth: manage XDP program pointers during channel resize
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (414 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 415/877] net/sched: act_gate: budget the per-entry list in get_fill_size Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 417/877] net: skbuff: fix pull-bound underflow in skb_checksum_setup_ipv6() Greg Kroah-Hartman
                   ` (468 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Weiming Shi, Stanislav Fomichev,
	Jiayuan Chen, Jason Xing, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jakub Kicinski <kuba@kernel.org>

[ Upstream commit 7104a370714346b667712913dc16abf14bbc97ed ]

veth_set_channels() tears down XDP resources for removed RX queues
without clearing rq->xdp_prog.  If the program is then detached or
replaced, those queues keep the old pointer after bpf_prog_put().
A later channel increase can re-enable NAPI and run the freed program.

  BUG: unable to handle page fault for address: ffffc90000256048
  Oops: Oops: 0000 [#1] SMP KASAN NOPTI
  RIP: veth_xdp_rcv_skb (include/linux/filter.h:779
                         include/net/xdp.h:696 drivers/net/veth.c:820)
  Call Trace:
   veth_xdp_rcv (drivers/net/veth.c:941)
   veth_poll (drivers/net/veth.c:986)
   __napi_poll (net/core/dev.c:7787)
   net_rx_action (net/core/dev.c:7850 net/core/dev.c:8007)
   handle_softirqs (kernel/softirq.c:645)
  Kernel panic - not syncing: Fatal exception in interrupt

Fixes: 4752eeb3d891 ("veth: implement support for set_channel ethtool op")
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
Link: https://patch.msgid.link/20260921231856.1798630-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/veth.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 03341951a2126..f3e5f8ce9ac20 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -1053,6 +1053,7 @@ static int __veth_napi_enable_range(struct net_device *dev, int start, int end)
 	for (i = start; i < end; i++) {
 		struct veth_rq *rq = &priv->rq[i];
 
+		rcu_assign_pointer(rq->xdp_prog, priv->_xdp_prog);
 		napi_enable(&rq->xdp_napi);
 		rcu_assign_pointer(priv->rq[i].napi, &priv->rq[i].xdp_napi);
 	}
@@ -1087,6 +1088,7 @@ static void veth_napi_del_range(struct net_device *dev, int start, int end)
 
 		rcu_assign_pointer(priv->rq[i].napi, NULL);
 		napi_disable(&rq->xdp_napi);
+		rcu_assign_pointer(rq->xdp_prog, NULL);
 		__netif_napi_del(&rq->xdp_napi);
 	}
 	synchronize_net();
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 417/877] net: skbuff: fix pull-bound underflow in skb_checksum_setup_ipv6()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (415 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 416/877] veth: manage XDP program pointers during channel resize Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 418/877] vrf: Stop corrupting skb->csum when capturing CHECKSUM_COMPLETE packets Greg Kroah-Hartman
                   ` (467 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Shihuang Liu,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Shihuang Liu <shlomojune6@gmail.com>

[ Upstream commit 3b4e0b0c008a8c1b474730248cd5b873026c74bd ]

skb_maybe_pull_tail() subtracts skb_headlen(skb) from the unsigned max
argument and passes the result to __pskb_pull_tail() as a signed int.  The
function does not ensure that max is at least skb_headlen(skb).

This can happen while parsing IPv6 extension headers when an skb already
has a linear area larger than MAX_IPV6_HDR_LEN.  Once the parser needs data
beyond the linear area, max - skb_headlen(skb) wraps and is converted to a
negative delta.  __pskb_pull_tail() then passes that negative length to
skb_copy_bits(), where it can become a very large copy length.

Pass the requested length itself as the pull bound at the three
extension-header call sites, so the delta can no longer go negative.

Fixes: 1431fb31ecba ("xen-netback: fix fragment detection in checksum setup")
Suggested-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Shihuang Liu <shlomojune6@gmail.com>
Link: https://patch.msgid.link/20260919133604.50948-1-shlomojune6@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/skbuff.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 1e4f7b8e952cc..623d9d10a208f 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -5841,7 +5841,8 @@ static int skb_checksum_setup_ipv6(struct sk_buff *skb, bool recalculate)
 			err = skb_maybe_pull_tail(skb,
 						  off +
 						  sizeof(struct ipv6_opt_hdr),
-						  MAX_IPV6_HDR_LEN);
+						  off +
+						  sizeof(struct ipv6_opt_hdr));
 			if (err < 0)
 				goto out;
 
@@ -5856,7 +5857,8 @@ static int skb_checksum_setup_ipv6(struct sk_buff *skb, bool recalculate)
 			err = skb_maybe_pull_tail(skb,
 						  off +
 						  sizeof(struct ip_auth_hdr),
-						  MAX_IPV6_HDR_LEN);
+						  off +
+						  sizeof(struct ip_auth_hdr));
 			if (err < 0)
 				goto out;
 
@@ -5871,7 +5873,8 @@ static int skb_checksum_setup_ipv6(struct sk_buff *skb, bool recalculate)
 			err = skb_maybe_pull_tail(skb,
 						  off +
 						  sizeof(struct frag_hdr),
-						  MAX_IPV6_HDR_LEN);
+						  off +
+						  sizeof(struct frag_hdr));
 			if (err < 0)
 				goto out;
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 418/877] vrf: Stop corrupting skb->csum when capturing CHECKSUM_COMPLETE packets
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (416 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 417/877] net: skbuff: fix pull-bound underflow in skb_checksum_setup_ipv6() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 419/877] bpf: Fix immediate JMP JEQ/JNE on MIPS32 Greg Kroah-Hartman
                   ` (466 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Stefano Sasso, Ido Schimmel,
	David Ahern, Eric Dumazet, Andrea Mayer, Jakub Kicinski,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ido Schimmel <idosch@nvidia.com>

[ Upstream commit ab7aa05c06ae340e5c7530bb78fa8d23794e460b ]

The VRF device is an Ethernet device but it can have non-Ethernet ports
such as IP tunnels. Before the cited commit, capturing packets from such
ports on the VRF device resulted in these packets being detected as
malformed since they lack an Ethernet header.

The cited commit fixed it by pushing a dummy Ethernet header to such
packets before the capture and pulling it afterwards. In the case of
CHECKSUM_COMPLETE packets it also updated skb->csum with the checksum of
the dummy Ethernet header. This is wrong as skb->csum should not include
the checksum of the Ethernet header ("checksum of the _whole_ packet as
seen by netif_rx()").

This also means that L4 protocols receive a corrupted skb->csum and
potentially drop the packet, as is the case with UDP packets whose
checksum was completed by software.

Fix by removing the unnecessary call to skb_postpush_rcsum().

Fixes: 048939088220 ("vrf: add mac header for tunneled packets when sniffer is attached")
Reported-by: Stefano Sasso <stesasso@gmail.com>
Closes: https://lore.kernel.org/netdev/CALtE316UtL3x7LL6uxfXzx8rW6AbzYPeDOb478hqJCr_-dj=Wg@mail.gmail.com/
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Andrea Mayer <andrea.mayer@uniroma2.it>
Link: https://patch.msgid.link/20260922131239.2509494-1-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/vrf.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index e684d59291efc..c071b3ccd8cb9 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -1224,8 +1224,6 @@ static int vrf_prepare_mac_header(struct sk_buff *skb,
 	skb->protocol = eth->h_proto;
 	skb->pkt_type = PACKET_HOST;
 
-	skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
-
 	skb_pull_inline(skb, ETH_HLEN);
 
 	return 0;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 419/877] bpf: Fix immediate JMP JEQ/JNE on MIPS32
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (417 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 418/877] vrf: Stop corrupting skb->csum when capturing CHECKSUM_COMPLETE packets Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 420/877] bpf: Fix BSWAP 32 and 16 on MIPS64 Greg Kroah-Hartman
                   ` (465 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Johan Almbladh, Alexei Starovoitov,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Johan Almbladh <johan.almbladh@anyfinetworks.com>

[ Upstream commit db762fd96be225bd06161c9631160c755d891693 ]

An addu instruction was emitted instead of addiu, causing the immediate
value 1 to be interpreted as register $at. This made the comparison
result invalid when the immediate operand was negative. Note that $at
is mapped to BPF_REG_AX, which is used for constant blinding.

Fix the instruction to use the immediate form.

Found with test_bpf on MIPS32r1 emulated by QEMU.

Fixes: eb63cfcd2ee8 ("mips, bpf: Add eBPF JIT for 32-bit MIPS")
Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20260923105158.3514342-1-johan.almbladh@anyfinetworks.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/mips/net/bpf_jit_comp32.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/net/bpf_jit_comp32.c b/arch/mips/net/bpf_jit_comp32.c
index 40a878b672f5d..15a2a153dc873 100644
--- a/arch/mips/net/bpf_jit_comp32.c
+++ b/arch/mips/net/bpf_jit_comp32.c
@@ -1111,7 +1111,7 @@ static void emit_jmp_i64(struct jit_context *ctx,
 			emit(ctx, xor, tmp, lo(dst), tmp);
 		}
 		if (imm < 0) { /* Compare sign extension */
-			emit(ctx, addu, MIPS_R_T9, hi(dst), 1);
+			emit(ctx, addiu, MIPS_R_T9, hi(dst), 1);
 			emit(ctx, or, tmp, tmp, MIPS_R_T9);
 		} else {       /* Compare zero extension */
 			emit(ctx, or, tmp, tmp, hi(dst));
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 420/877] bpf: Fix BSWAP 32 and 16 on MIPS64
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (418 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 419/877] bpf: Fix immediate JMP JEQ/JNE on MIPS32 Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 421/877] driver core: Add device probe log helper dev_warn_probe() Greg Kroah-Hartman
                   ` (464 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Johan Almbladh, Alexei Starovoitov,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Johan Almbladh <johan.almbladh@anyfinetworks.com>

[ Upstream commit 8110ba09777873443db286b3cbb89b0e6311c554 ]

The 16/32-bit byteswap implementations for MIPS64r1 and earlier do
not have an explicit zero extension afterwards. The input is first
sign-extended to 64 bits, and the byteswap sequence can then leave
the result sign-extended depending on the value of the low bits.

Add the missing zero-extension.

Found with test_bpf on MIPS64r1 emulated by QEMU.

Fixes: fbc802de6b10 ("mips, bpf: Add new eBPF JIT for 64-bit MIPS")
Signed-off-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20260923105158.3514342-2-johan.almbladh@anyfinetworks.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/mips/net/bpf_jit_comp64.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/mips/net/bpf_jit_comp64.c b/arch/mips/net/bpf_jit_comp64.c
index fa7e9aa37f498..6681ccac9dd9e 100644
--- a/arch/mips/net/bpf_jit_comp64.c
+++ b/arch/mips/net/bpf_jit_comp64.c
@@ -305,8 +305,7 @@ static void emit_bswap_r64(struct jit_context *ctx, u8 dst, u32 width)
 	case 16:
 		emit_sext(ctx, dst, dst);
 		emit_bswap_r(ctx, dst, width);
-		if (cpu_has_mips64r2 || cpu_has_mips64r6)
-			emit_zext(ctx, dst);
+		emit_zext(ctx, dst);
 		break;
 	}
 	clobber_reg(ctx, dst);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 421/877] driver core: Add device probe log helper dev_warn_probe()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (419 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 420/877] bpf: Fix BSWAP 32 and 16 on MIPS64 Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 422/877] tg3: use random MAC address when tg3_get_device_address fails Greg Kroah-Hartman
                   ` (463 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Dragan Simic,
	Hélène Vulquin, Mark Brown, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dragan Simic <dsimic@manjaro.org>

[ Upstream commit 36e69b160705b65bf136c2fb6a1194447eeb8478 ]

Some drivers can still provide their functionality to a certain extent
even when some of their resource acquisitions eventually fail.  In such
cases, emitting errors isn't the desired action, but warnings should be
emitted instead.

To solve this, introduce dev_warn_probe() as a new device probe log helper,
which behaves identically as the already existing dev_err_probe(), while it
produces warnings instead of errors.  The intended use is with the resources
that are actually optional for a particular driver.

While there, copyedit the kerneldoc for dev_err_probe() a bit, to simplify
its wording a bit, and reuse it as the kerneldoc for dev_warn_probe(), with
the necessary wording adjustments, of course.

Signed-off-by: Dragan Simic <dsimic@manjaro.org>
Tested-by: Hélène Vulquin <oss@helene.moe>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Link: https://patch.msgid.link/2be0a28538bb2a3d1bcc91e2ca1f2d0dc09146d9.1727601608.git.dsimic@manjaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 4eb3f195ef08 ("tg3: use random MAC address when tg3_get_device_address fails")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/base/core.c        | 129 +++++++++++++++++++++++++++++--------
 include/linux/dev_printk.h |   1 +
 2 files changed, 102 insertions(+), 28 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index 2e1cce6265e05..a6134a5e5e110 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -5112,6 +5112,49 @@ define_dev_printk_level(_dev_info, KERN_INFO);
 
 #endif
 
+static void __dev_probe_failed(const struct device *dev, int err, bool fatal,
+			       const char *fmt, va_list vargsp)
+{
+	struct va_format vaf;
+	va_list vargs;
+
+	/*
+	 * On x86_64 and possibly on other architectures, va_list is actually a
+	 * size-1 array containing a structure.  As a result, function parameter
+	 * vargsp decays from T[1] to T*, and &vargsp has type T** rather than
+	 * T(*)[1], which is expected by its assignment to vaf.va below.
+	 *
+	 * One standard way to solve this mess is by creating a copy in a local
+	 * variable of type va_list and then using a pointer to that local copy
+	 * instead, which is the approach employed here.
+	 */
+	va_copy(vargs, vargsp);
+
+	vaf.fmt = fmt;
+	vaf.va = &vargs;
+
+	switch (err) {
+	case -EPROBE_DEFER:
+		device_set_deferred_probe_reason(dev, &vaf);
+		dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
+		break;
+
+	case -ENOMEM:
+		/* Don't print anything on -ENOMEM, there's already enough output */
+		break;
+
+	default:
+		/* Log fatal final failures as errors, otherwise produce warnings */
+		if (fatal)
+			dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
+		else
+			dev_warn(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
+		break;
+	}
+
+	va_end(vargs);
+}
+
 /**
  * dev_err_probe - probe error check and log helper
  * @dev: the pointer to the struct device
@@ -5124,7 +5167,7 @@ define_dev_printk_level(_dev_info, KERN_INFO);
  * -EPROBE_DEFER and propagate error upwards.
  * In case of -EPROBE_DEFER it sets also defer probe reason, which can be
  * checked later by reading devices_deferred debugfs attribute.
- * It replaces code sequence::
+ * It replaces the following code sequence::
  *
  * 	if (err != -EPROBE_DEFER)
  * 		dev_err(dev, ...);
@@ -5136,47 +5179,77 @@ define_dev_printk_level(_dev_info, KERN_INFO);
  *
  * 	return dev_err_probe(dev, err, ...);
  *
- * Using this helper in your probe function is totally fine even if @err is
- * known to never be -EPROBE_DEFER.
+ * Using this helper in your probe function is totally fine even if @err
+ * is known to never be -EPROBE_DEFER.
  * The benefit compared to a normal dev_err() is the standardized format
- * of the error code, it being emitted symbolically (i.e. you get "EAGAIN"
- * instead of "-35") and the fact that the error code is returned which allows
- * more compact error paths.
+ * of the error code, which is emitted symbolically (i.e. you get "EAGAIN"
+ * instead of "-35"), and having the error code returned allows more
+ * compact error paths.
  *
  * Returns @err.
  */
 int dev_err_probe(const struct device *dev, int err, const char *fmt, ...)
 {
-	struct va_format vaf;
-	va_list args;
+	va_list vargs;
 
-	va_start(args, fmt);
-	vaf.fmt = fmt;
-	vaf.va = &args;
+	va_start(vargs, fmt);
 
-	switch (err) {
-	case -EPROBE_DEFER:
-		device_set_deferred_probe_reason(dev, &vaf);
-		dev_dbg(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
-		break;
+	/* Use dev_err() for logging when err doesn't equal -EPROBE_DEFER */
+	__dev_probe_failed(dev, err, true, fmt, vargs);
 
-	case -ENOMEM:
-		/*
-		 * We don't print anything on -ENOMEM, there is already enough
-		 * output.
-		 */
-		break;
+	va_end(vargs);
 
-	default:
-		dev_err(dev, "error %pe: %pV", ERR_PTR(err), &vaf);
-		break;
-	}
+	return err;
+}
+EXPORT_SYMBOL_GPL(dev_err_probe);
 
-	va_end(args);
+/**
+ * dev_warn_probe - probe error check and log helper
+ * @dev: the pointer to the struct device
+ * @err: error value to test
+ * @fmt: printf-style format string
+ * @...: arguments as specified in the format string
+ *
+ * This helper implements common pattern present in probe functions for error
+ * checking: print debug or warning message depending if the error value is
+ * -EPROBE_DEFER and propagate error upwards.
+ * In case of -EPROBE_DEFER it sets also defer probe reason, which can be
+ * checked later by reading devices_deferred debugfs attribute.
+ * It replaces the following code sequence::
+ *
+ * 	if (err != -EPROBE_DEFER)
+ * 		dev_warn(dev, ...);
+ * 	else
+ * 		dev_dbg(dev, ...);
+ * 	return err;
+ *
+ * with::
+ *
+ * 	return dev_warn_probe(dev, err, ...);
+ *
+ * Using this helper in your probe function is totally fine even if @err
+ * is known to never be -EPROBE_DEFER.
+ * The benefit compared to a normal dev_warn() is the standardized format
+ * of the error code, which is emitted symbolically (i.e. you get "EAGAIN"
+ * instead of "-35"), and having the error code returned allows more
+ * compact error paths.
+ *
+ * Returns @err.
+ */
+int dev_warn_probe(const struct device *dev, int err, const char *fmt, ...)
+{
+	va_list vargs;
+
+	va_start(vargs, fmt);
+
+	/* Use dev_warn() for logging when err doesn't equal -EPROBE_DEFER */
+	__dev_probe_failed(dev, err, false, fmt, vargs);
+
+	va_end(vargs);
 
 	return err;
 }
-EXPORT_SYMBOL_GPL(dev_err_probe);
+EXPORT_SYMBOL_GPL(dev_warn_probe);
 
 static inline bool fwnode_is_primary(struct fwnode_handle *fwnode)
 {
diff --git a/include/linux/dev_printk.h b/include/linux/dev_printk.h
index ca32b5bb28eb5..eb2094e43050c 100644
--- a/include/linux/dev_printk.h
+++ b/include/linux/dev_printk.h
@@ -276,6 +276,7 @@ do {									\
 			dev_driver_string(dev), dev_name(dev), ## arg)
 
 __printf(3, 4) int dev_err_probe(const struct device *dev, int err, const char *fmt, ...);
+__printf(3, 4) int dev_warn_probe(const struct device *dev, int err, const char *fmt, ...);
 
 /* Simple helper for dev_err_probe() when ERR_PTR() is to be returned. */
 #define dev_err_ptr_probe(dev, ___err, fmt, ...) \
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 422/877] tg3: use random MAC address when tg3_get_device_address fails
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (420 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 421/877] driver core: Add device probe log helper dev_warn_probe() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 423/877] net: bcmgenet: fix 64-bit RTNL stats reading in ethtool on 32-bit systems Greg Kroah-Hartman
                   ` (462 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jakub Kicinski, Ivan Delalande,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ivan Delalande <colona@arista.com>

[ Upstream commit 4eb3f195ef08c5acaed87958297e41cc49588dde ]

Some of the tg3 NICs we use (BCM57762) reset the SRAM MAC address to the
placeholder address on link flaps, tg3_chip_reset, etc. We've typically
fixed it from userspace, but since e4c00ba7274b ("tg3: replace
placeholder MAC address with device property") was merged, tg3 just
fails probe as we don't have a way to get it through the generic
device_get_mac_address infrastructure as fallback on our systems.

Make the driver assign a random address in this condition instead of
being fatal for probe. Set deferred_probe_reason through dev_warn_probe
if the address isn't yet available from the provider.

Fixes: e4c00ba7274b ("tg3: replace placeholder MAC address with device property")
Suggested-by: Jakub Kicinski <kuba@kernel.org>
Link: https://lore.kernel.org/netdev/20260909191751.651aa5c4@kernel.org/
Signed-off-by: Ivan Delalande <colona@arista.com>
Link: https://patch.msgid.link/20260918224715.GA654128@visor
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/broadcom/tg3.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 1df77bf9428b1..7f143e388d420 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -17899,11 +17899,14 @@ static int tg3_init_one(struct pci_dev *pdev,
 
 	err = tg3_get_device_address(tp, addr);
 	if (err) {
-		dev_err(&pdev->dev,
-			"Could not obtain valid ethernet address, aborting\n");
-		goto err_out_apeunmap;
+		dev_warn_probe(&pdev->dev, err,
+			       "Could not obtain a valid ethernet address\n");
+		if (err == -EPROBE_DEFER)
+			goto err_out_apeunmap;
+		eth_hw_addr_random(dev);
+	} else {
+		eth_hw_addr_set(dev, addr);
 	}
-	eth_hw_addr_set(dev, addr);
 
 	intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW;
 	rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 423/877] net: bcmgenet: fix 64-bit RTNL stats reading in ethtool on 32-bit systems
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (421 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 422/877] tg3: use random MAC address when tg3_get_device_address fails Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 424/877] net: bcmgenet: initialize u64 stats seq counter for all queues Greg Kroah-Hartman
                   ` (461 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Florian Fainelli,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Florian Fainelli <florian.fainelli@broadcom.com>

[ Upstream commit 0e2bec77ea62895416600c90588f593516572bca ]

When bcmgenet was converted to 64-bit statistics, STAT_RTNL members were
switched to point into struct rtnl_link_stats64, whose fields are 64-bit
(__u64) regardless of architecture.

However, bcmgenet_get_ethtool_stats() retained a legacy check:
  if (sizeof(unsigned long) != sizeof(u32) &&
      s->stat_sizeof == sizeof(unsigned long))

On 32-bit systems, sizeof(unsigned long) == sizeof(u32), causing this
condition to evaluate to false. As a result, 64-bit RTNL stats fields were
read via *(u32 *)p. On 32-bit Big-Endian systems (such as MIPS BE), this
reads the high 32 bits and returns 0 until the counter exceeds 4GB; on
32-bit Little-Endian systems (such as 32-bit ARM), the value is truncated
to 32 bits.

Fix this by checking if s->stat_sizeof == sizeof(u64) so 64-bit fields are
always read as 64-bit values.

Fixes: 59aa6e3072aa ("net: bcmgenet: switch to use 64bit statistics")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260921220021.281418-2-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index eb6ef5ad8c2e1..ba33161db296f 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1289,9 +1289,8 @@ static void bcmgenet_get_ethtool_stats(struct net_device *dev,
 				p = (char *)&stats64;
 
 			p += s->stat_offset;
-			if (sizeof(unsigned long) != sizeof(u32) &&
-				s->stat_sizeof == sizeof(unsigned long))
-				data[i] = *(unsigned long *)p;
+			if (s->stat_sizeof == sizeof(u64))
+				data[i] = *(u64 *)p;
 			else
 				data[i] = *(u32 *)p;
 		}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 424/877] net: bcmgenet: initialize u64 stats seq counter for all queues
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (422 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 423/877] net: bcmgenet: fix 64-bit RTNL stats reading in ethtool on 32-bit systems Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 425/877] net: bcmgenet: move bcmgenet_power_up into resume_noirq Greg Kroah-Hartman
                   ` (460 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Florian Fainelli,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Florian Fainelli <florian.fainelli@broadcom.com>

[ Upstream commit 3aeaa609fda19c09d5298c9fedaaa3b6229601b5 ]

bcmgenet_gstrings_stats statically defines ethtool statistics for queues
0 through GENET_MAX_MQ_CNT (4). However, bcmgenet_probe() only initialized
the u64_stats_sync seq counter up to priv->hw_params->rx_queues and
priv->hw_params->tx_queues.

Since priv->hw_params->rx_queues is 0 across all hardware versions (and
priv->hw_params->tx_queues is 0 on GENET V1), rings 1..4 have uninitialized
u64_stats_sync structures. When ethtool -S is run on 32-bit kernels,
bcmgenet_get_ethtool_stats() reads stats from rx_rings[1..4], causing
lockdep warnings due to the uninitialized sequence counters.

Initialize the sequence counters for all GENET_MAX_MQ_CNT + 1 queues.

Fixes: ffc2c8c4a714 ("net: bcmgenet: Initialize u64 stats seq counter")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260921220021.281418-3-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index ba33161db296f..aa565011fb808 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -4069,10 +4069,10 @@ static int bcmgenet_probe(struct platform_device *pdev)
 		priv->rx_rings[i].rx_max_coalesced_frames = 1;
 
 	/* Initialize u64 stats seq counter for 32bit machines */
-	for (i = 0; i <= priv->hw_params->rx_queues; i++)
+	for (i = 0; i <= GENET_MAX_MQ_CNT; i++) {
 		u64_stats_init(&priv->rx_rings[i].stats64.syncp);
-	for (i = 0; i <= priv->hw_params->tx_queues; i++)
 		u64_stats_init(&priv->tx_rings[i].stats64.syncp);
+	}
 
 	/* libphy will determine the link state */
 	netif_carrier_off(dev);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 425/877] net: bcmgenet: move bcmgenet_power_up into resume_noirq
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (423 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 424/877] net: bcmgenet: initialize u64 stats seq counter for all queues Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 426/877] net: bcmgenet: allow return of power up status Greg Kroah-Hartman
                   ` (459 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Doug Berger, Florian Fainelli,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Doug Berger <opendmb@gmail.com>

[ Upstream commit ffce2bedd361177718dc0c3787f4adb4785a0151 ]

The bcmgenet_power_up() function is moved from the resume method
to the resume_noirq method for symmetry with the suspend_noirq
method. This allows the wol_active flag to be removed.

The UMAC_IRQ_WAKE_EVENT interrupts that can be unmasked by the
bcmgenet_wol_power_down_cfg() function are now re-masked by the
bcmgenet_wol_power_up_cfg() function at the resume_noirq level
as well.

Signed-off-by: Doug Berger <opendmb@gmail.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20250306192643.2383632-13-opendmb@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: cbbc1aee7776 ("net: bcmgenet: do not skip WoL power up on GENET V1")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 .../net/ethernet/broadcom/genet/bcmgenet.c    | 24 +++++++++----------
 .../net/ethernet/broadcom/genet/bcmgenet.h    |  1 -
 .../ethernet/broadcom/genet/bcmgenet_wol.c    |  8 +++----
 3 files changed, 15 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index aa565011fb808..af7657de90591 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -4136,8 +4136,20 @@ static int bcmgenet_resume_noirq(struct device *d)
 		reg = bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_STAT);
 		if (reg & UMAC_IRQ_WAKE_EVENT)
 			pm_wakeup_event(&priv->pdev->dev, 0);
+
+		/* From WOL-enabled suspend, switch to regular clock */
+		bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC);
 	}
 
+	/* If this is an internal GPHY, power it back on now, before UniMAC is
+	 * brought out of reset as absolutely no UniMAC activity is allowed
+	 */
+	if (priv->internal_phy)
+		bcmgenet_power_up(priv, GENET_POWER_PASSIVE);
+
+	/* take MAC out of reset */
+	bcmgenet_umac_reset(priv);
+
 	bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_WAKE_EVENT, INTRL2_CPU_CLEAR);
 
 	return 0;
@@ -4154,18 +4166,6 @@ static int bcmgenet_resume(struct device *d)
 	if (!netif_running(dev))
 		return 0;
 
-	/* From WOL-enabled suspend, switch to regular clock */
-	if (device_may_wakeup(d) && priv->wolopts)
-		bcmgenet_power_up(priv, GENET_POWER_WOL_MAGIC);
-
-	/* If this is an internal GPHY, power it back on now, before UniMAC is
-	 * brought out of reset as absolutely no UniMAC activity is allowed
-	 */
-	if (priv->internal_phy)
-		bcmgenet_power_up(priv, GENET_POWER_PASSIVE);
-
-	bcmgenet_umac_reset(priv);
-
 	init_umac(priv);
 
 	phy_init_hw(dev->phydev);
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index 89b071da31142..3e0878a03b43d 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -658,7 +658,6 @@ struct bcmgenet_priv {
 	struct clk *clk_wol;
 	u32 wolopts;
 	u8 sopass[SOPASS_MAX];
-	bool wol_active;
 
 	struct bcmgenet_mib_counters mib;
 };
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
index 98358b71cef5c..d67f1cb14a800 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
@@ -199,7 +199,6 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
 		  retries);
 
 	clk_prepare_enable(priv->clk_wol);
-	priv->wol_active = 1;
 
 	if (hfb_enable) {
 		bcmgenet_hfb_reg_writel(priv, hfb_enable,
@@ -238,13 +237,12 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
 		return;
 	}
 
-	if (!priv->wol_active)
-		return;	/* failed to suspend so skip the rest */
-
-	priv->wol_active = 0;
 	clk_disable_unprepare(priv->clk_wol);
 	priv->crc_fwd_en = 0;
 
+	bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_WAKE_EVENT,
+				 INTRL2_CPU_MASK_SET);
+
 	/* Disable Magic Packet Detection */
 	if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
 		reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 426/877] net: bcmgenet: allow return of power up status
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (424 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 425/877] net: bcmgenet: move bcmgenet_power_up into resume_noirq Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 427/877] net: bcmgenet: do not skip WoL power up on GENET V1 Greg Kroah-Hartman
                   ` (458 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Doug Berger, Florian Fainelli,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Doug Berger <opendmb@gmail.com>

[ Upstream commit 2432b9817b7cb91aaae9e5032da0bb017cb3102d ]

It is possible for a WoL power up to fail due to the GENET being
reset while in the suspend state. Allow these failures to be
returned as error codes to allow different recovery behavior
when necessary.

Signed-off-by: Doug Berger <opendmb@gmail.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20250306192643.2383632-14-opendmb@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: cbbc1aee7776 ("net: bcmgenet: do not skip WoL power up on GENET V1")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c     | 13 ++++++++-----
 drivers/net/ethernet/broadcom/genet/bcmgenet.h     |  4 ++--
 drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c | 12 +++++++-----
 3 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index af7657de90591..fc1d4cef3ad81 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1693,13 +1693,14 @@ static int bcmgenet_power_down(struct bcmgenet_priv *priv,
 	return ret;
 }
 
-static void bcmgenet_power_up(struct bcmgenet_priv *priv,
-			      enum bcmgenet_power_mode mode)
+static int bcmgenet_power_up(struct bcmgenet_priv *priv,
+			     enum bcmgenet_power_mode mode)
 {
+	int ret = 0;
 	u32 reg;
 
 	if (!bcmgenet_has_ext(priv))
-		return;
+		return ret;
 
 	reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
 
@@ -1735,11 +1736,13 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv,
 		}
 		break;
 	case GENET_POWER_WOL_MAGIC:
-		bcmgenet_wol_power_up_cfg(priv, mode);
-		return;
+		ret = bcmgenet_wol_power_up_cfg(priv, mode);
+		break;
 	default:
 		break;
 	}
+
+	return ret;
 }
 
 static struct enet_cb *bcmgenet_get_txcb(struct bcmgenet_priv *priv,
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index 3e0878a03b43d..532a4ea04c6e6 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -739,8 +739,8 @@ void bcmgenet_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
 int bcmgenet_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
 int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
 				enum bcmgenet_power_mode mode);
-void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
-			       enum bcmgenet_power_mode mode);
+int bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
+			      enum bcmgenet_power_mode mode);
 
 void bcmgenet_eee_enable_set(struct net_device *dev, bool enable);
 
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
index d67f1cb14a800..945b32fe5697d 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
@@ -227,14 +227,14 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
 	return 0;
 }
 
-void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
-			       enum bcmgenet_power_mode mode)
+int bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
+			      enum bcmgenet_power_mode mode)
 {
 	u32 reg;
 
 	if (mode != GENET_POWER_WOL_MAGIC) {
 		netif_err(priv, wol, priv->dev, "invalid mode: %d\n", mode);
-		return;
+		return -EINVAL;
 	}
 
 	clk_disable_unprepare(priv->clk_wol);
@@ -247,7 +247,7 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
 	if (priv->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
 		reg = bcmgenet_umac_readl(priv, UMAC_MPD_CTRL);
 		if (!(reg & MPD_EN))
-			return;	/* already reset so skip the rest */
+			return -EPERM;	/* already reset so skip the rest */
 		reg &= ~(MPD_EN | MPD_PW_EN);
 		bcmgenet_umac_writel(priv, reg, UMAC_MPD_CTRL);
 	}
@@ -256,7 +256,7 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
 	if (priv->wolopts & WAKE_FILTER) {
 		reg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL);
 		if (!(reg & RBUF_ACPI_EN))
-			return;	/* already reset so skip the rest */
+			return -EPERM;	/* already reset so skip the rest */
 		reg &= ~(RBUF_HFB_EN | RBUF_ACPI_EN);
 		bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL);
 	}
@@ -267,4 +267,6 @@ void bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv,
 	reg &= ~CMD_CRC_FWD;
 	bcmgenet_umac_writel(priv, reg, UMAC_CMD);
 	spin_unlock_bh(&priv->reg_lock);
+
+	return 0;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 427/877] net: bcmgenet: do not skip WoL power up on GENET V1
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (425 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 426/877] net: bcmgenet: allow return of power up status Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 428/877] net: bcmgenet: validate Ethernet address in bcmgenet_set_mac_addr Greg Kroah-Hartman
                   ` (457 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Florian Fainelli,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Florian Fainelli <florian.fainelli@broadcom.com>

[ Upstream commit cbbc1aee7776c7fa1d89e6cb963a23e58c495dca ]

bcmgenet_power_up() had an early check for bcmgenet_has_ext(priv) before
dispatching by power mode. GENET V1 does not have the EXT block (unlike
GENET V2+), which causes bcmgenet_power_up() to immediately return 0.

As a consequence, when waking up from GENET_POWER_WOL_MAGIC on GENET V1,
bcmgenet_wol_power_up_cfg() is never invoked to disable the WoL clock,
clear wake event masks, and restore normal PHY and MAC operations.

Move the bcmgenet_has_ext() checks to the GENET_POWER_PASSIVE and
GENET_POWER_CABLE_SENSE cases where the EXT registers are actually
accessed, allowing GENET_POWER_WOL_MAGIC cleanup to execute on all
hardware versions.

Fixes: c3ae64ae0c08 ("net: bcmgenet: handle GENET_POWER_WOL_MAGIC")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260921220021.281418-4-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index fc1d4cef3ad81..dad5adfadb76d 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -1699,13 +1699,12 @@ static int bcmgenet_power_up(struct bcmgenet_priv *priv,
 	int ret = 0;
 	u32 reg;
 
-	if (!bcmgenet_has_ext(priv))
-		return ret;
-
-	reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
-
 	switch (mode) {
 	case GENET_POWER_PASSIVE:
+		if (!bcmgenet_has_ext(priv))
+			break;
+
+		reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
 		reg &= ~(EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS |
 			 EXT_ENERGY_DET_MASK);
 		if (GENET_IS_V5(priv) && !bcmgenet_has_ephy_16nm(priv)) {
@@ -1729,8 +1728,12 @@ static int bcmgenet_power_up(struct bcmgenet_priv *priv,
 		break;
 
 	case GENET_POWER_CABLE_SENSE:
+		if (!bcmgenet_has_ext(priv))
+			break;
+
 		/* enable APD */
 		if (!GENET_IS_V5(priv)) {
+			reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
 			reg |= EXT_PWR_DN_EN_LD;
 			bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
 		}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 428/877] net: bcmgenet: validate Ethernet address in bcmgenet_set_mac_addr
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (426 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 427/877] net: bcmgenet: do not skip WoL power up on GENET V1 Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 429/877] net: bcmgenet: mask DMA_TIMEOUT_MASK when reading DMA_RING0_TIMEOUT Greg Kroah-Hartman
                   ` (456 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Florian Fainelli,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Florian Fainelli <florian.fainelli@broadcom.com>

[ Upstream commit 273941c85fc2632cd3e56ddff737b9245de7697d ]

bcmgenet_set_mac_addr() did not check whether the provided MAC address is a
valid Ethernet address before applying it. Userspace could configure an
invalid address (such as all zeroes or a multicast address) while the
interface is down.

Add a call to is_valid_ether_addr() and return -EADDRNOTAVAIL if the MAC
address is not valid.

Fixes: 1c1008c793fa ("net: bcmgenet: add main driver file")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260921220021.281418-5-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index dad5adfadb76d..a326ee63c1b7c 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -3562,6 +3562,9 @@ static int bcmgenet_set_mac_addr(struct net_device *dev, void *p)
 	if (netif_running(dev))
 		return -EBUSY;
 
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
 	eth_hw_addr_set(dev, addr->sa_data);
 
 	return 0;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 429/877] net: bcmgenet: mask DMA_TIMEOUT_MASK when reading DMA_RING0_TIMEOUT
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (427 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 428/877] net: bcmgenet: validate Ethernet address in bcmgenet_set_mac_addr Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 430/877] ip_gre: Reject enabling collect metadata through changelink Greg Kroah-Hartman
                   ` (455 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Florian Fainelli,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Florian Fainelli <florian.fainelli@broadcom.com>

[ Upstream commit d64e277b955be4506931802837499b62c8f3968a ]

bcmgenet_get_coalesce() reads DMA_RING0_TIMEOUT to calculate
rx_coalesce_usecs without masking out bits outside DMA_TIMEOUT_MASK
(16 bits). If upper bits are non-zero or contain status/flags, the
computed value of rx_coalesce_usecs returned to userspace via ethtool
becomes corrupted.

Mask the register read with DMA_TIMEOUT_MASK before computing the
timeout in microseconds.

Fixes: 4a29645bfe6c ("net: bcmgenet: Implement RX coalescing control knobs")
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260921220021.281418-6-florian.fainelli@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index a326ee63c1b7c..14e891db97ea8 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -819,7 +819,8 @@ static int bcmgenet_get_coalesce(struct net_device *dev,
 	ec->rx_max_coalesced_frames =
 		bcmgenet_rdma_ring_readl(priv, 0, DMA_MBUF_DONE_THRESH);
 	ec->rx_coalesce_usecs =
-		bcmgenet_rdma_readl(priv, DMA_RING0_TIMEOUT) * 8192 / 1000;
+		(bcmgenet_rdma_readl(priv, DMA_RING0_TIMEOUT) &
+		 DMA_TIMEOUT_MASK) * 8192 / 1000;
 
 	for (i = 0; i <= priv->hw_params->rx_queues; i++) {
 		ring = &priv->rx_rings[i];
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 430/877] ip_gre: Reject enabling collect metadata through changelink
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (428 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 429/877] net: bcmgenet: mask DMA_TIMEOUT_MASK when reading DMA_RING0_TIMEOUT Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 431/877] vxlan: use one headroom snapshot for neighbour replies Greg Kroah-Hartman
                   ` (454 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Xuanqiang Luo, Ido Schimmel,
	Hangbin Liu, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>

[ Upstream commit a3f315be9d30eeb6938d11fa17fd4b32d52f7c42 ]

ipgre_netlink_parms() can enable collect_md on an existing GRE, GRETAP
or ERSPAN device. Unlike newlink, changelink does not enforce metadata
tunnel uniqueness. Converting a non-metadata device can therefore
replace the metadata receive entry for another device of the same type
in the same netns. Deleting either device then clears the shared entry,
breaking metadata receive lookup for the surviving device.

If parameter validation fails after collect_md is set, deleting the
modified device can also clear an entry it never owned.

Reject enabling metadata mode in both changelink callbacks before any
encapsulation or tunnel parameters are modified. Allow requests that
repeat the metadata attribute on an existing metadata device.

Fixes: 2e15ea390e6f ("ip_gre: Add support to collect tunnel metadata.")
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260921031859.9283-1-xuanqiang.luo@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv4/ip_gre.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index f344e9bb31fbb..5c5ea36584bf9 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1449,6 +1449,12 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
 	if (!rtnl_dev_link_net_capable(dev, t->net))
 		return -EPERM;
 
+	if (data && data[IFLA_GRE_COLLECT_METADATA] && !t->collect_md) {
+		NL_SET_ERR_MSG(extack,
+			       "Enabling collect_md on an existing device is not supported");
+		return -EOPNOTSUPP;
+	}
+
 	err = ipgre_newlink_encap_setup(dev, data);
 	if (err)
 		return err;
@@ -1481,6 +1487,12 @@ static int erspan_changelink(struct net_device *dev, struct nlattr *tb[],
 	if (!rtnl_dev_link_net_capable(dev, t->net))
 		return -EPERM;
 
+	if (data && data[IFLA_GRE_COLLECT_METADATA] && !t->collect_md) {
+		NL_SET_ERR_MSG(extack,
+			       "Enabling collect_md on an existing device is not supported");
+		return -EOPNOTSUPP;
+	}
+
 	err = ipgre_newlink_encap_setup(dev, data);
 	if (err)
 		return err;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 431/877] vxlan: use one headroom snapshot for neighbour replies
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (429 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 430/877] ip_gre: Reject enabling collect metadata through changelink Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 432/877] net: xps: reject an out of range traffic class Greg Kroah-Hartman
                   ` (453 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sanghyun Park, Jakub Kicinski,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sanghyun Park <sanghyun.park.cnu@gmail.com>

[ Upstream commit 481506a756dcd828ef42391cb08f38d8d96d38fc ]

vxlan_na_create() samples LL_RESERVED_SPACE() to size the reply skb and then
samples it again to reserve headroom. A concurrent vxlan_changelink() can
update needed_headroom between the two reads, creating a TOCTOU race. The
second value can exceed the allocation and make the Ethernet header write out
of bounds.

The race is reproducible on the unpatched kernel. It occurred when
vxlan_na_create() generated a neighbour reply while vxlan_changelink() changed
the link headroom. KASAN caught a four-byte write two bytes beyond a 704-byte
skbuff_small_head allocation.

Snapshot the headroom once and use that value for both allocation and
reservation.

Fixes: 4b29dba9c085 ("vxlan: fix nonfunctional neigh_reduce()")
Signed-off-by: Sanghyun Park <sanghyun.park.cnu@gmail.com>
Link: https://patch.msgid.link/20260918032842.502409-2-sanghyun.park.cnu@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/vxlan/vxlan_core.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index b14dbc6892078..f612def46c3c4 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -1979,13 +1979,15 @@ static struct sk_buff *vxlan_na_create(struct sk_buff *request,
 	struct ipv6hdr *pip6;
 	u8 *daddr;
 	int na_olen = 8; /* opt hdr + ETH_ALEN for target */
+	int headroom;
 	int ns_olen;
 	int i, len;
 
 	if (dev == NULL || !pskb_may_pull(request, request->len))
 		return NULL;
 
-	len = LL_RESERVED_SPACE(dev) + sizeof(struct ipv6hdr) +
+	headroom = LL_RESERVED_SPACE(dev);
+	len = headroom + sizeof(struct ipv6hdr) +
 		sizeof(*na) + na_olen + dev->needed_tailroom;
 	reply = alloc_skb(len, GFP_ATOMIC);
 	if (reply == NULL)
@@ -1993,7 +1995,7 @@ static struct sk_buff *vxlan_na_create(struct sk_buff *request,
 
 	reply->protocol = htons(ETH_P_IPV6);
 	reply->dev = dev;
-	skb_reserve(reply, LL_RESERVED_SPACE(request->dev));
+	skb_reserve(reply, headroom);
 	skb_push(reply, sizeof(struct ethhdr));
 	skb_reset_mac_header(reply);
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 432/877] net: xps: reject an out of range traffic class
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (430 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 431/877] vxlan: use one headroom snapshot for neighbour replies Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 433/877] drm/imagination: clamp freelist reconstruction requests Greg Kroah-Hartman
                   ` (452 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Jakub Kicinski,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Norbert Szetei <norbert@doyensec.com>

[ Upstream commit 4da3b7b8b50f3e2fde54a4c18a82a8e3f6223910 ]

Only the entries below dev->num_tc are valid in dev->tc_to_txq[], and
dev->prio_tc_map[] may only name classes below it. netdev_set_num_tc()
lowers dev->num_tc without touching either array.

netdev_txq_to_tc() walks all TC_MAX_QUEUE slots and
netdev_get_prio_tc_map() returns the entry as it stands, so a leftover
entry is handed out as a traffic class >= dev->num_tc. Taking that
class from netdev_txq_to_tc(), __netif_set_xps_queue() rejects only a
negative one and indexes an XPS map sized for dev->num_tc classes:

	tci = j * num_tc + tc;
	RCU_INIT_POINTER(new_dev_maps->attr_map[tci], map);

attr_map[] holds nr_ids * num_tc entries and j runs over the ids named
in the mask, so a class that is not below num_tc pushes tci past the end
of the map for the last ids and the store overruns it.

Any caller that lowers num_tc leaves such entries behind, and
mqprio_destroy() tears down with netdev_set_num_tc(dev, 0) rather than
netdev_reset_tc(). After mqprio with 8 classes then 1, tc_to_txq[1..7]
still describe txq 1..7. The splat is from an XPS write to txq 2 on a
veth with 8 rx queues: attr_map[] has 8 * 1 entries, tci = j + 2, and
j == 6 stores one past the end of the 88-byte map:

  BUG: KASAN: slab-out-of-bounds in __netif_set_xps_queue (net/core/dev.c:2954)
  Write of size 8 at addr ffff88813016bc58 by task xps_oob/634
   __netif_set_xps_queue (net/core/dev.c:2954)
   xps_rxqs_store (net/core/net-sysfs.c:1880)
   netdev_queue_attr_store (net/core/net-sysfs.c:1390)
  Allocated by task 634:
   __kmalloc_noprof (mm/slub.c:5439)
   __netif_set_xps_queue (net/core/dev.c:2937)
  The buggy address is located 0 bytes to the right of
   allocated 88-byte region [ffff88813016bc00, ffff88813016bc58)

Reject a class the map has no room for.

Fixes: 184c449f91fe ("net: Add support for XPS with QoS via traffic classes")
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Link: https://patch.msgid.link/162DD16F-54C6-444A-9E09-0B8CB3D591F2@doyensec.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/core/dev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index d4f0db3208483..6c63867ff76d6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2686,7 +2686,7 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
 		dev = netdev_get_tx_queue(dev, index)->sb_dev ? : dev;
 
 		tc = netdev_txq_to_tc(dev, index);
-		if (tc < 0)
+		if (tc < 0 || tc >= num_tc)
 			return -EINVAL;
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 433/877] drm/imagination: clamp freelist reconstruction requests
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (431 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 432/877] net: xps: reject an out of range traffic class Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 434/877] bonding: crypto offload enabled, non-offload slave failover, rekey failed Greg Kroah-Hartman
                   ` (451 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, Alessio Belle,
	Brajesh Gupta, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pengpeng Hou <hppiscas@163.com>

[ Upstream commit 45585c3aa285854face65293acc95eff73063d6d ]

The firmware reconstruction count controls accesses to the request's
fixed freelist ID array and the copy into the fixed response array.
Neither access currently bounds the count to those protocol arrays.

Clamp the count to the request capacity, which is shared by the response
layout, and use that count consistently for reconstruction and response
publication. Keep the firmware recovery exchange instead of dropping an
oversized request without a response, as discussed with the firmware
maintainer.

The issue was found by our static-analysis tool.

Fixes: 6eedddab733b ("drm/imagination: Implement free list and HWRT create and destroy ioctls")
Assisted-by: gpt 5
Signed-off-by: Pengpeng Hou <hppiscas@163.com>
Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
Link: https://patch.msgid.link/20260920034329.16614-1-hppiscas@163.com
Signed-off-by: Brajesh Gupta <brajesh.gupta@imgtec.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/gpu/drm/imagination/pvr_free_list.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/imagination/pvr_free_list.c b/drivers/gpu/drm/imagination/pvr_free_list.c
index 5e51bc980751c..083ae6fa09765 100644
--- a/drivers/gpu/drm/imagination/pvr_free_list.c
+++ b/drivers/gpu/drm/imagination/pvr_free_list.c
@@ -8,6 +8,7 @@
 #include "pvr_vm.h"
 
 #include <drm/drm_gem.h>
+#include <drm/drm_print.h>
 #include <linux/slab.h>
 #include <linux/xarray.h>
 #include <uapi/drm/pvr_drm.h>
@@ -613,13 +614,21 @@ pvr_free_list_process_reconstruct_req(struct pvr_device *pvr_dev,
 	};
 	struct rogue_fwif_freelists_reconstruction_data *resp =
 		&resp_cmd.cmd_data.free_lists_reconstruction_data;
+	u32 count = min_t(u32, req->freelist_count,
+			  ARRAY_SIZE(req->freelist_ids));
 
-	for (u32 i = 0; i < req->freelist_count; i++)
+	if (count != req->freelist_count) {
+		drm_warn_once(from_pvr_device(pvr_dev),
+			      "Requested reconstruction of %u freelists, limiting to %u\n",
+			      req->freelist_count, count);
+	}
+
+	for (u32 i = 0; i < count; i++)
 		pvr_free_list_reconstruct(pvr_dev, req->freelist_ids[i]);
 
-	resp->freelist_count = req->freelist_count;
+	resp->freelist_count = count;
 	memcpy(resp->freelist_ids, req->freelist_ids,
-	       req->freelist_count * sizeof(resp->freelist_ids[0]));
+	       count * sizeof(resp->freelist_ids[0]));
 
 	WARN_ON(pvr_kccb_send_cmd(pvr_dev, &resp_cmd, NULL));
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 434/877] bonding: crypto offload enabled, non-offload slave failover, rekey failed
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (432 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 433/877] drm/imagination: clamp freelist reconstruction requests Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 435/877] macsec: add some of the lower devices features when offloading Greg Kroah-Hartman
                   ` (450 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, David Dai, Hangbin Liu, Paolo Abeni,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: David Dai <zdai@linux.ibm.com>

[ Upstream commit 00efbbd40bd5fd92c67b7cf1aab8904fa59a96f6 ]

Create a bonding device (i.e. bond0) in active-backup mode, 2 slaves.
Active slave: offload capable interface (i.e. eth1), primary interface.
Backup slave: non-offload capable interface(i.e. eth2).
Configure strongswan service swantl.conf child SA "hw_offload = crypto"
Start strongswan service
IPSec Crytpo Offload is enabled on top of bond0. i.e.
ip xfrm state |grep offload
        crypto offload parameters: dev bond0 dir out mode crypto
	crypto offload parameters: dev bond0 dir in mode crypto

Active slave eth1 takes adavantage of IPSec Crypto Offload capability.

If active slave eth1 is down for any reason (i.e. eth1 link down):
ip link set down dev eth1
non-offload capable interface eth2 failover to becomes active slave.
The existing SAs can continue use software IPsec after failover.
Traffic still keeps going properly.

However if eth1 link had not recovered yet, strongswan service does
new child SA rekey, or uses swanctl command to do new child SA rekey,
it will fail because active slave eth2 doesn't support crypto offload.
In bond_ipsec_add_sa routine, it returns -EINVAL now, which is
treated as fatal error by xfrm_dev_state_add routine in kernel xfrm.

To make the non-offload active slave survive the child SA rekey, need
to make bond_ipsec_add_sa routine returns -EOPNOTSUPP instead when
active slave doesn't support IPsec Crypto offload, the xfrm will
gracefully fallback to create new SA using Software IPsec.
Network traffic can keep going.

After offload capable interface eth1 link is up, becomes active slave,
next time strongswan child SA rekey will create a new SA which enables
crypto offload again.

Fixes: 18cb261afd7b ("bonding: support hardware encryption offload to slaves")
Signed-off-by: David Dai <zdai@linux.ibm.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260918211155.1664493-1-zdai@linux.ibm.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/bonding/bond_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 5911dcaedf0fc..d10bbe4c35718 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -494,7 +494,7 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs,
 	    !real_dev->xfrmdev_ops->xdo_dev_state_add ||
 	    netif_is_bond_master(real_dev)) {
 		NL_SET_ERR_MSG_MOD(extack, "Slave does not support ipsec offload");
-		err = -EINVAL;
+		err = -EOPNOTSUPP;
 		goto out;
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 435/877] macsec: add some of the lower devices features when offloading
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (433 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 434/877] bonding: crypto offload enabled, non-offload slave failover, rekey failed Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits " Greg Kroah-Hartman
                   ` (449 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sabrina Dubroca, Simon Horman,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sabrina Dubroca <sd@queasysnail.net>

[ Upstream commit bd97c29f7e9e45980417973d5e8b755bd71e10a9 ]

This commit extends the set of netdevice features supported by macsec
devices when offload is enabled, which increases performance
significantly (for a single TCP stream: 17.5Gbps to 38.5Gbps on my
test machines).

Commit c850240b6c41 ("net: macsec: report real_dev features when HW
offloading is enabled") previously attempted something similar, but
had to be reverted (commit 8bcd560ae878 ("Revert "net: macsec: report
real_dev features when HW offloading is enabled"")) because the set of
features it exposed was too large.

During initialization, all features are set, and they're then removed
via ndo_fix_features (macsec_fix_features). This allows the
offloadable features to be automatically enabled if offloading is
turned on after device creation.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/8b32c3011d269d6f149724e80c1ffe67c9534067.1730929545.git.sd@queasysnail.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: c2de369c5c5b ("macsec: initialize SecY before registering the netdevice")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/macsec.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index 66f7407a2b178..b1eb6b5dde0fe 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -2695,6 +2695,8 @@ static int macsec_update_offload(struct net_device *dev, enum macsec_offload off
 	macsec_set_head_tail_room(dev);
 	macsec->insert_tx_tag = macsec_needs_tx_tag(macsec, ops);
 
+	netdev_update_features(dev);
+
 	return ret;
 }
 
@@ -3550,6 +3552,10 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
 #define MACSEC_FEATURES \
 	(NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST)
 
+#define MACSEC_OFFLOAD_FEATURES \
+	(MACSEC_FEATURES | NETIF_F_GSO_SOFTWARE | NETIF_F_SOFT_FEATURES | \
+	 NETIF_F_LRO | NETIF_F_RXHASH | NETIF_F_CSUM_MASK | NETIF_F_RXCSUM)
+
 static int macsec_dev_init(struct net_device *dev)
 {
 	struct macsec_dev *macsec = macsec_priv(dev);
@@ -3560,7 +3566,10 @@ static int macsec_dev_init(struct net_device *dev)
 	if (err)
 		return err;
 
-	dev->features = real_dev->features & MACSEC_FEATURES;
+	dev->hw_features = real_dev->hw_features & MACSEC_OFFLOAD_FEATURES;
+	dev->hw_features |= NETIF_F_GSO_SOFTWARE;
+
+	dev->features = real_dev->features & MACSEC_OFFLOAD_FEATURES;
 	dev->features |= NETIF_F_GSO_SOFTWARE;
 	dev->lltx = true;
 	dev->pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS;
@@ -3590,8 +3599,12 @@ static netdev_features_t macsec_fix_features(struct net_device *dev,
 {
 	struct macsec_dev *macsec = macsec_priv(dev);
 	struct net_device *real_dev = macsec->real_dev;
+	netdev_features_t mask;
+
+	mask = macsec_is_offloaded(macsec) ? MACSEC_OFFLOAD_FEATURES
+					   : MACSEC_FEATURES;
 
-	features &= (real_dev->features & MACSEC_FEATURES) |
+	features &= (real_dev->features & mask) |
 		    NETIF_F_GSO_SOFTWARE | NETIF_F_SOFT_FEATURES;
 
 	return features;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits when offloading
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (434 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 435/877] macsec: add some of the lower devices features when offloading Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-10-01  5:27   ` Karl Mehltretter
  2026-10-01 20:12   ` Harshit Mogalapalli
  2026-09-30 15:22 ` [PATCH 6.12 437/877] macsec: initialize SecY before registering the netdevice Greg Kroah-Hartman
                   ` (448 subsequent siblings)
  884 siblings, 2 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sabrina Dubroca, Simon Horman,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sabrina Dubroca <sd@queasysnail.net>

[ Upstream commit de187a390838c0b3dfd00ae5399aa406d0a79f13 ]

If macsec is offloaded, we need to follow the lower device's
capabilities, like VLAN devices do.

Leave the limits unchanged when the offload is disabled.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/8240c0181e851f169d815f59658a01fb9dfc5073.1730929545.git.sd@queasysnail.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: c2de369c5c5b ("macsec: initialize SecY before registering the netdevice")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/macsec.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index b1eb6b5dde0fe..ce4a08f77724f 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -2650,6 +2650,17 @@ static void macsec_set_head_tail_room(struct net_device *dev)
 	dev->needed_tailroom = real_dev->needed_tailroom + needed_tailroom;
 }
 
+static void macsec_inherit_tso_max(struct net_device *dev)
+{
+	struct macsec_dev *macsec = macsec_priv(dev);
+
+	/* if macsec is offloaded, we need to follow the lower
+	 * device's capabilities. otherwise, we can ignore them.
+	 */
+	if (macsec_is_offloaded(macsec))
+		netif_inherit_tso_max(dev, macsec->real_dev);
+}
+
 static int macsec_update_offload(struct net_device *dev, enum macsec_offload offload)
 {
 	enum macsec_offload prev_offload;
@@ -2695,6 +2706,8 @@ static int macsec_update_offload(struct net_device *dev, enum macsec_offload off
 	macsec_set_head_tail_room(dev);
 	macsec->insert_tx_tag = macsec_needs_tx_tag(macsec, ops);
 
+	macsec_inherit_tso_max(dev);
+
 	netdev_update_features(dev);
 
 	return ret;
@@ -3566,6 +3579,8 @@ static int macsec_dev_init(struct net_device *dev)
 	if (err)
 		return err;
 
+	macsec_inherit_tso_max(dev);
+
 	dev->hw_features = real_dev->hw_features & MACSEC_OFFLOAD_FEATURES;
 	dev->hw_features |= NETIF_F_GSO_SOFTWARE;
 
@@ -4521,6 +4536,13 @@ static int macsec_notify(struct notifier_block *this, unsigned long event,
 			if (dev->mtu > mtu)
 				dev_set_mtu(dev, mtu);
 		}
+		break;
+	case NETDEV_FEAT_CHANGE:
+		list_for_each_entry(m, &rxd->secys, secys) {
+			macsec_inherit_tso_max(m->secy.netdev);
+			netdev_update_features(m->secy.netdev);
+		}
+		break;
 	}
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 437/877] macsec: initialize SecY before registering the netdevice
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (435 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits " Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 438/877] net: dsa: mt7530: fix NULL dereference on unbind of MT7531 and MT7621 Greg Kroah-Hartman
                   ` (447 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+f2f6312ad1b5a0bfe316,
	Sabrina Dubroca, Haseeb Malik, Paolo Abeni, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Haseeb Malik <haseebulhaq55@gmail.com>

[ Upstream commit c2de369c5c5b8599ca10fd5ca8d11fcd845c1331 ]

Creating a MACsec device with MAC offload over an LRO-capable lower
device triggers a warning in rtmsg_ifinfo_build_skb() when IPv4
forwarding is enabled by default.

register_netdevice() invokes inetdev_init(), which disables LRO and emits
a NETDEV_FEAT_CHANGE notification. This reaches macsec_fill_info() before
macsec_add_dev() initializes the SecY. key_len is still zero, so
macsec_fill_info() returns -EMSGSIZE and trips the WARN_ON in
rtmsg_ifinfo_build_skb(), even though the skb has enough space.

Even without the warning, notifications during registration can report
uninitialized SecY attributes, including the SCI. This ordering has existed
since the driver was introduced.

Initialize the SecY and apply the new-link attributes before registration.
Move MAC address inheritance into macsec_newlink() so the SCI can also be
initialized before registration-time notifications report it. Move the
per-CPU statistics and metadata destination allocation into ndo_init(),
and release partial allocations on failure.

Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver")
Reported-by: syzbot+f2f6312ad1b5a0bfe316@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=f2f6312ad1b5a0bfe316
Suggested-by: Sabrina Dubroca <sd@queasysnail.net>
Link: https://lists.openwall.net/linux-kernel/2026/08/19/552
Signed-off-by: Haseeb Malik <haseebulhaq55@gmail.com>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Link: https://patch.msgid.link/20260921-fix-macsec-net-v3-1-accf94f93f5e@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/macsec.c | 84 +++++++++++++++++++++++---------------------
 1 file changed, 43 insertions(+), 41 deletions(-)

diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index ce4a08f77724f..fd6f88cfaff61 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -3579,6 +3579,22 @@ static int macsec_dev_init(struct net_device *dev)
 	if (err)
 		return err;
 
+	err = -ENOMEM;
+	macsec->stats = netdev_alloc_pcpu_stats(struct pcpu_secy_stats);
+	if (!macsec->stats)
+		goto destroy_gro_cells;
+
+	macsec->secy.tx_sc.stats =
+		netdev_alloc_pcpu_stats(struct pcpu_tx_sc_stats);
+	if (!macsec->secy.tx_sc.stats)
+		goto free_secy_stats;
+
+	macsec->secy.tx_sc.md_dst = metadata_dst_alloc(0, METADATA_MACSEC,
+						       GFP_KERNEL);
+	if (!macsec->secy.tx_sc.md_dst)
+		goto free_tx_sc_stats;
+	macsec->secy.tx_sc.md_dst->u.macsec_info.sci = macsec->secy.sci;
+
 	macsec_inherit_tso_max(dev);
 
 	dev->hw_features = real_dev->hw_features & MACSEC_OFFLOAD_FEATURES;
@@ -3591,8 +3607,6 @@ static int macsec_dev_init(struct net_device *dev)
 
 	macsec_set_head_tail_room(dev);
 
-	if (is_zero_ether_addr(dev->dev_addr))
-		eth_hw_addr_inherit(dev, real_dev);
 	if (is_zero_ether_addr(dev->broadcast))
 		memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len);
 
@@ -3600,6 +3614,14 @@ static int macsec_dev_init(struct net_device *dev)
 	netdev_hold(real_dev, &macsec->dev_tracker, GFP_KERNEL);
 
 	return 0;
+
+free_tx_sc_stats:
+	free_percpu(macsec->secy.tx_sc.stats);
+free_secy_stats:
+	free_percpu(macsec->stats);
+destroy_gro_cells:
+	gro_cells_destroy(&macsec->gro_cells);
+	return err;
 }
 
 static void macsec_dev_uninit(struct net_device *dev)
@@ -4127,26 +4149,11 @@ static sci_t dev_to_sci(struct net_device *dev, __be16 port)
 	return make_sci(dev->dev_addr, port);
 }
 
-static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len)
+static void macsec_init_secy(struct net_device *dev, sci_t sci, u8 icv_len)
 {
 	struct macsec_dev *macsec = macsec_priv(dev);
 	struct macsec_secy *secy = &macsec->secy;
 
-	macsec->stats = netdev_alloc_pcpu_stats(struct pcpu_secy_stats);
-	if (!macsec->stats)
-		return -ENOMEM;
-
-	secy->tx_sc.stats = netdev_alloc_pcpu_stats(struct pcpu_tx_sc_stats);
-	if (!secy->tx_sc.stats)
-		return -ENOMEM;
-
-	secy->tx_sc.md_dst = metadata_dst_alloc(0, METADATA_MACSEC, GFP_KERNEL);
-	if (!secy->tx_sc.md_dst)
-		/* macsec and secy percpu stats will be freed when unregistering
-		 * net_device in macsec_free_netdev()
-		 */
-		return -ENOMEM;
-
 	if (sci == MACSEC_UNDEF_SCI)
 		sci = dev_to_sci(dev, MACSEC_PORT_ES);
 
@@ -4160,15 +4167,12 @@ static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len)
 	secy->xpn = DEFAULT_XPN;
 
 	secy->sci = sci;
-	secy->tx_sc.md_dst->u.macsec_info.sci = sci;
 	secy->tx_sc.active = true;
 	secy->tx_sc.encoding_sa = DEFAULT_ENCODING_SA;
 	secy->tx_sc.encrypt = DEFAULT_ENCRYPT;
 	secy->tx_sc.send_sci = DEFAULT_SEND_SCI;
 	secy->tx_sc.end_station = false;
 	secy->tx_sc.scb = false;
-
-	return 0;
 }
 
 static struct lock_class_key macsec_netdev_addr_lock_key;
@@ -4228,6 +4232,24 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
 	if (rx_handler && rx_handler != macsec_handle_frame)
 		return -EBUSY;
 
+	if (is_zero_ether_addr(dev->dev_addr))
+		eth_hw_addr_inherit(dev, real_dev);
+
+	if (data && data[IFLA_MACSEC_SCI])
+		sci = nla_get_sci(data[IFLA_MACSEC_SCI]);
+	else if (data && data[IFLA_MACSEC_PORT])
+		sci = dev_to_sci(dev, nla_get_be16(data[IFLA_MACSEC_PORT]));
+	else
+		sci = dev_to_sci(dev, MACSEC_PORT_ES);
+
+	/* Registration can notify listeners before returning. */
+	macsec_init_secy(dev, sci, icv_len);
+	if (data) {
+		err = macsec_changelink_common(dev, data);
+		if (err)
+			return err;
+	}
+
 	err = register_netdevice(dev);
 	if (err < 0)
 		return err;
@@ -4240,31 +4262,11 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
 	if (err < 0)
 		goto unregister;
 
-	/* need to be already registered so that ->init has run and
-	 * the MAC addr is set
-	 */
-	if (data && data[IFLA_MACSEC_SCI])
-		sci = nla_get_sci(data[IFLA_MACSEC_SCI]);
-	else if (data && data[IFLA_MACSEC_PORT])
-		sci = dev_to_sci(dev, nla_get_be16(data[IFLA_MACSEC_PORT]));
-	else
-		sci = dev_to_sci(dev, MACSEC_PORT_ES);
-
 	if (rx_handler && sci_exists(real_dev, sci)) {
 		err = -EBUSY;
 		goto unlink;
 	}
 
-	err = macsec_add_dev(dev, sci, icv_len);
-	if (err)
-		goto unlink;
-
-	if (data) {
-		err = macsec_changelink_common(dev, data);
-		if (err)
-			goto del_dev;
-	}
-
 	/* If h/w offloading is available, propagate to the device */
 	if (macsec_is_offloaded(macsec)) {
 		const struct macsec_ops *ops;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 438/877] net: dsa: mt7530: fix NULL dereference on unbind of MT7531 and MT7621
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (436 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 437/877] macsec: initialize SecY before registering the netdevice Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 439/877] tcp: fix use-after-free of retransmit_skb_hint in tcp_send_synack() Greg Kroah-Hartman
                   ` (446 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Aleksei Sviridkin, Jakub Kicinski,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Aleksei Sviridkin <f@lex.la>

[ Upstream commit c2cdef41e0b4d8ed23a5b41e6ad4e64594e055e4 ]

The core and io supplies are only requested for ID_MT7530: both the
devm_regulator_get() in probe and the regulator_enable() in
mt7530_setup() are guarded by the switch id, but mt7530_remove()
disables them unconditionally. On an MT7621 or an MT7531 both pointers
are still NULL from devm_kzalloc(), so rmmod or a sysfs unbind calls
regulator_disable() on NULL.

Fixes: ddda1ac116c8 ("net: dsa: mt7530: support the 7530 switch on the Mediatek MT7621 SoC")
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Link: https://patch.msgid.link/20260918015020.2518315-2-f@lex.la
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/dsa/mt7530-mdio.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/net/dsa/mt7530-mdio.c b/drivers/net/dsa/mt7530-mdio.c
index e19b46449ffe6..9bc142e55df23 100644
--- a/drivers/net/dsa/mt7530-mdio.c
+++ b/drivers/net/dsa/mt7530-mdio.c
@@ -230,15 +230,17 @@ mt7530_remove(struct mdio_device *mdiodev)
 	if (!priv)
 		return;
 
-	ret = regulator_disable(priv->core_pwr);
-	if (ret < 0)
-		dev_err(priv->dev,
-			"Failed to disable core power: %d\n", ret);
-
-	ret = regulator_disable(priv->io_pwr);
-	if (ret < 0)
-		dev_err(priv->dev, "Failed to disable io pwr: %d\n",
-			ret);
+	if (priv->id == ID_MT7530) {
+		ret = regulator_disable(priv->core_pwr);
+		if (ret < 0)
+			dev_err(priv->dev,
+				"Failed to disable core power: %d\n", ret);
+
+		ret = regulator_disable(priv->io_pwr);
+		if (ret < 0)
+			dev_err(priv->dev, "Failed to disable io pwr: %d\n",
+				ret);
+	}
 
 	mt7530_remove_common(priv);
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 439/877] tcp: fix use-after-free of retransmit_skb_hint in tcp_send_synack()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (437 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 438/877] net: dsa: mt7530: fix NULL dereference on unbind of MT7531 and MT7621 Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 440/877] nfp: hold IPsec RX state under the XArray lock Greg Kroah-Hartman
                   ` (445 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kimi Security Team, Weiming Shi,
	Yilin Zhang, Eric Dumazet, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Yilin Zhang <yilinzhang@moonshot.ai>

[ Upstream commit fe99bbeee5c5dbd3abc30721a8079ced59649d97 ]

When tcp_send_synack() replaces the cloned SYN skb at the head of the
retransmit queue with a copy, it frees the original with
tcp_rtx_queue_unlink_and_free() and only repairs tp->highest_sack.
tp->retransmit_skb_hint keeps pointing at the freed
skbuff_fclone_cache object.

The dangling hint is read in tcp_verify_retransmit_hint() and used as
the root of the rbtree walk in tcp_xmit_retransmit_queue().  An
unprivileged TFO client (sendmsg(MSG_FASTOPEN)) can arm the hint with
an attacker-supplied ICMP fragmentation-needed message, after which a
simultaneous open frees the armed SYN skb:

  BUG: KASAN: slab-use-after-free in tcp_mark_skb_lost (net/ipv4/tcp_input.c:1316)
  Read of size 4 at addr ffff88800604d928 by task swapper/1/0
  Call Trace:
   tcp_mark_skb_lost (net/ipv4/tcp_input.c:1316)
   tcp_simple_retransmit (net/ipv4/tcp_input.c:3158)
   tcp_v4_err (net/ipv4/tcp_ipv4.c:587)

Sync the hint to the copy.

Fixes: c31b70c9968f ("tcp: Add logic to check for SYN w/ data in tcp_simple_retransmit")
Reported-by: Kimi Security Team <bug-report@moonshot.ai>
Tested-by: Weiming Shi <shiweiming@moonshot.ai>
Signed-off-by: Yilin Zhang <yilinzhang@moonshot.ai>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/8a9dff4063a2745653b7e88ceb745d75efa16e68.1790224474.git.yilinzhang@moonshot.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/ipv4/tcp_output.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index a8c4801228677..aa00a9fb2506c 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -3679,6 +3679,7 @@ void tcp_send_active_reset(struct sock *sk, enum sk_rst_reason reason)
  */
 int tcp_send_synack(struct sock *sk)
 {
+	struct tcp_sock *tp = tcp_sk(sk);
 	struct sk_buff *skb;
 
 	skb = tcp_rtx_queue_head(sk);
@@ -3696,6 +3697,8 @@ int tcp_send_synack(struct sock *sk)
 			if (!nskb)
 				return -ENOMEM;
 			INIT_LIST_HEAD(&nskb->tcp_tsorted_anchor);
+			if (skb == tp->retransmit_skb_hint)
+				tp->retransmit_skb_hint = nskb;
 			tcp_highest_sack_replace(sk, skb, nskb);
 			tcp_rtx_queue_unlink_and_free(skb, sk);
 			__skb_header_release(nskb);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 440/877] nfp: hold IPsec RX state under the XArray lock
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (438 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 439/877] tcp: fix use-after-free of retransmit_skb_hint in tcp_send_synack() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 441/877] net/smc: fix UAF on lgr list traversal in smcr_port_err() Greg Kroah-Hartman
                   ` (444 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Changyul Lee, Sang-Hoon Choi,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sang-Hoon Choi <csh0052@gmail.com>

[ Upstream commit 1a983a4e14c635c40354be110cd9a1a5c94e01e6 ]

nfp_net_ipsec_rx() drops the XArray lock before taking a reference to the
xfrm_state it found. The delete path can erase the entry and drop the last
state reference in that interval. RX can then try to increment a zero
refcount after the state has been queued for destruction.

The driver queues firmware invalidation asynchronously; the delete path
does not wait for the command to complete or drain pending RX processing.

The XFRM garbage collector waits for an RCU grace period before freeing
the state. That delays reclamation but does not make acquiring a reference
from zero valid.

Take the xfrm_state reference before releasing the XArray lock so
xa_erase() cannot run between lookup and reference acquisition.

Fixes: 57f273adbcd4 ("nfp: add framework to support ipsec offloading")
Reported-by: Changyul Lee <lcy8047@gmail.com>
Signed-off-by: Sang-Hoon Choi <csh0052@gmail.com>
Link: https://patch.msgid.link/179001455912.44752.17153022439349797877.idr-bug-92@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/netronome/nfp/crypto/ipsec.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
index 515069d5637b0..3925a00aeaf7e 100644
--- a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
+++ b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
@@ -637,11 +637,12 @@ int nfp_net_ipsec_rx(struct nfp_meta_parsed *meta, struct sk_buff *skb)
 
 	xa_lock(&nn->xa_ipsec);
 	x = xa_load(&nn->xa_ipsec, saidx);
+	if (x)
+		xfrm_state_hold(x);
 	xa_unlock(&nn->xa_ipsec);
 	if (!x)
 		return -EINVAL;
 
-	xfrm_state_hold(x);
 	sp->xvec[sp->len++] = x;
 	sp->olen++;
 	xo = xfrm_offload(skb);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 441/877] net/smc: fix UAF on lgr list traversal in smcr_port_err()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (439 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 440/877] nfp: hold IPsec RX state under the XArray lock Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 442/877] tipc: Fix a data race on mon->peer_cnt in mon_timeout() Greg Kroah-Hartman
                   ` (443 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mahanta Jambigi, Sidraya Jayagond,
	Dust Li, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sidraya Jayagond <sidraya@linux.ibm.com>

[ Upstream commit 61cb282fe97b3b0ba32ca09417a693162bf4ae3f ]

smcr_port_err() traverses smc_lgr_list.list without holding
smc_lgr_list.lock, allowing a concurrent smc_lgr_terminate_sched()
to free an lgr while it is still being dereferenced.

Hold smc_lgr_list.lock across the traversal. Update
smc_ib_gid_check() to call smcr_port_err() after releasing the lock.

Fixes: 541afa10c126 ("net/smc: add smcr_port_err() and smcr_link_down() processing")
Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Signed-off-by: Sidraya Jayagond <sidraya@linux.ibm.com>
Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
Link: https://patch.msgid.link/20260922073149.474762-1-sidraya@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/smc/smc_core.c |  2 ++
 net/smc/smc_ib.c   | 10 ++++++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c
index ed0027ba66c75..e0bf348bd812e 100644
--- a/net/smc/smc_core.c
+++ b/net/smc/smc_core.c
@@ -1830,6 +1830,7 @@ void smcr_port_err(struct smc_ib_device *smcibdev, u8 ibport)
 	struct smc_link_group *lgr, *n;
 	int i;
 
+	spin_lock_bh(&smc_lgr_list.lock);
 	list_for_each_entry_safe(lgr, n, &smc_lgr_list.list, list) {
 		if (strncmp(smcibdev->pnetid[ibport - 1], lgr->pnet_id,
 			    SMC_MAX_PNETID_LEN))
@@ -1844,6 +1845,7 @@ void smcr_port_err(struct smc_ib_device *smcibdev, u8 ibport)
 				smcr_link_down_cond_sched(lnk);
 		}
 	}
+	spin_unlock_bh(&smc_lgr_list.lock);
 }
 
 static void smc_link_down_work(struct work_struct *work)
diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c
index fc07fc4ed9986..0cca7b9ca044e 100644
--- a/net/smc/smc_ib.c
+++ b/net/smc/smc_ib.c
@@ -333,6 +333,7 @@ static bool smc_ib_check_link_gid(u8 gid[SMC_GID_SIZE], bool smcrv2,
 static void smc_ib_gid_check(struct smc_ib_device *smcibdev, u8 ibport)
 {
 	struct smc_link_group *lgr;
+	bool stale_gid = false;
 	int i;
 
 	spin_lock_bh(&smc_lgr_list.lock);
@@ -348,11 +349,16 @@ static void smc_ib_gid_check(struct smc_ib_device *smcibdev, u8 ibport)
 				continue;
 			if (!smc_ib_check_link_gid(lgr->lnk[i].gid,
 						   lgr->smc_version == SMC_V2,
-						   smcibdev, ibport))
-				smcr_port_err(smcibdev, ibport);
+						   smcibdev, ibport)) {
+				stale_gid = true;
+				goto out;
+			}
 		}
 	}
+out:
 	spin_unlock_bh(&smc_lgr_list.lock);
+	if (stale_gid)
+		smcr_port_err(smcibdev, ibport);
 }
 
 static int smc_ib_remember_port_attr(struct smc_ib_device *smcibdev, u8 ibport)
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 442/877] tipc: Fix a data race on mon->peer_cnt in mon_timeout()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (440 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 441/877] net/smc: fix UAF on lgr list traversal in smcr_port_err() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 443/877] net: ethernet: stmmac: dwmac-rk: fix bulk clock leak when the PHY clock fails Greg Kroah-Hartman
                   ` (442 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ginger Li, Tung Nguyen,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ginger Li <ginger.jzllee@gmail.com>

[ Upstream commit 8e1937fed6738460554ec123c64839e2445e7d53 ]

mon_timeout() evaluates dom_size(mon->peer_cnt) before it takes mon->lock,
while mon->peer_cnt is updated under that lock by tipc_mon_add_peer() and
tipc_mon_remove_peer().  The value can therefore be stale, and the decision
whether the local domain has to be recomputed can be based on an outdated
member count.

Read mon->peer_cnt inside the write_lock_bh(&mon->lock) protected region.

Fixes: 35c55c9877f8 ("tipc: add neighbor monitoring framework")
Signed-off-by: Ginger Li <ginger.jzllee@gmail.com>
Reviewed-by: Tung Nguyen <tung.quang.nguyen@est.tech>
Link: https://patch.msgid.link/20260922080909.21123-1-ginger.jzllee@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/tipc/monitor.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c
index b45c5b91bc7af..5e4585b034970 100644
--- a/net/tipc/monitor.c
+++ b/net/tipc/monitor.c
@@ -632,9 +632,10 @@ static void mon_timeout(struct timer_list *t)
 {
 	struct tipc_monitor *mon = from_timer(mon, t, timer);
 	struct tipc_peer *self;
-	int best_member_cnt = dom_size(mon->peer_cnt) - 1;
+	int best_member_cnt;
 
 	write_lock_bh(&mon->lock);
+	best_member_cnt = dom_size(mon->peer_cnt) - 1;
 	self = mon->self;
 	if (self && (best_member_cnt != self->applied)) {
 		mon_update_local_domain(mon);
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 443/877] net: ethernet: stmmac: dwmac-rk: fix bulk clock leak when the PHY clock fails
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (441 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 442/877] tipc: Fix a data race on mon->peer_cnt in mon_timeout() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 444/877] llc: fix skb UAF and leaks on llc_mac_hdr_init() failure Greg Kroah-Hartman
                   ` (441 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Maxime Chevallier, Heiko Stuebner,
	Lorenzo Bianconi, Coia Prant, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Coia Prant <coiaprant@gmail.com>

[ Upstream commit 8db67bb6a1fffa4df68fbbc22e39943aeeff9178 ]

gmac_clk_enable() enables the bulk clocks first and then the optional
PHY clock. If clk_prepare_enable() on the PHY clock fails, the function
returns without rolling back the bulk clocks, and bsp_priv->clk_enabled
stays false, so the later gmac_clk_enable(bsp_priv, false) becomes a
no-op and the bulk clock references are leaked.

Add the missing clk_bulk_disable_unprepare() on that failure path.

Fixes: ea449f7fa0bf ("net: ethernet: stmmac: dwmac-rk: rework optional clock handling")
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Acked-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Signed-off-by: Coia Prant <coiaprant@gmail.com>
Link: https://patch.msgid.link/20260923123713.3137146-1-coiaprant@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index d152afa48d5c2..e093bf4cd56a8 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1709,8 +1709,11 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
 				return ret;
 
 			ret = clk_prepare_enable(bsp_priv->clk_phy);
-			if (ret)
+			if (ret) {
+				clk_bulk_disable_unprepare(bsp_priv->num_clks,
+							   bsp_priv->clks);
 				return ret;
+			}
 
 			if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
 				bsp_priv->ops->set_clock_selection(bsp_priv,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 444/877] llc: fix skb UAF and leaks on llc_mac_hdr_init() failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (442 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 443/877] net: ethernet: stmmac: dwmac-rk: fix bulk clock leak when the PHY clock fails Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 445/877] bridge: check llc_mac_hdr_init() return value in br_send_bpdu() Greg Kroah-Hartman
                   ` (440 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Jakub Kicinski,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit 72f9dd522f8d6c5a00be9695c7bb74631eb5069e ]

In llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(), if llc_mac_hdr_init()
fails, kfree_skb(skb) is called instead of kfree_skb(nskb). This leaks
the newly allocated nskb, reads from the freed skb via LLC_I_GET_NR(pdu),
and double-frees skb when llc_conn_state_process() drops its reference.

In llc_sap_action_send_xid_r() and llc_sap_action_send_test_r(), nskb is
leaked if llc_mac_hdr_init() returns an error.

Free nskb in all three error paths.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Closes: https://lore.kernel.org/netdev/179022851638.2160803.1808206741379444999@kernel.org/
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260924082951.1599377-2-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/llc/llc_c_ac.c | 2 +-
 net/llc/llc_s_ac.c | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
index 40ca3c1e42a2e..5c8483f63ebbc 100644
--- a/net/llc/llc_c_ac.c
+++ b/net/llc/llc_c_ac.c
@@ -443,7 +443,7 @@ int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
 		if (likely(!rc))
 			llc_conn_send_pdu(sk, nskb);
 		else
-			kfree_skb(skb);
+			kfree_skb(nskb);
 	}
 	if (rc) {
 		nr = LLC_I_GET_NR(pdu);
diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c
index 7a0cae9a81114..cc6fb29a9510a 100644
--- a/net/llc/llc_s_ac.c
+++ b/net/llc/llc_s_ac.c
@@ -127,6 +127,8 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)
 	rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
 	if (likely(!rc))
 		rc = dev_queue_xmit(nskb);
+	else
+		kfree_skb(nskb);
 out:
 	return rc;
 }
@@ -176,6 +178,8 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)
 	rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
 	if (likely(!rc))
 		rc = dev_queue_xmit(nskb);
+	else
+		kfree_skb(nskb);
 out:
 	return rc;
 }
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 445/877] bridge: check llc_mac_hdr_init() return value in br_send_bpdu()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (443 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 444/877] llc: fix skb UAF and leaks on llc_mac_hdr_init() failure Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 446/877] net/sched: sch_teql: fix shadowed err in __teql_resolve() Greg Kroah-Hartman
                   ` (439 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nikolay Aleksandrov, Ido Schimmel,
	bridge, Eric Dumazet, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit ac704ff08e511c87643799c385f55ecd69b85e03 ]

If llc_mac_hdr_init() fails (for instance if the port device type does
not support LLC or dev_hard_header() fails), br_send_bpdu() should drop
the skb instead of resetting the mac header to the LLC payload and
transmitting a malformed frame.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Closes: https://lore.kernel.org/netdev/179022851638.2160803.1808206741379444999@kernel.org/
Cc: Nikolay Aleksandrov <razor@blackwall.org>
Cc: Ido Schimmel <idosch@nvidia.com>
Cc: bridge@lists.linux.dev
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20260924082951.1599377-3-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/bridge/br_stp_bpdu.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index 7895489ac6fe7..e44e448b1157b 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -52,7 +52,10 @@ static void br_send_bpdu(struct net_bridge_port *p,
 			    LLC_SAP_BSPAN, LLC_PDU_CMD);
 	llc_pdu_init_as_ui_cmd(skb);
 
-	llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr);
+	if (llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr)) {
+		kfree_skb(skb);
+		return;
+	}
 
 	skb_reset_mac_header(skb);
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 446/877] net/sched: sch_teql: fix shadowed err in __teql_resolve()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (444 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 445/877] bridge: check llc_mac_hdr_init() return value in br_send_bpdu() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 447/877] vlan: ensure sufficient headroom in vlan_dev_hard_header() Greg Kroah-Hartman
                   ` (438 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jamal Hadi Salim, Jiri Pirko,
	Eric Dumazet, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit 907b978e82cb4c1c245fc2985bb27c5d5c88c8f6 ]

__teql_resolve() declares an inner 'int err;' inside the
'if (neigh_event_send(n, skb_res) == 0)' block, shadowing the outer
'int err = 0;'. As a result, a negative return from dev_hard_header()
is written to the inner variable and __teql_resolve() still returns 0.

Remove the shadowed variable and set the outer err to -EINVAL when
dev_hard_header() returns a negative error.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Closes: https://lore.kernel.org/netdev/179022851638.2160803.1808206741379444999@kernel.org/
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260924082951.1599377-4-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/sched/sch_teql.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index eb424b20027e5..d3baf17ebe6ce 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -265,14 +265,11 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res,
 	}
 
 	if (neigh_event_send(n, skb_res) == 0) {
-		int err;
 		char haddr[MAX_ADDR_LEN];
 
 		neigh_ha_snapshot(haddr, n, dev);
-		err = dev_hard_header(skb, dev, ntohs(skb_protocol(skb, false)),
-				      haddr, NULL, skb->len);
-
-		if (err < 0)
+		if (dev_hard_header(skb, dev, ntohs(skb_protocol(skb, false)),
+				    haddr, NULL, skb->len) < 0)
 			err = -EINVAL;
 	} else {
 		err = (skb_res == NULL) ? -EAGAIN : 1;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 447/877] vlan: ensure sufficient headroom in vlan_dev_hard_header()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (445 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 446/877] net/sched: sch_teql: fix shadowed err in __teql_resolve() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 448/877] autofs: fix sbi->pipe file reference leak in autofs_kill_sb() Greg Kroah-Hartman
                   ` (437 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Zixuan Chai, Hangbin Liu,
	Eric Dumazet, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit cd5dd68267c4238795fadaf02b3575ca3f8a6500 ]

Callers that only reserve ETH_HLEN or less (such as llc_alloc_frame()),
or skbs allocated before dynamic device/headroom changes (e.g. toggling
VLAN_FLAG_REORDER_HDR or bonding/team switching slaves), can reach
vlan_dev_hard_header() with insufficient headroom and trigger
skb_under_panic().

Use skb_cow_head() in vlan_dev_hard_header() when VLAN_FLAG_REORDER_HDR
is not set to ensure sufficient headroom for the VLAN header(s) and the
underlying device hard header.

Use READ_ONCE() to read dev->hard_header_len and dev->needed_headroom as
they can be updated concurrently under RTNL (e.g. in
vlan_transfer_features()) while vlan_dev_hard_header() runs locklessly on
the transmit path. Also avoid LL_RESERVED_SPACE(dev) here so that the
extra HH_DATA_MOD alignment padding does not trigger unnecessary
pskb_expand_head() reallocations on inner stacked VLAN devices after the
outer VLAN header has been pushed.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Zixuan Chai <petalzu987@gmail.com>
Closes: https://lore.kernel.org/netdev/cover.1789987105.git.petalzu987@gmail.com/
Link: https://lore.kernel.org/netdev/179022851638.2160803.1808206741379444999@kernel.org/
Cc: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260924082951.1599377-5-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/8021q/vlan_dev.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index e7e5b903fa8c3..61fb68fadea33 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -54,6 +54,11 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
 	int rc;
 
 	if (!(vlan->flags & VLAN_FLAG_REORDER_HDR)) {
+		unsigned int hlen = READ_ONCE(dev->hard_header_len) +
+				    READ_ONCE(dev->needed_headroom);
+
+		if (skb_cow_head(skb, hlen) < 0)
+			return -ENOMEM;
 		vhdr = skb_push(skb, VLAN_HLEN);
 
 		vlan_tci = vlan->vlan_id;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 448/877] autofs: fix sbi->pipe file reference leak in autofs_kill_sb()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (446 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 447/877] vlan: ensure sufficient headroom in vlan_dev_hard_header() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 449/877] perf/x86/intel: Ensure KVM guest PEBS path doesnt set unwanted PERF_GLOBAL_CTRL bits Greg Kroah-Hartman
                   ` (436 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Hui Peng,
	Christian Brauner (Amutable), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Hui Peng <benquike@gmail.com>

[ Upstream commit aa5e44b29ffe4eaa08cc2237fd65bc2596bc023e ]

When autofs_fill_super() fails before clearing AUTOFS_SBI_CATATONIC (for
example, when find_get_pid() fails on an invalid pgrp mount option, or
when an fs_context is closed before mounting), deactivate_locked_super()
invokes autofs_kill_sb() -> autofs_catatonic_mode(sbi).

Because AUTOFS_SBI_CATATONIC is still set in sbi->flags,
autofs_catatonic_mode() returns early without calling fput(sbi->pipe),
permanently leaking the pipe struct file reference.

Explicitly release sbi->pipe in autofs_kill_sb() if it is still non-NULL
after autofs_catatonic_mode().

Fixes: ebc921ca9b92 ("autofs: copy autofs4 to autofs")
Signed-off-by: Hui Peng <benquike@gmail.com>
Link: https://patch.msgid.link/20260919204808.2812930-1-benquike@gmail.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 fs/autofs/inode.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
index ec3c1ac1c1f9d..7203dba0ebce4 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -51,6 +51,10 @@ void autofs_kill_sb(struct super_block *sb)
 	if (sbi) {
 		/* Free wait queues, close pipe */
 		autofs_catatonic_mode(sbi);
+		if (sbi->pipe) {
+			fput(sbi->pipe);
+			sbi->pipe = NULL;
+		}
 		put_pid(sbi->oz_pgrp);
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 449/877] perf/x86/intel: Ensure KVM guest PEBS path doesnt set unwanted PERF_GLOBAL_CTRL bits
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (447 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 448/877] autofs: fix sbi->pipe file reference leak in autofs_kill_sb() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 450/877] perf/x86/intel: Dont write PEBS_ENABLED on host<=>guest xfers if CPU has PEBS isolation, to fix stuck PEBS_ENABLED Greg Kroah-Hartman
                   ` (435 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sean Christopherson,
	Peter Zijlstra (Intel), Ingo Molnar, Dapeng Mi, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sean Christopherson <seanjc@google.com>

[ Upstream commit cec38d5c098a350dcf084d345025136ade7e6d1e ]

When reinstating PEBS counters into PERF_GLOBAL_CTRL for a KVM guest, mask
the value with perf's desired/original PERF_GLOBAL_CTRL value to ensure
KVM doesn't unintentionally set reserved bits in PERF_GLOBAL_CTRL.  E.g.
if the guest's PEBS_ENABLE value had bit 63, "Enable Precise Store", set,
then using the raw guest PEBS value would propagate bit 63 to the guest's
PERF_GLOBAL_CTRL value (which thankfully would be a failed VM-Entry, not
a VMX Abort).

The only reason this bug isn't reachable is because KVM doesn't support
"Enable Precise Store" (which is probably a KVM bug?), i.e. bit 63 can't
be set in kvm_pmu->pebs_enable and thus not in arr[pebs_enable].guest.  In
other words, this _should_ be a glorified NOP in the current code base.

Fixes: c59a1f106f5c ("KVM: x86/pmu: Add IA32_PEBS_ENABLE MSR emulation for extended PEBS")
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20260921191418.950933-2-seanjc@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/x86/events/intel/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 27001daade100..b4c1875ef1373 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -4355,7 +4355,7 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data)
 		arr[pebs_enable].guest &= ~kvm_pmu->host_cross_mapped_mask;
 		arr[global_ctrl].guest &= ~kvm_pmu->host_cross_mapped_mask;
 		/* Set hw GLOBAL_CTRL bits for PEBS counter when it runs for guest */
-		arr[global_ctrl].guest |= arr[pebs_enable].guest;
+		arr[global_ctrl].guest |= intel_ctrl & arr[pebs_enable].guest;
 	}
 
 	return arr;
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 450/877] perf/x86/intel: Dont write PEBS_ENABLED on host<=>guest xfers if CPU has PEBS isolation, to fix stuck PEBS_ENABLED
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (448 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 449/877] perf/x86/intel: Ensure KVM guest PEBS path doesnt set unwanted PERF_GLOBAL_CTRL bits Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 451/877] perf/x86/intel: Dont pointlessly context switch DS_AREA (and PEBS config) if PEBS is unused Greg Kroah-Hartman
                   ` (434 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sean Christopherson,
	Peter Zijlstra (Intel), Ingo Molnar, Dapeng Mi, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sean Christopherson <seanjc@google.com>

[ Upstream commit 4b64dbdc5861477f148e13d1ed127e7fe7182e4f ]

When filling the list of MSRs to be loaded by KVM on VM-Enter and VM-Exit,
*never* insert an entry for PEBS_ENABLED if the CPU properly isolates PEBS
events, in which case disabling counters via PERF_GLOBAL_CTRL is sufficient
to prevent unwanted PEBS events in the guest (or host).  Because perf loads
PEBS_ENABLE with the unfiltered cpu_hw_events.pebs_enabled, i.e. with both
host and guest masks, there is no need to load different values for the
guest versus host, perf+KVM can and should simply control which counters
are enabled/disabled via PERF_GLOBAL_CTRL.

Avoiding touching PEBS_ENABLED "fixes" a bug where PEBS_ENABLED can end up
with "stuck" bits if a PEBS event is throttled between generating the list
and actually entering the guest (Intel CPUs can't arbtitrarily block NMIs).
Fixes in quotes because leaving PEBS_ENABLED as-is doesn't fix the
underlying problem of perf (via PMIs) being able to modify state after the
perf<=>KVM handoff.

But not writing PEBS_ENABLED is desirable no matter what, as stating the
obvious, leaving PEBS_ENABLED as-is avoids three MSR writes on every VMX
transition: one each on entry/exit, and one more explicit WRMSR to zero
PEBS_ENABLED before VM-Entry (KVM assumes the only reason PEBS_ENABLED is
in the load list is if the CPU lacks PEBS isolation and thus needs a
quiescent period).

Opportunistically add comments to (better) explain the rules for generating
the set of PEBS counters that will be active while the guest is running,
along with a FIXME for the suspected hack-a-fix where perf disables guest
PEBS if _any_ PEBS event is configured to count in the host (commit
854250329c02 ("KVM: x86/pmu: Disable guest PEBS temporarily in two rare
situations") doesn't explain the motivation, at all).

Fixes: c59a1f106f5c ("KVM: x86/pmu: Add IA32_PEBS_ENABLE MSR emulation for extended PEBS")
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20260921191418.950933-3-seanjc@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/x86/events/intel/core.c | 55 ++++++++++++++++++++++++------------
 1 file changed, 37 insertions(+), 18 deletions(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index b4c1875ef1373..573298a35005f 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -4288,12 +4288,15 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data)
 	struct kvm_pmu *kvm_pmu = (struct kvm_pmu *)data;
 	u64 intel_ctrl = hybrid(cpuc->pmu, intel_ctrl);
 	u64 pebs_mask = cpuc->pebs_enabled & x86_pmu.pebs_capable;
-	int global_ctrl, pebs_enable;
+	u64 guest_pebs_mask;
+	int global_ctrl;
 
 	/*
 	 * In addition to obeying exclude_guest/exclude_host, remove bits being
 	 * used for PEBS when running a guest, because PEBS writes to virtual
-	 * addresses (not physical addresses).
+	 * addresses (not physical addresses).  If the guest wants to utilize
+	 * PEBS, and PEBS can be safely enabled in the guest, bits for the guest's
+	 * PEBS-enabled counters will be OR'd back in as appropriate.
 	 */
 	*nr = 0;
 	global_ctrl = (*nr)++;
@@ -4340,24 +4343,40 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data)
 		};
 	}
 
-	pebs_enable = (*nr)++;
-	arr[pebs_enable] = (struct perf_guest_switch_msr){
-		.msr = MSR_IA32_PEBS_ENABLE,
-		.host = cpuc->pebs_enabled & ~cpuc->intel_ctrl_guest_mask,
-		.guest = pebs_mask & ~cpuc->intel_ctrl_host_mask & kvm_pmu->pebs_enable,
-	};
+	/*
+	 * Restrict guest PEBS events to counters that (a) perf supports, (b)
+	 * the guest wants to use for PEBS, (c) are not excluded from counting
+	 * in the guest, and (d) _are_ excluded from counting in the host.
+	 */
+	guest_pebs_mask = pebs_mask & intel_ctrl & kvm_pmu->pebs_enable &
+			  ~cpuc->intel_ctrl_host_mask &
+			  cpuc->intel_ctrl_guest_mask;
 
-	if (arr[pebs_enable].host) {
-		/* Disable guest PEBS if host PEBS is enabled. */
-		arr[pebs_enable].guest = 0;
-	} else {
-		/* Disable guest PEBS thoroughly for cross-mapped PEBS counters. */
-		arr[pebs_enable].guest &= ~kvm_pmu->host_cross_mapped_mask;
-		arr[global_ctrl].guest &= ~kvm_pmu->host_cross_mapped_mask;
-		/* Set hw GLOBAL_CTRL bits for PEBS counter when it runs for guest */
-		arr[global_ctrl].guest |= intel_ctrl & arr[pebs_enable].guest;
-	}
+	/*
+	 * Disable counters where the guest PMC is different than the host PMC
+	 * being used on behalf of the guest, as the PEBS record includes
+	 * PERF_GLOBAL_STATUS, i.e. the guest will see overflow status for the
+	 * wrong counter(s).
+	 */
+	guest_pebs_mask &= ~kvm_pmu->host_cross_mapped_mask;
+
+	/*
+	 * FIXME: Allow guest and host usage of PEBS events to co-exist instead
+	 *        of disabling guest PEBS entirely if the host is using PEBS.
+	 *        What exactly goes wrong if guest and host are using PEBS is
+	 *        unknown.
+	 */
+	if (pebs_mask & ~cpuc->intel_ctrl_guest_mask)
+		guest_pebs_mask = 0;
 
+	/*
+	 * Do NOT mess with PEBS_ENABLED.  As above, disabling counters via
+	 * PERF_GLOBAL_CTRL is sufficient, and loading a stale PEBS_ENABLED,
+	 * e.g. on VM-Exit, can put the system in a bad state.  Simply enable
+	 * counters in PERF_GLOBAL_CTRL, as perf load PEBS_ENABLED with the
+	 * full value, i.e. perf *also* relies on PERF_GLOBAL_CTRL.
+	 */
+	arr[global_ctrl].guest |= guest_pebs_mask;
 	return arr;
 }
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 451/877] perf/x86/intel: Dont pointlessly context switch DS_AREA (and PEBS config) if PEBS is unused
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (449 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 450/877] perf/x86/intel: Dont write PEBS_ENABLED on host<=>guest xfers if CPU has PEBS isolation, to fix stuck PEBS_ENABLED Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 452/877] perf/x86/intel: Make @data a mandatory param for intel_guest_get_msrs() Greg Kroah-Hartman
                   ` (433 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sean Christopherson,
	Peter Zijlstra (Intel), Ingo Molnar, Jim Mattson, Dapeng Mi,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sean Christopherson <seanjc@google.com>

[ Upstream commit d06260e99eb93d2942b7af4ccd789eb8a6c829d3 ]

When filling the list of MSRs to be loaded by KVM on VM-Enter and VM-Exit,
load the guest values for DS_AREA and (conditionally) MSR_PEBS_DATA_CFG if
and only if PEBS will be active in the guest, i.e. only if a PEBS record
may be generated while running the guest.  As shown by the !pebs_ept path,
it's perfectly safe to run with the host's DS_AREA, so long as PEBS-enabled
counters are disabled via PERF_GLOBAL_CTRL.

Omitting DS_AREA and MSR_PEBS_DATA_CFG when PEBS is unused saves two MSR
writes per MSR on each VMX transition, i.e. eliminates two/four pointless
MSR writes on each VMX roundtrip when PEBS isn't being used by the guest.

Fixes: c59a1f106f5c ("KVM: x86/pmu: Add IA32_PEBS_ENABLE MSR emulation for extended PEBS")
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20260921191418.950933-4-seanjc@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/x86/events/intel/core.c | 39 +++++++++++++++++++++++-------------
 1 file changed, 25 insertions(+), 14 deletions(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 573298a35005f..313456a90bcbe 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -4326,23 +4326,14 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data)
 		return arr;
 	}
 
+	/*
+	 * If the guest won't use PEBS or the CPU doesn't support PEBS in the
+	 * guest, then there's nothing more to do as disabling PMCs via
+	 * PERF_GLOBAL_CTRL is sufficient on CPUs with guest/host isolation.
+	 */
 	if (!kvm_pmu || !x86_pmu.pebs_ept)
 		return arr;
 
-	arr[(*nr)++] = (struct perf_guest_switch_msr){
-		.msr = MSR_IA32_DS_AREA,
-		.host = (unsigned long)cpuc->ds,
-		.guest = kvm_pmu->ds_area,
-	};
-
-	if (x86_pmu.intel_cap.pebs_baseline) {
-		arr[(*nr)++] = (struct perf_guest_switch_msr){
-			.msr = MSR_PEBS_DATA_CFG,
-			.host = cpuc->active_pebs_data_cfg,
-			.guest = kvm_pmu->pebs_data_cfg,
-		};
-	}
-
 	/*
 	 * Restrict guest PEBS events to counters that (a) perf supports, (b)
 	 * the guest wants to use for PEBS, (c) are not excluded from counting
@@ -4369,6 +4360,26 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data)
 	if (pebs_mask & ~cpuc->intel_ctrl_guest_mask)
 		guest_pebs_mask = 0;
 
+	/*
+	 * Context switch DS_AREA and PEBS_DATA_CFG if and only if PEBS will be
+	 * active in the guest; if no records will be generated while the guest
+	 * is running, then simply keep the host values resident in hardware.
+	 */
+	arr[(*nr)++] = (struct perf_guest_switch_msr){
+		.msr = MSR_IA32_DS_AREA,
+		.host = (unsigned long)cpuc->ds,
+		.guest = guest_pebs_mask ? kvm_pmu->ds_area : (unsigned long)cpuc->ds,
+	};
+
+	if (x86_pmu.intel_cap.pebs_baseline) {
+		arr[(*nr)++] = (struct perf_guest_switch_msr){
+			.msr = MSR_PEBS_DATA_CFG,
+			.host = cpuc->active_pebs_data_cfg,
+			.guest = guest_pebs_mask ? kvm_pmu->pebs_data_cfg :
+						   cpuc->active_pebs_data_cfg,
+		};
+	}
+
 	/*
 	 * Do NOT mess with PEBS_ENABLED.  As above, disabling counters via
 	 * PERF_GLOBAL_CTRL is sufficient, and loading a stale PEBS_ENABLED,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 452/877] perf/x86/intel: Make @data a mandatory param for intel_guest_get_msrs()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (450 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 451/877] perf/x86/intel: Dont pointlessly context switch DS_AREA (and PEBS config) if PEBS is unused Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 453/877] mptcp: return sk_wait_data() errors from recvmsg() Greg Kroah-Hartman
                   ` (432 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sean Christopherson,
	Peter Zijlstra (Intel), Ingo Molnar, Jim Mattson, Dapeng Mi,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sean Christopherson <seanjc@google.com>

[ Upstream commit a391618e1d563f099e4c2a704f45d08329ccdf7c ]

Drop "support" for passing a NULL @data/@kvm_pmu param when getting guest
MSRs.  KVM, the only in-tree user, unconditionally passes a non-NULL
pointer, and carrying code that suggests @data may be NULL is confusing,
e.g. incorrectly implies that there are scenarios where KVM doesn't pass
a PMU context.

Fixes: 8183a538cd95 ("KVM: x86/pmu: Add IA32_DS_AREA MSR emulation to support guest DS")
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Jim Mattson <jmattson@google.com>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Link: https://patch.msgid.link/20260921191418.950933-5-seanjc@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 arch/x86/events/intel/core.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 313456a90bcbe..8298b5462d49e 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -4327,11 +4327,11 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr, void *data)
 	}
 
 	/*
-	 * If the guest won't use PEBS or the CPU doesn't support PEBS in the
-	 * guest, then there's nothing more to do as disabling PMCs via
-	 * PERF_GLOBAL_CTRL is sufficient on CPUs with guest/host isolation.
+	 * If the CPU doesn't support PEBS in the guest, then there's nothing
+	 * more to do as disabling PMCs via PERF_GLOBAL_CTRL is sufficient on
+	 * CPUs with guest/host isolation.
 	 */
-	if (!kvm_pmu || !x86_pmu.pebs_ept)
+	if (!x86_pmu.pebs_ept)
 		return arr;
 
 	/*
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 453/877] mptcp: return sk_wait_data() errors from recvmsg()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (451 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 452/877] perf/x86/intel: Make @data a mandatory param for intel_guest_get_msrs() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 454/877] rculist: add list_splice_rcu() for private lists Greg Kroah-Hartman
                   ` (431 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mark Amirkan, Matthieu Baerts (NGI0),
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mark Amirkan <markdamirkan@gmail.com>

[ Upstream commit 60404266ef3e0a1cd8f7a164060e0c83efb72f4b ]

Commit 581302298524 ("mptcp: error out earlier on disconnect") made
mptcp_recvmsg() stop when sk_wait_data() returns an error.  The error is
stored in err, but the function then jumps to a path which returns
copied.  When no data was copied, recvmsg() therefore returns zero and
reports a false EOF.

Store the result in copied, which is the value returned by the function.
This also keeps the usual partial-read result when data was copied before
the error.

A recvmsg() blocked in one thread reproduces the issue when another
thread disconnects the same MPTCP socket with connect(AF_UNSPEC).
Before this change recvmsg() returns zero; afterwards it returns -EPIPE.

Fixes: 581302298524 ("mptcp: error out earlier on disconnect")
Cc: stable@vger.kernel.org
Signed-off-by: Mark Amirkan <markdamirkan@gmail.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260913-b4-send-mptcp-recv-error-v1-1-4eaa3684a8b8@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/mptcp/protocol.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index ee160c783ff5a..4e467e7d3b362 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2364,7 +2364,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 		mptcp_cleanup_rbuf(msk, copied);
 		err = sk_wait_data(sk, &timeo, NULL);
 		if (err < 0) {
-			err = copied ? : err;
+			copied = copied ? : err;
 			goto out_err;
 		}
 	}
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 454/877] rculist: add list_splice_rcu() for private lists
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (452 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 453/877] mptcp: return sk_wait_data() errors from recvmsg() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 455/877] netfilter: nf_tables: join hook list via splice_list_rcu() in commit phase Greg Kroah-Hartman
                   ` (430 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Paul E. McKenney, Pablo Neira Ayuso,
	Benjamin Robin (Schneider Electric), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pablo Neira Ayuso <pablo@netfilter.org>

[ Upstream commit f902877b635551513729bdf9a8d1422c4aab7741 ]

This patch adds a helper function, list_splice_rcu(), to safely splice
a private (non-RCU-protected) list into an RCU-protected list.

The function ensures that only the pointer visible to RCU readers
(prev->next) is updated using rcu_assign_pointer(), while the rest of
the list manipulations are performed with regular assignments, as the
source list is private and not visible to concurrent RCU readers.

This is useful for moving elements from a private list into a global
RCU-protected list, ensuring safe publication for RCU readers.
Subsystems with some sort of batching mechanism from userspace can
benefit from this new function.

The function __list_splice_rcu() has been added for clarity and to
follow the same pattern as in the existing list_splice*() interfaces,
where there is a check to ensure that the list to splice is not
empty. Note that __list_splice_rcu() has no documentation for this
reason.

Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Benjamin Robin (Schneider Electric) <benjamin.robin@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/linux/rculist.h | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/include/linux/rculist.h b/include/linux/rculist.h
index 14dfa6008467e..2e4d990f07ad4 100644
--- a/include/linux/rculist.h
+++ b/include/linux/rculist.h
@@ -207,6 +207,35 @@ static inline void list_replace_rcu(struct list_head *old,
 	old->prev = LIST_POISON2;
 }
 
+static inline void __list_splice_rcu(struct list_head *list,
+				     struct list_head *prev,
+				     struct list_head *next)
+{
+	struct list_head *first = list->next;
+	struct list_head *last = list->prev;
+
+	last->next = next;
+	first->prev = prev;
+	next->prev = last;
+	rcu_assign_pointer(list_next_rcu(prev), first);
+}
+
+/**
+ * list_splice_rcu - splice a non-RCU list into an RCU-protected list,
+ *                   designed for stacks.
+ * @list:	the non RCU-protected list to splice
+ * @head:	the place in the existing RCU-protected list to splice
+ *
+ * The list pointed to by @head can be RCU-read traversed concurrently with
+ * this function.
+ */
+static inline void list_splice_rcu(struct list_head *list,
+				   struct list_head *head)
+{
+	if (!list_empty(list))
+		__list_splice_rcu(list, head, head->next);
+}
+
 /**
  * __list_splice_init_rcu - join an RCU-protected list into an existing list.
  * @list:	the RCU-protected list to splice
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 455/877] netfilter: nf_tables: join hook list via splice_list_rcu() in commit phase
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (453 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 454/877] rculist: add list_splice_rcu() for private lists Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 456/877] x86/mce: Fix hardware debug register corruption on task migration Greg Kroah-Hartman
                   ` (429 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Pablo Neira Ayuso, Sasha Levin,
	Benjamin Robin (Schneider Electric)

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pablo Neira Ayuso <pablo@netfilter.org>

[ Upstream commit a6134e62dba2ea4f760b29d5226907f447c92400 ]

Publish new hooks in the list into the basechain/flowtable using
splice_list_rcu() to ensure netlink dump list traversal via rcu is safe
while concurrent ruleset update is going on.

Fixes: 78d9f48f7f44 ("netfilter: nf_tables: add devices to existing flowtable")
Fixes: b9703ed44ffb ("netfilter: nf_tables: support for adding new devices to an existing netdev chain")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Benjamin Robin (Schneider Electric) <benjamin.robin@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/netfilter/nf_tables_api.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index af9df95ddf055..0aa96283385a6 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -10360,8 +10360,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
 				nft_chain_commit_update(nft_trans_container_chain(trans));
 				nf_tables_chain_notify(&ctx, NFT_MSG_NEWCHAIN,
 						       &nft_trans_chain_hooks(trans));
-				list_splice(&nft_trans_chain_hooks(trans),
-					    &nft_trans_basechain(trans)->hook_list);
+				list_splice_rcu(&nft_trans_chain_hooks(trans),
+						&nft_trans_basechain(trans)->hook_list);
 				/* trans destroyed after rcu grace period */
 			} else {
 				nft_chain_commit_drop_policy(nft_trans_container_chain(trans));
@@ -10513,8 +10513,8 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
 							   nft_trans_flowtable(trans),
 							   &nft_trans_flowtable_hooks(trans),
 							   NFT_MSG_NEWFLOWTABLE);
-				list_splice(&nft_trans_flowtable_hooks(trans),
-					    &nft_trans_flowtable(trans)->hook_list);
+				list_splice_rcu(&nft_trans_flowtable_hooks(trans),
+						&nft_trans_flowtable(trans)->hook_list);
 			} else {
 				nft_clear(net, nft_trans_flowtable(trans));
 				nf_tables_flowtable_notify(&ctx,
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 456/877] x86/mce: Fix hardware debug register corruption on task migration
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (454 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 455/877] netfilter: nf_tables: join hook list via splice_list_rcu() in commit phase Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 457/877] x86/PCI: Disable enhanced atomics on AMD NBIO 7.7 and 7.11 Greg Kroah-Hartman
                   ` (428 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Masami Hiramatsu (Google),
	Borislav Petkov (AMD), Peter Zijlstra (Intel), stable

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Masami Hiramatsu (Google) <mhiramat@kernel.org>

commit b8d1d5b63a8ef532038eebd9d97d406860385668 upstream.

In exc_machine_check_user(), local_db_save() and local_db_restore() are
invoked in the outer entry stubs (DEFINE_IDTENTRY_MCE_USER,
DEFINE_FREDENTRY_MCE, and DEFINE_IDTENTRY_RAW), surrounding
exc_machine_check_user().

However, exc_machine_check_user() calls irqentry_exit_to_user_mode(), which
handles pending thread work and may schedule() if TIF_NEED_RESCHED is set. If
the task migrates to another CPU during schedule(), local_db_restore() runs on
the new CPU with the dr7 state saved from the old CPU. This corrupts the new
CPU's DR7 hardware debug register and leaves the old CPU's DR7 disabled.  In
short, local_db_save() and local_db_restore() pair must be run on the same
CPU.

To fix this, move local_db_save() and local_db_restore() inside
exc_machine_check_user() and exc_machine_check_kernel(). In
exc_machine_check_user(), DR7 is saved and restored strictly around
do_machine_check() to avoid schedule() during migration. In
exc_machine_check_kernel(), local_db_save() is called at the entry point to
prevent early memory accesses from triggering nested #DB exceptions, and
restored on all exits.

Fixes: cd840e424f27 ("x86/entry, mce: Disallow #DB during #MC")
Assisted-by: LLM
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: <stable@kernel.org>
Link: https://patch.msgid.link/179005109564.388919.3937970081044095776.stgit@devnote2
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/kernel/cpu/mce/core.c |   27 ++++++++++-----------------
 1 file changed, 10 insertions(+), 17 deletions(-)

--- a/arch/x86/kernel/cpu/mce/core.c
+++ b/arch/x86/kernel/cpu/mce/core.c
@@ -2135,6 +2135,9 @@ bool filter_mce(struct mce *m)
 static __always_inline void exc_machine_check_kernel(struct pt_regs *regs)
 {
 	irqentry_state_t irq_state;
+	unsigned long dr7;
+
+	dr7 = local_db_save();
 
 	WARN_ON_ONCE(user_mode(regs));
 
@@ -2143,20 +2146,26 @@ static __always_inline void exc_machine_
 	 * mce_check_crashing_cpu() for details.
 	 */
 	if (mca_cfg.initialized && mce_check_crashing_cpu())
-		return;
+		goto out;
 
 	irq_state = irqentry_nmi_enter(regs);
 
 	do_machine_check(regs);
 
 	irqentry_nmi_exit(regs, irq_state);
+out:
+	local_db_restore(dr7);
 }
 
 static __always_inline void exc_machine_check_user(struct pt_regs *regs)
 {
+	unsigned long dr7;
+
 	irqentry_enter_from_user_mode(regs);
 
+	dr7 = local_db_save();
 	do_machine_check(regs);
+	local_db_restore(dr7);
 
 	irqentry_exit_to_user_mode(regs);
 }
@@ -2165,21 +2174,13 @@ static __always_inline void exc_machine_
 /* MCE hit kernel mode */
 DEFINE_IDTENTRY_MCE(exc_machine_check)
 {
-	unsigned long dr7;
-
-	dr7 = local_db_save();
 	exc_machine_check_kernel(regs);
-	local_db_restore(dr7);
 }
 
 /* The user mode variant. */
 DEFINE_IDTENTRY_MCE_USER(exc_machine_check)
 {
-	unsigned long dr7;
-
-	dr7 = local_db_save();
 	exc_machine_check_user(regs);
-	local_db_restore(dr7);
 }
 
 #ifdef CONFIG_X86_FRED
@@ -2196,28 +2197,20 @@ DEFINE_IDTENTRY_MCE_USER(exc_machine_che
  */
 DEFINE_FREDENTRY_MCE(exc_machine_check)
 {
-	unsigned long dr7;
-
-	dr7 = local_db_save();
 	if (user_mode(regs))
 		exc_machine_check_user(regs);
 	else
 		exc_machine_check_kernel(regs);
-	local_db_restore(dr7);
 }
 #endif
 #else
 /* 32bit unified entry point */
 DEFINE_IDTENTRY_RAW(exc_machine_check)
 {
-	unsigned long dr7;
-
-	dr7 = local_db_save();
 	if (user_mode(regs))
 		exc_machine_check_user(regs);
 	else
 		exc_machine_check_kernel(regs);
-	local_db_restore(dr7);
 }
 #endif
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 457/877] x86/PCI: Disable enhanced atomics on AMD NBIO 7.7 and 7.11
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (455 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 456/877] x86/mce: Fix hardware debug register corruption on task migration Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 458/877] virtio_net: copy zerocopy frags in start_xmit without NAPI Greg Kroah-Hartman
                   ` (427 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mikael Etienne, Arthur Husband,
	Alvin Lim, Mario Limonciello, Bjorn Helgaas, David Laight,
	John Smith, Lennert Buytenhek, Niklas Cassel, Roland Waltersson

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mario Limonciello <mario.limonciello@amd.com>

commit 4fde448225123442c5796f54b7a4400e2d3cbaf6 upstream.

Multiple users report data corruption during 64-bit DMA transfers on
systems with AMD NBIO 7.7 and 7.11 controllers.

This occurs when BIOS enables AMD "enhanced atomic operations" on PCIe Root
Ports. When enhanced atomics are enabled, any 64-bit DMA access may be
corrupted.

Disable enhanced atomics using SMN for NBIO 7.7 and 7.11 based models.

Reported-by: Mikael Etienne <mikael1022bzh@gmail.com>
Closes: https://lore.kernel.org/178789300872.392066.15963676631650361573@gmail.com/
Reported-by: Arthur Husband <artmoty@gmail.com>
Closes: https://lore.kernel.org/20260406222335.379935-1-artmoty@gmail.com/
Reported-by: Alvin Lim <alvinwylim@gmail.com>
Closes: https://lore.kernel.org/20260621100844.1224301-1-alvinwylim@gmail.com/
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
[bhelgaas: commit log, s/IOVA/DMA/ in comment]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org
Cc: David Laight <david.laight.linux@gmail.com>
Cc: John Smith <imjohnsmith4000@gmail.com>
Cc: Lennert Buytenhek <kernel@wantstofly.org>
Cc: Niklas Cassel <cassel@kernel.org>
Cc: Roland Waltersson <roland.waltersson@netinsight.net>
Link: https://patch.msgid.link/20260908190600.226485-2-mario.limonciello@amd.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/pci/fixup.c |   99 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

--- a/arch/x86/pci/fixup.c
+++ b/arch/x86/pci/fixup.c
@@ -846,6 +846,105 @@ static void quirk_clear_strap_no_soft_re
 	}
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x15b8, quirk_clear_strap_no_soft_reset_dev2_f0);
+
+/*
+ * Enhanced atomic operations can cause corruption with 64-bit DMA
+ * on these devices.
+ */
+#define RX_ENH_ATOMIC_EN		BIT(8)
+
+static const u32 nbio_7_7_pcie_smn_addrs[] = {
+	0x111401d0,
+	0x111411d0,
+	0x111421d0,
+	0x111431d0,
+	0x111441d0,
+	0x112401d0,
+	0x112411d0,
+	0x112421d0,
+	0x112431d0,
+	0x112441d0,
+	0x112451d0,
+	0x113401d0,
+	0x114401d0,
+};
+
+static const u32 nbio_7_11_pcie_smn_addrs[] = {
+	0x112401d0,
+	0x112411d0,
+	0x112421d0,
+	0x112431d0,
+	0x112441d0,
+	0x112451d0,
+	0x113401d0,
+	0x113411d0,
+	0x113421d0,
+	0x113431d0,
+	0x113441d0,
+	0x113451d0,
+};
+
+static void quirk_amd_nbio_enhanced_atomic(struct pci_dev *host_bridge,
+					   const u32 *smn_addrs,
+					   size_t nr_smn_addrs)
+{
+	bool changed = false;
+	size_t i;
+	u32 data;
+	int ret;
+
+	for (i = 0; i < nr_smn_addrs; i++) {
+		ret = amd_smn_read(0, smn_addrs[i], &data);
+		if (ret)
+			continue;
+		if (!(data & RX_ENH_ATOMIC_EN))
+			continue;
+		data = data & ~RX_ENH_ATOMIC_EN;
+		ret = amd_smn_write(0, smn_addrs[i], data);
+		if (ret)
+			continue;
+		if (changed)
+			continue;
+		ret = amd_smn_read(0, smn_addrs[i], &data);
+		if (ret)
+			continue;
+		if (data & RX_ENH_ATOMIC_EN)
+			continue;
+		changed = true;
+	}
+
+	if (changed)
+		pci_info(host_bridge, "enhanced atomics disabled\n");
+}
+
+static void quirk_amd_nbio_7_7_disable_enhanced_atomic(struct pci_dev *dev)
+{
+	quirk_amd_nbio_enhanced_atomic(dev, nbio_7_7_pcie_smn_addrs,
+				       ARRAY_SIZE(nbio_7_7_pcie_smn_addrs));
+}
+
+static void quirk_amd_nbio_7_11_disable_enhanced_atomic(struct pci_dev *dev)
+{
+	quirk_amd_nbio_enhanced_atomic(dev, nbio_7_11_pcie_smn_addrs,
+				       ARRAY_SIZE(nbio_7_11_pcie_smn_addrs));
+}
+
+/* Phoenix, Hawk Point (NBIO 7.7) */
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x14E8,
+			quirk_amd_nbio_7_7_disable_enhanced_atomic);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x14E8,
+			quirk_amd_nbio_7_7_disable_enhanced_atomic);
+
+/* Strix, Krackan, Strix Halo (NBIO 7.11) */
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1507,
+			quirk_amd_nbio_7_11_disable_enhanced_atomic);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1507,
+			quirk_amd_nbio_7_11_disable_enhanced_atomic);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x1122,
+			quirk_amd_nbio_7_11_disable_enhanced_atomic);
+DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1122,
+			quirk_amd_nbio_7_11_disable_enhanced_atomic);
+
 #endif
 
 /*



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 458/877] virtio_net: copy zerocopy frags in start_xmit without NAPI
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (456 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 457/877] x86/PCI: Disable enhanced atomics on AMD NBIO 7.7 and 7.11 Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 459/877] tipc: reject invalid and unexpected GRP_ACK_MSG to prevent bc_ackers underflow Greg Kroah-Hartman
                   ` (426 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, mst, jasowangio, Willem de Bruijn,
	Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Willem de Bruijn <willemb@google.com>

commit 07e1a9408b6c2f9d0cfb757b67dabb52da7a32b2 upstream.

Virtio-net without NAPI frees completed skbs lazily on the next
start_xmit. Senders waiting for in-flight zerocopy buffers can
deadlock if they cannot transmit more packets, as then no
completed packets will be freed.

When !use_napi, virtio-net already calls skb_orphan to avoid waiting
up for transmitted skbs to be freed. For zerocopy packets that
require deep copying on orphan (i.e. those that do not set
SKBFL_DONT_ORPHAN, such as PACKET_TX_RING), call skb_orphan_frags
before orphaning to release the buffers.

This fixes the tpacket_snd slot reuse bug on skb_orphan for
virtio-net, and prevents PACKET_TX_RING from running out of slots.

This fix also touches vhost_net zerocopy packets, which also do not
set SKBFL_DONT_ORPHAN. This is fine: vhost_net packets only encounter
virtio-net in nested virtualization, and only if napi_tx is
explicitly disabled (it has been default-enabled since Linux 4.12).
In that rare case, copying the frags is desirable anyway to prevent
holding guest descriptors pinned across unbounded intervals.

This is a prerequisite for the next patch, which converts
PACKET_TX_RING to standard zerocopy completion. Without this patch
first, a bounded ring sender can stall indefinitely behind a
virtio-net virtqueue that cannot reclaim.

Fixes: 5cd8d46ea156 ("packet: copy user buffers before orphan or clone")
Cc: stable@vger.kernel.org
Cc: mst@redhat.com
Cc: jasowangio@gmail.com
Signed-off-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260919004748.1463985-2-willemdebruijn.kernel@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/virtio_net.c |    9 +++++++++
 1 file changed, 9 insertions(+)

--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -3141,6 +3141,14 @@ static netdev_tx_t start_xmit(struct sk_
 	} while (use_napi && !xmit_more &&
 	       unlikely(!virtqueue_enable_cb_delayed(sq->vq)));
 
+	if (!use_napi &&
+	    unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) {
+		DEV_STATS_INC(dev, tx_dropped);
+		dev_kfree_skb_any(skb);
+		kick = !xmit_more || netif_xmit_stopped(txq);
+		goto kick_vq;
+	}
+
 	/* timestamp packet in software */
 	skb_tx_timestamp(skb);
 
@@ -3170,6 +3178,7 @@ static netdev_tx_t start_xmit(struct sk_
 
 	kick = use_napi ? __netdev_tx_sent_queue(txq, skb->len, xmit_more) :
 			  !xmit_more || netif_xmit_stopped(txq);
+kick_vq:
 	if (kick) {
 		if (virtqueue_kick_prepare(sq->vq) && virtqueue_notify(sq->vq)) {
 			u64_stats_update_begin(&sq->stats.syncp);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 459/877] tipc: reject invalid and unexpected GRP_ACK_MSG to prevent bc_ackers underflow
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (457 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 458/877] virtio_net: copy zerocopy frags in start_xmit without NAPI Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 460/877] tcp: prevent collapsing skbs across boundary in rtx queue Greg Kroah-Hartman
                   ` (425 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, James Burton, Eric Dumazet,
	Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <edumazet@google.com>

commit 99cc2a62e07a44a22254d7beca9ef1f8ad886d0d upstream.

Commit 48a5fe38772b ("tipc: fix bc_ackers underflow on duplicate
GRP_ACK_MSG") rejected duplicate/stale ACKs in tipc_group_proto_rcv()
by returning early when less_eq(acked, m->bc_acked).

However, that check remains incomplete in two ways:

1. When grp->bc_ackers is zero (e.g. on a quiet group, when replicast
   ACKs were not requested, or after all expected members have already
   acknowledged), an unexpected GRP_ACK_MSG with acked > m->bc_acked
   passes less_eq() and unconditionally decrements grp->bc_ackers.
   Because bc_ackers is a u16, this wraps to 65535, causing
   tipc_group_bc_cong() to permanently report congestion and blocking
   all future group broadcasts on the socket.

2. During an active broadcast round (grp->bc_ackers > 0), the sender
   transmits packet S and advances grp->bc_snd_nxt to S + 1. Receivers
   increment their expected counter to S + 1 upon consuming packet S,
   so the only valid ACK value for the current round is strictly
   acked == grp->bc_snd_nxt.

   However, tipc_group_update_bc_members() initializes each member's
   m->bc_acked to prev = grp->bc_snd_nxt - 1 (S - 1 before increment).
   This leaves a 2-sequence gap (S - 1 to S + 1) in sequence space.
   An incoming ACK is therefore neither rejected as duplicate nor
   prevented from decrementing grp->bc_ackers if an unexpected or stale
   value (such as S) is received. A member sending acked = S followed
   by acked = S + 1 could decrement grp->bc_ackers twice in the same
   round, prematurely clearing bc_ackers or underflowing it.

Fix this by:
- Dropping GRP_ACK_MSG immediately if grp->bc_ackers is zero.
- Requiring acked == grp->bc_snd_nxt and rejecting duplicates where
  m->bc_acked == acked. Because replicast broadcast rounds are strictly
  sequential, only grp->bc_snd_nxt can be acknowledged, and each member
  can acknowledge at most once per round.

Note that a related pre-existing issue in tipc_group_delete_member()
(where grp->bc_ackers decrementing to zero upon member departure does
not restore *grp->open or trigger a socket wakeup) will be addressed
in a separate patch.

Fixes: 48a5fe38772b ("tipc: fix bc_ackers underflow on duplicate GRP_ACK_MSG")
Fixes: 2f487712b893 ("tipc: guarantee that group broadcast doesn't bypass group unicast")
Reported-by: James Burton <jamesburton@meta.com>
Cc: stable@vger.kernel.org
Signed-off-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260913044233.193927-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/tipc/group.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/net/tipc/group.c
+++ b/net/tipc/group.c
@@ -797,10 +797,10 @@ void tipc_group_proto_rcv(struct tipc_gr
 		tipc_group_open(m, usr_wakeup);
 		return;
 	case GRP_ACK_MSG:
-		if (!m)
+		if (!m || !grp->bc_ackers)
 			return;
 		acked = msg_grp_bc_acked(hdr);
-		if (less_eq(acked, m->bc_acked))
+		if (acked != grp->bc_snd_nxt || m->bc_acked == acked)
 			return;
 		m->bc_acked = acked;
 		if (--grp->bc_ackers)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 460/877] tcp: prevent collapsing skbs across boundary in rtx queue
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (458 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 459/877] tipc: reject invalid and unexpected GRP_ACK_MSG to prevent bc_ackers underflow Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 461/877] sctp: discard the rest of the packet on a stale-cookie error Greg Kroah-Hartman
                   ` (424 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Willem de Bruijn, Eric Dumazet,
	Daniel Zahka, Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Willem de Bruijn <willemb@google.com>

commit fc6d80eb504458d6416b75a94188b268c95c6533 upstream.

tcp_write_collapse_fence() sets TCP_SKB_CB(skb)->eor = 1 on
tcp_write_queue_tail(sk) to prevent skbs queued after a switch to
device encryption from being collapsed into earlier skbs.

The fence is a no-op if all earlier data has already been transmitted
when the switch happens: sk->sk_write_queue is empty. The not yet
acknowledged earlier skbs wait in sk->tcp_rtx_queue with eor 0.

On a subsequent retransmit or SACK shift, tcp_retrans_try_collapse() or
tcp_shift_skb_data() can then merge an skb queued after the switch into
one queued before it.

Both users of the fence are affected:

- psp: devices only encrypt skbs with skb->decrypted set. The merged skb
  keeps decrypted = 0 from the earlier skb, so merged data sent after
  psp_sock_assoc_set_tx() is retransmitted in cleartext.

- tls device offload: the merged skb straddles the start marker set in
  tls_set_device_offload(). The software fallback (fill_sg_in() returns
  -EINVAL) and the mlx5, nfp and funeth drivers cannot handle such an
  skb and drop it. Every retransmit rebuilds the same skb, so the
  connection stalls.

Fix this in two places, for defense in depth:

1. Fall back to tcp_rtx_queue_tail(sk) in tcp_write_collapse_fence()
   when tcp_write_queue_tail(sk) is NULL.

2. Check !skb_cmp_decrypted(to, from) in tcp_skb_can_collapse(), as
   tcp_skb_can_collapse_rx() does on receive. skb_shift(), which both
   collapse paths call, already has a DEBUG_NET_WARN_ON_ONCE() for this
   condition.

Fixes: e8f69799810c ("net/tls: Add generic NIC offload infrastructure")
Cc: stable@vger.kernel.org
Signed-off-by: Willem de Bruijn <willemb@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Daniel Zahka <daniel.zahka@gmail.com>
Link: https://patch.msgid.link/20260924154427.953800-1-willemdebruijn.kernel@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/net/tcp.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1058,9 +1058,9 @@ static inline bool tcp_skb_can_collapse_
 static inline bool tcp_skb_can_collapse(const struct sk_buff *to,
 					const struct sk_buff *from)
 {
-	/* skb_cmp_decrypted() not needed, use tcp_write_collapse_fence() */
 	return likely(tcp_skb_can_collapse_to(to) &&
 		      mptcp_skb_can_collapse(to, from) &&
+		      !skb_cmp_decrypted(to, from) &&
 		      skb_pure_zcopy_same(to, from) &&
 		      skb_frags_readable(to) == skb_frags_readable(from));
 }
@@ -2119,7 +2119,7 @@ static inline void tcp_rtx_queue_unlink_
 
 static inline void tcp_write_collapse_fence(struct sock *sk)
 {
-	struct sk_buff *skb = tcp_write_queue_tail(sk);
+	struct sk_buff *skb = tcp_write_queue_tail(sk) ?: tcp_rtx_queue_tail(sk);
 
 	if (skb)
 		TCP_SKB_CB(skb)->eor = 1;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 461/877] sctp: discard the rest of the packet on a stale-cookie error
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (459 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 460/877] tcp: prevent collapsing skbs across boundary in rtx queue Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 462/877] af_packet: fix integer overflow in prb_calc_retire_blk_tmo() Greg Kroah-Hartman
                   ` (423 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Xin Long, TencentOS Corvus AI,
	Aohan Mei, Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Aohan Mei <henrymei@tencent.com>

commit 4498467a8af06cfa3d71cb04bd7c4170dec8f449 upstream.

When an association is in COOKIE-ECHOED state and the peer sends a
bundled [ERROR(Stale Cookie)][DATA] packet from one of its non-primary
addresses, processing the ERROR chunk takes the non-fatal stale-cookie
retry path sctp_sf_do_5_2_6_stale(), which queues
SCTP_CMD_DEL_NON_PRIMARY while keeping the association alive.
sctp_cmd_del_non_primary() removes every non-primary transport -
including the very transport this packet arrived on, which is still
referenced by the receive lookup and shared by all chunks of the
packet via chunk->transport.

sctp_assoc_rm_peer() does redirect asoc->peer.last_data_from away from
the removed transport, but right afterwards the bundled DATA chunk
makes sctp_assoc_bh_rcv() re-register
asoc->peer.last_data_from = chunk->transport unconditionally, undoing
the redirection with the just-removed transport.

Once the packet is done, the receive reference is dropped and the
transport is RCU-freed, while the surviving association keeps the
dangling last_data_from.  A later FWD-TSN (or the delayed SACK timer)
makes sctp_gen_sack() dereference it (->param_flags and friends), and
sctp_make_sack()/sctp_outq_select_transport() may write to the freed
object and link it into the live transport list.  This is a
use-after-free triggerable by any malicious SCTP peer (or a local
unprivileged user acting as one) with no capabilities required:

  BUG: KASAN: slab-use-after-free in sctp_do_sm+0x498a/0x5660
  Read of size 4 at addr ffff88800e1e356c by task poc/115
  Call Trace: sctp_do_sm <- sctp_assoc_bh_rcv <- sctp_inq_push <-
              sctp_rcv <- ip_protocol_deliver_rcu <- ip_rcv
  Allocated: sctp_transport_new <- sctp_assoc_add_peer <-
             sctp_process_init (INIT-ACK processing)
  Freed: kfree <- sctp_transport_destroy_rcu <- rcu_core
         (call_rcu queued by sctp_transport_put at end of sctp_rcv)
  The buggy address is located 364 bytes inside of freed 1024-byte
  region [ffff88800e1e3400, ffff88800e1e3800), cache kmalloc-1k

Note that commit 03a9d10ecf71 ("sctp: drop a chunk if its transport
was removed") only covers the window between the receive lookup and
the chunk processing (e.g. an ASCONF DEL-IP racing the socket backlog);
here the transport is removed *while* the packet is being processed,
by an earlier chunk of the same packet, so the drop in sctp_inq_push()
does not reach this path.  Verified with the bundled [ERROR(Stale
Cookie)][DATA] + FWD-TSN reproducer: the KASAN report above still
fires with that commit applied, and is gone with this patch on top.

Fix it by discarding the rest of the packet on this path, as suggested
by Xin.  After the stale-cookie ERROR has sent the association back to
COOKIE-WAIT and removed the non-primary transports, the remaining
chunks of the packet can only run against the restarted handshake
while referencing the removed arrival transport through
chunk->transport: besides the last_data_from registration above,
sctp_cmd_setup_t2() and the sctp_make_*() reply builders would also
copy that pointer into association-lifetime state that
sctp_assoc_rm_peer() has already sanitized.  Let the peer retransmit
them, in line with what sctp_inq_push() does for chunks whose
transport was removed before processing.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Suggested-by: Xin Long <lucien.xin@gmail.com>
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Cc: stable@vger.kernel.org
Signed-off-by: Aohan Mei <henrymei@tencent.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20260921093707.1432184-1-ljp1205831794@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/sctp/sm_statefuns.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -2624,6 +2624,8 @@ static enum sctp_disposition sctp_sf_do_
 
 	sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(reply));
 
+	sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL());
+
 	return SCTP_DISPOSITION_CONSUME;
 
 nomem:



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 462/877] af_packet: fix integer overflow in prb_calc_retire_blk_tmo()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (460 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 461/877] sctp: discard the rest of the packet on a stale-cookie error Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 463/877] ata: libata-scsi: bound the ATA passthru sense descriptor writes Greg Kroah-Hartman
                   ` (422 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Dairui Zhang, Willem de Bruijn,
	Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dairui Zhang <zhangdairui@gmail.com>

commit 56d82862a0a243ac14ba11b6d7b57ddc2d064b95 upstream.

prb_calc_retire_blk_tmo() computes in 32-bit int arithmetic:

        mbits = (blk_size_in_bytes * 8) / (1024 * 1024);

If I'm reading the validation right, tp_block_size is user
controlled and packet_set_ring() only rejects values that are <= 0
as int or not page aligned, so a 256MiB block goes right through
(and alloc_one_pg_vec_page() even has a vzalloc fallback for it).
0x10000000 * 8 wraps to INT_MIN, and on a NIC reporting 1 Gbps
(div == 1) the function ends up returning -2047.

The condition is actually (8 * size) mod 2^32 >= 2^31 && div == 1,
so the trigger set is [256,512), [768,1024), [1280,1536) and
[1792,2048) MiB. Other sizes wrap to non-negative values and faster
links divide the unsigned value back below 2^31, which is why this
doesn't blow up for everyone.

What makes it fatal is what happens next in init_prb_bdqc():

        p1->interval_ktime = ms_to_ktime(prb_calc_retire_blk_tmo(...));
        hrtimer_start(&p1->retire_blk_timer, p1->interval_ktime,
                      HRTIMER_MODE_REL_SOFT);

A negative relative timeout expires immediately. The callback
unconditionally returns HRTIMER_RESTART, and hrtimer_forward() turns
the negative interval into hrtimer_resolution:

        if (interval < hrtimer_resolution)
                interval = hrtimer_resolution;

So the SOFT timer re-fires at the maximum rate forever, holding
sk_receive_queue.lock each pass. One CPU spins in softirq until the
socket is closed. Repeat with more rings and the machine is gone.

The overflow itself is ancient - it was introduced together with
TPACKET_V3 in f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer
implementation."). Its effect prior to f7460d2989fa ("net:
af_packet: Use hrtimer to do the retire operation", v6.18) was not
as clear-cut, though: the return value was stored into an unsigned
short retire_blk_tov, so a negative result was truncated, and a
0-jiffy delay loop could be programmed as well. Neither is nearly
as detrimental as the immediate maximum-rate spin the hrtimer
conversion turned it into.

(Unrelated to CVE-2019-20812 - that one was the ethtool failure path
returning 0, which now returns DEFAULT_PRB_RETIRE_TOV.)

Reproducer, needs CAP_NET_RAW (a --network host container has it by
default) and a 1 Gbps NIC (QEMU e1000 works):

        int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
        bind(fd, ...);
        int v = TPACKET_V3;
        setsockopt(fd, SOL_PACKET, PACKET_VERSION, &v, sizeof(v));
        struct tpacket_req3 req = {
                .tp_block_size = 0x10000000,
                .tp_block_nr = 1,
                .tp_frame_size = 2048,
                .tp_frame_nr = 0x10000000 / 2048,
                .tp_retire_blk_tov = 0,
        };
        setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req));

Compute in 64 bits instead. The operands are already bounded by the
existing validation, so nothing else changes. If you'd prefer a
different fix, just say so and I'll respin.

Fixes: f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.")
Cc: stable@vger.kernel.org
Signed-off-by: Dairui Zhang <zhangdairui@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260923050101.1510064-1-zhangdairui@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/packet/af_packet.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -636,7 +636,7 @@ static int prb_calc_retire_blk_tmo(struc
 		return DEFAULT_PRB_RETIRE_TOV;
 
 	div = ecmd.base.speed / 1000;
-	mbits = (blk_size_in_bytes * 8) / (1024 * 1024);
+	mbits = (u64)blk_size_in_bytes * 8 / (1024 * 1024);
 
 	if (div)
 		mbits /= div;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 463/877] ata: libata-scsi: bound the ATA passthru sense descriptor writes
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (461 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 462/877] af_packet: fix integer overflow in prb_calc_retire_blk_tmo() Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 464/877] cgroup/pids: Restore pids.events notifications in local mode Greg Kroah-Hartman
                   ` (421 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Damien Le Moal, Matthias Goergens,
	Niklas Cassel

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Matthias Goergens <matthias.goergens@gmail.com>

commit 80320b278fea07ffcda3f57b67b61658e0a4e1ca upstream.

When an ATA PASS-THROUGH command to an ATAPI device fails, the sense
buffer holds the device's REQUEST SENSE reply, and
ata_scsi_set_passthru_sense_fields() trusts its additional length
byte, sb[7], when adding the ATA Status Return descriptor.  A faulty
or malicious device can use that to make the kernel read and write
past the 96-byte buffer in three ways:

- scsi_sense_desc_find() is passed sb[7] + 8 as the buffer length, so
  its clamp against sb[7] does nothing and the walk runs off the end.
- A type-9 descriptor found near the end is filled in unchecked.
- A new descriptor at sb[8 + len] needs len + 22 bytes, not len + 14,
  so len 75..82 writes up to 8 bytes past the end.

Reproduced with KASAN under qemu, with the emulated ATAPI REQUEST SENSE
reply patched:

  BUG: KASAN: slab-out-of-bounds in scsi_sense_desc_find+0x1a5/0x210
  BUG: KASAN: slab-out-of-bounds in ata_scsi_qc_complete+0x1a15/0x1a50

Both are gone with this patch, and a valid descriptor is still filled
in.

Fixes: 97981926224a ("ata: libata-scsi: Do not overwrite valid sense data when CK_COND=1")
Cc: stable@vger.kernel.org
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com>
Link: https://lore.kernel.org/r/20260923175203.1576825-1-matthias.goergens@gmail.com
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/ata/libata-scsi.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -257,12 +257,18 @@ static void ata_scsi_set_passthru_sense_
 
 		/* descriptor format */
 		len = sb[7];
-		desc = (char *)scsi_sense_desc_find(sb, len + 8, 9);
+		desc = (char *)scsi_sense_desc_find(sb, SCSI_SENSE_BUFFERSIZE, 9);
 		if (!desc) {
-			if (SCSI_SENSE_BUFFERSIZE < len + 14)
+			/*
+			 * The descriptor is written at sb[8 + len] and is 14
+			 * bytes long, so it needs len + 22 bytes of buffer.
+			 */
+			if (len + 22 > SCSI_SENSE_BUFFERSIZE)
 				return;
 			sb[7] = len + 14;
 			desc = sb + 8 + len;
+		} else if (desc - sb > SCSI_SENSE_BUFFERSIZE - 14) {
+			return;
 		}
 		desc[0] = 9;
 		desc[1] = 12;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 464/877] cgroup/pids: Restore pids.events notifications in local mode
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (462 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 463/877] ata: libata-scsi: bound the ATA passthru sense descriptor writes Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 465/877] fou: reject omitted FOU_ATTR_IPPROTO on FOU_ENCAP_DIRECT Greg Kroah-Hartman
                   ` (420 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Guopeng Zhang, Tejun Heo

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Guopeng Zhang <zhangguopeng@kylinos.cn>

commit 1765a153d985c231357145e26798f9408db10e42 upstream.

A fork rejected by the pids controller increments the counter reported by
pids.events. When local event accounting is selected, however, pids_event()
returns after notifying only events_local_file, leaving pids.events pollers
asleep.

On legacy hierarchies, pids.events.local does not exist. With
pids_localevents, pids.events reports the same local counter. In both
cases, pids.events changes without generating a notification.

This can be reproduced with a pids_localevents mount:

    mkdir /tmp/test
    mount -t cgroup2 -o pids_localevents none /tmp/test
    mkdir /tmp/test/t
    echo 1 > /tmp/test/t/pids.max
    cat /tmp/test/t/pids.events                 # max 0
    timeout 3 inotifywait -e modify /tmp/test/t/pids.events &
    sh -c 'echo $$ > /tmp/test/t/cgroup.procs; (true &)' 2>/dev/null
    wait
    cat /tmp/test/t/pids.events                 # max 1

Without this patch, inotifywait times out without reporting an event.
Notify pids.events before returning from the local event path.

Fixes: 3f26a885a068 ("cgroup/pids: Add pids.events.local")
Cc: stable@vger.kernel.org # v6.11+
Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/cgroup/pids.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/kernel/cgroup/pids.c b/kernel/cgroup/pids.c
index ecbb839d2acb..78cdc0558d0c 100644
--- a/kernel/cgroup/pids.c
+++ b/kernel/cgroup/pids.c
@@ -253,6 +253,11 @@ static void pids_event(struct pids_cgroup *pids_forking,
 	}
 	if (!cgroup_subsys_on_dfl(pids_cgrp_subsys) ||
 	    cgrp_dfl_root.flags & CGRP_ROOT_PIDS_LOCAL_EVENTS) {
+		/*
+		 * pids.events reports the local counter on legacy hierarchies
+		 * and when pids_localevents is enabled.
+		 */
+		cgroup_file_notify(&p->events_file);
 		cgroup_file_notify(&p->events_local_file);
 		return;
 	}
-- 
2.55.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 465/877] fou: reject omitted FOU_ATTR_IPPROTO on FOU_ENCAP_DIRECT
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (463 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 464/877] cgroup/pids: Restore pids.events notifications in local mode Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 466/877] fs/ntfs3: use d_instantiate_new() in ntfs_create_inode() and murder syzbots "WARNING in do_new_mount" saga Greg Kroah-Hartman
                   ` (419 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Hui Peng, Hangbin Liu,
	Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Hui Peng <benquike@gmail.com>

commit d22609f3d13fc5baacd92c222731b03c593401db upstream.

Commit 7a9bc9e3f423 ("fou: Don't allow 0 for FOU_ATTR_IPPROTO.") added
NLA_POLICY_MIN(NLA_U8, 1) to fou_nl_policy[FOU_ATTR_IPPROTO], which
rejects an explicitly supplied FOU_ATTR_IPPROTO == 0 attribute with
-ERANGE.

However, FOU_ATTR_IPPROTO is an optional netlink attribute. When a user
sends FOU_CMD_ADD with FOU_ATTR_TYPE set to FOU_ENCAP_DIRECT and omits
FOU_ATTR_IPPROTO entirely, nla_policy validation succeeds and
parse_nl_config() leaves cfg->protocol as 0 (from memset(cfg, 0,
sizeof(*cfg))). fou_create() then creates a FOU_ENCAP_DIRECT socket with
fou->protocol == 0.

In fou_udp_recv(), returning -fou->protocol to udp_queue_rcv_one_skb()
triggers IP protocol resubmission when fou->protocol > 0, whereas
returning 0 tells the UDP tunnel layer that the skb was consumed without
freeing it. When fou->protocol == 0, every packet received on the socket
returns 0 from fou_udp_recv() and leaks the sk_buff.

Reject FOU_ENCAP_DIRECT when !cfg->protocol in fou_create() so that
creating a direct encapsulation port without FOU_ATTR_IPPROTO fails with
-EINVAL while leaving FOU_CMD_DEL and FOU_CMD_GET (which share
parse_nl_config()) unaffected.

Tested in QEMU against Linux 7.3.0-rc3 by sending a FOU_CMD_ADD Generic
Netlink request with FOU_ATTR_PORT = 5555 and FOU_ATTR_TYPE =
FOU_ENCAP_DIRECT while omitting FOU_ATTR_IPPROTO. On the unfixed kernel,
FOU_CMD_ADD succeeds (err = 0), FOU_CMD_GET reports fou->type = 1 and
fou->protocol = 0, and sending 4000 UDP packets to 127.0.0.1:5555 leaks
all 4000 sk_buffs (SUnreclaim in /proc/meminfo grows from 41456 kB to
59008 kB, +17552 kB); with this patch applied, FOU_CMD_ADD is rejected
with -EINVAL (-22).

Fixes: 23461551c006 ("fou: Support for foo-over-udp RX path")
Fixes: 7a9bc9e3f423 ("fou: Don't allow 0 for FOU_ATTR_IPPROTO.")
Cc: stable@vger.kernel.org
Signed-off-by: Hui Peng <benquike@gmail.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260921045920.1613098-1-benquike@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv4/fou_core.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/net/ipv4/fou_core.c
+++ b/net/ipv4/fou_core.c
@@ -607,6 +607,10 @@ static int fou_create(struct net *net, s
 	/* Initial for fou type */
 	switch (cfg->type) {
 	case FOU_ENCAP_DIRECT:
+		if (!cfg->protocol) {
+			err = -EINVAL;
+			goto error;
+		}
 		tunnel_cfg.encap_rcv = fou_udp_recv;
 		tunnel_cfg.gro_receive = fou_gro_receive;
 		tunnel_cfg.gro_complete = fou_gro_complete;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 466/877] fs/ntfs3: use d_instantiate_new() in ntfs_create_inode() and murder syzbots "WARNING in do_new_mount" saga
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (464 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 465/877] fou: reject omitted FOU_ATTR_IPPROTO on FOU_ENCAP_DIRECT Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 467/877] writeback: bound cleanup_offline_cgwb() rescans by rotating scanned inodes Greg Kroah-Hartman
                   ` (418 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jan Kara,
	syzbot+2a13ad6914e6fcec716c, Christian Brauner (Amutable)

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Christian Brauner <brauner@kernel.org>

commit 1abd643f3783ea8f8e273c18697ff0413aa92dc7 upstream.

ntfs_create_inode() creates a new inode via ntfs_new_inode(). It hashes
it with insert_inode_locked() and so it's marked as I_NEW until
unlock_new_inode().

ntfs 3 calls d_instantiate() in between though... Since the dentry was
already hashed by the lookup before the create any path walk finds it
without touching the parent's i_rwsem and so can lock the inode.

If the inode is a directory unlock_new_inode() calls
lockdep_annotate_inode_mutex_key() and marks i_rwsem with the
i_mutex_dir_key class.

That resets the count and the owner of a lock somebody else may already
hold by now...

syzbot has been spamming us with the same godforsaken bug

  "WARNING in do_new_mount"

since 2023. I can't take it anymore so I went looking. Afaict, syzbot's
executor chdirs into a freshly mounted ntfs3 image, creates a
directory and then mounts some pseudofs on it. Everytime the mkdir()
takes longer than syzbot waits mount() runs concurrently:

  mkdir("./sys")                        mount(NULL, "./sys", "sysfs")
  ntfs_create_inode()
    d_instantiate()
                                        user_path_at() finds the dentry
                                        do_lock_mount()
                                          inode_lock(inode)
                                          namespace_lock()
    unlock_new_inode()
      lockdep_annotate_inode_mutex_key()
        init_rwsem(&inode->i_rwsem)
                                        unlock_mount()
                                          inode_unlock(inode)

The mount side then releases a lock that according to the rwsem nobody
holds:

  DEBUG_RWSEMS_WARN_ON((rwsem_owner(sem) != current) && ...):
  count = 0x0, magic = 0xffff888043a854e8, owner = 0x0,
  curr 0xffff888000244880, list empty
  WARNING: CPU: 0 PID: 5346 at kernel/locking/rwsem.c:1368 __up_write
  Call Trace:
   inode_unlock include/linux/fs.h:877 [inline]
   unlock_mount fs/namespace.c:2892 [inline]
   do_new_mount_fc fs/namespace.c:3828 [inline]
   do_new_mount+0x777/0xa40 fs/namespace.c:3887

On PREEMPT_RT the same thing shows up as

  DEBUG_LOCKS_WARN_ON(rt_mutex_owner(lock) != current)
  WARNING: kernel/locking/rtmutex_common.h:193 at rt_mutex_slowunlock

The up_write() underflows the reset count. A following inode_lock() on
that directory then never returns. A path walk into the new directory
racing with the mkdir() corrupts the lock the same way via
inode_lock_shared() in lookup_slow().

Switch to d_instantiate_new() and drop the trailing unlock_new_inode().
All error paths bail out before that point with I_NEW still set and
keep using discard_new_inode().

May we never see this fscking bug report again.

Link: https://patch.msgid.link/20260909-work-ntfs3-d_instantiate_new-v1-1-2db697162ce8@kernel.org
Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block")
Reviewed-by: Jan Kara <jack@suse.cz>
Cc: stable@vger.kernel.org # v5.15+
Reported-by: syzbot+2a13ad6914e6fcec716c@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/6a9beced.a5e650b3.26d8a.000b.GAE@google.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/ntfs3/inode.c |    7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

--- a/fs/ntfs3/inode.c
+++ b/fs/ntfs3/inode.c
@@ -1677,10 +1677,10 @@ int ntfs_create_inode(struct mnt_idmap *
 		goto out6;
 
 	/*
-	 * Call 'd_instantiate' after inode->i_op is set
+	 * Call 'd_instantiate_new' after inode->i_op is set
 	 * but before finish_open.
 	 */
-	d_instantiate(dentry, inode);
+	d_instantiate_new(dentry, inode);
 
 	/* Set original time. inode times (i_ctime) may be changed in ntfs_init_acl. */
 	inode_set_atime_to_ts(inode, ni->i_crtime);
@@ -1728,9 +1728,6 @@ out1:
 	if (!fnd)
 		ni_unlock(dir_ni);
 
-	if (!err)
-		unlock_new_inode(inode);
-
 	return err;
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 467/877] writeback: bound cleanup_offline_cgwb() rescans by rotating scanned inodes
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (465 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 466/877] fs/ntfs3: use d_instantiate_new() in ntfs_create_inode() and murder syzbots "WARNING in do_new_mount" saga Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:22 ` [PATCH 6.12 468/877] workqueue: Fix NULL current_pwq deref in flush dependency check Greg Kroah-Hartman
                   ` (417 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Tejun Heo, Roman Gushchin,
	Patrick Lu (Anthropic), Jan Kara, Christian Brauner (Amutable)

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Patrick Lu (Anthropic) <perf.patrick.lu@gmail.com>

commit f6988c90671e83db79df1b7b9d6fdb0e5947fd84 upstream.

cleanup_offline_cgwb() prepares at most WB_MAX_INODES_PER_ISW inodes
per call and is called again until the dying wb is drained, but every
call walks wb->b_attached and then wb->b_dirty_time from the same end.
Inodes already prepared (they stay on the list with I_WB_SWITCH set
until the switch worker runs) and inodes that cannot be switched
(I_FREEING, I_WILL_FREE, !SB_ACTIVE, DAX, already on the target wb)
stay where they are, so each pass rescans a growing run of them under
wb->list_lock and a full drain is quadratic in the number of inodes on
the list. With ~17M inodes attached to one dying cgwb we saw this end
in soft lockups, with CPUs reported stuck for 21-48s.

Walk both lists from the oldest end and move every scanned inode to
the newest end, so the next pass starts where the previous one stopped
and the drain becomes linear. b_attached is unordered, so nobody sees
the reorder there. b_dirty_time is ordered by dirtied_when, but the
oldest unscanned inode stays at the end move_expired_inodes() picks
from, sync takes the whole list regardless of order, and prepared
inodes leave the list as soon as the switch work runs and get a new
dirtied_time_when on the new wb anyway, so the only inodes left out of
order are the ones that can never switch (DAX), and only on the dying
wb.

Fixes: c22d70a162d3 ("writeback, cgroup: release dying cgwbs by switching attached inodes")
Cc: stable@vger.kernel.org
Acked-by: Tejun Heo <tj@kernel.org>
Acked-by: Roman Gushchin <roman.gushchin@linux.dev>
Signed-off-by: Patrick Lu (Anthropic) <perf.patrick.lu@gmail.com>
Link: https://patch.msgid.link/20260911-wb-cgwb-rotate-v2-1-a9ab253a1295@gmail.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/fs-writeback.c |   25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -693,19 +693,34 @@ static bool isw_prepare_wbs_switch(struc
 				   struct inode_switch_wbs_context *isw,
 				   struct list_head *list, int *nr)
 {
-	struct inode *inode;
+	struct inode *inode, *tmp;
+	LIST_HEAD(scanned);
+	bool full = false;
+
+	/*
+	 * Walk from the oldest end and move scanned inodes to the newest
+	 * end, so the next scan resumes at unscanned inodes instead of
+	 * re-walking an ever-growing run of prepared and skipped ones.
+	 * For b_dirty_time this keeps the oldest unscanned inode at the
+	 * end move_expired_inodes() picks from; b_attached is unordered.
+	 */
+	list_for_each_entry_safe_reverse(inode, tmp, list, i_io_list) {
+		list_move(&inode->i_io_list, &scanned);
 
-	list_for_each_entry(inode, list, i_io_list) {
 		if (!inode_prepare_wbs_switch(inode, new_wb))
 			continue;
 
 		isw->inodes[*nr] = inode;
 		(*nr)++;
 
-		if (*nr >= WB_MAX_INODES_PER_ISW - 1)
-			return true;
+		if (*nr >= WB_MAX_INODES_PER_ISW - 1) {
+			full = true;
+			break;
+		}
 	}
-	return false;
+	list_splice(&scanned, list);
+
+	return full;
 }
 
 /**



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 468/877] workqueue: Fix NULL current_pwq deref in flush dependency check
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (466 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 467/877] writeback: bound cleanup_offline_cgwb() rescans by rotating scanned inodes Greg Kroah-Hartman
@ 2026-09-30 15:22 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 469/877] writeback: report a Tasks-RCU quiescent state per cgwb drain pass Greg Kroah-Hartman
                   ` (416 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:22 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Pavankumar Kondeti, Tejun Heo

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pavankumar Kondeti <pavan.kondeti@oss.qualcomm.com>

commit db6365ced4d5855e321f772b240c0e473bcfcdd5 upstream.

check_flush_dependency() uses current_wq_worker() to determine whether
the caller is a workqueue worker and then dereferences worker->current_pwq
to test whether the current workqueue is WQ_MEM_RECLAIM.

current_wq_worker() only means that %current has PF_WQ_WORKER set. A
kworker can reach check_flush_dependency() while it is not executing a
work item. One such path is worker_thread() acting as the pool manager,
where create_worker() does GFP_KERNEL allocation and the allocation path
invokes the OOM notifier. In that state worker->current_pwq is NULL
because current_pwq is set only by process_one_work() and cleared again
after the work function returns.

[  416.760634][  T375] Call trace:
[  416.760638][  T375]  check_flush_dependency+0x80/0x120 (P)
[  416.760648][  T375]  __flush_work+0x98/0x224
[  416.760657][  T375]  flush_work+0x30/0x44
[  416.760665][  T375]  ...
[  416.760710][  T375]  blocking_notifier_call_chain+0x58/0xa0
[  416.760719][  T375]  out_of_memory+0xb4/0x458
[  416.760730][  T375]  __alloc_pages_may_oom+0x11c/0x1a8
[  416.760739][  T375]  __alloc_pages_slowpath+0x314/0x46c
[  416.760746][  T375]  __alloc_frozen_pages_noprof+0x110/0x1a4
[  416.760753][  T375]  new_slab+0x12c/0x484
[  416.760759][  T375]  ___slab_alloc+0x7a8/0xc7c
[  416.760765][  T375]  __slab_alloc+0x74/0xd8
[  416.760772][  T375]  __kmalloc_cache_node_noprof+0x2ac/0x304
[  416.760779][  T375]  alloc_worker+0x28/0x60
[  416.760785][  T375]  create_worker+0x4c/0x20c
[  416.760790][  T375]  worker_thread+0xe8/0x2b8
[  416.760796][  T375]  kthread+0x1a8/0x200
[  416.760805][  T375]  ret_from_fork+0x10/0x20

Guard the WQ_MEM_RECLAIM-worker warning with worker->current_pwq. If the
kworker is not currently executing a work item, there is no current
workqueue to diagnose with that warning. The PF_MEMALLOC warning is left
unchanged so explicit reclaim context flushing a !WQ_MEM_RECLAIM target
is still reported.

Fixes: fca839c00a12 ("workqueue: warn if memory reclaim tries to flush !WQ_MEM_RECLAIM workqueue")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Pavankumar Kondeti <pavan.kondeti@oss.qualcomm.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/workqueue.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3762,7 +3762,7 @@ static void check_flush_dependency(struc
 	WARN_ONCE(current->flags & PF_MEMALLOC,
 		  "workqueue: PF_MEMALLOC task %d(%s) is flushing !WQ_MEM_RECLAIM %s:%ps",
 		  current->pid, current->comm, target_wq->name, target_func);
-	WARN_ONCE(worker && ((worker->current_pwq->wq->flags &
+	WARN_ONCE(worker && worker->current_pwq && ((worker->current_pwq->wq->flags &
 			      (WQ_MEM_RECLAIM | __WQ_LEGACY)) == WQ_MEM_RECLAIM),
 		  "workqueue: WQ_MEM_RECLAIM %s:%ps is flushing !WQ_MEM_RECLAIM %s:%ps",
 		  worker->current_pwq->wq->name, worker->current_func,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 469/877] writeback: report a Tasks-RCU quiescent state per cgwb drain pass
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (467 preceding siblings ...)
  2026-09-30 15:22 ` [PATCH 6.12 468/877] workqueue: Fix NULL current_pwq deref in flush dependency check Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 470/877] fsl/fman: Fix clk reference leak in read_dts_node() Greg Kroah-Hartman
                   ` (415 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Josef Bacik, Andrew Morton,
	Tejun Heo, Roman Gushchin, Jan Kara, Lorenzo Stoakes (ARM),
	David Hildenbrand, Dennis Zhou, Liam R. Howlett,
	Matthew Wilcox (Oracle), Michal Hocko, Mike Rapoport,
	Paul E . McKenney, Suren Baghdasaryan, Vlastimil Babka

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Josef Bacik <josef@toxicpanda.com>

commit 407a5d205179a4ab186571b0e16ec42725dc77bc upstream.

cleanup_offline_cgwbs_workfn() drains a dying cgwb by calling
cleanup_offline_cgwb() until it returns false, with a cond_resched()
between passes.  On a CONFIG_PREEMPTION kernel that cond_resched() does
nothing: _cond_resched() is a plain "return 0", and under PREEMPT_DYNAMIC
the full and lazy modes disable it.  Since commit 7dadeaa6e851 ("sched:
Further restrict the preemption modes") those are the only two models on
the architectures with PREEMPT_LAZY support, arm64 and x86 among them, so
the drain loop never reports a Tasks-RCU quiescent state.

A worker draining a cgwb with millions of attached inodes runs for
minutes.  On a 6.18 arm64 host in lazy mode the cgwb worker drained one
dying cgroup's writeback domain for over 11 minutes.  A BPF program unlink
(bpf_trampoline_unlink_prog -> bpf_trampoline_update ->
unregister_ftrace_direct -> ftrace_shutdown -> synchronize_rcu_tasks())
waited on that grace period while holding the trampoline mutex, 42 tasks
queued behind it in D state, and the hung task detector fired at 614 s and
panicked the host.  Any BPF or ftrace detach during a long drain inherits
the drain's length.

Fix this by calling cond_resched_tasks_rcu_qs() so we do not stall out
anybody who calls sycnrhonize_rcu_tasks().  We put this in a do { } while
loop because if we have many small cgroups cleanup_offline_cgwb() will
return false and we will never call cond_resched_tasks_rcu_qs(), creating
the same problem.

Link: https://lore.kernel.org/20260909-cgwb-tasks-rcu-qs-v1-1-967a7754771f@toxicpanda.com
Fixes: c22d70a162d3 ("writeback, cgroup: release dying cgwbs by switching attached inodes")
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Link: https://lore.kernel.org/bpf/9d444098-7c03-4163-af12-bd0a79a51443@paulmck-laptop/
Assisted-by: LLM
Acked-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Roman Gushchin <roman.gushchin@linux.dev>
Reviewed-by: Jan Kara <jack@suse.cz>
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: "Paul E . McKenney" <paulmck@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 mm/backing-dev.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -910,8 +910,9 @@ static void cleanup_offline_cgwbs_workfn
 			continue;
 
 		spin_unlock_irq(&cgwb_lock);
-		while (cleanup_offline_cgwb(wb))
-			cond_resched();
+		do {
+			cond_resched_tasks_rcu_qs();
+		} while (cleanup_offline_cgwb(wb));
 		spin_lock_irq(&cgwb_lock);
 
 		wb_put(wb);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 470/877] fsl/fman: Fix clk reference leak in read_dts_node()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (468 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 469/877] writeback: report a Tasks-RCU quiescent state per cgwb drain pass Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 471/877] ipe: protect the dm-verity root hash with RCU Greg Kroah-Hartman
                   ` (414 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Simon Horman,
	Paolo Abeni

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wentao Liang <vulab@iscas.ac.cn>

commit a644f09b2090ad22a13fbcf9d141084f573108ef upstream.

of_clk_get() returns a clock with its reference count incremented, but
read_dts_node() only uses it to read the rate and never calls clk_put().
The clock is not stored anywhere, so the reference cannot be released
later either.

Release the clock once its rate has been read, which also covers the
error path taken when the rate is zero.

Fixes: 414fd46e7762 ("fsl/fman: Add FMan support")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260917110135.2148068-1-vulab@iscas.ac.cn
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/freescale/fman/fman.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/net/ethernet/freescale/fman/fman.c
+++ b/drivers/net/ethernet/freescale/fman/fman.c
@@ -2747,6 +2747,7 @@ static struct fman *read_dts_node(struct
 	}
 
 	clk_rate = clk_get_rate(clk);
+	clk_put(clk);
 	if (!clk_rate) {
 		err = -EINVAL;
 		dev_err(&of_dev->dev, "%s: Failed to determine FM%d clock rate\n",



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 471/877] ipe: protect the dm-verity root hash with RCU
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (469 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 470/877] fsl/fman: Fix clk reference leak in read_dts_node() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 472/877] ipv6: do not let ipv6_find_hdr() return an offset past the packet end Greg Kroah-Hartman
                   ` (413 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Fan Wu <wufan@kernel.org>

commit 2776e9c28513a1c855a94792b292cbcc533418c8 upstream.

ipe_bdev_setintegrity() frees the old root hash when dm-verity publishes
a new one on ->preresume, while policy evaluation can still be
dereferencing it.

Protect the root hash with RCU. The evaluation path already runs under
rcu_read_lock().

Fixes: e155858dd995 ("ipe: add support for dm-verity as a trust provider")
Cc: stable@vger.kernel.org
Assisted-by: LLM
[FW: remove model name according to latest guideline]
Signed-off-by: Fan Wu <wufan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 security/ipe/eval.c  |   12 ++++++++----
 security/ipe/eval.h  |    2 +-
 security/ipe/hooks.c |   22 +++++++++++++++++-----
 3 files changed, 26 insertions(+), 10 deletions(-)

--- a/security/ipe/eval.c
+++ b/security/ipe/eval.c
@@ -134,10 +134,14 @@ static bool evaluate_boot_verified(const
 static bool evaluate_dmv_roothash(const struct ipe_eval_ctx *const ctx,
 				  struct ipe_prop *p)
 {
-	return !!ctx->ipe_bdev &&
-	       !!ctx->ipe_bdev->root_hash &&
-	       ipe_digest_eval(p->value,
-			       ctx->ipe_bdev->root_hash);
+	const struct digest_info *root_hash;
+
+	if (!ctx->ipe_bdev)
+		return false;
+
+	root_hash = rcu_dereference(ctx->ipe_bdev->root_hash);
+
+	return root_hash && ipe_digest_eval(p->value, root_hash);
 }
 #else
 static bool evaluate_dmv_roothash(const struct ipe_eval_ctx *const ctx,
--- a/security/ipe/eval.h
+++ b/security/ipe/eval.h
@@ -27,7 +27,7 @@ struct ipe_bdev {
 #ifdef CONFIG_IPE_PROP_DM_VERITY_SIGNATURE
 	bool dm_verity_signed;
 #endif /* CONFIG_IPE_PROP_DM_VERITY_SIGNATURE */
-	struct digest_info *root_hash;
+	struct digest_info __rcu *root_hash;
 };
 #endif /* CONFIG_IPE_PROP_DM_VERITY */
 
--- a/security/ipe/hooks.c
+++ b/security/ipe/hooks.c
@@ -9,6 +9,7 @@
 #include <linux/binfmts.h>
 #include <linux/mman.h>
 #include <linux/blk_types.h>
+#include <linux/rcupdate.h>
 
 #include "ipe.h"
 #include "hooks.h"
@@ -204,7 +205,20 @@ void ipe_bdev_free_security(struct block
 {
 	struct ipe_bdev *blob = ipe_bdev(bdev);
 
-	ipe_digest_free(blob->root_hash);
+	ipe_digest_free(rcu_access_pointer(blob->root_hash));
+}
+
+static void ipe_set_dmverity_roothash(struct ipe_bdev *blob,
+				      struct digest_info *info)
+{
+	struct digest_info *old;
+
+	/* Protected by device-mapper's md->suspend_lock */
+	old = rcu_replace_pointer(blob->root_hash, info, true);
+	if (old) {
+		synchronize_rcu();
+		ipe_digest_free(old);
+	}
 }
 
 #ifdef CONFIG_IPE_PROP_DM_VERITY_SIGNATURE
@@ -252,8 +266,7 @@ int ipe_bdev_setintegrity(struct block_d
 		return -EINVAL;
 
 	if (!value) {
-		ipe_digest_free(blob->root_hash);
-		blob->root_hash = NULL;
+		ipe_set_dmverity_roothash(blob, NULL);
 
 		return 0;
 	}
@@ -273,8 +286,7 @@ int ipe_bdev_setintegrity(struct block_d
 
 	info->digest_len = digest->digest_len;
 
-	ipe_digest_free(blob->root_hash);
-	blob->root_hash = info;
+	ipe_set_dmverity_roothash(blob, info);
 
 	return 0;
 err:



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 472/877] ipv6: do not let ipv6_find_hdr() return an offset past the packet end
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (470 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 471/877] ipe: protect the dm-verity root hash with RCU Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 473/877] ipv6: sr: enforce exact attribute length for SEG6_ATTR_DST Greg Kroah-Hartman
                   ` (412 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ilya Maximets, Eric Dumazet,
	Norbert Szetei, Ido Schimmel, Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Norbert Szetei <norbert@doyensec.com>

commit ee319bd3a0e976af5087cbe59ebc50a66f31d202 upstream.

ipv6_find_hdr() walks the extension header chain, skipping each header by
the length that header itself declares.  ipv6_optlen() returns up to 2048,
and the skip is never checked against skb->len, so the offset stored in
*offset can point past the end of the packet.

openvswitch installs that offset as the transport header, and
update_ipv6_checksum() then reads and writes the transport checksum field
out of bounds:

  BUG: KASAN: slab-use-after-free in inet_proto_csum_replace16+0x445/0x470
  Read of size 2 at addr ffff88810b754b06 by task ovs_ipv6_oob/629
  CPU: 4 UID: 1000 PID: 629 Comm: ovs_ipv6_oob Tainted: G N 7.3.0-rc3+ #348
  Call Trace:
   inet_proto_csum_replace16+0x445/0x470
   set_ipv6_addr+0x3dd/0x460
   do_execute_actions+0x6a3d/0x7c40
   ovs_execute_actions+0xfd/0x480
   ovs_packet_cmd_execute+0xc38/0xf20
   genl_rcv_msg+0x59e/0x870
   netlink_rcv_skb+0x18b/0x450
   genl_rcv+0x2d/0x40
   netlink_unicast+0x6bc/0xa20

  The buggy address belongs to the object at ffff88810b754980
   which belongs to the cache skbuff_small_head of size 704
  The buggy address is located 390 bytes inside of
   freed 704-byte region [ffff88810b754980, ffff88810b754c40)

Other callers use that offset too, so bound it here rather than in one
caller.

Reject a header whose declared length does not fit in the packet.
ipv6_find_hdr() already fails with -EBADMSG on a malformed chain, so this
adds no new failure mode.

Fixes: f8f626754ebe ("ipv6: Move ipv6_find_hdr() out of Netfilter code.")
Suggested-by: Ilya Maximets <i.maximets@ovn.org>
Suggested-by: Eric Dumazet <edumazet@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Link: https://patch.msgid.link/8F80BA1A-DDFD-432D-9075-242A3435FEB5@doyensec.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv6/exthdrs_core.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/net/ipv6/exthdrs_core.c
+++ b/net/ipv6/exthdrs_core.c
@@ -271,6 +271,9 @@ int ipv6_find_hdr(const struct sk_buff *
 			hdrlen = ipv6_optlen(hp);
 
 		if (!found) {
+			if (skb->len - start < hdrlen)
+				return -EBADMSG;
+
 			nexthdr = hp->nexthdr;
 			start += hdrlen;
 		}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 473/877] ipv6: sr: enforce exact attribute length for SEG6_ATTR_DST
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (471 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 472/877] ipv6: do not let ipv6_find_hdr() return an offset past the packet end Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 474/877] gpio: arizona: Fix runtime PM leak in arizona_gpio_direction_out() Greg Kroah-Hartman
                   ` (411 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Hui Peng, Hangbin Liu, Justin Iurman,
	Andrea Mayer, Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Hui Peng <benquike@gmail.com>

commit 2d959c75c27f90e9ec489d18ce5ee6b852ad4741 upstream.

In seg6_genl_policy, SEG6_ATTR_DST is defined with .type = NLA_BINARY and
.len = sizeof(struct in6_addr). For NLA_BINARY, .len only enforces the
maximum payload length and permits shorter payloads (e.g., 0 bytes).
When seg6_genl_set_tunsrc() copies sizeof(struct in6_addr) bytes via
kmemdup(val, sizeof(*val), GFP_KERNEL), a short SEG6_ATTR_DST attribute
triggers a 16-byte out-of-bounds read past skb->tail into uninitialized
skb->head memory, which is stored in sdata->tun_src and leaked back to
userspace via SEG6_CMD_GET_TUNSRC.

Switch SEG6_ATTR_DST in seg6_genl_policy to
NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)) so that generic netlink
validation rejects any attribute whose length is not exactly
sizeof(struct in6_addr) with -ERANGE.

Tested in QEMU against Linux 7.3.0-rc3 by sending a SEG6_CMD_SET_TUNSRC
Generic Netlink message with a 0-byte SEG6_ATTR_DST attribute followed
by SEG6_CMD_GET_TUNSRC. On the unfixed kernel, SEG6_CMD_SET_TUNSRC
succeeds (err = 0) and SEG6_CMD_GET_TUNSRC leaks 16 bytes of
uninitialized kernel heap memory (tun_src =
836a61ecc4d25a1042a8d60411cfb378); with this patch applied,
SEG6_CMD_SET_TUNSRC is rejected by netlink policy validation with
-ERANGE (-34) and tun_src remains zeroed.

Fixes: 915d7e5e5930 ("ipv6: sr: add code base for control plane support of SR-IPv6")
Cc: stable@vger.kernel.org
Signed-off-by: Hui Peng <benquike@gmail.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Reviewed-by: Justin Iurman <justin.iurman@gmail.com>
Reviewed-by: Andrea Mayer <andrea.mayer@uniroma2.it>
Link: https://patch.msgid.link/20260921044025.1535982-1-benquike@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv6/seg6.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/net/ipv6/seg6.c
+++ b/net/ipv6/seg6.c
@@ -138,8 +138,8 @@ out:
 static struct genl_family seg6_genl_family;
 
 static const struct nla_policy seg6_genl_policy[SEG6_ATTR_MAX + 1] = {
-	[SEG6_ATTR_DST]				= { .type = NLA_BINARY,
-		.len = sizeof(struct in6_addr) },
+	[SEG6_ATTR_DST]				=
+		NLA_POLICY_EXACT_LEN(sizeof(struct in6_addr)),
 	[SEG6_ATTR_DSTLEN]			= { .type = NLA_S32, },
 	[SEG6_ATTR_HMACKEYID]		= { .type = NLA_U32, },
 	[SEG6_ATTR_SECRET]			= { .type = NLA_BINARY, },



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 474/877] gpio: arizona: Fix runtime PM leak in arizona_gpio_direction_out()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (472 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 473/877] ipv6: sr: enforce exact attribute length for SEG6_ATTR_DST Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 475/877] gpio: zynq: fix runtime PM leak on request error path Greg Kroah-Hartman
                   ` (410 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Wentao Liang, Charles Keepax,
	Bartosz Golaszewski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wentao Liang <vulab@iscas.ac.cn>

commit e9d810279f84b30738f7790c0ed15f8dd5b9024a upstream.

Switching a persistent GPIO line from input to output acquires a
runtime PM reference on the parent device, but if the subsequent
regmap_update_bits() fails the reference is never dropped and no later
direction_in() can balance it since the direction was never changed.
Drop the reference on the update failure path.

Fixes: 27a49ed17e22 ("gpio: arizona: Add support for GPIOs that need to be maintained")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://patch.msgid.link/20260916094701.2007509-1-vulab@iscas.ac.cn
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpio/gpio-arizona.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

--- a/drivers/gpio/gpio-arizona.c
+++ b/drivers/gpio/gpio-arizona.c
@@ -117,8 +117,12 @@ static int arizona_gpio_direction_out(st
 	if (value)
 		value = ARIZONA_GPN_LVL;
 
-	return regmap_update_bits(arizona->regmap, ARIZONA_GPIO1_CTRL + offset,
-				  ARIZONA_GPN_DIR | ARIZONA_GPN_LVL, value);
+	ret = regmap_update_bits(arizona->regmap, ARIZONA_GPIO1_CTRL + offset,
+				 ARIZONA_GPN_DIR | ARIZONA_GPN_LVL, value);
+	if (ret < 0 && (val & ARIZONA_GPN_DIR) && persistent)
+		pm_runtime_put_autosuspend(chip->parent);
+
+	return ret;
 }
 
 static void arizona_gpio_set(struct gpio_chip *chip, unsigned offset, int value)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 475/877] gpio: zynq: fix runtime PM leak on request error path
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (473 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 474/877] gpio: arizona: Fix runtime PM leak in arizona_gpio_direction_out() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 476/877] llc: reserve device headroom for allocated frames Greg Kroah-Hartman
                   ` (409 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Ridham Khurana, Bartosz Golaszewski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ridham Khurana <khurana.ridham222@gmail.com>

commit e9438ab5328a177c9c0e5df87eb92a7162841e98 upstream.

pm_runtime_get_sync() leaves the usage counter incremented even when it
fails, and zynq_gpio_request() returns the error without dropping it.

gpiolib does not call ->free() when ->request() fails, so zynq_gpio_free(),
which holds the only matching pm_runtime_put(), never runs. The reference
is leaked and the controller can no longer runtime-suspend, so its clock
stays enabled.

Switch to pm_runtime_resume_and_get(), which only increments the usage
counter on success.

Fixes: 3242ba117e9b ("gpio: Add driver for Zynq GPIO controller")
Cc: stable@vger.kernel.org
Signed-off-by: Ridham Khurana <khurana.ridham222@gmail.com>
Link: https://patch.msgid.link/20260922092102.1053513-1-khurana.ridham222@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpio/gpio-zynq.c |   10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

--- a/drivers/gpio/gpio-zynq.c
+++ b/drivers/gpio/gpio-zynq.c
@@ -795,15 +795,7 @@ static int __maybe_unused zynq_gpio_runt
 
 static int zynq_gpio_request(struct gpio_chip *chip, unsigned int offset)
 {
-	int ret;
-
-	ret = pm_runtime_get_sync(chip->parent);
-
-	/*
-	 * If the device is already active pm_runtime_get() will return 1 on
-	 * success, but gpio_request still needs to return 0.
-	 */
-	return ret < 0 ? ret : 0;
+	return pm_runtime_resume_and_get(chip->parent);
 }
 
 static void zynq_gpio_free(struct gpio_chip *chip, unsigned int offset)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 476/877] llc: reserve device headroom for allocated frames
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (474 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 475/877] gpio: zynq: fix runtime PM leak on request error path Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 477/877] mctp: route: iterate socket tag list in mctp_lookup_prealloc_tag() Greg Kroah-Hartman
                   ` (408 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, VEGA, Zixuan Chai, Ren Wei,
	Eric Dumazet, Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Zixuan Chai <petalzu987@gmail.com>

commit 72b5b9a28b996e09b8b5b944370c79851bb68f52 upstream.

llc_alloc_frame() reserves link-layer headroom using the device type.
This is insufficient for stacked Ethernet devices such as VLAN devices,
where vlan_dev_hard_header() pushes a VLAN header before the lower
device's Ethernet header. An LLC response on such a device can
therefore underflow skb headroom in eth_header().

Use LL_RESERVED_SPACE() to account for the device's actual required
headroom while preserving the existing LLC device-type check.

Fixes: bf9ae5386bca ("llc: use dev_hard_header")
Cc: stable@vger.kernel.org
Reported-by: VEGA <vega@nebusec.ai>
Signed-off-by: Zixuan Chai <petalzu987@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260924012613.2533934-1-weir@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/llc/llc_sap.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -25,12 +25,12 @@
 #include <linux/llc.h>
 #include <linux/slab.h>
 
-static int llc_mac_header_len(unsigned short devtype)
+static int llc_mac_header_len(struct net_device *dev)
 {
-	switch (devtype) {
+	switch (dev->type) {
 	case ARPHRD_ETHER:
 	case ARPHRD_LOOPBACK:
-		return sizeof(struct ethhdr);
+		return LL_RESERVED_SPACE(dev);
 	}
 	return 0;
 }
@@ -51,7 +51,7 @@ struct sk_buff *llc_alloc_frame(struct s
 	int hlen = type == LLC_PDU_TYPE_U ? 3 : 4;
 	struct sk_buff *skb;
 
-	hlen += llc_mac_header_len(dev->type);
+	hlen += llc_mac_header_len(dev);
 	skb = alloc_skb(hlen + data_size, GFP_ATOMIC);
 
 	if (skb) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 477/877] mctp: route: iterate socket tag list in mctp_lookup_prealloc_tag()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (475 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 476/877] llc: reserve device headroom for allocated frames Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 478/877] rds: ib: Clear the sg list when mapping an MR fails Greg Kroah-Hartman
                   ` (407 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Jeremy Kerr, Hui Peng,
	Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Hui Peng <benquike@gmail.com>

commit 26cc0e69cce062cd3aa6fae33074684669c35a71 upstream.

When a socket transmits a packet with MCTP_TAG_PREALLOC set,
mctp_lookup_prealloc_tag() iterates over the per-netns &mns->keys list
and matches netid, req_tag, peer_addr, and manual_alloc, without
checking whether tmp->sk == &msk->sk. This allows any MCTP socket in the
same network namespace to use and consume another socket's preallocated
tag.

Iterate the socket's own tag list (&msk->keys via sklist) instead of the
namespace-wide &mns->keys list in mctp_lookup_prealloc_tag(), ensuring
that only tags allocated by msk are matched.

Tested in QEMU against Linux 7.3.0-rc3 by allocating a manual tag
(0x18) on socket A via SIOCMCTPALLOCTAG for peer EID 9 and sending a
4-byte message with MCTP_TAG_PREALLOC from socket B in the same network
namespace. On the unfixed kernel, sendto(sock_b) using socket A's
preallocated tag succeeds (ret = 4); with this patch applied,
sendto(sock_b) fails with -ENOENT (errno = 2) while sendto(sock_a)
succeeds (ret = 4).

Fixes: 63ed1aab3d40 ("mctp: Add SIOCMCTP{ALLOC,DROP}TAG ioctls for tag control")
Suggested-by: Jeremy Kerr <jk@codeconstruct.com.au>
Cc: stable@vger.kernel.org
Signed-off-by: Hui Peng <benquike@gmail.com>
Link: https://patch.msgid.link/20260921051002.1656692-1-benquike@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mctp/route.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/mctp/route.c
+++ b/net/mctp/route.c
@@ -775,7 +775,7 @@ static struct mctp_sk_key *mctp_lookup_p
 
 	spin_lock_irqsave(&mns->keys_lock, flags);
 
-	hlist_for_each_entry(tmp, &mns->keys, hlist) {
+	hlist_for_each_entry(tmp, &msk->keys, sklist) {
 		if (tmp->net != netid)
 			continue;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 478/877] rds: ib: Clear the sg list when mapping an MR fails
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (476 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 477/877] mctp: route: iterate socket tag list in mctp_lookup_prealloc_tag() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 479/877] drm/imagination: Propagate map failures correctly from pvr_mmu_map_sgl() Greg Kroah-Hartman
                   ` (406 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Dongliang Qin, Allison Henderson,
	Paolo Abeni

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dongliang Qin <cccccccccccc777777@gmail.com>

commit 58eb1b3325edac42dc6df72c80962bd53a3c8ca7 upstream.

rds_ib_map_frmr() stores the caller's scatterlist in the MR before DMA
mapping and registration can fail. On failure, __rds_rdma_map() unpins
the pages and frees the scatterlist, but rds_ib_free_frmr() can still
return the MR to the pool with the stale pointer set.

This leaves the pool with a dangling scatterlist and can lead to local
privilege escalation. KASAN detects the resulting use-after-free when the
MR is later torn down:

BUG: KASAN: slab-use-after-free in __rds_ib_teardown_mr
Read of size 8

Call Trace:
 __rds_ib_teardown_mr
 rds_ib_unreg_frmr
 rds_ib_flush_mr_pool
 rds_ib_flush_mrs
 rds_free_mr
 rds_setsockopt

Store the scatterlist in the MR only after DMA mapping succeeds. If DMA
mapping fails, return directly while the MR fields remain clear; the caller
keeps ownership of the scatterlist and its pinned pages. If a later
registration step fails, unmap the scatterlist and clear the MR fields
before returning.

Fixes: 1659185fb4d0 ("RDS: IB: Support Fastreg MR (FRMR) memory registration mode")
Cc: stable@vger.kernel.org
Signed-off-by: Dongliang Qin <cccccccccccc777777@gmail.com>
Reviewed-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260922031546.3874605-1-cccccccccccc777777@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rds/ib_frmr.c |   11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

--- a/net/rds/ib_frmr.c
+++ b/net/rds/ib_frmr.c
@@ -204,19 +204,16 @@ static int rds_ib_map_frmr(struct rds_ib
 	 */
 	rds_ib_teardown_mr(ibmr);
 
-	ibmr->sg = sg;
-	ibmr->sg_len = sg_len;
-	ibmr->sg_dma_len = 0;
 	frmr->sg_byte_len = 0;
-	WARN_ON(ibmr->sg_dma_len);
-	ibmr->sg_dma_len = ib_dma_map_sg(dev, ibmr->sg, ibmr->sg_len,
+	ibmr->sg_dma_len = ib_dma_map_sg(dev, sg, sg_len,
 					 DMA_BIDIRECTIONAL);
 	if (unlikely(!ibmr->sg_dma_len)) {
 		pr_warn("RDS/IB: %s failed!\n", __func__);
 		return -EBUSY;
 	}
 
-	frmr->sg_byte_len = 0;
+	ibmr->sg = sg;
+	ibmr->sg_len = sg_len;
 	frmr->dma_npages = 0;
 	len = 0;
 
@@ -264,6 +261,8 @@ out_unmap:
 	ib_dma_unmap_sg(rds_ibdev->dev, ibmr->sg, ibmr->sg_len,
 			DMA_BIDIRECTIONAL);
 	ibmr->sg_dma_len = 0;
+	ibmr->sg = NULL;
+	ibmr->sg_len = 0;
 	return ret;
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 479/877] drm/imagination: Propagate map failures correctly from pvr_mmu_map_sgl()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (477 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 478/877] rds: ib: Clear the sg list when mapping an MR fails Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 480/877] drm/imagination: Fix page count for page table for map() interface Greg Kroah-Hartman
                   ` (405 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Alexandru Dadu, Alessio Belle,
	Brajesh Gupta

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Brajesh Gupta <brajesh.gupta@imgtec.com>

commit 7b824c293a6b56de8285a97984c507cba56bc4c4 upstream.

Map failure from pvr_mmu_map_sgl() interface was not returned correctly
to pvr_mmu_map() interface. This resulted in pvr_mmu_map() interface to
continue instead of returning an error to caller.
Fix it by returning a proper error code from pvr_mmu_map_sgl() interface.

Call stack for crash:
[ 1179.286237] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
[ 1179.295067] Mem abort info:
[ 1179.297877]   ESR = 0x0000000096000004
[ 1179.301656]   EC = 0x25: DABT (current EL), IL = 32 bits
[ 1179.306987]   SET = 0, FnV = 0
[ 1179.310048]   EA = 0, S1PTW = 0
[ 1179.313198]   FSC = 0x04: level 0 translation fault
[ 1179.318096] Data abort info:
[ 1179.320993]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
[ 1179.326483]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[ 1179.331546]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[ 1179.336895] user pgtable: 4k pages, 48-bit VAs, pgdp=000000009822a000
[ 1179.343402] [0000000000000008] pgd=0000000000000000, p4d=0000000000000000
[ 1179.350243] Internal error: Oops: 0000000096000004 [#2]  SMP
[ 1179.355908] Modules linked in: powervr gpu_sched drm_shmem_helper drm_gpuvm drm_exec xhci_plat_hcd xhci_hcd dwc3 usbcore usb_common snd_soc_simple_card snd_soc_simple_card_utils dwc3_am62 at24 sa2ul sha512 libsha512 sha256 authenc sch_fq_codel fuse dm_mod ipv6
[ 1179.378992] CPU: 1 UID: 1000 PID: 680 Comm: deqp-vk Tainted: G      D             6.17.0 #1 PREEMPT
[ 1179.388120] Tainted: [D]=DIE
[ 1179.390994] Hardware name: Texas Instruments AM625 SK (DT)
[ 1179.396467] pstate: 00000005 (nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 1179.403415] pc : pvr_mmu_op_context_unmap_curr_page+0x6c/0x134 [powervr]
[ 1179.410140] lr : pvr_mmu_op_context_unmap_curr_page+0x58/0x134 [powervr]
[ 1179.416848] sp : ffff8000839ab8c0
[ 1179.420153] x29: ffff8000839ab8c0 x28: 0000000000000001 x27: 000000008f386000
[ 1179.427283] x26: ffff000016d1df98 x25: 0000000000247000 x24: 00000000000001e6
[ 1179.434413] x23: 0000000000000002 x22: 000000000000ffff x21: 0000000000000247
[ 1179.441540] x20: 0000000000000245 x19: ffff000016d1df60 x18: 0000000000000002
[ 1179.448668] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000001
[ 1179.455793] x14: 0000000000060810 x13: ffff80007fffffff x12: ffff000004190480
[ 1179.462921] x11: ffff8000853f7000 x10: ffff8000811ae000 x9 : ffff0000041900b8
[ 1179.470051] x8 : 0000000000000000 x7 : 00000000990c4001 x6 : 0000000000000007
[ 1179.477177] x5 : ffff000016d1df60 x4 : 0000000000000000 x3 : ffff00000a7d8000
[ 1179.484306] x2 : 00000000000001ff x1 : 0000000000000000 x0 : 0000000000000000
[ 1179.491433] Call trace:
[ 1179.493872]  pvr_mmu_op_context_unmap_curr_page+0x6c/0x134 [powervr] (P)
[ 1179.500582]  pvr_mmu_map+0x31c/0x388 [powervr]
[ 1179.505027]  pvr_vm_gpuva_map+0x40/0x88 [powervr]
[ 1179.509732]  __drm_gpuvm_sm_map+0x250/0x44c [drm_gpuvm]
[ 1179.514952]  drm_gpuvm_sm_map+0x48/0x5c [drm_gpuvm]
[ 1179.519822]  pvr_vm_bind_op_exec+0x64/0x70 [powervr]
[ 1179.524785]  pvr_vm_map+0x1f8/0x2a8 [powervr]
[ 1179.529142]  pvr_ioctl_vm_map+0x12c/0x188 [powervr]
[ 1179.534018]  drm_ioctl_kernel+0xb8/0x128
[ 1179.537941]  drm_ioctl+0x21c/0x4ec
[ 1179.541337]  __arm64_sys_ioctl+0xac/0x108
[ 1179.545344]  invoke_syscall+0x44/0x100
[ 1179.549091]  el0_svc_common.constprop.0+0x40/0xe0
[ 1179.553790]  do_el0_svc+0x1c/0x28
[ 1179.557106]  el0_svc+0x34/0xf0
[ 1179.560159]  el0t_64_sync_handler+0xd0/0xe4
[ 1179.564334]  el0t_64_sync+0x198/0x19c
[ 1179.567996] Code: 54000300 35000360 f9402261 79409a62 (f9400421)
[ 1179.574081] ---[ end trace 0000000000000000 ]---

Fixes: ff5f643de0bf ("drm/imagination: Add GEM and VM related code")
Reviewed-by: Alexandru Dadu <alexandru.dadu@imgtec.com>
Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260922-mmu_fix-v4-1-12f1a871456a@imgtec.com
Signed-off-by: Brajesh Gupta <brajesh.gupta@imgtec.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/imagination/pvr_mmu.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/imagination/pvr_mmu.c
+++ b/drivers/gpu/drm/imagination/pvr_mmu.c
@@ -12,6 +12,7 @@
 #include "pvr_rogue_mmu_defs.h"
 
 #include <drm/drm_drv.h>
+#include <drm/drm_print.h>
 #include <linux/atomic.h>
 #include <linux/bitops.h>
 #include <linux/dma-mapping.h>
@@ -2550,7 +2551,9 @@ pvr_mmu_map_sgl(struct pvr_mmu_op_contex
 
 err_destroy_pages:
 	memcpy(&op_ctx->curr_page, &ptr_copy, sizeof(op_ctx->curr_page));
-	err = pvr_mmu_op_context_unmap_curr_page(op_ctx, page);
+	if (pvr_mmu_op_context_unmap_curr_page(op_ctx, page))
+		drm_err(from_pvr_device(op_ctx->mmu_ctx->pvr_dev),
+			"%s : Failure in unmapping pages\n", __func__);
 
 	return err;
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 480/877] drm/imagination: Fix page count for page table for map() interface
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (478 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 479/877] drm/imagination: Propagate map failures correctly from pvr_mmu_map_sgl() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 481/877] drm/i915: fix incorrect RCU teardown order Greg Kroah-Hartman
                   ` (404 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Alexandru Dadu, Alessio Belle,
	Brajesh Gupta

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Brajesh Gupta <brajesh.gupta@imgtec.com>

commit 0a8224058a5835297dcf4a46bbcd16f77a9fe424 upstream.

The GPU virtual start address wasn't included in the calculation for the
amount of page tables required for mapping a BO object in map() interface.
It resulted in map failure later due to not enough pages at L0/L1 level.
Update pvr_mmu_op_context_create() interface to pass device address as well
to allow correct calculation for page table memory.

If L0 tables cover 2MB (0x200000), the range defined by device address
0x80001ff000 (general heap at 2MB - 4KB) and size 0x2000 (two 4KB pages)
requires two L0 pages to be mapped, but without the base
address a range of 0x2000 computes to a single L0 page which is not enough.

Fixes: ff5f643de0bf ("drm/imagination: Add GEM and VM related code")
Reviewed-by: Alexandru Dadu <alexandru.dadu@imgtec.com>
Reviewed-by: Alessio Belle <alessio.belle@imgtec.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260922-mmu_fix-v4-2-12f1a871456a@imgtec.com
Signed-off-by: Brajesh Gupta <brajesh.gupta@imgtec.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/imagination/pvr_mmu.c |   14 ++++++++------
 drivers/gpu/drm/imagination/pvr_mmu.h |    2 +-
 drivers/gpu/drm/imagination/pvr_vm.c  |    4 ++--
 3 files changed, 11 insertions(+), 9 deletions(-)

--- a/drivers/gpu/drm/imagination/pvr_mmu.c
+++ b/drivers/gpu/drm/imagination/pvr_mmu.c
@@ -2332,6 +2332,7 @@ void pvr_mmu_op_context_destroy(struct p
  * pvr_mmu_op_context_create() - Create an MMU op context.
  * @ctx: MMU context associated with owning VM context.
  * @sgt: Scatter gather table containing pages pinned for use by this context.
+ * @device_addr: Virtual device address at the start of the requested mapping.
  * @sgt_offset: Start offset of the requested device-virtual memory mapping.
  * @size: Size in bytes of the requested device-virtual memory mapping. For an
  * unmapping, this should be zero so that no page tables are allocated.
@@ -2343,8 +2344,9 @@ void pvr_mmu_op_context_destroy(struct p
  */
 struct pvr_mmu_op_context *
 pvr_mmu_op_context_create(struct pvr_mmu_context *ctx, struct sg_table *sgt,
-			  u64 sgt_offset, u64 size)
+			  u64 device_addr, u64 sgt_offset, u64 size)
 {
+	u64 start_addr = device_addr + sgt_offset;
 	int err;
 
 	struct pvr_mmu_op_context *op_ctx =
@@ -2361,16 +2363,16 @@ pvr_mmu_op_context_create(struct pvr_mmu
 	if (size) {
 		/*
 		 * The number of page table objects we need to prealloc is
-		 * indicated by the mapping size, start offset and the sizes
+		 * indicated by the mapping size, start address and the sizes
 		 * of the areas mapped per PT or PD. The range calculation is
 		 * identical to that for the index into a table for a device
 		 * address, so we reuse those functions here.
 		 */
-		const u32 l1_start_idx = pvr_page_table_l2_idx(sgt_offset);
-		const u32 l1_end_idx = pvr_page_table_l2_idx(sgt_offset + size);
+		const u32 l1_start_idx = pvr_page_table_l2_idx(start_addr);
+		const u32 l1_end_idx = pvr_page_table_l2_idx(start_addr + size);
 		const u32 l1_count = l1_end_idx - l1_start_idx + 1;
-		const u32 l0_start_idx = pvr_page_table_l1_idx(sgt_offset);
-		const u32 l0_end_idx = pvr_page_table_l1_idx(sgt_offset + size);
+		const u32 l0_start_idx = pvr_page_table_l1_idx(start_addr);
+		const u32 l0_end_idx = pvr_page_table_l1_idx(start_addr + size);
 		const u32 l0_count = l0_end_idx - l0_start_idx + 1;
 
 		/*
--- a/drivers/gpu/drm/imagination/pvr_mmu.h
+++ b/drivers/gpu/drm/imagination/pvr_mmu.h
@@ -99,7 +99,7 @@ dma_addr_t pvr_mmu_get_root_table_dma_ad
 void pvr_mmu_op_context_destroy(struct pvr_mmu_op_context *op_ctx);
 struct pvr_mmu_op_context *
 pvr_mmu_op_context_create(struct pvr_mmu_context *ctx,
-			  struct sg_table *sgt, u64 sgt_offset, u64 size);
+			  struct sg_table *sgt, u64 device_addr, u64 sgt_offset, u64 size);
 
 int pvr_mmu_map(struct pvr_mmu_op_context *op_ctx, u64 size, u64 flags,
 		u64 device_addr);
--- a/drivers/gpu/drm/imagination/pvr_vm.c
+++ b/drivers/gpu/drm/imagination/pvr_vm.c
@@ -270,7 +270,7 @@ pvr_vm_bind_op_map_init(struct pvr_vm_bi
 		goto err_bind_op_fini;
 
 	bind_op->mmu_op_ctx =
-		pvr_mmu_op_context_create(vm_ctx->mmu_ctx, sgt, offset, size);
+		pvr_mmu_op_context_create(vm_ctx->mmu_ctx, sgt, device_addr, offset, size);
 	err = PTR_ERR_OR_ZERO(bind_op->mmu_op_ctx);
 	if (err) {
 		bind_op->mmu_op_ctx = NULL;
@@ -312,7 +312,7 @@ pvr_vm_bind_op_unmap_init(struct pvr_vm_
 	}
 
 	bind_op->mmu_op_ctx =
-		pvr_mmu_op_context_create(vm_ctx->mmu_ctx, NULL, 0, 0);
+		pvr_mmu_op_context_create(vm_ctx->mmu_ctx, NULL, device_addr, 0, 0);
 	err = PTR_ERR_OR_ZERO(bind_op->mmu_op_ctx);
 	if (err) {
 		bind_op->mmu_op_ctx = NULL;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 481/877] drm/i915: fix incorrect RCU teardown order
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (479 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 480/877] drm/imagination: Fix page count for page table for map() interface Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 482/877] drm/amd/display: Fix dc stream excess put in dm_update_crtc_state() Greg Kroah-Hartman
                   ` (403 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Christian König, Tvrtko Ursulin,
	Tvrtko Ursulin, Jani Nikula

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Christian König <ckoenig.leichtzumerken@gmail.com>

commit d2da6696e0c4e60414706e607029d0bb0330c67e upstream.

i915_gem_busy_ioctl uses dma_resv_for_each_fence_unlocked() to iterate
over the fences in an GEM object without holding a reference but only
the RCU read side lock.

What can happen here is that the GEM object is destroyed concurrently
while i915_gem_busy_ioctl is still running. This won't free the GEM
objects memory, but still drops all the dma_fence references.

Now when dma_resv_for_each_fence_unlocked() sees a destroyed dma_fence it
assumes that a new fence list was installed and re-starts the loop.

But in the case of a destroyed GEM object a new fence list is never
installed, only the old one freed and therefore the iteration never
finishes resulting in an endless loop.

The solution is to drop the fence references only after the RCU grace
period.

The fixes tag is not necessary the patch introducing the problem, but the
one making it so worse that we need to address it.

This problem was pointed out by Sashiko-bot.

Signed-off-by: Christian König <christian.koenig@amd.com>
Fixes: 912ff2ebd695 ("drm/i915: use the new iterator in i915_gem_busy_ioctl v2")
CC: stable@vger.kernel.org
Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Signed-off-by: Tvrtko Ursulin <tursulin@ursulin.net>
Link: https://lore.kernel.org/r/20260903113621.54660-1-christian.koenig@amd.com
(cherry picked from commit 5113479556025093bf8133bb2dcaa33be2d50921)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/i915/gem/i915_gem_object.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/gpu/drm/i915/gem/i915_gem_object.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c
@@ -87,6 +87,7 @@ struct drm_i915_gem_object *i915_gem_obj
 
 void i915_gem_object_free(struct drm_i915_gem_object *obj)
 {
+	dma_resv_fini(&obj->base._resv);
 	return kmem_cache_free(slab_objects, obj);
 }
 
@@ -142,7 +143,6 @@ void __i915_gem_object_fini(struct drm_i
 {
 	mutex_destroy(&obj->mm.get_page.lock);
 	mutex_destroy(&obj->mm.get_dma_page.lock);
-	dma_resv_fini(&obj->base._resv);
 }
 
 /**



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 482/877] drm/amd/display: Fix dc stream excess put in dm_update_crtc_state()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (480 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 481/877] drm/i915: fix incorrect RCU teardown order Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 483/877] drm/amd/display: Bump frame warning limit for clang builds of dml Greg Kroah-Hartman
                   ` (402 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Alex Deucher

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wentao Liang <vulab@iscas.ac.cn>

commit c5fd4eaad50d620c7e09ac2082b2fb55ee54170e upstream.

In dm_update_crtc_state(), when a modeset is required the newly created
stream is stored in dm_new_crtc_state->stream and an extra reference is
taken with dc_stream_retain().  The reference returned by
create_validate_stream_for_sink() is released as an extra reference at
the skip_modeset label, leaving the stream owned by the new CRTC state.

If amdgpu_dm_check_crtc_color_mgmt() fails afterwards, the code jumps
to the fail label which releases new_stream again.  Since the extra
reference was already released at skip_modeset, this drops the
reference owned by dm_new_crtc_state->stream and the stream is
released while the atomic state still points to it, leading to a
premature free of the dc stream.

Set new_stream to NULL after releasing the extra reference at the
skip_modeset label so that a later goto fail cannot release the
reference owned by the new CRTC state.

Fixes: 7cd4b70091a5 ("drm/amd/display: Rework CRTC color management")
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 102a47065a62dc8f6bbbb47cf082a2934282eb08)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -10834,8 +10834,10 @@ static int dm_update_crtc_state(struct a
 
 skip_modeset:
 	/* Release extra reference */
-	if (new_stream)
+	if (new_stream) {
 		dc_stream_release(new_stream);
+		new_stream = NULL;
+	}
 	new_stream = NULL;
 
 	/*



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 483/877] drm/amd/display: Bump frame warning limit for clang builds of dml
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (481 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 482/877] drm/amd/display: Fix dc stream excess put in dm_update_crtc_state() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 484/877] drm/amdgpu: Fix last_update fence leak in amdgpu_vm_init() Greg Kroah-Hartman
                   ` (401 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Ivan Lipski, Alex Deucher

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ivan Lipski <ivan.lipski@amd.com>

commit 18779dd84515db093fedb4ebaf0998c9b165a5fb upstream.

[Why&How]
When building the DML files with clang without any sanitizer or LTO,
the following -Wframe-larger-than errors break the build under
CONFIG_WERROR:

  display_mode_vba_30.c: error: stack frame size (2512) exceeds limit
    (2048) in 'dml30_ModeSupportAndSystemConfigurationFull'
  display_mode_vba_31.c: error: stack frame size (2416) exceeds limit
    (2048) in 'dml31_ModeSupportAndSystemConfigurationFull'
  display_mode_vba_314.c: error: stack frame size (2392) exceeds limit
    (2048) in 'dml314_ModeSupportAndSystemConfigurationFull'

Clang consistently spills more than gcc, pushing the frame past the 2048
byte limit.

Apply an existing approach of increasing the warn stack size to the
non-sanitizer path so plain clang builds use a 3072 byte limit.

Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/5642
Signed-off-by: Ivan Lipski <ivan.lipski@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 21711b6e66bb7b41b1aec67b2d99aafe768c8fcb)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/display/dc/dml/Makefile |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/amd/display/dc/dml/Makefile
+++ b/drivers/gpu/drm/amd/display/dc/dml/Makefile
@@ -36,7 +36,11 @@ ifneq ($(CONFIG_FRAME_WARN),0)
             frame_warn_limit := 3072
         endif
     else
-        frame_warn_limit := 2048
+        ifeq ($(CONFIG_CC_IS_CLANG),y)
+            frame_warn_limit := 3072
+        else
+            frame_warn_limit := 2048
+        endif
     endif
 
     ifeq ($(call test-lt, $(CONFIG_FRAME_WARN), $(frame_warn_limit)),y)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 484/877] drm/amdgpu: Fix last_update fence leak in amdgpu_vm_init()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (482 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 483/877] drm/amd/display: Bump frame warning limit for clang builds of dml Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 485/877] drm/amdgpu: Fix runtime PM leak in amdgpu_debugfs_test_ib_show() Greg Kroah-Hartman
                   ` (400 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Alex Deucher

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wentao Liang <vulab@iscas.ac.cn>

commit b4f7b4459b1b155e4c4977a6482b5df2cf08758c upstream.

amdgpu_vm_init() initializes vm->last_update, vm->last_unlocked and
vm->last_tlb_flush with references to the stub fence taken via
dma_fence_get_stub().  The error label at the end of the function
releases the last_unlocked and last_tlb_flush references with
dma_fence_put(), but the reference stored in vm->last_update is never
dropped, so whenever the page table root creation, the reservation of
the root BO or the PASID registration fails, the stub fence reference
leaks.

Drop the vm->last_update reference together with the other stub fence
references on the error path.

Fixes: 187916e6ed9d ("drm/amdgpu: install stub fence into potential unused fence pointers")
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit e7979c84fc05a176bdf855ee664871b1648404c9)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2498,6 +2498,7 @@ error_free_root:
 	amdgpu_bo_unref(&root_bo);
 
 error_free_delayed:
+	dma_fence_put(vm->last_update);
 	dma_fence_put(vm->last_tlb_flush);
 	dma_fence_put(vm->last_unlocked);
 	ttm_lru_bulk_move_fini(&adev->mman.bdev, &vm->lru_bulk_move);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 485/877] drm/amdgpu: Fix runtime PM leak in amdgpu_debugfs_test_ib_show()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (483 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 484/877] drm/amdgpu: Fix last_update fence leak in amdgpu_vm_init() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 486/877] drm/amdgpu: Fix vmid_wait fence leak in amdgpu_ring_init() Greg Kroah-Hartman
                   ` (399 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Alex Deucher

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wentao Liang <vulab@iscas.ac.cn>

commit 2b86ab1bd6673c525adda88819d7658ba9e784ec upstream.

amdgpu_debugfs_test_ib_show() resumes the device with
pm_runtime_get_sync() before taking the reset domain semaphore with
down_write_killable().  If the write lock acquisition is interrupted,
the function returns without calling pm_runtime_put_autosuspend(),
leaking the runtime PM reference acquired for the device and keeping
the GPU awake.

Drop the runtime PM reference on the interrupted down_write_killable()
error path before returning.

Fixes: 6049db43d6dd ("drm/amdgpu: change reset lock from mutex to rw_semaphore")
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit ec30a576c2d4c0364549e6c04218f50704ef56c8)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -1671,8 +1671,10 @@ static int amdgpu_debugfs_test_ib_show(s
 
 	/* Avoid accidently unparking the sched thread during GPU reset */
 	r = down_write_killable(&adev->reset_domain->sem);
-	if (r)
+	if (r) {
+		pm_runtime_put_autosuspend(dev->dev);
 		return r;
+	}
 
 	/* hold on the scheduler */
 	for (i = 0; i < AMDGPU_MAX_RINGS; i++) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 486/877] drm/amdgpu: Fix vmid_wait fence leak in amdgpu_ring_init()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (484 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 485/877] drm/amdgpu: Fix runtime PM leak in amdgpu_debugfs_test_ib_show() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 487/877] drm/nouveau/uvmm: fix UAF in nouveau_uvmm_sm when BO is in TTM_PL_SYSTEM Greg Kroah-Hartman
                   ` (398 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Alex Deucher

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wentao Liang <vulab@iscas.ac.cn>

commit aea841bc62a76242396610d22d8ff40c13065f64 upstream.

amdgpu_ring_init() initializes ring->vmid_wait with a reference to the
stub fence taken via dma_fence_get_stub().  When a later step of the
initialization fails, e.g. amdgpu_fence_driver_init_ring(), a writeback
slot allocation or the ring buffer allocation, the function returns an
error without releasing the stub fence reference and the reference is
leaked if the ring is torn down without amdgpu_ring_fini().

Move the stub fence assignment to the end of the initialization, right
before the ring is registered with the GPU scheduler, where no further
failure is possible.  The stub fence is only consumed by command
submission handling in amdgpu_ids.c once the ring is up and running, so
nothing reads it during the error-prone part of the initialization.

Fixes: 48e9fbd1a284 ("drm/amdgpu: initialize the vmid_wait with the stub fence")
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit f2b96986851203e9c50ca0d13aaa3581ca3e8ebd)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
@@ -226,7 +226,6 @@ int amdgpu_ring_init(struct amdgpu_devic
 		ring->adev = adev;
 		ring->num_hw_submission = sched_hw_submission;
 		ring->sched_score = sched_score;
-		ring->vmid_wait = dma_fence_get_stub();
 
 		if (!ring->is_mes_queue) {
 			ring->idx = adev->num_rings++;
@@ -355,6 +354,7 @@ int amdgpu_ring_init(struct amdgpu_devic
 
 	ring->max_dw = max_dw;
 	ring->hw_prio = hw_prio;
+	ring->vmid_wait = dma_fence_get_stub();
 
 	if (!ring->no_scheduler && ring->funcs->type < AMDGPU_HW_IP_NUM) {
 		hw_ip = ring->funcs->type;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 487/877] drm/nouveau/uvmm: fix UAF in nouveau_uvmm_sm when BO is in TTM_PL_SYSTEM
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (485 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 486/877] drm/amdgpu: Fix vmid_wait fence leak in amdgpu_ring_init() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 488/877] drm/nouveau: fix autosuspend cleanup during teardown Greg Kroah-Hartman
                   ` (397 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Peiyang He, Lyude Paul

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Peiyang He <peiyang_he@smail.nju.edu.cn>

commit 3359a372efb6d585c97019ee1b7f1874442bcebe upstream.

nouveau_uvmm_sm() calls op_map(), which passes bo->resource through
nouveau_mem() to nouveau_uvma_map(). nouveau_uvmm_vmm_map() then reads
mem->mem.type.

But this is only valid when bo->resource is backed by struct nouveau_mem,
as is the case for VRAM and TT resources. If the BO is left in
TTM_PL_SYSTEM, bo->resource is only a struct ttm_resource. Treating it
as struct nouveau_mem makes the mem->mem.type read past the end of the
resource, causing a KASAN: slab-use-after-free Read in nouveau_uvmm_sm
report:

BUG: KASAN: slab-use-after-free in nouveau_uvmm_vmm_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:152 [inline]
BUG: KASAN: slab-use-after-free in nouveau_uvma_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:199 [inline]
BUG: KASAN: slab-use-after-free in op_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:849 [inline]
BUG: KASAN: slab-use-after-free in nouveau_uvmm_sm.constprop.0+0x6ab/0x900 drivers/gpu/drm/nouveau/nouveau_uvmm.c:903
Read of size 1 at addr ffff888127d3e3a0 by task kworker/0:1/11

CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 7.2.0 #5 PREEMPT(lazy)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Workqueue: nouveau_sched_wq_2224 drm_sched_run_job_work
Call Trace:
 <TASK>
 __dump_stack lib/dump_stack.c:94 [inline]
 dump_stack_lvl+0x95/0xe0 lib/dump_stack.c:120
 print_address_description mm/kasan/report.c:378 [inline]
 print_report+0xcb/0x5a0 mm/kasan/report.c:482
 kasan_report+0xca/0x100 mm/kasan/report.c:595
 nouveau_uvmm_vmm_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:152 [inline]
 nouveau_uvma_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:199 [inline]
 op_map drivers/gpu/drm/nouveau/nouveau_uvmm.c:849 [inline]
 nouveau_uvmm_sm.constprop.0+0x6ab/0x900 drivers/gpu/drm/nouveau/nouveau_uvmm.c:903
 nouveau_uvmm_sm_unmap drivers/gpu/drm/nouveau/nouveau_uvmm.c:932 [inline]
 nouveau_uvmm_bind_job_run+0xd6/0x250 drivers/gpu/drm/nouveau/nouveau_uvmm.c:1532
 nouveau_job_run drivers/gpu/drm/nouveau/nouveau_sched.c:350 [inline]
 nouveau_sched_run_job+0x62/0xd0 drivers/gpu/drm/nouveau/nouveau_sched.c:364
 drm_sched_run_job_work+0x356/0xa10 drivers/gpu/drm/scheduler/sched_main.c:1061
 process_one_work+0x8a5/0x1900 kernel/workqueue.c:3322
 process_scheduled_works kernel/workqueue.c:3405 [inline]
 worker_thread+0x5dd/0xd80 kernel/workqueue.c:3486
 kthread+0x31d/0x420 kernel/kthread.c:436
 ret_from_fork+0x662/0x940 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
 </TASK>

Allocated by task 2224 on cpu 0 at 66.550027s:
 kasan_save_stack+0x24/0x50 mm/kasan/common.c:57
 kasan_save_track+0x17/0x60 mm/kasan/common.c:78
 poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
 __kasan_kmalloc+0xaa/0xb0 mm/kasan/common.c:415
 kasan_kmalloc include/linux/kasan.h:263 [inline]
 __do_kmalloc_node mm/slub.c:5334 [inline]
 __kmalloc_noprof+0x304/0x7c0 mm/slub.c:5359
 _kmalloc_noprof include/linux/slab.h:992 [inline]
 dma_resv_list_alloc+0x27/0x90 drivers/dma-buf/dma-resv.c:106
 dma_resv_reserve_fences+0x60e/0xa30 drivers/dma-buf/dma-resv.c:205
 ttm_bo_alloc_resource+0x12c/0xbd0 drivers/gpu/drm/ttm/ttm_bo.c:721
 ttm_bo_validate+0x1bc/0x4a0 drivers/gpu/drm/ttm/ttm_bo.c:856
 ttm_bo_init_reserved+0x2c3/0x570 drivers/gpu/drm/ttm/ttm_bo.c:970
 nouveau_bo_init+0x159/0x2c0 drivers/gpu/drm/nouveau/nouveau_bo.c:359
 nouveau_gem_new+0x234/0x5f0 drivers/gpu/drm/nouveau/nouveau_gem.c:272
 nouveau_gem_ioctl_new+0x1eb/0x420 drivers/gpu/drm/nouveau/nouveau_gem.c:352
 drm_ioctl_kernel+0x192/0x350 drivers/gpu/drm/drm_ioctl.c:817
 drm_ioctl+0x4f8/0xb40 drivers/gpu/drm/drm_ioctl.c:914
 nouveau_drm_ioctl+0xea/0x2c0 drivers/gpu/drm/nouveau/nouveau_drm.c:1338
 vfs_ioctl fs/ioctl.c:51 [inline]
 __do_sys_ioctl fs/ioctl.c:597 [inline]
 __se_sys_ioctl fs/ioctl.c:583 [inline]
 __x64_sys_ioctl+0x180/0x1d0 fs/ioctl.c:583
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0x115/0x690 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

Freed by task 2223 on cpu 0 at 66.554063s:
 kasan_save_stack+0x24/0x50 mm/kasan/common.c:57
 kasan_save_track+0x17/0x60 mm/kasan/common.c:78
 kasan_save_free_info+0x3b/0x60 mm/kasan/generic.c:584
 poison_slab_object mm/kasan/common.c:253 [inline]
 __kasan_slab_free+0x61/0x80 mm/kasan/common.c:285
 kasan_slab_free include/linux/kasan.h:235 [inline]
 slab_free_hook mm/slub.c:2677 [inline]
 __rcu_free_sheaf_prepare+0xb6/0x2e0 mm/slub.c:2928
 rcu_free_sheaf+0x1b/0x120 mm/slub.c:5978
 rcu_do_batch kernel/rcu/tree.c:2645 [inline]
 rcu_core+0x521/0x1490 kernel/rcu/tree.c:2897
 handle_softirqs+0x1b1/0x8a0 kernel/softirq.c:622
 __do_softirq kernel/softirq.c:656 [inline]
 invoke_softirq kernel/softirq.c:496 [inline]
 __irq_exit_rcu+0x137/0x1c0 kernel/softirq.c:735
 irq_exit_rcu+0x9/0x20 kernel/softirq.c:752
 instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1062 [inline]
 sysvec_apic_timer_interrupt+0x70/0x80 arch/x86/kernel/apic/apic.c:1062
 asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:674

The buggy address belongs to the object at ffff888127d3e380
 which belongs to the cache kmalloc-96 of size 96
The buggy address is located 32 bytes inside of
 freed 96-byte region [ffff888127d3e380, ffff888127d3e3e0)

The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x127d3e
flags: 0x200000000000000(node=0|zone=2)
page_type: f5(slab)
raw: 0200000000000000 ffff888100041280 dead000000000122 0000000000000000
raw: 0000000000000000 0000000000200020 00000000f5000000 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff888127d3e280: 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc fc
 ffff888127d3e300: 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc fc
>ffff888127d3e380: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
                               ^
 ffff888127d3e400: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
 ffff888127d3e480: 00 00 00 00 00 00 00 00 00 00 fc fc fc fc fc fc

Fix by resetting the placement to the BO's valid domains before
calling nouveau_bo_validate(), matching the handling in
nouveau_uvmm_bo_validate(), so map jobs do not run for SYSTEM resources;
Reject BO that cannot reside in VRAM or GART;
Also skip op_map() when the GPUVA has been invalidated, matching the
handling in the unmap and remap paths.

Found when fuzzing the nouveau driver with a modified Syzkaller.

Fixes: b88baab82871 ("drm/nouveau: implement new VM_BIND uAPI")
Cc: stable@vger.kernel.org
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Assisted-by: Codex:gpt-5.5
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/0D77BEC410CE0129+20260907052204.1431488-1-peiyang_he@smail.nju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/nouveau/nouveau_uvmm.c |   13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

--- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
@@ -780,6 +780,9 @@ op_map(struct nouveau_uvma *uvma)
 {
 	struct nouveau_bo *nvbo = nouveau_gem_object(uvma->va.gem.obj);
 
+	if (drm_gpuva_invalidated(&uvma->va))
+		return;
+
 	nouveau_uvma_map(uvma, nouveau_mem(nvbo->bo.resource));
 }
 
@@ -1164,6 +1167,7 @@ bind_lock_validate(struct nouveau_job *j
 
 		drm_gpuva_for_each_op(va_op, op->ops) {
 			struct drm_gem_object *obj = op_gem_obj(va_op);
+			struct nouveau_bo *nvbo;
 
 			if (unlikely(!obj))
 				continue;
@@ -1178,8 +1182,13 @@ bind_lock_validate(struct nouveau_job *j
 			if (va_op->op == DRM_GPUVA_OP_UNMAP)
 				continue;
 
-			ret = nouveau_bo_validate(nouveau_gem_object(obj),
-						  true, false);
+			nvbo = nouveau_gem_object(obj);
+			if (!(nvbo->valid_domains &
+			      (NOUVEAU_GEM_DOMAIN_VRAM | NOUVEAU_GEM_DOMAIN_GART)))
+				return -EINVAL;
+
+			nouveau_bo_placement_set(nvbo, nvbo->valid_domains, 0);
+			ret = nouveau_bo_validate(nvbo, true, false);
 			if (ret)
 				return ret;
 		}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 488/877] drm/nouveau: fix autosuspend cleanup during teardown
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (486 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 487/877] drm/nouveau/uvmm: fix UAF in nouveau_uvmm_sm when BO is in TTM_PL_SYSTEM Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 489/877] drm/nouveau: Fix bridge reference leak in nv1a_ram_new() Greg Kroah-Hartman
                   ` (396 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Lyude Paul

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Guangshuo Li <lgs201920130244@gmail.com>

commit fefd9480ec361969f1a836df46326a1801062c26 upstream.

nouveau_drm_device_init() calls pm_runtime_use_autosuspend(), but
nouveau_drm_device_fini() does not call the matching
pm_runtime_dont_use_autosuspend().

If the autosuspend delay is set to a negative value while autosuspend
is enabled, the runtime PM core increments usage_count to prevent
runtime suspend. Without calling pm_runtime_dont_use_autosuspend()
during teardown, this reference is not dropped and usage_count remains
unbalanced.

The documentation for pm_runtime_use_autosuspend() also notes that it
is important to undo it with pm_runtime_dont_use_autosuspend() at
driver exit time, unless runtime PM was initially enabled with
devm_pm_runtime_enable().

Add the missing pm_runtime_dont_use_autosuspend() call to the common
device teardown path.

This issue was found by manual code inspection.

Fixes: 5addcf0a5f0f ("nouveau: add runtime PM support (v0.9)")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260808134137.2864847-1-lgs201920130244@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/nouveau/nouveau_drm.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -563,6 +563,7 @@ nouveau_drm_device_fini(struct nouveau_d
 	if (nouveau_pmops_runtime()) {
 		pm_runtime_get_sync(dev->dev);
 		pm_runtime_forbid(dev->dev);
+		pm_runtime_dont_use_autosuspend(dev->dev);
 	}
 
 	nouveau_led_fini(dev);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 489/877] drm/nouveau: Fix bridge reference leak in nv1a_ram_new()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (487 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 488/877] drm/nouveau: fix autosuspend cleanup during teardown Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 490/877] drm/nouveau: fix double-free in nvif_vmm_dtor Greg Kroah-Hartman
                   ` (395 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Lyude Paul

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wentao Liang <vulab@iscas.ac.cn>

commit 67b4411538c8341692548429d43256f25be99f7a upstream.

pci_get_domain_bus_and_slot() takes a reference to the PCI device,
which is never released once the memory size has been read from its
config space.  Drop the reference before returning.

Fixes: 2fa6d6cdaf283c05 ("drm/nouveau: deprecate pci_get_bus_and_slot()")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260916180036.2090118-1-vulab@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv1a.c
@@ -51,6 +51,8 @@ nv1a_ram_new(struct nvkm_fb *fb, struct
 		mib = ((mem >> 4) & 127) + 1;
 	}
 
+	pci_dev_put(bridge);
+
 	return nvkm_ram_new_(&nv04_ram_func, fb, NVKM_RAM_TYPE_STOLEN,
 			     mib * 1024 * 1024, pram);
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 490/877] drm/nouveau: fix double-free in nvif_vmm_dtor
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (488 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 489/877] drm/nouveau: Fix bridge reference leak in nv1a_ram_new() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 491/877] drm/nouveau: Fix gem reference leak in validate_init() Greg Kroah-Hartman
                   ` (394 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Peiyang He, Lyude Paul

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Peiyang He <peiyang_he@smail.nju.edu.cn>

commit 97077ac87afe9e91ec074ef0be64454e7ccbf344 upstream.

On failure, nouveau_cli_init() calls nouveau_cli_fini() to tear
the client down. Then, nouveau_drm_open() also enters into its
cleanup path and calls nouveau_cli_fini() AGAIN. nouveau_cli_fini()
calls nouveau_vmm_fini():

	void
	nouveau_vmm_fini(struct nouveau_vmm *vmm)
	{
		nouveau_svmm_fini(&vmm->svmm);
		nvif_vmm_dtor(&vmm->vmm);
		vmm->cli = NULL;
	}

Inside nvif_vmm_dtor(), vmm->page is freed unconditionally:

	void
	nvif_vmm_dtor(struct nvif_vmm *vmm)
	{
		kfree(vmm->page);
		nvif_object_dtor(&vmm->object);
	}

vmm->page is never cleared after being freed, so the second call of
nvif_vmm_dtor() will cause a double-free.

Found by fuzzing the nouveau driver with a modified Syzkaller:

	BUG: KASAN: double-free in nvif_vmm_dtor+0x31/0x50 drivers/gpu/drm/nouveau/nvif/vmm.c:194
	Free of addr ffff888010fcdc30 by task syz.0.173/2567

	CPU: 1 UID: 0 PID: 2567 Comm: syz.0.173 Not tainted 7.2.0 #24 PREEMPT(lazy)
	Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
	Call Trace:
	<TASK>
	__dump_stack lib/dump_stack.c:94 [inline]
	dump_stack_lvl+0x95/0xe0 lib/dump_stack.c:120
	print_address_description mm/kasan/report.c:378 [inline]
	print_report+0xcb/0x5a0 mm/kasan/report.c:482
	kasan_report_invalid_free+0xaa/0xd0 mm/kasan/report.c:557
	check_slab_allocation+0xe4/0x110 mm/kasan/common.c:235
	kasan_slab_pre_free include/linux/kasan.h:199 [inline]
	slab_free_hook mm/slub.c:2622 [inline]
	slab_free mm/slub.c:6377 [inline]
	kfree+0x192/0x590 mm/slub.c:6692
	nvif_vmm_dtor+0x31/0x50 drivers/gpu/drm/nouveau/nvif/vmm.c:194
	nouveau_vmm_fini+0x16/0x50 drivers/gpu/drm/nouveau/nouveau_vmm.c:127
	nouveau_cli_fini+0x10e/0x210 drivers/gpu/drm/nouveau/nouveau_drm.c:225
	nouveau_drm_open+0x24e/0x740 drivers/gpu/drm/nouveau/nouveau_drm.c:1255
	drm_file_alloc+0x5f2/0xad0 drivers/gpu/drm/drm_file.c:176
	drm_open_helper+0x1d7/0x4a0 drivers/gpu/drm/drm_file.c:335
	drm_open+0x190/0x3d0 drivers/gpu/drm/drm_file.c:388
	drm_stub_open+0x1f2/0x460 drivers/gpu/drm/drm_drv.c:1211
	chrdev_open+0x21c/0x660 fs/char_dev.c:411
	do_dentry_open+0x59d/0x12b0 fs/open.c:947
	vfs_open+0x82/0x390 fs/open.c:1052
	do_open fs/namei.c:4700 [inline]
	path_openat+0x2345/0x3420 fs/namei.c:4863
	do_file_open+0x207/0x460 fs/namei.c:4892
	do_sys_openat2+0xd1/0x1d0 fs/open.c:1368
	do_sys_open fs/open.c:1374 [inline]
	__do_sys_openat fs/open.c:1390 [inline]
	__se_sys_openat fs/open.c:1385 [inline]
	__x64_sys_openat+0x144/0x200 fs/open.c:1385
	do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
	do_syscall_64+0x115/0x690 arch/x86/entry/syscall_64.c:94
	entry_SYSCALL_64_after_hwframe+0x77/0x7f
	RIP: 0033:0x7fc6d687594d
	Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
	RSP: 002b:00007fc6d5295008 EFLAGS: 00000246 ORIG_RAX: 0000000000000101
	RAX: ffffffffffffffda RBX: 00007fc6d6b06180 RCX: 00007fc6d687594d
	RDX: 0000000000022501 RSI: 0000200000000000 RDI: ffffffffffffff9c
	RBP: 00007fc6d691c303 R08: 0000000000000000 R09: 0000000000000000
	R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
	R13: 00007fc6d6b06218 R14: 00007fc6d6b06180 R15: 00007ffd9451d760
	</TASK>

	Allocated by task 2567 on cpu 1 at 163.593900s:
	kasan_save_stack+0x24/0x50 mm/kasan/common.c:57
	kasan_save_track+0x17/0x60 mm/kasan/common.c:78
	poison_kmalloc_redzone mm/kasan/common.c:398 [inline]
	__kasan_kmalloc+0xaa/0xb0 mm/kasan/common.c:415
	kasan_kmalloc include/linux/kasan.h:263 [inline]
	__do_kmalloc_node mm/slub.c:5334 [inline]
	__kmalloc_noprof+0x304/0x7c0 mm/slub.c:5359
	_kmalloc_noprof include/linux/slab.h:992 [inline]
	nvif_vmm_ctor+0x3c0/0x7e0 drivers/gpu/drm/nouveau/nvif/vmm.c:237
	nouveau_vmm_init+0x40/0x90 drivers/gpu/drm/nouveau/nouveau_vmm.c:134
	nouveau_cli_init+0x7b9/0xe10 drivers/gpu/drm/nouveau/nouveau_drm.c:293
	nouveau_drm_open+0x236/0x740 drivers/gpu/drm/nouveau/nouveau_drm.c:1243
	drm_file_alloc+0x5f2/0xad0 drivers/gpu/drm/drm_file.c:176
	drm_open_helper+0x1d7/0x4a0 drivers/gpu/drm/drm_file.c:335
	drm_open+0x190/0x3d0 drivers/gpu/drm/drm_file.c:388
	drm_stub_open+0x1f2/0x460 drivers/gpu/drm/drm_drv.c:1211
	chrdev_open+0x21c/0x660 fs/char_dev.c:411
	do_dentry_open+0x59d/0x12b0 fs/open.c:947
	vfs_open+0x82/0x390 fs/open.c:1052
	do_open fs/namei.c:4700 [inline]
	path_openat+0x2345/0x3420 fs/namei.c:4863
	do_file_open+0x207/0x460 fs/namei.c:4892
	do_sys_openat2+0xd1/0x1d0 fs/open.c:1368
	do_sys_open fs/open.c:1374 [inline]
	__do_sys_openat fs/open.c:1390 [inline]
	__se_sys_openat fs/open.c:1385 [inline]
	__x64_sys_openat+0x144/0x200 fs/open.c:1385
	do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
	do_syscall_64+0x115/0x690 arch/x86/entry/syscall_64.c:94
	entry_SYSCALL_64_after_hwframe+0x77/0x7f

	Freed by task 2567 on cpu 1 at 163.601355s:
	kasan_save_stack+0x24/0x50 mm/kasan/common.c:57
	kasan_save_track+0x17/0x60 mm/kasan/common.c:78
	kasan_save_free_info+0x3b/0x60 mm/kasan/generic.c:584
	poison_slab_object mm/kasan/common.c:253 [inline]
	__kasan_slab_free+0x61/0x80 mm/kasan/common.c:285
	kasan_slab_free include/linux/kasan.h:235 [inline]
	slab_free_hook mm/slub.c:2677 [inline]
	slab_free mm/slub.c:6377 [inline]
	kfree+0x383/0x590 mm/slub.c:6692
	nvif_vmm_dtor+0x31/0x50 drivers/gpu/drm/nouveau/nvif/vmm.c:194
	nouveau_vmm_fini+0x16/0x50 drivers/gpu/drm/nouveau/nouveau_vmm.c:127
	nouveau_cli_fini+0x10e/0x210 drivers/gpu/drm/nouveau/nouveau_drm.c:225
	nouveau_cli_init+0x593/0xe10 drivers/gpu/drm/nouveau/nouveau_drm.c:324
	nouveau_drm_open+0x236/0x740 drivers/gpu/drm/nouveau/nouveau_drm.c:1243
	drm_file_alloc+0x5f2/0xad0 drivers/gpu/drm/drm_file.c:176
	drm_open_helper+0x1d7/0x4a0 drivers/gpu/drm/drm_file.c:335
	drm_open+0x190/0x3d0 drivers/gpu/drm/drm_file.c:388
	drm_stub_open+0x1f2/0x460 drivers/gpu/drm/drm_drv.c:1211
	chrdev_open+0x21c/0x660 fs/char_dev.c:411
	do_dentry_open+0x59d/0x12b0 fs/open.c:947
	vfs_open+0x82/0x390 fs/open.c:1052
	do_open fs/namei.c:4700 [inline]
	path_openat+0x2345/0x3420 fs/namei.c:4863
	do_file_open+0x207/0x460 fs/namei.c:4892
	do_sys_openat2+0xd1/0x1d0 fs/open.c:1368
	do_sys_open fs/open.c:1374 [inline]
	__do_sys_openat fs/open.c:1390 [inline]
	__se_sys_openat fs/open.c:1385 [inline]
	__x64_sys_openat+0x144/0x200 fs/open.c:1385
	do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
	do_syscall_64+0x115/0x690 arch/x86/entry/syscall_64.c:94
	entry_SYSCALL_64_after_hwframe+0x77/0x7f

	The buggy address belongs to the object at ffff888010fcdc30
	which belongs to the cache kmalloc-16 of size 16
	The buggy address is located 0 bytes inside of
	16-byte region [ffff888010fcdc30, ffff888010fcdc40)

	The buggy address belongs to the physical page:
	page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10fcd
	flags: 0x100000000000000(node=0|zone=1)
	page_type: f5(slab)
	raw: 0100000000000000 ffff88800d441640 dead000000000100 dead000000000122
	raw: 0000000000000000 0000000000550055 00000000f5000000 0000000000000000
	page dumped because: kasan: bad access detected

	Memory state around the buggy address:
	ffff888010fcdb00: fc fc 00 04 fc fc fc fc fa fb fc fc fc fc fa fb
	ffff888010fcdb80: fc fc fc fc fa fb fc fc fc fc 00 07 fc fc fc fc
	>ffff888010fcdc00: fa fb fc fc fc fc fa fb fc fc fc fc fa fb fc fc
										^
	ffff888010fcdc80: fc fc fa fb fc fc fc fc 00 04 fc fc fc fc fa fb
	ffff888010fcdd00: fc fc fc fc 00 00 fc fc fc fc fa fb fc fc fc fc

Fix by removing the redundant teardown in nouveau_drm_open(),
since nouveau_cli_init() already does the cleanup work.
Also clear vmm->page after its freeing.

Cc: stable@vger.kernel.org
Fixes: 20d8a88e557a ("drm/nouveau: tidy up the client init/fini interfaces")
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Assisted-by: LLM
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/03BA723D9E5FF725+20260916103138.2651605-1-peiyang_he@smail.nju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/nouveau/nouveau_drm.c |    4 +---
 drivers/gpu/drm/nouveau/nvif/vmm.c    |    1 +
 2 files changed, 2 insertions(+), 3 deletions(-)

--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -1192,10 +1192,8 @@ nouveau_drm_open(struct drm_device *dev,
 	mutex_unlock(&drm->clients_lock);
 
 done:
-	if (ret && cli) {
-		nouveau_cli_fini(cli);
+	if (ret && cli)
 		kfree(cli);
-	}
 
 	pm_runtime_mark_last_busy(dev->dev);
 	pm_runtime_put_autosuspend(dev->dev);
--- a/drivers/gpu/drm/nouveau/nvif/vmm.c
+++ b/drivers/gpu/drm/nouveau/nvif/vmm.c
@@ -192,6 +192,7 @@ void
 nvif_vmm_dtor(struct nvif_vmm *vmm)
 {
 	kfree(vmm->page);
+	vmm->page = NULL;
 	nvif_object_dtor(&vmm->object);
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 491/877] drm/nouveau: Fix gem reference leak in validate_init()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (489 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 490/877] drm/nouveau: fix double-free in nvif_vmm_dtor Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 492/877] drm/nouveau: Fix runtime PM leak in nouveau_connector_detect() Greg Kroah-Hartman
                   ` (393 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Lyude Paul

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wentao Liang <vulab@iscas.ac.cn>

commit 5ea72f7b7139b123713a7983448f910bc4514d9e upstream.

On the ttm_bo_reserve() failure and "vma not found" error paths, the
loop breaks without adding the looked-up object to any validate list,
so the reference taken by drm_gem_object_lookup() is never released;
validate_fini() only walks the spliced lists.  Drop the reference
before breaking out on both paths.

Fixes: 19ca10d82e33bcfe ("drm/nouveau/gem: lookup VMAs for buffers referenced by pushbuf ioctl")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260916180202.2090231-1-vulab@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/nouveau/nouveau_gem.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -522,6 +522,7 @@ retry:
 			if (unlikely(ret)) {
 				if (ret != -ERESTARTSYS)
 					NV_PRINTK(err, cli, "fail reserve\n");
+				drm_gem_object_put(gem);
 				break;
 			}
 		}
@@ -531,6 +532,7 @@ retry:
 			struct nouveau_vma *vma = nouveau_vma_find(nvbo, vmm);
 			if (!vma) {
 				NV_PRINTK(err, cli, "vma not found!\n");
+				drm_gem_object_put(gem);
 				ret = -EINVAL;
 				break;
 			}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 492/877] drm/nouveau: Fix runtime PM leak in nouveau_connector_detect()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (490 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 491/877] drm/nouveau: Fix gem reference leak in validate_init() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 493/877] drm/nouveau: RCU-free the scheduler-containing nouveau_sched Greg Kroah-Hartman
                   ` (392 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Lyude Paul

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wentao Liang <vulab@iscas.ac.cn>

commit 1e04611d3735543bd80a67d9d13dc13f503746fb upstream.

If nvif_outp_edid_get() fails, nouveau_connector_detect() returns
early without dropping the runtime PM reference taken at the start
of the function, keeping the device powered on until the next
successful detect.

Balance the reference on the error path like the other exit paths
do.

Fixes: 0cd7e0718139 ("drm/nouveau/disp: add output method to fetch edid")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260916180342.2090360-1-vulab@iscas.ac.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/nouveau/nouveau_connector.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/nouveau/nouveau_connector.c
+++ b/drivers/gpu/drm/nouveau/nouveau_connector.c
@@ -601,8 +601,11 @@ nouveau_connector_detect(struct drm_conn
 				new_edid = drm_get_edid(connector, nv_encoder->i2c);
 		} else {
 			ret = nvif_outp_edid_get(&nv_encoder->outp, (u8 **)&new_edid);
-			if (ret < 0)
+			if (ret < 0) {
+				pm_runtime_mark_last_busy(dev->dev);
+				pm_runtime_put_autosuspend(dev->dev);
 				return connector_status_disconnected;
+			}
 		}
 
 		nouveau_connector_set_edid(nv_connector, new_edid);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 493/877] drm/nouveau: RCU-free the scheduler-containing nouveau_sched
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (491 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 492/877] drm/nouveau: Fix runtime PM leak in nouveau_connector_detect() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 494/877] drm/nouveau: dont bump pin count on failed re-pin in nouveau_bo_pin_locked() Greg Kroah-Hartman
                   ` (391 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Jonghyuk Kim(MalHyuk), Lyude Paul

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jonghyuk Kim(MalHyuk) <malhyuk97@gmail.com>

commit f7eae6d8d768fabd6b59779ca7da79e02c74e113 upstream.

struct nouveau_sched embeds a struct drm_gpu_scheduler (base).
nouveau_sched_destroy() calls nouveau_sched_fini() (which does
drm_sched_fini(&sched->base)) and then frees the object with plain
kfree(sched).

drm_sched_fence_get_timeline_name() returns fence->sched->name, and the
scheduler fence keeps a .release callback so it is not ops-detached on
signalling.  A finished fence exported to userspace via drm_syncobj /
sync_file therefore keeps pointing at &sched->base after nouveau_sched_destroy(),
and a later get_timeline_name() -- reachable unprivileged through
SYNC_IOC_FILE_INFO -- dereferences freed memory (KASAN slab-use-after-free
read).

Per the dma-fence lifetime contract the exporter must keep the data backing a
signalled fence alive for an RCU grace period.  Free the scheduler-containing
object with kfree_rcu() instead of kfree().

Fixes: 5f03a507b29e ("drm/nouveau: implement 1:1 scheduler - entity relationship")
Cc: stable@vger.kernel.org
Signed-off-by: Jonghyuk Kim(MalHyuk) <malhyuk97@gmail.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/20260902012717.880724-1-malhyuk97@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/nouveau/nouveau_sched.c |    2 +-
 drivers/gpu/drm/nouveau/nouveau_sched.h |    1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/nouveau/nouveau_sched.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sched.c
@@ -512,7 +512,7 @@ nouveau_sched_destroy(struct nouveau_sch
 	struct nouveau_sched *sched = *psched;
 
 	nouveau_sched_fini(sched);
-	kfree(sched);
+	kfree_rcu(sched, rcu);
 
 	*psched = NULL;
 }
--- a/drivers/gpu/drm/nouveau/nouveau_sched.h
+++ b/drivers/gpu/drm/nouveau/nouveau_sched.h
@@ -98,6 +98,7 @@ void nouveau_job_free(struct nouveau_job
 
 struct nouveau_sched {
 	struct drm_gpu_scheduler base;
+	struct rcu_head rcu;
 	struct drm_sched_entity entity;
 	struct workqueue_struct *wq;
 	struct mutex mutex;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 494/877] drm/nouveau: dont bump pin count on failed re-pin in nouveau_bo_pin_locked()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (492 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 493/877] drm/nouveau: RCU-free the scheduler-containing nouveau_sched Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 495/877] drm/xe: Limit sg segment size to PAGE_SIZE on Xen PV Greg Kroah-Hartman
                   ` (390 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Peiyang He, Lyude Paul

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Peiyang He <peiyang_he@smail.nju.edu.cn>

commit 6a6870d3077faa501ca97760057ddca22b68418d upstream.

nouveau_bo_pin_locked() checks whether an already pinned BO is in a
memory domain compatible with a new pin request. When the domains are
incompatible, it sets -EBUSY but still calls ttm_bo_pin() before
returning.

Callers treat a failed nouveau_bo_pin() as not having acquired a new pin,
so the extra pin count is never decreased by a matching unpin.
This triggers the warning in ttm_bo_release():

	WARN_ON_ONCE(bo->pin_count);

Found when fuzzing the nouveau driver with a modified Syzkaller:

	WARNING: drivers/gpu/drm/ttm/ttm_bo.c:256 at ttm_bo_release+0x827/0x9e0 drivers/gpu/drm/ttm/ttm_bo.c:256, CPU#1: syz.3.24/2212
	Modules linked in:
	CPU: 1 UID: 0 PID: 2212 Comm: syz.3.24 Not tainted 7.2.0 #24 PREEMPT(lazy)
	nouveau 0000:01:00.0: gsp:msg fn:103 len:0x40/0x20 res:0x19 resp:0x19
	Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
	RIP: 0010:ttm_bo_release+0x827/0x9e0 drivers/gpu/drm/ttm/ttm_bo.c:256
	Code: 02 00 0f 85 51 01 00 00 48 8b 7b 08 e8 d2 20 01 00 e9 80 fd ff ff e8 d8 15 c0 fe 90 0f 0b 90 e9 e1 f8 ff ff e8 ca 15 c0 fe 90 <0f> 0b 90 e9 a4 f8 ff ff e8 bc 15 c0 fe be 03 00 00 00 4c 89 e7 e8
	msg: 00000000: 05 00 d0 c1 04 00 f0 f1 01 30 00 00 2d 90 00 00  .........0..-...
	RSP: 0018:ffffc9000f5cf710 EFLAGS: 00010293
	RAX: 0000000000000000 RBX: ffff888018e5d2a8 RCX: ffffffff82bb1b36
	RDX: ffff888017b68000 RSI: 0000000000000004 RDI: ffff888018e5d2a8
	msg: 00000010: 19 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
	RBP: ffff88801261c720 R08: 0000000000000001 R09: ffffed10031cba55
	R10: ffff888018e5d2ab R11: 00000000000000f3 R12: ffff888018e5d290
	R13: ffff888018e5d2d4 R14: ffff88801b219c18 R15: dffffc0000000000
	FS:  0000000000000000(0000) GS:ffff8880e0f6f000(0000) knlGS:0000000000000000
	CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
	CR2: 0000001b31223ffc CR3: 0000000028e00005 CR4: 0000000000770ef0
	PKRU: 80000000
	Call Trace:
	<TASK>
	kref_put include/linux/kref.h:65 [inline]
	ttm_bo_put drivers/gpu/drm/ttm/ttm_bo.c:325 [inline]
	ttm_bo_fini+0x55/0x80 drivers/gpu/drm/ttm/ttm_bo.c:330
	nouveau_gem_object_del+0xb2/0x1b0 drivers/gpu/drm/nouveau/nouveau_gem.c:90
	drm_gem_object_free+0x5f/0x90 drivers/gpu/drm/drm_gem.c:1165
	kref_put include/linux/kref.h:65 [inline]
	__drm_gem_object_put include/drm/drm_gem.h:562 [inline]
	drm_gem_object_put include/drm/drm_gem.h:575 [inline]
	nouveau_abi16_chan_fini.constprop.0+0x44f/0x5a0 drivers/gpu/drm/nouveau/nouveau_abi16.c:195
	nouveau 0000:01:00.0: syz.2.23[2209]: Unknown handle 0x00000000
	nouveau_abi16_fini+0x1d0/0x340 drivers/gpu/drm/nouveau/nouveau_abi16.c:225
	nouveau_drm_postclose+0x18b/0x3e0 drivers/gpu/drm/nouveau/nouveau_drm.c:1284
	nouveau 0000:01:00.0: syz.2.23[2209]: validate_init
	drm_file_free.part.0+0x6d6/0xb60 drivers/gpu/drm/drm_file.c:267
	drm_file_free drivers/gpu/drm/drm_file.c:237 [inline]
	drm_close_helper.isra.0+0x11a/0x160 drivers/gpu/drm/drm_file.c:290
	drm_release+0x1ab/0x330 drivers/gpu/drm/drm_file.c:438
	__fput+0x39c/0xa60 fs/file_table.c:512
	nouveau 0000:01:00.0: syz.2.23[2209]: validate: -2
	task_work_run+0x15a/0x230 kernel/task_work.c:233
	exit_task_work include/linux/task_work.h:40 [inline]
	do_exit+0x82b/0x25a0 kernel/exit.c:1009
	do_group_exit+0xc2/0x280 kernel/exit.c:1152
	get_signal+0x1d6e/0x1f30 kernel/signal.c:3046
	arch_do_signal_or_restart+0x7d/0x6e0 arch/x86/kernel/signal.c:337
	__exit_to_user_mode_loop kernel/entry/common.c:66 [inline]
	exit_to_user_mode_loop+0xdf/0x440 kernel/entry/common.c:101
	__exit_to_user_mode_prepare include/linux/irq-entry-common.h:207 [inline]
	syscall_exit_to_user_mode_prepare include/linux/irq-entry-common.h:230 [inline]
	syscall_exit_to_user_mode include/linux/entry-common.h:318 [inline]
	do_syscall_64+0x4f8/0x690 arch/x86/entry/syscall_64.c:100
	entry_SYSCALL_64_after_hwframe+0x77/0x7f
	RIP: 0033:0x7f12bac8594d
	Code: Unable to access opcode bytes at 0x7f12bac85923.
	RSP: 002b:00007f12b96e70d8 EFLAGS: 00000246 ORIG_RAX: 00000000000000ca
	RAX: 0000000000000001 RBX: 00007f12baf15fa8 RCX: 00007f12bac8594d
	RDX: 00000000000f4240 RSI: 0000000000000081 RDI: 00007f12baf15fac
	RBP: 00007f12baf15fa0 R08: 00007f12baee8000 R09: 0000000000000000
	R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
	R13: 00007f12baf16038 R14: 0000000000000006 R15: 00007ffe2ed394b0
	</TASK>
	irq event stamp: 47867
	hardirqs last  enabled at (47883): [<ffffffff815cafc6>] __up_console_sem+0x66/0x70 kernel/printk/printk.c:347
	hardirqs last disabled at (47892): [<ffffffff815cafab>] __up_console_sem+0x4b/0x70 kernel/printk/printk.c:345
	softirqs last  enabled at (47880): [<ffffffff81434277>] __do_softirq kernel/softirq.c:656 [inline]
	softirqs last  enabled at (47880): [<ffffffff81434277>] invoke_softirq kernel/softirq.c:496 [inline]
	softirqs last  enabled at (47880): [<ffffffff81434277>] __irq_exit_rcu+0x137/0x1c0 kernel/softirq.c:735
	softirqs last disabled at (47875): [<ffffffff81434277>] __do_softirq kernel/softirq.c:656 [inline]
	softirqs last disabled at (47875): [<ffffffff81434277>] invoke_softirq kernel/softirq.c:496 [inline]
	softirqs last disabled at (47875): [<ffffffff81434277>] __irq_exit_rcu+0x137/0x1c0 kernel/softirq.c:735

Fix by calling ttm_bo_pin() only when the existing placement is compatible
with the new pin request. This matches the correct behavior in other DRM
drivers such as amdgpu_bo_pin() in amdgpu.

Cc: stable@vger.kernel.org
Fixes: ad76b3f7c7a0 ("drm/nouveau: teach nouveau_bo_pin() how to force a contig vram allocation")
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Assisted-by: LLM
Reviewed-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Lyude Paul <lyude@redhat.com>
Link: https://patch.msgid.link/EACEF2F4E098413F+20260918025312.2814889-1-peiyang_he@smail.nju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/nouveau/nouveau_bo.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -501,8 +501,9 @@ int nouveau_bo_pin_locked(struct nouveau
 				      "0x%08x vs 0x%08x\n", bo,
 				 bo->resource->mem_type, domain);
 			ret = -EBUSY;
+		} else {
+			ttm_bo_pin(&nvbo->bo);
 		}
-		ttm_bo_pin(&nvbo->bo);
 		goto out;
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 495/877] drm/xe: Limit sg segment size to PAGE_SIZE on Xen PV
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (493 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 494/877] drm/nouveau: dont bump pin count on failed re-pin in nouveau_bo_pin_locked() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 496/877] drm/virtio: fix memory leak of fence event on execbuffer failure Greg Kroah-Hartman
                   ` (389 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Marek Marczykowski-Górecki,
	Christoph Hellwig, Robert Beckett, Szymon Acedański,
	Thomas Hellström, Rodrigo Vivi

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Szymon Acedański <accek@invisiblethingslab.com>

commit 141008dec73521ccf64878517460cec8b3297251 upstream.

Fix display corruption on Xen PV dom0, where DMA buffers are not
guaranteed machine-contiguous, in which case bounce buffering kicks
in, breaking xe's memory coherency assumptions.

Apply the same workaround i915 carries in i915_sg_segment_size() since
commit 78a07fe777c4 ("drm/i915: stop abusing swiotlb_max_segment").

Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs")
Reported-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/8382
Link: https://lore.kernel.org/xen-devel/aYtznP_tT6xNPwf-@mail-itl/
Link: https://lore.kernel.org/all/20221020110308.1582518-1-hch@lst.de/ # i915 counterpart
Cc: Christoph Hellwig <hch@lst.de>
Cc: Robert Beckett <bob.beckett@collabora.com>
Cc: stable@vger.kernel.org # v6.8+
Signed-off-by: Szymon Acedański <accek@invisiblethingslab.com>
Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Link: https://patch.msgid.link/20260916173030.3223833-1-accek@invisiblethingslab.com
(cherry picked from commit 77f704158f099b952681f207478a22d5b8218edb)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/xe/xe_bo.h |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

--- a/drivers/gpu/drm/xe/xe_bo.h
+++ b/drivers/gpu/drm/xe/xe_bo.h
@@ -8,6 +8,8 @@
 
 #include <drm/ttm/ttm_tt.h>
 
+#include <xen/xen.h>
+
 #include "xe_bo_types.h"
 #include "xe_macros.h"
 #include "xe_vm_types.h"
@@ -328,6 +330,23 @@ static inline unsigned int xe_sg_segment
 	struct scatterlist __maybe_unused sg;
 	size_t max = BIT_ULL(sizeof(sg.length) * 8) - 1;
 
+	/*
+	 * For Xen PV guests pages aren't contiguous in DMA (machine) address
+	 * space.  The DMA API takes care of that both in dma_alloc_* (by
+	 * calling into the hypervisor to make the pages contiguous) and in
+	 * dma_map_* (by bounce buffering).  But xe (like i915, see commit
+	 * 78a07fe777c4) ignores the coherency aspects of the DMA API and thus
+	 * can't cope with bounce buffering actually happening, so add a hack
+	 * here to force small allocations and mappings when running in PV
+	 * mode on Xen.
+	 *
+	 * Note this will still break if bounce buffering is required for other
+	 * reasons, like confidential computing hypervisors or PCIe root ports
+	 * with addressing limitations.
+	 */
+	if (xen_pv_domain())
+		return PAGE_SIZE;
+
 	max = min_t(size_t, max, dma_max_mapping_size(dev));
 
 	/*



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 496/877] drm/virtio: fix memory leak of fence event on execbuffer failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (494 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 495/877] drm/xe: Limit sg segment size to PAGE_SIZE on Xen PV Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 497/877] drm/virtio: fix NULL pointer dereference on fence allocation failure Greg Kroah-Hartman
                   ` (388 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Peiyang He, Dmitry Osipenko

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Peiyang He <peiyang_he@smail.nju.edu.cn>

commit b74aad23d99b279bb34d135795f39a6d8ecdc075 upstream.

virtio_gpu_execbuffer_ioctl() reserves a DRM event with
drm_event_reserve_init() when VIRTGPU_EXECBUF_RING_IDX selects a ring that
userspace has enabled polling for. virtio_gpu_init_submit() does this
before the BO handles, the command buffer, the syncobj arrays and the
in-fence are processed, so every later error path runs with the event
already pending, including plain argument validation failures such as an
invalid bo_handle or an in-syncobj that carries no fence.

On those paths, virtio_gpu_cleanup_submit() drops the out-fence without
cancelling the event. The fence is freed without ever having been emitted,
taking the only driver-side pointer to the event with it. Closing the DRM
file does not help. drm_events_release() unlinks pending events but
deliberately leaves the freeing to the driver's later drm_send_event(),
which never runs for an orphaned event, so the allocation is leaked
permanently.

Found when fuzzing the virtio driver with Syzkaller:

	BUG: memory leak
	unreferenced object 0xffff88802c176e80 (size 96):
	comm "syz.1.367", pid 10561, jiffies 4294960122
	hex dump (first 32 bytes):
		00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
		c8 6e 17 2c 80 88 ff ff 00 00 00 00 00 00 00 00  .n.,............
	backtrace (crc e1973c6b):
		kmemleak_alloc_recursive include/linux/kmemleak.h:44 [inline]
		slab_post_alloc_hook mm/slub.c:4597 [inline]
		slab_alloc_node mm/slub.c:4917 [inline]
		__kmalloc_cache_noprof+0x49d/0x6f0 mm/slub.c:5485
		_kmalloc_noprof include/linux/slab.h:988 [inline]
		_kzalloc_noprof include/linux/slab.h:1309 [inline]
		virtio_gpu_fence_event_create drivers/gpu/drm/virtio/virtgpu_submit.c:282 [inline]
		virtio_gpu_init_submit drivers/gpu/drm/virtio/virtgpu_submit.c:398 [inline]
		virtio_gpu_execbuffer_ioctl+0xbbf/0x1aa0 drivers/gpu/drm/virtio/virtgpu_submit.c:505
		drm_ioctl_kernel+0x1f4/0x3e0 drivers/gpu/drm/drm_ioctl.c:817
		drm_ioctl+0x5f4/0xc70 drivers/gpu/drm/drm_ioctl.c:914
		vfs_ioctl fs/ioctl.c:51 [inline]
		__do_sys_ioctl fs/ioctl.c:597 [inline]
		__se_sys_ioctl fs/ioctl.c:583 [inline]
		__x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583
		do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
		do_syscall_64+0x116/0x800 arch/x86/entry/syscall_64.c:94
		entry_SYSCALL_64_after_hwframe+0x77/0x7f

Fix by cancelling and freeing the DRM event on the execbuffer error path
before dropping the fence. Clear the fence's event pointer after
cancellation so it does not retain a dangling pointer.

Fixes: cd7f5ca33585 ("drm/virtio: implement context init: add virtio_gpu_fence_event")
Cc: stable@vger.kernel.org
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Assisted-by: Codex:gpt-5.6-luna
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/D320EAB5680C1411+20260908121323.2405044-1-peiyang_he@smail.nju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/virtio/virtgpu_submit.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/drivers/gpu/drm/virtio/virtgpu_submit.c
+++ b/drivers/gpu/drm/virtio/virtgpu_submit.c
@@ -538,6 +538,10 @@ int virtio_gpu_execbuffer_ioctl(struct d
 	virtio_gpu_process_post_deps(&submit);
 	virtio_gpu_complete_submit(&submit);
 cleanup:
+	if (ret && submit.out_fence && submit.out_fence->e) {
+		drm_event_cancel_free(dev, &submit.out_fence->e->base);
+		submit.out_fence->e = NULL;
+	}
 	virtio_gpu_cleanup_submit(&submit);
 
 	return ret;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 497/877] drm/virtio: fix NULL pointer dereference on fence allocation failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (495 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 496/877] drm/virtio: fix memory leak of fence event on execbuffer failure Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 498/877] gpio: tps65219: Fix GPIO input value reads Greg Kroah-Hartman
                   ` (387 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Peiyang He, Dmitry Osipenko

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Peiyang He <peiyang_he@smail.nju.edu.cn>

commit 846b3c64fe3e77d9db20a7e3e62dbbb637c773e1 upstream.

virtio_gpu_fence_alloc() can fail due to memory pressure and return NULL,
but its caller like virtio_gpu_init_submit() never checks it. Later,
virtio_gpu_init_submit() passes the NULL fence to
virtio_gpu_fence_event_create(), which unconditionally dereferences it.

Found when fuzzing the virtio driver with Syzkaller:

	Oops: general protection fault, probably for non-canonical address 0xdffffc0000000012: 0000 [#1] SMP KASAN NOPTI
	KASAN: null-ptr-deref in range [0x0000000000000090-0x0000000000000097]
	CPU: 1 UID: 0 PID: 9991 Comm: syz.0.121 Not tainted 7.2.0 #4 PREEMPT(full)
	Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
	RIP: 0010:virtio_gpu_fence_event_create drivers/gpu/drm/virtio/virtgpu_submit.c:295 [inline]
	RIP: 0010:virtio_gpu_init_submit drivers/gpu/drm/virtio/virtgpu_submit.c:398 [inline]
	RIP: 0010:virtio_gpu_execbuffer_ioctl+0xc78/0x1aa0 drivers/gpu/drm/virtio/virtgpu_submit.c:505
	Code: 85 ed 0f 85 21 09 00 00 e8 05 5a c9 fb 48 8b 44 24 10 48 8d b8 90 00 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 9a 0d 00 00 48 8b 44 24 10 4c 89 b0 90 00 00 00
	RSP: 0018:ffffc900039dfad0 EFLAGS: 00010216
	RAX: dffffc0000000000 RBX: ffffc900039dfdd8 RCX: ffffffff85f6fd3d
	RDX: 0000000000000012 RSI: ffffffff85f6fd4b RDI: 0000000000000090
	RBP: 0000000000000000 R0virtio_gpu_virgl_process_cmd: ctrl 0x102, error 0x1203
	R10: 0000000000000000 R11: 0000000000000000 R12: ffff8880132c4000
	R13: 0000000000000000 R14: ffff888073b6c700 R15: 000000000000003b
	FS:  00007fab480b96c0(0000) GS:ffff8880eb6e9000(0000) knlGS:0000000000000000
	CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
	CR2: 00007effbf5e55a8 CR3: 0000000048d19000 CR4: 0000000000350ef0
	Call Trace:
	<TASK>
	drm_ioctl_kernel+0x1f4/0x3e0 drivers/gpu/drm/drm_ioctl.c:817
	drm_ioctl+0x5f4/0xc70 drivers/gpu/drm/drm_ioctl.c:914
	vfs_ioctl fs/ioctl.c:51 [inline]
	__do_sys_ioctl fs/ioctl.c:597 [inline]
	__se_sys_ioctl fs/ioctl.c:583 [inline]
	__x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583
	do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
	do_syscall_64+0x116/0x800 arch/x86/entry/syscall_64.c:94
	entry_SYSCALL_64_after_hwframe+0x77/0x7f
	RIP: 0033:0x7fab471a82bd
	Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
	RSP: 002b:00007fab480b9018 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
	RAX: ffffffffffffffda RBX: 00007fab47435fa0 RCX: 00007fab471a82bd
	RDX: 00002000000000c0 RSI: 00000000c0406442 RDI: 0000000000000003
	RBP: 00007fab480b9080 R08: 0000000000000000 R09: 0000000000000000
	R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
	R13: 00007fab47436038 R14: 00007fab47435fa0 R15: 00007ffe85ab0740
	</TASK>
	Modules linked in:
	---[ end trace 0000000000000000 ]---
	RIP: 0010:virtio_gpu_fence_event_create drivers/gpu/drm/virtio/virtgpu_submit.c:295 [inline]
	RIP: 0010:virtio_gpu_init_submit drivers/gpu/drm/virtio/virtgpu_submit.c:398 [inline]
	RIP: 0010:virtio_gpu_execbuffer_ioctl+0xc78/0x1aa0 drivers/gpu/drm/virtio/virtgpu_submit.c:505
	Code: 85 ed 0f 85 21 09 00 00 e8 05 5a c9 fb 48 8b 44 24 10 48 8d b8 90 00 00 00 48 b8 00 00 00 00 00 fc ff df 48 89 fa 48 c1 ea 03 <80> 3c 02 00 0f 85 9a 0d 00 00 48 8b 44 24 10 4c 89 b0 90 00 00 00
	RSP: 0018:ffffc900039dfad0 EFLAGS: 00010216
	RAX: dffffc0000000000 RBX: ffffc900039dfdd8 RCX: ffffffff85f6fd3d
	RDX: 0000000000000012 RSI: ffffffff85f6fd4b RDI: 0000000000000090
	RBP: 0000000000000000 R08: 0000000000000005 R09: 0000000000000000
	R10: 0000000000000000 R11: 0000000000000000 R12: ffff8880132c4000
	R13: 0000000000000000 R14: ffff888073b6c700 R15: 000000000000003b
	FS:  00007fab480b96c0(0000) GS:ffff888098ae9000(0000) knlGS:0000000000000000
	CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
	CR2: 00007f24c3759000 CR3: 0000000048d19000 CR4: 0000000000350ef0
	----------------
	Code disassembly (best guess):
	0:	85 ed                	test   %ebp,%ebp
	2:	0f 85 21 09 00 00    	jne    0x929
	8:	e8 05 5a c9 fb       	call   0xfbc95a12
	d:	48 8b 44 24 10       	mov    0x10(%rsp),%rax
	12:	48 8d b8 90 00 00 00 	lea    0x90(%rax),%rdi
	19:	48 b8 00 00 00 00 00 	movabs $0xdffffc0000000000,%rax
	20:	fc ff df
	23:	48 89 fa             	mov    %rdi,%rdx
	26:	48 c1 ea 03          	shr    $0x3,%rdx
	* 2a:	80 3c 02 00          	cmpb   $0x0,(%rdx,%rax,1) <-- trapping instruction
	2e:	0f 85 9a 0d 00 00    	jne    0xdce
	34:	48 8b 44 24 10       	mov    0x10(%rsp),%rax
	39:	4c 89 b0 90 00 00 00 	mov    %r14,0x90(%rax)

Fix by checking virtio_gpu_fence_alloc() in virtio_gpu_init_submit() and
returning -ENOMEM before any later code can dereference the NULL fence.

Fixes: 70d1ace56db6 ("drm/virtio: Conditionally allocate virtio_gpu_fence")
Cc: stable@vger.kernel.org
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Assisted-by: Codex:gpt-5.5
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/00EFE4BA92889B14+20260909091114.2622550-1-peiyang_he@smail.nju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/virtio/virtgpu_submit.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

--- a/drivers/gpu/drm/virtio/virtgpu_submit.c
+++ b/drivers/gpu/drm/virtio/virtgpu_submit.c
@@ -389,10 +389,13 @@ static int virtio_gpu_init_submit(struct
 	if ((exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_OUT) ||
 	    exbuf->num_out_syncobjs ||
 	    exbuf->num_bo_handles ||
-	    drm_fence_event)
+	    drm_fence_event) {
 		out_fence = virtio_gpu_fence_alloc(vgdev, fence_ctx, ring_idx);
-	else
+		if (!out_fence)
+			return -ENOMEM;
+	} else {
 		out_fence = NULL;
+	}
 
 	if (drm_fence_event) {
 		err = virtio_gpu_fence_event_create(dev, file, out_fence, ring_idx);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 498/877] gpio: tps65219: Fix GPIO input value reads
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (496 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 497/877] drm/virtio: fix NULL pointer dereference on fence allocation failure Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 499/877] mm/hugetlb: preserve mremap address delta when skipping page tables Greg Kroah-Hartman
                   ` (386 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Jonathan Cormier,
	Bartosz Golaszewski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Karl Mehltretter <kmehltretter@gmail.com>

commit 4cbe530c0233c7413aaaeb029a4f32dd6aadacbb upstream.

TPS65219_MFP_GPIO_STATUS_MASK is already BIT(4). Passing it to BIT()
again tests bit 16, which cannot be set in the 8-bit MFP_CTRL register,
so GPIO0 is always reported low when configured as an input.

Test the register value with the mask directly.

Fixes: 57e30e00bd5b ("gpio: tps65219: add GPIO support for TPS65219 PMIC")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Jonathan Cormier <jcormier@criticallink.com>
Link: https://patch.msgid.link/20260919171100.90430-2-kmehltretter@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpio/gpio-tps65219.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/gpio/gpio-tps65219.c
+++ b/drivers/gpio/gpio-tps65219.c
@@ -53,7 +53,7 @@ static int tps65219_gpio_get(struct gpio
 	if (ret)
 		return ret;
 
-	ret = !!(val & BIT(TPS65219_MFP_GPIO_STATUS_MASK));
+	ret = !!(val & TPS65219_MFP_GPIO_STATUS_MASK);
 	dev_warn(dev, "GPIO%d = %d, MULTI_DEVICE_ENABLE, not a standard GPIO\n", offset, ret);
 
 	/*



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 499/877] mm/hugetlb: preserve mremap address delta when skipping page tables
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (497 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 498/877] gpio: tps65219: Fix GPIO input value reads Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 500/877] PCI: of_property: Omit bus properties without a subordinate bus Greg Kroah-Hartman
                   ` (385 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jaewook You, Andrew Morton,
	David Hildenbrand (Arm), Johan Hovold, Muchun Song,
	Oscar Salvador

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jaewook You <jaewook376@gmail.com>

commit 9bdad082d44bdcf93716973dcba6be77e8a06e7b upstream.

move_hugetlb_page_tables() optimizes mremap() by advancing to the last
entry in the page table when the source page table does not exist, either
initially or after unsharing a PMD table.  The common loop increment then
steps to the first entry in the next page table.

However, the code advances both the source and destination addresses to
the last entries in their respective page tables, which is wrong.  The
destination address must be advanced only by the same amount as the source
address.

If the source and destination offsets within their page tables differ, the
destination address can be advanced too far, causing follow-up issues.
Fix this by advancing the destination address by the source advance
distance.

With a reproducer, we were able to trigger a kernel panic on x86-64.  With
this fix in place, we can no longer reproduce the issue.

Link: https://lore.kernel.org/20260914132352.472-1-jaewook376@gmail.com
Fixes: e95a9851787b ("hugetlb: skip to end of PT page mapping when pte not present")
Fixes: 4ddb4d91b82f ("hugetlb: do not update address in huge_pmd_unshare")
Signed-off-by: Jaewook You <jaewook376@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Johan Hovold <johan@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: <stable@vger.kernel.org>
Assisted-by: LLM
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 mm/hugetlb.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5473,18 +5473,21 @@ int move_hugetlb_page_tables(struct vm_a
 	hugetlb_vma_lock_write(vma);
 	i_mmap_lock_write(mapping);
 	for (; old_addr < old_end; old_addr += sz, new_addr += sz) {
+		const unsigned long offset_to_last_entry =
+			(old_addr | last_addr_mask) - old_addr;
+
 		src_pte = hugetlb_walk(vma, old_addr, sz);
 		if (!src_pte) {
-			old_addr |= last_addr_mask;
-			new_addr |= last_addr_mask;
+			old_addr += offset_to_last_entry;
+			new_addr += offset_to_last_entry;
 			continue;
 		}
 		if (huge_pte_none(huge_ptep_get(mm, old_addr, src_pte)))
 			continue;
 
 		if (huge_pmd_unshare(&tlb, vma, old_addr, src_pte)) {
-			old_addr |= last_addr_mask;
-			new_addr |= last_addr_mask;
+			old_addr += offset_to_last_entry;
+			new_addr += offset_to_last_entry;
 			continue;
 		}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 500/877] PCI: of_property: Omit bus properties without a subordinate bus
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (498 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 499/877] mm/hugetlb: preserve mremap address delta when skipping page tables Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 501/877] HID: alps: fix use-after-free on input2 registration failure Greg Kroah-Hartman
                   ` (384 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Angel J, Bjorn Helgaas

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Angel J <iamanaws@httpd.dev>

commit 8805840aad73df7146778be243a196d48b4f6430 upstream.

A bridge (a device with a Type 1 header) may not have a secondary bus
allocated (pdev->subordinate), e.g., if there are no available bus numbers
or the bridge secondary/subordinate bus numbers are not writable.

The dynamic OF helpers of_pci_prop_bus_range() and of_pci_prop_intr_map()
dereference pdev->subordinate without checking it.  When
CONFIG_PCI_DYNAMIC_OF_NODES is enabled, this can cause a NULL pointer
dereference and early boot hang.

Generate 'bus-range' and 'interrupt-map' properties only when a subordinate
bus exists.  Keep the node and its remaining properties for bridges without
one.

The problem was latent since 407d1a51921e ("PCI: Create device tree node
for bridge"), but wasn't reachable until 1f340724419e ("PCI: of: Create
device tree PCI host bridge node"), which appeared in v6.15.  Before
1f340724419e, of_pci_make_dev_node() returned early because the parent OF
node was missing.

Fixes: 407d1a51921e ("PCI: Create device tree node for bridge")
Signed-off-by: Angel J <iamanaws@httpd.dev>
[bhelgaas: move pdev->subordinate test to callees, commit log]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org	# v6.6+
Link: https://patch.msgid.link/20260918195540.GA1187209@bhelgaas
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/pci/of_property.c |   11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

--- a/drivers/pci/of_property.c
+++ b/drivers/pci/of_property.c
@@ -91,9 +91,13 @@ static int of_pci_prop_bus_range(struct
 				 struct of_changeset *ocs,
 				 struct device_node *np)
 {
-	u32 bus_range[] = { pdev->subordinate->busn_res.start,
-			    pdev->subordinate->busn_res.end };
+	u32 bus_range[2];
 
+	if (!pdev->subordinate)
+		return 0;
+
+	bus_range[0] = pdev->subordinate->busn_res.start;
+	bus_range[1] = pdev->subordinate->busn_res.end;
 	return of_changeset_add_prop_u32_array(ocs, np, "bus-range", bus_range,
 					       ARRAY_SIZE(bus_range));
 }
@@ -216,6 +220,9 @@ static int of_pci_prop_intr_map(struct p
 	int ret;
 	u8 pin;
 
+	if (!pdev->subordinate)
+		return 0;
+
 	pnode = pci_device_to_OF_node(pdev->bus->self);
 	if (!pnode)
 		pnode = pci_bus_to_OF_node(pdev->bus);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 501/877] HID: alps: fix use-after-free on input2 registration failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (499 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 500/877] PCI: of_property: Omit bus properties without a subordinate bus Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 502/877] HID: quirks: add ALWAYS_POLL quirk for SDINNOVATION gaming keyboard Greg Kroah-Hartman
                   ` (383 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Chen Changcheng, Jiri Kosina

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Chen Changcheng <chenchangcheng@kylinos.cn>

commit d3aba3442798ce4a4c8ce3104d7b286d61e605f9 upstream.

alps_input_configured() stores data->input2 before calling
input_register_device().  If registration fails, input_free_device()
frees the input device but data->input2 still points to the freed memory.
alps_input_configured() calls hid_hw_open() before allocating input2, so
URBs are already active and raw_event can fire during the failure window.
A U1_SP_ABSOLUTE_REPORT_ID report arriving then causes u1_raw_event()
to dereference the freed data->input2 -> use-after-free.

Fix by only storing input2 into drvdata after successful registration
and adding a NULL guard in the raw_event path.

Fixes: 2562756dde55 ("HID: add Alps I2C HID Touchpad-Stick support")
Cc: stable@vger.kernel.org
Signed-off-by: Chen Changcheng <chenchangcheng@kylinos.cn>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/hid/hid-alps.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

--- a/drivers/hid/hid-alps.c
+++ b/drivers/hid/hid-alps.c
@@ -407,6 +407,8 @@ static int u1_raw_event(struct alps_dev
 		return 1;
 
 	case U1_SP_ABSOLUTE_REPORT_ID:
+		if (!hdata->input2)
+			return 0;
 		sp_x = get_unaligned_le16(data+2);
 		sp_y = get_unaligned_le16(data+4);
 
@@ -738,7 +740,6 @@ static int alps_input_configured(struct
 			goto exit;
 		}
 
-		data->input2 = input2;
 		input2->phys = input->phys;
 		input2->name = "DualPoint Stick";
 		input2->id.bustype = BUS_I2C;
@@ -762,11 +763,12 @@ static int alps_input_configured(struct
 		__set_bit(INPUT_PROP_POINTER, input2->propbit);
 		__set_bit(INPUT_PROP_POINTING_STICK, input2->propbit);
 
-		if (input_register_device(data->input2)) {
+		if (input_register_device(input2)) {
 			input_free_device(input2);
 			ret = -ENOENT;
 			goto exit;
 		}
+		data->input2 = input2;
 	}
 
 exit:



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 502/877] HID: quirks: add ALWAYS_POLL quirk for SDINNOVATION gaming keyboard
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (500 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 501/877] HID: alps: fix use-after-free on input2 registration failure Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 503/877] HID: wacom: fix OOB read in wacom_wac_pen_serial_enforce() Greg Kroah-Hartman
                   ` (382 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Marco Carvalho, Junjie Cao,
	Benjamin Tissoires

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Junjie Cao <junjie.cao@intel.com>

commit cdb669a3b8f844aca71fc3224990157d61562165 upstream.

The SDINNOVATION gaming keyboard (USB ID 36ae:feab) stops reporting
input events after its RGB lighting mode is switched about twice.
Disabling USB autosuspend and unbinding the other HID interfaces make
no difference; the issue does not occur on Windows.

HID_QUIRK_ALWAYS_POLL alone resolves it, verified on 7.1.8 via
usbhid.quirks=0x36ae:0xfeab:0x400.

Reported-by: Marco Carvalho <marcocarvalho.web@gmail.com>
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2514627
Cc: stable@vger.kernel.org
Signed-off-by: Junjie Cao <junjie.cao@intel.com>
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/hid/hid-ids.h    |    3 +++
 drivers/hid/hid-quirks.c |    1 +
 2 files changed, 4 insertions(+)

--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -1218,6 +1218,9 @@
 #define USB_DEVICE_ID_SAMSUNG_WIRELESS_UNIVERSAL_KBD	0xa006
 #define USB_DEVICE_ID_SAMSUNG_WIRELESS_MULTI_HOGP_KBD	0xa064
 
+#define USB_VENDOR_ID_SDINNOVATION		0x36ae
+#define USB_DEVICE_ID_SDINNOVATION_GAMING_KBD	0xfeab
+
 #define USB_VENDOR_ID_SEMICO			0x1a2c
 #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD	0x0023
 #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD2	0x0027
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -182,6 +182,7 @@ static const struct hid_device_id hid_qu
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_2), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X52_PRO), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_X65), HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SDINNOVATION, USB_DEVICE_ID_SDINNOVATION_GAMING_KBD), HID_QUIRK_ALWAYS_POLL },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD2), HID_QUIRK_NO_INIT_REPORTS },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SEMICO, USB_DEVICE_ID_SEMICO_USB_KEYKOARD), HID_QUIRK_NO_INIT_REPORTS },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB), HID_QUIRK_NOGET },



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 503/877] HID: wacom: fix OOB read in wacom_wac_pen_serial_enforce()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (501 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 502/877] HID: quirks: add ALWAYS_POLL quirk for SDINNOVATION gaming keyboard Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 504/877] net/mlx5: Fix rev_entry reference leak in mlx5_tc_ct_shared_counter_get() Greg Kroah-Hartman
                   ` (381 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jason Gerecke, Wei Jie Law,
	Jason Gerecke, Jiri Kosina

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wei Jie LAW <98lawweijie@gmail.com>

commit 9aa237cf66495b2426ddde8532e9b08a0ed83aaa upstream.

The 'wacom_wac_pen_serial_enforce()' function may calculate and pass an
invalid offset to hid_field_extract(), resulting in memory reads at
incorrect addresses -- possibly beyond the end of the report.  If a
field in the HID descriptor lists more usages than its Report Count
actually reserves space for, the function's inner 'j' will walk past
the end of the field:

	for (i = 0; i < report->maxfield; i++) {
		for (j = 0; j < report->field[i]->maxusage; j++) {
			...
			value = hid_field_extract(hdev, raw_data + 1,
						  offset + j * size, size);

A descriptor listing 12288 usages against Report Count 1 has the loop
extract the usage at index 12287 from bit offset 98296 -- about 12 KB
past a 2-byte received report.  The value is stored in
wacom_wac->serial[0] and can reach userspace as an MSC_SERIAL event,
making this an information disclosure.

Clamp the loop to field->report_count, the number of value slots the
report holds.  Value slots past the last declared usage are still
scanned; they reuse that usage (HID 1.11, 6.2.2.8).

Verified on v6.12.105 with a UHID reproducer: a 2-byte report from
such a descriptor trips KASAN before the patch and not after it.

Fixes: 83417206427b ("HID: wacom: Queue events with missing type/serial data for later processing")
Suggested-by: Jason Gerecke <killertofu@gmail.com>
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Assisted-by: GLM:glm-5.3
Signed-off-by: Wei Jie Law <98lawweijie@gmail.com>
Reviewed-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/hid/wacom_sys.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -97,8 +97,9 @@ static int wacom_wac_pen_serial_enforce(
 
 	/* Queue events which have invalid tool type or serial number */
 	for (i = 0; i < report->maxfield; i++) {
-		for (j = 0; j < report->field[i]->maxusage; j++) {
-			struct hid_field *field = report->field[i];
+		struct hid_field *field = report->field[i];
+
+		for (j = 0; j < field->report_count; j++) {
 			struct hid_usage *usage = &field->usage[j];
 			unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid);
 			unsigned int offset;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 504/877] net/mlx5: Fix rev_entry reference leak in mlx5_tc_ct_shared_counter_get()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (502 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 503/877] HID: wacom: fix OOB read in wacom_wac_pen_serial_enforce() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 505/877] net/mlx5e: advertise MACsec offload only when supported Greg Kroah-Hartman
                   ` (380 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Wentao Liang, Tariq Toukan,
	Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wentao Liang <vulab@iscas.ac.cn>

commit 0bf6bb567f0edaa771e7dd208ef98da50e6a4485 upstream.

When the reverse entry is found but its counter is already being
released, refcount_inc_not_zero() fails and the reference taken by
mlx5_tc_ct_entry_get() is never dropped before falling through to
create_counter.  Drop it so the reverse entry is not kept alive forever
by a shared counter lookup that did not use it.

Fixes: 1edae2335adf ("net/mlx5e: CT: Use the same counter for both directions")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260917113131.2149024-1-vulab@iscas.ac.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
@@ -1082,6 +1082,9 @@ mlx5_tc_ct_shared_counter_get(struct mlx
 
 	spin_unlock_bh(&ct_priv->ht_lock);
 
+	if (rev_entry)
+		mlx5_tc_ct_entry_put(rev_entry);
+
 create_counter:
 
 	shared_counter = mlx5_tc_ct_counter_create(ct_priv);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 505/877] net/mlx5e: advertise MACsec offload only when supported
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (503 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 504/877] net/mlx5: Fix rev_entry reference leak in mlx5_tc_ct_shared_counter_get() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 506/877] net/sched: reject IDR error pointers when deleting actions Greg Kroah-Hartman
                   ` (379 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Tariq Toukan, Ralf Lici,
	Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ralf Lici <ralf@mandelbit.com>

commit 4581c3d2adc3c73a019bc38db64ca11f28bbd7fd upstream.

Commit 339ccec8d43d ("net/mlx5: Enable MACsec offload feature for VLAN
interface") added NETIF_F_HW_MACSEC unconditionally to vlan_features so
that VLAN devices could inherit MACsec offload support.

mlx5e_build_nic_netdev subsequently copies vlan_features into
hw_features and features. As a result, all mlx5e NIC netdevices
advertise MACsec hardware offload, even when the firmware does not
support it and the driver does not install macsec_ops.

Set the MACsec feature bits in mlx5e_macsec_build_netdev, after device
capabilities have been validated. This preserves MACsec-over-VLAN
support and the ethtool feature control on capable devices, without
advertising either on unsupported hardware.

Fixes: 339ccec8d43d ("net/mlx5: Enable MACsec offload feature for VLAN interface")
Cc: stable@vger.kernel.org
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Link: https://patch.msgid.link/20260917122724.654639-1-ralf@mandelbit.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c |    2 ++
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c         |    1 -
 2 files changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
@@ -1727,6 +1727,8 @@ void mlx5e_macsec_build_netdev(struct ml
 	mlx5_core_dbg(priv->mdev, "mlx5e: MACsec acceleration enabled\n");
 	netdev->macsec_ops = &macsec_offload_ops;
 	netdev->features |= NETIF_F_HW_MACSEC;
+	netdev->hw_features |= NETIF_F_HW_MACSEC;
+	netdev->vlan_features |= NETIF_F_HW_MACSEC;
 	netif_keep_dst(netdev);
 }
 
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -5433,7 +5433,6 @@ static void mlx5e_build_nic_netdev(struc
 
 	netdev->vlan_features    |= NETIF_F_SG;
 	netdev->vlan_features    |= NETIF_F_HW_CSUM;
-	netdev->vlan_features    |= NETIF_F_HW_MACSEC;
 	netdev->vlan_features    |= NETIF_F_GRO;
 	netdev->vlan_features    |= NETIF_F_TSO;
 	netdev->vlan_features    |= NETIF_F_TSO6;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 506/877] net/sched: reject IDR error pointers when deleting actions
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (504 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 505/877] net/mlx5e: advertise MACsec offload only when supported Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 507/877] net: arp: terminate device name before lookup Greg Kroah-Hartman
                   ` (378 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Xiang Mei, Weiming Shi,
	Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Weiming Shi <bestswngs@gmail.com>

commit c82b797abe668d0b668601a93ba2c0b071a63574 upstream.

tcf_action_delete() drops the reference held by its lookup before calling
tcf_idr_delete_index() with the saved action index.  An unlocked
classifier can remove that action and reserve the same IDR slot with
ERR_PTR(-EBUSY) in between.

tcf_idr_delete_index() only checks the lookup result for NULL.  It
therefore treats the reservation as a tc_action and dereferences
tcfa_bindcnt.  A hardware execution breakpoint was used to schedule the
interleaving without changing the kernel source.  KASAN reported this
decoded trace:

  BUG: KASAN: null-ptr-deref in tca_action_gd+0x5b9/0x1010
  Read of size 4 at addr 0000000000000010 by task poc/150
  Oops: general protection fault, probably for non-canonical address 0xdffffc0000000002
  RIP: tca_action_gd+0x5c0/0x1010:
    arch_atomic_read at arch/x86/include/asm/atomic.h:23
    raw_atomic_read at include/linux/atomic/atomic-arch-fallback.h:457
    atomic_read at include/linux/atomic/atomic-instrumented.h:33
    tcf_idr_delete_index at net/sched/act_api.c:766
    tcf_action_delete at net/sched/act_api.c:1859
    tcf_del_notify at net/sched/act_api.c:2014
    tca_action_gd at net/sched/act_api.c:2064
  R13: 0000000000000010 R15: fffffffffffffff0
  Kernel panic - not syncing: Fatal exception

R15 contains ERR_PTR(-EBUSY), and adding the tcfa_bindcnt offset produces
the address in R13.  With the guard applied, the same reproducer returned
-ENOENT without a KASAN report or panic.  Treat error pointers as absent
and return -ENOENT.

Fixes: 0190c1d452a9 ("net: sched: atomically check-allocate action")
Cc: stable@vger.kernel.org
Reported-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Link: https://patch.msgid.link/20260914065123.4109709-2-bestswngs@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/sched/act_api.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -714,7 +714,7 @@ static int tcf_idr_delete_index(struct t
 
 	mutex_lock(&idrinfo->lock);
 	p = idr_find(&idrinfo->action_idr, index);
-	if (!p) {
+	if (IS_ERR_OR_NULL(p)) {
 		mutex_unlock(&idrinfo->lock);
 		return -ENOENT;
 	}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 507/877] net: arp: terminate device name before lookup
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (505 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 506/877] net/sched: reject IDR error pointers when deleting actions Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 508/877] net: atl1: fix soft lockup on out-of-range cmb_tpd_next_to_clean read Greg Kroah-Hartman
                   ` (377 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Zijie Huang, Ren Wei,
	Ido Schimmel, Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Zijie Huang <milkory@outlook.com>

commit d8b6529e80bcb4fb8177121404cbb3377acaebd2 upstream.

The ARP ioctl copies a user-provided struct arpreq into a stack object. Its
arp_dev field may contain IFNAMSIZ bytes without a NUL terminator.

Such input is passed to dev_get_by_name_rcu() or __dev_get_by_name(), where
strcmp() can read past the end of the stack object when a matching
alternative interface name exists.

Terminate the field before the lookup to prevent the out-of-bounds read.

Fixes: 36fbf1e52bd3 ("net: rtnetlink: add linkprop commands to add and delete alternative ifnames")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zijie Huang <milkory@outlook.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/fabf02a70787d17299e4b3153eadffaf20d154b3.1789910973.git.milkory@outlook.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv4/arp.c |    1 +
 1 file changed, 1 insertion(+)

--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1276,6 +1276,7 @@ int arp_ioctl(struct net *net, unsigned
 		err = copy_from_user(&r, arg, sizeof(struct arpreq));
 		if (err)
 			return -EFAULT;
+		r.arp_dev[IFNAMSIZ - 1] = '\0';
 		break;
 	default:
 		return -EINVAL;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 508/877] net: atl1: fix soft lockup on out-of-range cmb_tpd_next_to_clean read
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (506 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 507/877] net: arp: terminate device name before lookup Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 509/877] net: hisilicon: hns_dsaf_mac: fix mdio device leak in hns_mac_register_phy() Greg Kroah-Hartman
                   ` (376 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Gajdos Tamás, Paolo Abeni

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Gajdos Tamás <tamas@rimpianto.com>

commit 43e746821f5f5afbbf68e388bf9fbe221e03bfca upstream.

Same issue as atl1c (see the first commit in this series, "net:
atl1c: fix soft lockup on out-of-range tpd_cons read"): the hardware
can report an out-of-range cmb_tpd_next_to_clean (seen as 0xffff)
while the PCIe link/MAC is resetting. An out-of-range value can
never be reached and the loop below would spin forever. Treat it as
"nothing new to clean" instead.

Fixes: f3cc28c797604f ("Add Attansic L1 ethernet driver.")
Cc: stable@vger.kernel.org
Signed-off-by: Gajdos Tamás <tamas@rimpianto.com>
Link: https://patch.msgid.link/20260921091334.3571525-4-tamas@rimpianto.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/atheros/atlx/atl1.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/net/ethernet/atheros/atlx/atl1.c
+++ b/drivers/net/ethernet/atheros/atlx/atl1.c
@@ -2066,6 +2066,9 @@ static int atl1_intr_tx(struct atl1_adap
 	sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean);
 	cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx);
 
+	if (unlikely(cmb_tpd_next_to_clean >= tpd_ring->count))
+		cmb_tpd_next_to_clean = sw_tpd_next_to_clean;
+
 	while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) {
 		buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean];
 		if (buffer_info->dma) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 509/877] net: hisilicon: hns_dsaf_mac: fix mdio device leak in hns_mac_register_phy()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (507 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 508/877] net: atl1: fix soft lockup on out-of-range cmb_tpd_next_to_clean read Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 510/877] net: openvswitch: conntrack: avoid modifying shared unconfirmed ct entry Greg Kroah-Hartman
                   ` (375 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Simon Horman,
	Paolo Abeni

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wentao Liang <vulab@iscas.ac.cn>

commit 999e8295bc41d6ce45b8e54f88150efa96f3f01e upstream.

hns_dsaf_find_platform_device() returns the mdio platform device with its
reference count incremented. hns_mac_register_phy() never drops that
reference, so the mdio device can not be released.

Release the reference on both the deferred probe and the normal path.

Fixes: 1d1afa2ebf82 ("net: hns: register phy device in each mac initial sequence")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260917110828.2148390-1-vulab@iscas.ac.cn
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
@@ -793,6 +793,7 @@ static int hns_mac_register_phy(struct h
 		dev_err(mac_cb->dev,
 			"mac%d mdio is NULL, dsaf will probe again later\n",
 			mac_cb->mac_id);
+		put_device(&pdev->dev);
 		return -EPROBE_DEFER;
 	}
 
@@ -801,6 +802,8 @@ static int hns_mac_register_phy(struct h
 		dev_dbg(mac_cb->dev, "mac%d register phy addr:%d\n",
 			mac_cb->mac_id, addr);
 
+	put_device(&pdev->dev);
+
 	return rc;
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 510/877] net: openvswitch: conntrack: avoid modifying shared unconfirmed ct entry
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (508 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 509/877] net: hisilicon: hns_dsaf_mac: fix mdio device leak in hns_mac_register_phy() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 511/877] net: openvswitch: conntrack: remove add_helper dead code Greg Kroah-Hartman
                   ` (374 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Axel Mierczuk, Ilya Maximets,
	Aaron Conole, Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ilya Maximets <i.maximets@ovn.org>

commit 26b2bd70d22457556e2fa01cbf1192cb1a94d619 upstream.

In a case where skb with an unconfirmed ct entry gets cloned, we may
end up committing both but with different sets of extensions.

The series of events:

 1. The first clone wants to commit and runs the helpers wiring up
    the extension pointer into the expectation list.
 2. Then it looses the confirmation keeping the entry unconfirmed.
 3. Second clone now wants to commit labels and adds the new extension
    for that breaking the pointer in the expectation list causing
    UAF on the destruction path later.

While this is possible to trigger, there should be no practical
network pipeline where committing both clones without modifications
into the same zone is needed.  So, let's just reset the entry in case
for some reason we got an skb with a shared one during commit.  This
doesn't affect any known use cases, but avoids any potential problems
with sharing and modification of the unconfirmed ct entry.

The fixes tag points to the introduction of helpers, since that's the
main UAF trigger for the sharing.

Fixes: cae3a2627520 ("openvswitch: Allow attaching helpers to ct action")
Cc: stable@vger.kernel.org
Reported-by: Axel Mierczuk <axel.mierczuk@1password.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/20260921145655.3167436-2-i.maximets@ovn.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/net/netfilter/nf_conntrack.h |    5 +++++
 net/openvswitch/conntrack.c          |   12 ++++++++++++
 2 files changed, 17 insertions(+)

--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -186,6 +186,11 @@ static inline void nf_ct_put(struct nf_c
 		nf_ct_destroy(&ct->ct_general);
 }
 
+static inline bool nf_ct_shared(const struct nf_conn *ct)
+{
+	return refcount_read(&ct->ct_general.use) > 1;
+}
+
 /* load module; enable/disable conntrack in this namespace */
 int nf_ct_netns_get(struct net *net, u8 nfproto);
 void nf_ct_netns_put(struct net *net, u8 nfproto);
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -734,6 +734,18 @@ static int __ovs_ct_lookup(struct net *n
 	enum ip_conntrack_info ctinfo;
 	struct nf_conn *ct;
 
+	/* If the ct entry is not confirmed and shared with some other skb,
+	 * e.g., a cloned one, we can't just modify it with the commit as we
+	 * must not modify the extension set.  Reset.
+	 */
+	if (cached && info->commit) {
+		ct = nf_ct_get(skb, &ctinfo);
+		if (ct && !nf_ct_is_confirmed(ct) && nf_ct_shared(ct)) {
+			nf_reset_ct(skb);
+			cached = false;
+		}
+	}
+
 	if (!cached) {
 		struct nf_hook_state state = {
 			.hook = NF_INET_PRE_ROUTING,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 511/877] net: openvswitch: conntrack: remove add_helper dead code
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (509 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 510/877] net: openvswitch: conntrack: avoid modifying shared unconfirmed ct entry Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 512/877] net: openvswitch: conntrack: fix helper UAF due to extensions realloc Greg Kroah-Hartman
                   ` (373 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ilya Maximets, Aaron Conole,
	Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ilya Maximets <i.maximets@ovn.org>

commit 5e6c14dd42a1c1fe938e573dc6c9098145b2b0c4 upstream.

This variable can only become 'true' when the connection is not
confirmed, but it is only checked when it is confirmed.  So, it can be
treated as being always false and just removed.

Fixes: 3c1860543fcc ("openvswitch: add nf_ct_is_confirmed check before assigning the helper")
Cc: stable@vger.kernel.org
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/20260921145655.3167436-3-i.maximets@ovn.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/openvswitch/conntrack.c |   10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -779,8 +779,6 @@ static int __ovs_ct_lookup(struct net *n
 
 	ct = nf_ct_get(skb, &ctinfo);
 	if (ct) {
-		bool add_helper = false;
-
 		/* Packets starting a new connection must be NATted before the
 		 * helper, so that the helper knows about the NAT.  We enforce
 		 * this by delaying both NAT and helper calls for unconfirmed
@@ -812,7 +810,6 @@ static int __ovs_ct_lookup(struct net *n
 							    GFP_ATOMIC);
 			if (err)
 				return err;
-			add_helper = true;
 
 			/* helper installed, add seqadj if NAT is required */
 			if (info->nat && !nfct_seqadj(ct)) {
@@ -822,13 +819,10 @@ static int __ovs_ct_lookup(struct net *n
 		}
 
 		/* Call the helper only if:
-		 * - nf_conntrack_in() was executed above ("!cached") or a
-		 *   helper was just attached ("add_helper") for a confirmed
-		 *   connection, or
+		 * - nf_conntrack_in() was executed above ("!cached"), or
 		 * - When committing an unconfirmed connection.
 		 */
-		if ((nf_ct_is_confirmed(ct) ? !cached || add_helper :
-					      info->commit)) {
+		if ((nf_ct_is_confirmed(ct) ? !cached : info->commit)) {
 			int err = nf_ct_helper(skb, ct, ctinfo, info->family);
 
 			err = verdict_to_errno(err);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 512/877] net: openvswitch: conntrack: fix helper UAF due to extensions realloc
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (510 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 511/877] net: openvswitch: conntrack: remove add_helper dead code Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 513/877] net: atl1c: fix soft lockup on out-of-range tpd_cons read Greg Kroah-Hartman
                   ` (372 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Axel Mierczuk, Ilya Maximets,
	Aaron Conole, Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ilya Maximets <i.maximets@ovn.org>

commit 1a4151e6be57b098b7a5ebfbde58585e83200cdc upstream.

While calling the helpers, a raw pointer to the extensions area is
wired into expectations list:

  -> nf_ct_helper()
   -> helper->help()
    -> nf_ct_expect_related_report()
     -> nf_ct_expect_insert()
      -> hlist_add_head_rcu(&exp->lnode, &master_help->expectations)

In case the connection is not confirmed yet, more extensions can be
added afterwards with *_ext_add() calls reallocating the extension
space and leaving the now invalid pointer in the expectations list
that is later accessed while removing the expectation.

Make sure that helpers are called at the end after all the other
extensions are already added.

Note that the helper rejection now leaves the mark and labels set,
but that's not different from how the NAT was handled before or how
the mark and the labels were handled on confirmation failure.  And
there are no atomicity guarantees provided by the API anyway.

Fixes: cae3a2627520 ("openvswitch: Allow attaching helpers to ct action")
Cc: stable@vger.kernel.org
Reported-by: Axel Mierczuk <axel.mierczuk@1password.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/20260921145655.3167436-4-i.maximets@ovn.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/openvswitch/conntrack.c |   19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -818,11 +818,14 @@ static int __ovs_ct_lookup(struct net *n
 			}
 		}
 
-		/* Call the helper only if:
-		 * - nf_conntrack_in() was executed above ("!cached"), or
-		 * - When committing an unconfirmed connection.
+		/* Call the helper only if nf_conntrack_in() was executed
+		 * above ("!cached").
+		 *
+		 * For unconfirmed connections it will be called later during
+		 * commit as we need to have all the other extensions allocated
+		 * before the call.
 		 */
-		if ((nf_ct_is_confirmed(ct) ? !cached : info->commit)) {
+		if (nf_ct_is_confirmed(ct) && !cached) {
 			int err = nf_ct_helper(skb, ct, ctinfo, info->family);
 
 			err = verdict_to_errno(err);
@@ -1025,6 +1028,14 @@ static int ovs_ct_commit(struct net *net
 			return err;
 
 		nf_conn_act_ct_ext_add(skb, ct, ctinfo);
+
+		/* Call the helpers now.  We couldn't do this before as
+		 * all the extensions must be allocated before the call.
+		 */
+		err = nf_ct_helper(skb, ct, ctinfo, info->family);
+		err = verdict_to_errno(err);
+		if (err)
+			return err;
 	} else if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS) &&
 		   labels_nonzero(&info->labels.mask)) {
 		err = ovs_ct_set_labels(ct, key, &info->labels.value,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 513/877] net: atl1c: fix soft lockup on out-of-range tpd_cons read
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (511 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 512/877] net: openvswitch: conntrack: fix helper UAF due to extensions realloc Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 514/877] net: atl1e: fix soft lockup on out-of-range hw_next_to_clean read Greg Kroah-Hartman
                   ` (371 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Gajdos Tamás, Paolo Abeni

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Gajdos Tamás <tamas@rimpianto.com>

commit 36c2009d90f2210ef92e6f4f2850e8b57b09e754 upstream.

The hardware can report an out-of-range tpd_cons (seen as 0xffff)
while the PCIe link/MAC is resetting. An out-of-range value can
never be reached and the loop below would spin forever. To avoid
a soft lockup treat it as "nothing new to clean" instead.

Reproduced on two machines, same NIC (Qualcomm Atheros AR8151 v2.0,
4-port), triggered by rebooting a Mikrotik CCR2004 PCIe card that
the ports are directly linked to:

- Ubuntu 26.04.1 LTS, kernel 7.0.0-31-generic. The link-flap
  precursor, before the lockup was captured with a full trace
  elsewhere:

    atl1c 0000:05:00.0 enp5s0f0: NETDEV WATCHDOG: CPU: 4: transmit queue 2 timed out 489984 ms
    atl1c 0000:05:00.0: MAC state machine can't be idle since disabled for 10ms second
    atl1c 0000:05:00.0: atl1c: enp5s0f0 NIC Link is Up<65535 Mbps Full Duplex>

  65535 (0xffff) here is the same value tpd_cons reads back once the
  loop below gets stuck.

- Proxmox VE, kernel 7.0.14-11-pve. Same NIC/trigger, this time
  caught by the soft lockup watchdog with a full stack trace:

    watchdog: BUG: soft lockup - CPU#12 stuck for 354s! [napi/eth%d-0:329]
    CPU: 12 UID: 0 PID: 329 Comm: napi/eth%d-0 Tainted: P O L 7.0.14-11-pve #1 PREEMPT(lazy)
    RIP: 0010:atl1c_clean_tx+0x142/0x2d0 [atl1c]
    Call Trace:
     <TASK>
     __napi_poll+0x32/0x1e0
     napi_threaded_poll_loop+0x286/0x2e0
     napi_threaded_poll+0xfd/0x140
     kthread+0xf7/0x130
     ret_from_fork+0x2da/0x3a0
     ret_from_fork_asm+0x1a/0x30
     </TASK>

Fixes: 43250ddd75a35d ("atl1c: Atheros L1C Gigabit Ethernet driver")
Cc: stable@vger.kernel.org
Signed-off-by: Gajdos Tamás <tamas@rimpianto.com>
Link: https://patch.msgid.link/20260921091334.3571525-2-tamas@rimpianto.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/atheros/atl1c/atl1c_main.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -1602,6 +1602,9 @@ static int atl1c_clean_tx(struct napi_st
 	AT_READ_REGW(&adapter->hw, atl1c_qregs[tpd_ring->num].tpd_cons,
 		     &hw_next_to_clean);
 
+	if (unlikely(hw_next_to_clean >= tpd_ring->count))
+		hw_next_to_clean = next_to_clean;
+
 	while (next_to_clean != hw_next_to_clean) {
 		buffer_info = &tpd_ring->buffer_info[next_to_clean];
 		if (buffer_info->skb) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 514/877] net: atl1e: fix soft lockup on out-of-range hw_next_to_clean read
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (512 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 513/877] net: atl1c: fix soft lockup on out-of-range tpd_cons read Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 515/877] net: bridge: mdb: restart port group walk after deletion Greg Kroah-Hartman
                   ` (370 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Gajdos Tamás, Paolo Abeni

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Gajdos Tamás <tamas@rimpianto.com>

commit 374bf9e4b90f979e052332c4faca2d745c491a12 upstream.

Same issue as atl1c (see the first commit in this series, "net:
atl1c: fix soft lockup on out-of-range tpd_cons read"): the hardware
can report an out-of-range hw_next_to_clean (seen as 0xffff) while
the PCIe link/MAC is resetting. An out-of-range value can never be
reached and the loop below would spin forever. Treat it as "nothing
new to clean" instead.

Fixes: a6a5325239c202 ("atl1e: Atheros L1E Gigabit Ethernet driver")
Cc: stable@vger.kernel.org
Signed-off-by: Gajdos Tamás <tamas@rimpianto.com>
Link: https://patch.msgid.link/20260921091334.3571525-3-tamas@rimpianto.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/atheros/atl1e/atl1e_main.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
+++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c
@@ -1234,6 +1234,9 @@ static bool atl1e_clean_tx_irq(struct at
 	u16 hw_next_to_clean = AT_READ_REGW(&adapter->hw, REG_TPD_CONS_IDX);
 	u16 next_to_clean = atomic_read(&tx_ring->next_to_clean);
 
+	if (unlikely(hw_next_to_clean >= tx_ring->count))
+		hw_next_to_clean = next_to_clean;
+
 	while (next_to_clean != hw_next_to_clean) {
 		tx_buffer = &tx_ring->tx_buffer[next_to_clean];
 		if (tx_buffer->dma) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 515/877] net: bridge: mdb: restart port group walk after deletion
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (513 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 514/877] net: atl1e: fix soft lockup on out-of-range hw_next_to_clean read Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 516/877] net: usb: cdc_mbim: add MeiG Smart SRM821 to ZLP whitelist Greg Kroah-Hartman
                   ` (369 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Fourie Zhang, Nikolay Aleksandrov,
	Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Fourie Zhang <littleddfu@gmail.com>

commit ab1404ac81154a89fb61ac50ae9a04cd8d4834dc upstream.

br_mdb_flush_pgs() keeps a pointer-to-pointer cursor while walking
mp->ports. br_multicast_del_pg() can re-enter the same MDB entry through
br_multicast_sg_del_exclude_ports() and unlink other port groups. If the
cursor points into one of those groups, the next iteration dereferences a
stale cursor and can leave mp->ports pointing at freed memory.

A following RTM_GETMDB exposes the dangling pointer:

  BUG: KASAN: slab-use-after-free in br_mdb_dump
  Read of size 8
    br_mdb_dump
    rtnl_mdb_dump
    rtnl_dumpit
    netlink_dump

Reset the cursor to mp->ports after every deletion. The deletion removes at
least the selected group, so the restarted walk always makes progress.

Fixes: a6acb535afb2 ("bridge: mdb: Add MDB bulk deletion support")
Cc: stable@vger.kernel.org
Signed-off-by: Fourie Zhang <fouriezhang@tencent.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20260920110852.60293-1-fouriezhang@tencent.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/bridge/br_mdb.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/net/bridge/br_mdb.c
+++ b/net/bridge/br_mdb.c
@@ -1505,6 +1505,8 @@ static void br_mdb_flush_pgs(struct net_
 		}
 
 		br_multicast_del_pg(mp, p, pp);
+		/* br_multicast_del_pg() can remove other groups from this list. */
+		pp = &mp->ports;
 	}
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 516/877] net: usb: cdc_mbim: add MeiG Smart SRM821 to ZLP whitelist
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (514 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 515/877] net: bridge: mdb: restart port group walk after deletion Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 517/877] net: usb: lan78xx: Fix URB reference leak in lan78xx_submit_deferred_urbs() Greg Kroah-Hartman
                   ` (368 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Ming Wang, Jakub Kicinski

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ming Wang <wangming01@loongson.cn>

commit f75f21ef36285e5f56ee0c428bd2909ee81165b9 upstream.

The MeiG Smart SRM821 5G module (0x2dee:0x4d53) crashes and drops off
the USB bus when it receives a Zero Length Packet (ZLP) after sending
or receiving an NTB of exactly 16384 bytes (tx_max).

According to the MBIM specification, devices do not require a ZLP
if the NTB size is exactly dwNtbOutMaxSize. However, the cdc_mbim
driver defaults to sending ZLPs for devices not explicitly whitelisted
to accommodate non-conformant hardware. This default behavior breaks
the strictly conformant MeiG SRM821 module.

Add this device to the ZLP conformance whitelist (cdc_mbim_info) so
the driver will pad the NTB to avoid sending ZLPs, preventing the
device firmware from crashing.

Cc: stable@vger.kernel.org
Signed-off-by: Ming Wang <wangming01@loongson.cn>
Link: https://patch.msgid.link/20260920074500.826121-1-wangming01@loongson.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/usb/cdc_mbim.c |    5 +++++
 1 file changed, 5 insertions(+)

--- a/drivers/net/usb/cdc_mbim.c
+++ b/drivers/net/usb/cdc_mbim.c
@@ -634,6 +634,11 @@ static const struct usb_device_id mbim_d
 	  .driver_info = (unsigned long)&cdc_mbim_info,
 	},
 
+	/* MeiG Smart SRM821 ZLP conformance */
+	{ USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d53, USB_CLASS_COMM, USB_CDC_SUBCLASS_MBIM, USB_CDC_PROTO_NONE),
+	  .driver_info = (unsigned long)&cdc_mbim_info,
+	},
+
 	/* Some Huawei devices, ME906s-158 (12d1:15c1) and E3372
 	 * (12d1:157d), are known to fail unless the NDP is placed
 	 * after the IP packets.  Applying the quirk to all Huawei



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 517/877] net: usb: lan78xx: Fix URB reference leak in lan78xx_submit_deferred_urbs()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (515 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 516/877] net: usb: cdc_mbim: add MeiG Smart SRM821 to ZLP whitelist Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 518/877] netfilter: ip6t_rpfilter: reject routes without inet6_dev Greg Kroah-Hartman
                   ` (367 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Paolo Abeni

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wentao Liang <vulab@iscas.ac.cn>

commit 17741334d00bf5ebd37f8c1c36bc9c146a351deb upstream.

usb_get_from_anchor() hands over a reference to the URB, which the caller
must release. lan78xx_submit_deferred_urbs() never does, so every deferred
Tx URB keeps an extra reference: the counter grows on each suspend/resume
cycle and the URBs are never freed when the buffers are released. Drop
the reference after submitting, and on the path that drops the packet
instead of submitting it.

Fixes: 5f4cc6e25148 ("lan78xx: Fix race conditions in suspend/resume handling")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260917115811.2150119-1-vulab@iscas.ac.cn
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/usb/lan78xx.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -4932,10 +4932,12 @@ static bool lan78xx_submit_deferred_urbs
 		    !netif_carrier_ok(dev->net) ||
 		    pipe_halted) {
 			lan78xx_release_tx_buf(dev, skb);
+			usb_put_urb(urb);
 			continue;
 		}
 
 		ret = usb_submit_urb(urb, GFP_ATOMIC);
+		usb_put_urb(urb);
 
 		if (ret == 0) {
 			netif_trans_update(dev->net);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 518/877] netfilter: ip6t_rpfilter: reject routes without inet6_dev
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (516 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 517/877] net: usb: lan78xx: Fix URB reference leak in lan78xx_submit_deferred_urbs() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 519/877] netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read Greg Kroah-Hartman
                   ` (366 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, co+459f67f4d8af8ce6,
	Florian Westphal, Weiming Shi, Pablo Neira Ayuso

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Weiming Shi <bestswngs@gmail.com>

commit 1b9b5323725e458906c7620a3bc10398b51ad954 upstream.

ip6_route_lookup() can return an error-free route whose rt6i_idev is
NULL. Lowering an external nexthop device's MTU below IPV6_MIN_MTU tears
down its inet6_dev while fib6_ifdown() leaves routes using nexthop objects
in the FIB. An unprivileged user can construct this state with rtnetlink
in a private user and network namespace, then trigger a NULL dereference
through an IPv6 rpfilter lookup:

  Oops: general protection fault, probably for non-canonical address
  0xdffffc0000000000
  KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
  RIP: rpfilter_mt (net/ipv6/netfilter/ip6t_rpfilter.c:75)
  Call Trace:
  ip6t_do_table (net/ipv6/netfilter/ip6_tables.c:316)
  nf_hook_slow (net/netfilter/core.c:619)
  ipv6_rcv (net/ipv6/ip6_input.c:351)
  __netif_receive_skb_one_core (net/core/dev.c:6216)
  process_backlog (net/core/dev.c:6680)
  __napi_poll (net/core/dev.c:7739)
  net_rx_action (net/core/dev.c:7959)
  handle_softirqs (kernel/softirq.c:622)
  do_softirq.part.0 (kernel/softirq.c:523)
  __local_bh_enable_ip (kernel/softirq.c:450)
  __dev_queue_xmit (net/core/dev.c:4913)
  packet_sendmsg (net/packet/af_packet.c:3139)
  __sys_sendto (net/socket.c:2252)
  __x64_sys_sendto (net/socket.c:2259)
  do_syscall_64 (arch/x86/entry/syscall_64.c:94)
  entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
  Kernel panic - not syncing: Fatal exception in interrupt

Reject routes without an inet6_dev immediately after lookup. Such routes
are not eligible for reverse-path filtering, and the check protects all
later rt6i_idev dereferences.

Fixes: e26f9a480fb6 ("netfilter: add ipv6 reverse path filter match")
Reported-by: co+459f67f4d8af8ce6@bugs.sh
Closes: https://lore.kernel.org/all/VtWUkE8QzJt5CroTj2V2v3ZQ0gwbXZ7nq7I3@bugs.sh/
Suggested-by: Florian Westphal <fw@strlen.de>
Assisted-by: Claude:gpt-5
Cc: stable@vger.kernel.org
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv6/netfilter/ip6t_rpfilter.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/ipv6/netfilter/ip6t_rpfilter.c
+++ b/net/ipv6/netfilter/ip6t_rpfilter.c
@@ -61,7 +61,7 @@ static bool rpfilter_lookup_reverse6(str
 		fl6.flowi6_oif = dev->ifindex;
 
 	rt = (void *)ip6_route_lookup(net, &fl6, skb, lookup_flags);
-	if (rt->dst.error)
+	if (rt->dst.error || !rt->rt6i_idev)
 		goto out;
 
 	if (rt->rt6i_flags & (RTF_REJECT|RTF_ANYCAST))



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 519/877] netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (517 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 518/877] netfilter: ip6t_rpfilter: reject routes without inet6_dev Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 520/877] netfilter: nf_tables: skip expired catchall elements on insert and delete Greg Kroah-Hartman
                   ` (365 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Florian Westphal, Luxiao Xu,
	Ren Wei, Pablo Neira Ayuso

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Luxiao Xu <rakukuip@gmail.com>

commit 82313c169eddc02b1bf5ba6b427803e272d3ec42 upstream.

rt_mt6_check() permits rules to be configured with rtinfo->addrnr == 0
even when address matching (IP6T_RT_FST_MASK) is requested.

In the IP6T_RT_FST_NSTRICT path, rt_mt6() evaluates packet routing
addresses against rtinfo->addrs[i] and terminates backwards at the bottom
of the loop:

    if (ipv6_addr_equal(ap, &rtinfo->addrs[i])) {
        i++;
    }
    if (i == rtinfo->addrnr)
        break;

When addrnr is 0, if the first packet address matches rtinfo->addrs[0],
i is incremented to 1. Because i is now strictly greater than addrnr (0),
the loop termination condition (i == rtinfo->addrnr) is bypassed and will
never be satisfied.

If a crafted IPv6 packet contains matching routing addresses, i will
advance past IP6T_RT_HOPS (16). The subsequent call to ipv6_addr_equal()
reads beyond struct ip6t_rt, triggering UBSAN/KASAN out-of-bounds warnings
or kernel panics.

Fix this by:
1. Rejecting rules in rt_mt6_check() where IP6T_RT_FST_MASK is set but
   rtinfo->addrnr is zero.
2. In rt_mt6(), moving the termination condition (i < rtinfo->addrnr)
   into the for-loop header condition and removing the backwards break
   at the end of the loop body.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Suggested-by: Florian Westphal <fw@strlen.de>
Assisted-by: LLM
Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv6/netfilter/ip6t_rt.c |   11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -96,7 +96,8 @@ static bool rt_mt6(const struct sk_buff
 			unsigned int i = 0;
 
 			for (temp = 0;
-			     temp < (unsigned int)((hdrlen - 8) / 16);
+			     temp < (unsigned int)((hdrlen - 8) / 16) &&
+			     i < rtinfo->addrnr;
 			     temp++) {
 				ap = skb_header_pointer(skb,
 							ptr
@@ -112,8 +113,6 @@ static bool rt_mt6(const struct sk_buff
 
 				if (ipv6_addr_equal(ap, &rtinfo->addrs[i]))
 					i++;
-				if (i == rtinfo->addrnr)
-					break;
 			}
 			if (i == rtinfo->addrnr)
 				return ret;
@@ -162,6 +161,12 @@ static int rt_mt6_check(const struct xt_
 		pr_debug("too many addresses specified\n");
 		return -EINVAL;
 	}
+
+	if ((rtinfo->flags & IP6T_RT_FST_MASK) && !rtinfo->addrnr) {
+		pr_info_ratelimited("address list match requested but addrnr is 0\n");
+		return -EINVAL;
+	}
+
 	if ((rtinfo->flags & (IP6T_RT_RES | IP6T_RT_FST_MASK)) &&
 	    (!(rtinfo->flags & IP6T_RT_TYP) ||
 	     (rtinfo->rt_type != 0) ||



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 520/877] netfilter: nf_tables: skip expired catchall elements on insert and delete
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (518 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 519/877] netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 521/877] nfc: fix use-after-free in nfc_get_local_general_bytes Greg Kroah-Hartman
                   ` (364 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, TencentOS Corvus AI, Aohan Mei,
	Pablo Neira Ayuso

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Aohan Mei <henrymei@tencent.com>

commit 70194dc37670bd08e44b471389861cc01bd3a3c9 upstream.

nft_setelem_catchall_insert() looks up duplicates with
nft_set_elem_active() only, while nft_set_catchall_lookup() and the
dump path additionally skip expired elements.

Once a catchall element with a timeout expires, this predicate drift
makes it invisible to userspace dumps, yet it still blocks
re-insertion: with NLM_F_EXCL the request fails with -EEXIST, and
without it the request reports success but silently inserts nothing.
The stale entry only goes away when the (user-tunable) gc interval
elapses, so the catchall rule may silently stop matching for an
arbitrarily long time after its first expiration.

The delete path shows the same drift: nft_setelem_catchall_deactivate()
picks the first active-next entry in the catchall list, so with an
expired entry still pending GC it retires the stale entry instead of
the fresh one, and it deactivates an element that userspace no longer
sees instead of failing with -ENOENT.

Align both walks with the lookup and dump predicates: only an element
that is active and not expired counts as a duplicate or delete
candidate, using the per-netns timestamp taken at transaction start,
in line with the set backend .insert/.deactivate and catchall GC sync
paths.

Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Cc: stable@vger.kernel.org
Fixes: aaa31047a6d2 ("netfilter: nftables: add catch-all set element support")
Assisted-by: CodeBuddy:Kimi-K3
Signed-off-by: Aohan Mei <henrymei@tencent.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/netfilter/nf_tables_api.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -6617,11 +6617,14 @@ static int nft_setelem_catchall_insert(c
 {
 	struct nft_set_elem_catchall *catchall;
 	u8 genmask = nft_genmask_next(net);
+	u64 tstamp = nft_net_tstamp(net);
 	struct nft_set_ext *ext;
 
 	list_for_each_entry(catchall, &set->catchall_list, list) {
 		ext = nft_set_elem_ext(set, catchall->elem);
-		if (nft_set_elem_active(ext, genmask)) {
+		if (nft_set_elem_active(ext, genmask) &&
+		    !__nft_set_elem_expired(ext, tstamp) &&
+		    !nft_set_elem_is_dead(ext)) {
 			*priv = catchall->elem;
 			return -EEXIST;
 		}
@@ -6682,11 +6685,14 @@ static int nft_setelem_catchall_deactiva
 					   struct nft_set_elem *elem)
 {
 	struct nft_set_elem_catchall *catchall;
+	u64 tstamp = nft_net_tstamp(net);
 	struct nft_set_ext *ext;
 
 	list_for_each_entry(catchall, &set->catchall_list, list) {
 		ext = nft_set_elem_ext(set, catchall->elem);
-		if (!nft_is_active_next(net, ext))
+		if (!nft_is_active_next(net, ext) ||
+		    __nft_set_elem_expired(ext, tstamp) ||
+		    nft_set_elem_is_dead(ext))
 			continue;
 
 		kfree(elem->priv);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 521/877] nfc: fix use-after-free in nfc_get_local_general_bytes
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (519 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 520/877] netfilter: nf_tables: skip expired catchall elements on insert and delete Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 522/877] nfc: llcp: drop truncated I/RR/RNR PDUs in nfc_llcp_recv_hdlc() Greg Kroah-Hartman
                   ` (363 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Luxiao Xu, Ren Wei,
	Simon Horman, David Heidelberg

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Luxiao Xu <rakukuip@gmail.com>

commit dcab71a7011918f6fdba7adcec02d217dcb84b8d upstream.

Commit 6709d4b7bc2e ("net: nfc: Fix use-after-free caused by
nfc_llcp_find_local") attempted to fix a use-after-free (UAF) issue by
invoking nfc_llcp_local_put(local) after accessing local->gb. However,
if the reference count drops to zero, local is freed immediately,
leading to a use-after-free when callers access the returned pointer.
Alternative approaches using dynamic allocation (e.g. kmemdup) introduced
memory leaks because callers consistently treat the returned pointer as
borrowed memory.

Fix this properly by refactoring nfc_llcp_general_bytes() and
nfc_get_local_general_bytes() to accept a caller-provided output buffer
(out_gb) and its maximum length (gb_max_len). The general bytes are
safely copied into out_gb before calling nfc_llcp_local_put(local),
ensuring safe lifetime management without ownership transfer complications.

Update all callers across drivers (microread, pn533, pn544, st21nfca,
digital_dep, and nci) to provide their own destination buffers and pass
them to nfc_get_local_general_bytes().

Fixes: 6709d4b7bc2e ("net: nfc: Fix use-after-free caused by nfc_llcp_find_local")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/3cbaac3bee23f8ff3a3284ed32d347696eb1d208.1788841683.git.rakukuip@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/nfc/microread/microread.c |    6 +++---
 drivers/nfc/pn533/pn533.c         |   14 ++++++++------
 drivers/nfc/pn533/pn533.h         |    4 +++-
 drivers/nfc/pn544/pn544.c         |    7 +++----
 drivers/nfc/st21nfca/core.c       |    8 ++++----
 include/net/nfc/hci.h             |    2 +-
 include/net/nfc/nfc.h             |    3 ++-
 net/nfc/core.c                    |   15 +++++++--------
 net/nfc/digital_dep.c             |    8 ++++----
 net/nfc/llcp_core.c               |   17 +++++++++++++----
 net/nfc/nci/core.c                |   10 +++++-----
 net/nfc/nfc.h                     |    3 ++-
 12 files changed, 55 insertions(+), 42 deletions(-)

--- a/drivers/nfc/microread/microread.c
+++ b/drivers/nfc/microread/microread.c
@@ -251,9 +251,9 @@ static int microread_start_poll(struct n
 		param[1] |= (1 << 1);
 
 	if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) {
-		hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
-						       &hdev->gb_len);
-		if (hdev->gb == NULL || hdev->gb_len == 0) {
+		nfc_get_local_general_bytes(hdev->ndev, hdev->gb,
+					    sizeof(hdev->gb), &hdev->gb_len);
+		if (hdev->gb_len == 0) {
 			im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
 			tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
 		}
--- a/drivers/nfc/pn533/pn533.c
+++ b/drivers/nfc/pn533/pn533.c
@@ -1355,10 +1355,11 @@ static int pn533_poll_dep(struct nfc_dev
 	u8 *next, nfcid3[NFC_NFCID3_MAXSIZE];
 	u8 passive_data[PASSIVE_DATA_LEN] = {0x00, 0xff, 0xff, 0x00, 0x3};
 
-	if (!dev->gb) {
-		dev->gb = nfc_get_local_general_bytes(nfc_dev, &dev->gb_len);
-
-		if (!dev->gb || !dev->gb_len) {
+	if (!dev->gb_len) {
+		nfc_get_local_general_bytes(nfc_dev, dev->gb,
+					    sizeof(dev->gb),
+					    &dev->gb_len);
+		if (!dev->gb_len) {
 			dev->poll_dep = 0;
 			queue_work(dev->wq, &dev->rf_work);
 		}
@@ -1660,8 +1661,9 @@ static int pn533_start_poll(struct nfc_d
 	}
 
 	if (tm_protocols) {
-		dev->gb = nfc_get_local_general_bytes(nfc_dev, &dev->gb_len);
-		if (dev->gb == NULL)
+		nfc_get_local_general_bytes(nfc_dev, dev->gb,
+					    sizeof(dev->gb), &dev->gb_len);
+		if (dev->gb_len == 0)
 			tm_protocols = 0;
 	}
 
--- a/drivers/nfc/pn533/pn533.h
+++ b/drivers/nfc/pn533/pn533.h
@@ -6,6 +6,8 @@
  * Copyright (C) 2012-2013 Tieto Poland
  */
 
+#include <net/nfc/nfc.h>
+
 #define PN533_DEVICE_STD		0x1
 #define PN533_DEVICE_PASORI		0x2
 #define PN533_DEVICE_ACR122U		0x3
@@ -166,7 +168,7 @@ struct pn533 {
 	struct timer_list listen_timer;
 	int cancel_listen;
 
-	u8 *gb;
+	u8 gb[NFC_MAX_GT_LEN];
 	size_t gb_len;
 
 	u8 tgt_available_prots;
--- a/drivers/nfc/pn544/pn544.c
+++ b/drivers/nfc/pn544/pn544.c
@@ -377,10 +377,9 @@ static int pn544_hci_start_poll(struct n
 		return r;
 
 	if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) {
-		hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
-							&hdev->gb_len);
-		pr_debug("generate local bytes %p\n", hdev->gb);
-		if (hdev->gb == NULL || hdev->gb_len == 0) {
+		nfc_get_local_general_bytes(hdev->ndev, hdev->gb,
+					    sizeof(hdev->gb), &hdev->gb_len);
+		if (hdev->gb_len == 0) {
 			im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
 			tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
 		}
--- a/drivers/nfc/st21nfca/core.c
+++ b/drivers/nfc/st21nfca/core.c
@@ -351,10 +351,10 @@ static int st21nfca_hci_start_poll(struc
 			if (r < 0)
 				return r;
 		} else {
-			hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
-							       &hdev->gb_len);
-
-			if (hdev->gb == NULL || hdev->gb_len == 0) {
+			nfc_get_local_general_bytes(hdev->ndev, hdev->gb,
+						    sizeof(hdev->gb),
+						    &hdev->gb_len);
+			if (hdev->gb_len == 0) {
 				im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
 				tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
 			}
--- a/include/net/nfc/hci.h
+++ b/include/net/nfc/hci.h
@@ -144,7 +144,7 @@ struct nfc_hci_dev {
 	data_exchange_cb_t async_cb;
 	void *async_cb_context;
 
-	u8 *gb;
+	u8 gb[NFC_MAX_GT_LEN];
 	size_t gb_len;
 
 	unsigned long quirks;
--- a/include/net/nfc/nfc.h
+++ b/include/net/nfc/nfc.h
@@ -269,7 +269,8 @@ struct sk_buff *nfc_alloc_recv_skb(unsig
 
 int nfc_set_remote_general_bytes(struct nfc_dev *dev,
 				 const u8 *gt, u8 gt_len);
-u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len);
+u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *out_gb,
+				size_t gb_max_len, size_t *gb_len);
 
 int nfc_fw_download_done(struct nfc_dev *dev, const char *firmware_name,
 			 u32 result);
--- a/net/nfc/core.c
+++ b/net/nfc/core.c
@@ -279,10 +279,10 @@ static struct nfc_target *nfc_find_targe
 
 int nfc_dep_link_up(struct nfc_dev *dev, int target_index, u8 comm_mode)
 {
-	int rc = 0;
-	u8 *gb;
-	size_t gb_len;
 	struct nfc_target *target;
+	u8 gb[NFC_MAX_GT_LEN];
+	size_t gb_len = 0;
+	int rc = 0;
 
 	pr_debug("dev_name=%s comm %d\n", dev_name(&dev->dev), comm_mode);
 
@@ -301,7 +301,7 @@ int nfc_dep_link_up(struct nfc_dev *dev,
 		goto error;
 	}
 
-	gb = nfc_llcp_general_bytes(dev, &gb_len);
+	nfc_get_local_general_bytes(dev, gb, sizeof(gb), &gb_len);
 	if (gb_len > NFC_MAX_GT_LEN) {
 		rc = -EINVAL;
 		goto error;
@@ -644,11 +644,10 @@ int nfc_set_remote_general_bytes(struct
 }
 EXPORT_SYMBOL(nfc_set_remote_general_bytes);
 
-u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len)
+u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *out_gb,
+				size_t gb_max_len, size_t *gb_len)
 {
-	pr_debug("dev_name=%s\n", dev_name(&dev->dev));
-
-	return nfc_llcp_general_bytes(dev, gb_len);
+	return nfc_llcp_general_bytes(dev, out_gb, gb_max_len, gb_len);
 }
 EXPORT_SYMBOL(nfc_get_local_general_bytes);
 
--- a/net/nfc/digital_dep.c
+++ b/net/nfc/digital_dep.c
@@ -1490,14 +1490,14 @@ static int digital_tg_send_atr_res(struc
 				   struct digital_atr_req *atr_req)
 {
 	struct digital_atr_res *atr_res;
+	u8 gb[NFC_MAX_GT_LEN];
 	struct sk_buff *skb;
-	u8 *gb, payload_bits;
+	u8 payload_bits;
 	size_t gb_len;
 	int rc;
 
-	gb = nfc_get_local_general_bytes(ddev->nfc_dev, &gb_len);
-	if (!gb)
-		gb_len = 0;
+	nfc_get_local_general_bytes(ddev->nfc_dev, gb, sizeof(gb),
+				    &gb_len);
 
 	skb = digital_skb_alloc(ddev, sizeof(struct digital_atr_res) + gb_len);
 	if (!skb)
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -651,23 +651,32 @@ out:
 	return ret;
 }
 
-u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len)
+u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, u8 *out_gb, size_t gb_max_len,
+			   size_t *general_bytes_len)
 {
 	struct nfc_llcp_local *local;
 
+	if (!out_gb || !general_bytes_len)
+		return NULL;
+
 	local = nfc_llcp_find_local(dev);
-	if (local == NULL) {
+	if (!local) {
 		*general_bytes_len = 0;
 		return NULL;
 	}
 
 	nfc_llcp_build_gb(local);
 
-	*general_bytes_len = local->gb_len;
+	if (local->gb_len) {
+		*general_bytes_len = min_t(size_t, local->gb_len, gb_max_len);
+		memcpy(out_gb, local->gb, *general_bytes_len);
+	} else {
+		*general_bytes_len = 0;
+	}
 
 	nfc_llcp_local_put(local);
 
-	return local->gb;
+	return out_gb;
 }
 
 int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len)
--- a/net/nfc/nci/core.c
+++ b/net/nfc/nci/core.c
@@ -772,15 +772,15 @@ static int nci_set_local_general_bytes(s
 {
 	struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
 	struct nci_set_config_param param;
+	u8 gb[NFC_MAX_GT_LEN];
 	int rc;
 
-	param.val = nfc_get_local_general_bytes(nfc_dev, &param.len);
-	if ((param.val == NULL) || (param.len == 0))
+	nfc_get_local_general_bytes(nfc_dev, gb, sizeof(gb),
+				    &param.len);
+	if (param.len == 0)
 		return 0;
 
-	if (param.len > NFC_MAX_GT_LEN)
-		return -EINVAL;
-
+	param.val = gb;
 	param.id = NCI_PN_ATR_REQ_GEN_BYTES;
 
 	rc = nci_request(ndev, nci_set_config_req, &param,
--- a/net/nfc/nfc.h
+++ b/net/nfc/nfc.h
@@ -49,7 +49,8 @@ void nfc_llcp_mac_is_up(struct nfc_dev *
 int nfc_llcp_register_device(struct nfc_dev *dev);
 void nfc_llcp_unregister_device(struct nfc_dev *dev);
 int nfc_llcp_set_remote_gb(struct nfc_dev *dev, const u8 *gb, u8 gb_len);
-u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, size_t *general_bytes_len);
+u8 *nfc_llcp_general_bytes(struct nfc_dev *dev, u8 *out_gb, size_t gb_max_len,
+			   size_t *general_bytes_len);
 int nfc_llcp_data_received(struct nfc_dev *dev, struct sk_buff *skb);
 struct nfc_llcp_local *nfc_llcp_find_local(struct nfc_dev *dev);
 int nfc_llcp_local_put(struct nfc_llcp_local *local);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 522/877] nfc: llcp: drop truncated I/RR/RNR PDUs in nfc_llcp_recv_hdlc()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (520 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 521/877] nfc: fix use-after-free in nfc_get_local_general_bytes Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 523/877] nfc: port100: reject frames whose declared length exceeds the received data Greg Kroah-Hartman
                   ` (362 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Aamir Ahmed, Simon Horman,
	David Heidelberg

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Aamir Ahmed <elb12345@hotmail.co.uk>

commit 273f9d667cde649f8de9d72b1303cc2f4b658c50 upstream.

nfc_llcp_recv_hdlc() reads the sequence byte skb->data[2], via
nfc_llcp_ns()/nfc_llcp_nr(), before any length check. The receive path
only guarantees the two-byte LLCP header -- __nfc_llcp_recv() checks it
with pskb_may_pull() and nfc_llcp_recv_agf() admits two-byte inner PDUs
-- so a two-byte I, RR or RNR PDU reads one byte of uninitialised skb
tailroom. The byte becomes N(R)/N(S); a peer can already set those with
a well-formed PDU, so this is acting on uninitialised memory, not new
peer control.

Guard the read with pskb_may_pull(), as commit 95674f506c63 ("nfc: llcp:
reject PDUs shorter than the LLCP header") did for the two-byte header,
so the sequence byte is present and linear before it is read. RR and RNR
PDUs are LLCP_HEADER_SIZE + LLCP_SEQUENCE_SIZE bytes and an I PDU is
longer, so no valid frame is rejected; a truncated PDU is malformed, so
return without a DM reply.

Fixes: d646960f7986 ("NFC: Initial LLCP support")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Aamir Ahmed <elb12345@hotmail.co.uk>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/AS8P251MB0001789BBF04B72745C7D96BC8BA2@AS8P251MB0001.EURP251.PROD.OUTLOOK.COM
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/nfc/llcp_core.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -1099,6 +1099,9 @@ static void nfc_llcp_recv_hdlc(struct nf
 	struct sock *sk;
 	u8 dsap, ssap, ptype, ns, nr;
 
+	if (!pskb_may_pull(skb, LLCP_HEADER_SIZE + LLCP_SEQUENCE_SIZE))
+		return;
+
 	ptype = nfc_llcp_ptype(skb);
 	dsap = nfc_llcp_dsap(skb);
 	ssap = nfc_llcp_ssap(skb);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 523/877] nfc: port100: reject frames whose declared length exceeds the received data
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (521 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 522/877] nfc: llcp: drop truncated I/RR/RNR PDUs in nfc_llcp_recv_hdlc() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 524/877] scsi: libiscsi_tcp: Check the data direction of a Data-In PDU Greg Kroah-Hartman
                   ` (361 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Doruk Tan Ozturk, Simon Horman,
	David Heidelberg

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Doruk Tan Ozturk <doruk@0sec.ai>

commit 092c6a605cbd6414ef499834c2e0da69c2c3388e upstream.

port100_recv_response() passes the URB transfer buffer to
port100_rx_frame_is_valid(), which checksums le16_to_cpu(frame->datalen)
bytes of frame->data. datalen is a 16-bit field supplied by the device
and is never checked against the number of bytes actually received
(urb->actual_length), so a device reporting a datalen larger than the
received frame makes port100_data_checksum() read out of bounds past the
transfer buffer.

Reject a response whose declared frame size does not fit the received
length before validating it.

Found by 0sec (https://0sec.ai) using automated source analysis; the
missing bound is evident from source. Compile-tested.

Fixes: 562d4d59b8a1 ("NFC: Sony Port-100 Series driver")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:claude-opus-4-8
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260711123651.32595-1-doruk@0sec.ai
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/nfc/port100.c |    7 +++++++
 1 file changed, 7 insertions(+)

--- a/drivers/nfc/port100.c
+++ b/drivers/nfc/port100.c
@@ -636,6 +636,13 @@ static void port100_recv_response(struct
 
 	in_frame = dev->in_urb->transfer_buffer;
 
+	if (urb->actual_length < PORT100_FRAME_HEADER_LEN ||
+	    urb->actual_length < port100_rx_frame_size(in_frame)) {
+		nfc_err(&dev->interface->dev, "Received a truncated frame\n");
+		cmd->status = -EIO;
+		goto sched_wq;
+	}
+
 	if (!port100_rx_frame_is_valid(in_frame)) {
 		nfc_err(&dev->interface->dev, "Received an invalid frame\n");
 		cmd->status = -EIO;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 524/877] scsi: libiscsi_tcp: Check the data direction of a Data-In PDU
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (522 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 523/877] nfc: port100: reject frames whose declared length exceeds the received data Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 525/877] perf/core: Fix NULL pmu_ctx passed to pmu->sched_task() Greg Kroah-Hartman
                   ` (360 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yehyeong Lee, Mike Christie,
	Martin K. Petersen (Oracle)

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Yehyeong Lee <yhlee@isslab.korea.ac.kr>

commit bce07e2f37b5e4a427d36fd6b1c14067b27591db upstream.

The Data-In branch of iscsi_tcp_hdr_dissect() resolves the ITT to a task
and copies the PDU's data segment into that command's scatterlist without
asking whether the command was reading. iscsi_tcp_r2t_rsp() in the same
file does ask, and rejects an R2T for a command that is not DMA_TO_DEVICE.

A target that answers a WRITE command's ITT with a Data-In therefore has
the initiator write target-supplied bytes into the pages that write was
about to send. Those are the caller's own pinned pages for an O_DIRECT
write, and page cache pages for a buffered one.

Observed against a test target that emits one 512-byte Data-In naming a 128
KB write's ITT, after the R2T for that write. With O_DIRECT the caller's
buffer ends up holding 512 bytes of the target's data while pwrite()
returns 131072. Buffered is quieter: pwrite() and fsync() both succeed,
nothing is logged, and reading those blocks back returns the target's bytes
out of the page cache without a command going on the wire.

Check the direction before using the scatterlist, the way the R2T path
already does.

Cc: stable@vger.kernel.org
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Link: https://patch.msgid.link/20260801133635.1986706-1-yhlee@isslab.korea.ac.kr
Fixes: a081c13e39b5 ("[SCSI] iscsi_tcp: split module into lib and lld")
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/libiscsi_tcp.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -491,6 +491,9 @@ static int iscsi_tcp_data_in(struct iscs
 	int datasn = be32_to_cpu(rhdr->datasn);
 	unsigned total_in_length = task->sc->sdb.length;
 
+	if (task->sc->sc_data_direction != DMA_FROM_DEVICE)
+		return ISCSI_ERR_PROTO;
+
 	/*
 	 * lib iscsi will update this in the completion handling if there
 	 * is status.



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 525/877] perf/core: Fix NULL pmu_ctx passed to pmu->sched_task()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (523 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 524/877] scsi: libiscsi_tcp: Check the data direction of a Data-In PDU Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 526/877] perf/core: Run sched_task() for PMUs with only CPU-wide events Greg Kroah-Hartman
                   ` (359 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Puranjay Mohan,
	Peter Zijlstra (Intel), Yifan Wu

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Puranjay Mohan <puranjay@kernel.org>

commit 36bb85cf36cab15fb611cb44b78a5df06e4e69a2 upstream.

perf_pmu_sched_task() returns early when cpuctx->task_ctx is set, and
cpc->task_epc is only non-NULL while a task context is scheduled in on
this CPU. __perf_pmu_sched_task() therefore always passes NULL:

  Unable to handle kernel NULL pointer dereference at virtual address 00
  pc : armv8pmu_sched_task+0x14/0x50
  Call trace:
   armv8pmu_sched_task+0x14/0x50 (P)
   perf_pmu_sched_task+0xac/0x108
   __perf_event_task_sched_out+0x6c/0xe0

Pass &cpc->epc instead, the CPU-wide context for this PMU, which the
function already dereferences a few lines up to find pmu.

armv8pmu_sched_task() is the only in-tree implementation that
dereferences the argument, and it only reads ->pmu, so the oops needs
BRBE, added in v6.17.

Fixes: bd2756811766 ("perf: Rewrite core context handling")
Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Yifan Wu <wuyifan50@huawei.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260810133540.1947118-2-puranjay@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/events/core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3754,7 +3754,7 @@ static void __perf_pmu_sched_task(struct
 	perf_ctx_lock(cpuctx, cpuctx->task_ctx);
 	perf_pmu_disable(pmu);
 
-	pmu->sched_task(cpc->task_epc, task, sched_in);
+	pmu->sched_task(&cpc->epc, task, sched_in);
 
 	perf_pmu_enable(pmu);
 	perf_ctx_unlock(cpuctx, cpuctx->task_ctx);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 526/877] perf/core: Run sched_task() for PMUs with only CPU-wide events
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (524 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 525/877] perf/core: Fix NULL pmu_ctx passed to pmu->sched_task() Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 527/877] pinctrl: single: free the IRQ on domain creation failure Greg Kroah-Hartman
                   ` (358 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Puranjay Mohan,
	Peter Zijlstra (Intel), Yifan Wu

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Puranjay Mohan <puranjay@kernel.org>

commit 3d8d74100954a3b17e5c5e37adfe14e16b1db103 upstream.

perf_pmu_sched_task() returns early when cpuctx->task_ctx is set and
leaves the work to perf_ctx_sched_task_cb(), which only walks
ctx->pmu_ctx_list. A PMU whose events are all CPU-wide is not on that
list, so nothing calls its sched_task(). With

  perf record -b -e cycles -a -- ls

armv8pmu_sched_task() is skipped on every switch to a task that has a
perf context but no event on that PMU, and BRBE records leak across the
task boundary. intel_pmu_lbr_add() calls perf_sched_cb_inc()
unconditionally too, so LBR records leak the same way on x86.

Drop the early return and skip only the CPCs that
perf_ctx_sched_task_cb() handles. That one needs a gate of its own to
make the split exact: it tests cpc->sched_cb_usage, which
perf_sched_cb_inc() sets per CPU for every branch stack user, so a task
with an event for that PMU pinned to another CPU would be handled twice.
On x86 the second __intel_pmu_lbr_restore() finds lbr_stack_state ==
LBR_NONE and calls intel_pmu_lbr_reset(), throwing away the callstack
the first one restored.

cpc->task_epc is set only while a task context is scheduled in, and
there is one epc per PMU on ctx->pmu_ctx_list, so the two gates are
inverses.

For the CPCs perf_pmu_sched_task() picks up, the callback now runs
outside the perf_ctx_disable() and perf_ctx_enable() pair in
perf_event_context_sched_in(). __perf_pmu_sched_task() disables the PMU
around the call itself.

Fixes: bd2756811766 ("perf: Rewrite core context handling")
Signed-off-by: Puranjay Mohan <puranjay@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: Yifan Wu <wuyifan50@huawei.com>
Link: https://patch.msgid.link/20260810133540.1947118-3-puranjay@kernel.org
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/events/core.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3603,6 +3603,9 @@ static void perf_ctx_sched_task_cb(struc
 	list_for_each_entry(pmu_ctx, &ctx->pmu_ctx_list, pmu_ctx_entry) {
 		cpc = this_cpu_ptr(pmu_ctx->pmu->cpu_pmu_context);
 
+		if (cpc->task_epc != pmu_ctx)
+			continue;
+
 		if (cpc->sched_cb_usage && pmu_ctx->pmu->sched_task)
 			pmu_ctx->pmu->sched_task(pmu_ctx, task, sched_in);
 	}
@@ -3764,15 +3767,17 @@ static void perf_pmu_sched_task(struct t
 				struct task_struct *next,
 				bool sched_in)
 {
-	struct perf_cpu_context *cpuctx = this_cpu_ptr(&perf_cpu_context);
 	struct perf_cpu_pmu_context *cpc, *cpc2;
 
-	/* cpuctx->task_ctx will be handled in perf_event_context_sched_in/out */
-	if (prev == next || cpuctx->task_ctx)
+	if (prev == next)
 		return;
 
-	list_for_each_entry_safe(cpc, cpc2, this_cpu_ptr(&sched_cb_list), sched_cb_entry)
+	list_for_each_entry_safe(cpc, cpc2, this_cpu_ptr(&sched_cb_list), sched_cb_entry) {
+		if (cpc->task_epc)
+			continue;
+
 		__perf_pmu_sched_task(cpc, sched_in ? next : prev, sched_in);
+	}
 }
 
 static void perf_event_switch(struct task_struct *task,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 527/877] pinctrl: single: free the IRQ on domain creation failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (525 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 526/877] perf/core: Run sched_task() for PMUs with only CPU-wide events Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:23 ` [PATCH 6.12 528/877] pinctrl: sunxi: keep a shadow copy of the data register output latches Greg Kroah-Hartman
                   ` (357 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak,
	Linus Walleij

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Myeonghun Pak <mhun512@gmail.com>

commit 1d9bb9c870632adea249cfdec49ac37e6f069164 upstream.

pcs_irq_init_chained_handler() requests a shared IRQ on affected SoCs, but
its domain creation failure path only removes a chained handler. That does
not release the action installed by request_irq(). The probe can continue
without interrupt support while leaving the shared IRQ action registered.

Use pcs_irq_free() to undo the appropriate type of handler registration.
At this point pcs->domain is NULL, so the helper only releases the parent
IRQ handler. Then mark the IRQ invalid, as the other initialization error
paths already do, to prevent another release from a later probe unwind or
remove.

This issue was identified during our ongoing static-analysis research while
reviewing kernel code.

Fixes: 3e6cee1786a1 ("pinctrl: single: Add support for wake-up interrupts")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Signed-off-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/pinctrl/pinctrl-single.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/pinctrl/pinctrl-single.c
+++ b/drivers/pinctrl/pinctrl-single.c
@@ -1626,7 +1626,8 @@ static int pcs_irq_init_chained_handler(
 					    &pcs_irqdomain_ops,
 					    pcs_soc);
 	if (!pcs->domain) {
-		irq_set_chained_handler(pcs_soc->irq, NULL);
+		pcs_irq_free(pcs);
+		pcs_soc->irq = -1;
 		return -EINVAL;
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 528/877] pinctrl: sunxi: keep a shadow copy of the data register output latches
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (526 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 527/877] pinctrl: single: free the IRQ on domain creation failure Greg Kroah-Hartman
@ 2026-09-30 15:23 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 529/877] s390/cio: Fix NULL pointer dereference in ccw_device_get_util_str() Greg Kroah-Hartman
                   ` (356 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:23 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Ilya Titov, Linus Walleij

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ilya Titov <ilya.titov@wirenboard.com>

commit a13f7f5d14af9baf34eb12c25962f8d3542b281d upstream.

On Allwinner SoCs, reading a bank's data register returns the pin level,
not the output latch, for pins that are muxed as inputs.  Writing a GPIO
therefore corrupts the output latches of all input-muxed pins in the
same bank: the read-modify-write in sunxi_pinctrl_gpio_set() reads back
their pin levels and writes those into their latches.

This breaks emulated open-drain lines (e.g. a bit-banged I2C bus from
i2c-gpio).  Such a line is released high by muxing it as input and
letting the pull-up raise it, so any concurrent GPIO write in the same
bank stores 1 into its latch.  Driving the line low afterwards is a
non-atomic data-then-mux sequence in sunxi_pinctrl_gpio_direction_output();
if the poisoning write lands between the two steps, the pin actively
drives high (push-pull) instead of low.

Observed in practice as sporadic glitches on a T507 board bit-banging
I2C on port E while other PE GPIOs are toggled.  On a scope the failure
is unmistakable: on a clock pulse where SCL should fall to GND, the line
instead steps *above* its idle high level for the whole low phase — the
pad drives a strong push-pull 3.3 V high, higher than the level the
pull-up sustains on the loaded bus — before the next transition recovers
it.  The same can hit SDA, corrupting data instead of clocks.

Steps to reproduce on any sunxi board with a bit-banged (i2c-gpio) bus:

  # background: toggle any other GPIO of the same bank, e.g. line 21
  gpioset -c <chip> --toggle 100us 21=0 &

  # foreground: keep the bit-banged bus busy
  while :; do i2cdetect -y <bus> 0x50 0x57; done

  # watch SCL/SDA with a scope or logic analyzer: sporadic clock-low
  # phases driven high (above the pull-up level) instead of low

The bank spinlock cannot help: the racing write is a perfectly valid
whole-register RMW that faithfully writes back what the hardware
returned.  There are no set/clear registers on this IP to write a single
bit atomically.

Fix it the same way gpio-mmio handles hardware whose data register read
does not return the output latch: keep a shadow copy of each bank's
latches, base the read-modify-write on the shadow, and only write the
register.  The shadow is seeded from the hardware at probe time so pins
left in output mode by the bootloader keep their state.  Pins that reach
output mode through the gpiolib paths write their value (and thereby
their shadow bit) before the mux switch in
sunxi_pinctrl_gpio_direction_output(); pins muxed to gpio_out directly
through a pinmux node bypass that path, so sunxi_pmx_set() refreshes
their shadow bit from the latch (readable once the pin is in output
mode) to keep them driving their pre-existing level.

Seeding the shadow reads the PIO registers at probe time, which requires
the bus clock to be enabled.  The clock was only requested at the very
end of probe, after devm_pinctrl_register() had already claimed the pin
hogs described in the device tree - which mux pins, and thus access
registers, with the clock still gated.  Move the request ahead of both.
Boards whose bootloader leaves the PIO clock running are unaffected,
which is why the pre-existing hog problem has gone unnoticed since
commit 950707c0eb5c ("pinctrl: sunxi: add clock support").

Fixes: df7b34f4c3d2 ("pinctrl: sunxi: Fix gpio_set behaviour")
Cc: stable@vger.kernel.org
Signed-off-by: Ilya Titov <ilya.titov@wirenboard.com>
Signed-off-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/pinctrl/sunxi/pinctrl-sunxi.c |   76 +++++++++++++++++++++++++++-------
 drivers/pinctrl/sunxi/pinctrl-sunxi.h |    7 +++
 2 files changed, 68 insertions(+), 15 deletions(-)

--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c
@@ -792,6 +792,21 @@ static void sunxi_pmx_set(struct pinctrl
 	writel((readl(pctl->membase + reg) & ~mask) | config << shift,
 	       pctl->membase + reg);
 
+	/*
+	 * A pin muxed to gpio_out directly through a pinmux node bypasses
+	 * sunxi_pinctrl_gpio_set() and drives whatever its output latch
+	 * holds.  Now that the pin is in output mode the data register
+	 * reads back the latch, so refresh the shadow to keep such pins
+	 * driving their pre-existing level.
+	 */
+	if (config == SUN4I_FUNC_OUTPUT) {
+		u32 *shadow = &pctl->dat_shadow[pin / PINS_PER_BANK];
+
+		sunxi_data_reg(pctl, pin, &reg, &shift, &mask);
+		*shadow = (*shadow & ~mask) |
+			  (readl(pctl->membase + reg) & mask);
+	}
+
 	raw_spin_unlock_irqrestore(&pctl->lock, flags);
 }
 
@@ -948,21 +963,29 @@ static void sunxi_pinctrl_gpio_set(struc
 				unsigned offset, int value)
 {
 	struct sunxi_pinctrl *pctl = gpiochip_get_data(chip);
-	u32 reg, shift, mask, val;
+	u32 *shadow = &pctl->dat_shadow[offset / PINS_PER_BANK];
+	u32 reg, shift, mask;
 	unsigned long flags;
 
 	sunxi_data_reg(pctl, offset, &reg, &shift, &mask);
 
 	raw_spin_lock_irqsave(&pctl->lock, flags);
 
-	val = readl(pctl->membase + reg);
-
+	/*
+	 * Reading the data register returns the pin level, not the output
+	 * latch, for pins muxed as inputs.  A read-modify-write based on
+	 * the register would therefore corrupt the latches of input-muxed
+	 * pins in the same bank (e.g. an emulated open-drain I2C line
+	 * released high), making them drive the wrong level once switched
+	 * to output.  Base the read-modify-write on a shadow copy of the
+	 * latches instead.
+	 */
 	if (value)
-		val |= mask;
+		*shadow |= mask;
 	else
-		val &= ~mask;
+		*shadow &= ~mask;
 
-	writel(val, pctl->membase + reg);
+	writel(*shadow, pctl->membase + reg);
 
 	raw_spin_unlock_irqrestore(&pctl->lock, flags);
 }
@@ -1486,7 +1509,7 @@ int sunxi_pinctrl_init_with_variant(stru
 	struct pinctrl_pin_desc *pins;
 	struct sunxi_pinctrl *pctl;
 	struct pinmux_ops *pmxops;
-	int i, ret, last_pin, pin_idx;
+	int i, ret, last_pin, pin_idx, nbanks;
 	struct clk *clk;
 
 	pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
@@ -1520,6 +1543,37 @@ int sunxi_pinctrl_init_with_variant(stru
 	if (!pctl->irq_array)
 		return -ENOMEM;
 
+	/*
+	 * The bus clock has to be enabled before the pinctrl device
+	 * registers, as the pin hogs claimed from there access registers.
+	 */
+	ret = of_clk_get_parent_count(node);
+	clk = devm_clk_get_enabled(&pdev->dev, ret == 1 ? NULL : "apb");
+	if (IS_ERR(clk))
+		return PTR_ERR(clk);
+
+	/*
+	 * Seed the output latch shadow from the hardware so pins the
+	 * bootloader left in output mode keep their state; see
+	 * sunxi_pinctrl_gpio_set() for why a shadow is needed.  This must
+	 * happen before the pinctrl device registers, as pin hogs can mux
+	 * pins to gpio_out and thereby update the shadow.
+	 */
+	last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
+	nbanks = DIV_ROUND_UP(last_pin + 1 - pctl->desc->pin_base,
+			      PINS_PER_BANK);
+	pctl->dat_shadow = devm_kcalloc(&pdev->dev, nbanks,
+					sizeof(*pctl->dat_shadow), GFP_KERNEL);
+	if (!pctl->dat_shadow)
+		return -ENOMEM;
+
+	for (i = 0; i < nbanks; i++) {
+		u32 reg, shift, mask;
+
+		sunxi_data_reg(pctl, i * PINS_PER_BANK, &reg, &shift, &mask);
+		pctl->dat_shadow[i] = readl(pctl->membase + reg);
+	}
+
 	ret = sunxi_pinctrl_build_state(pdev);
 	if (ret) {
 		dev_err(&pdev->dev, "dt probe failed: %d\n", ret);
@@ -1574,7 +1628,6 @@ int sunxi_pinctrl_init_with_variant(stru
 	if (!pctl->chip)
 		return -ENOMEM;
 
-	last_pin = pctl->desc->pins[pctl->desc->npins - 1].pin.number;
 	pctl->chip->owner = THIS_MODULE;
 	pctl->chip->request = gpiochip_generic_request;
 	pctl->chip->free = gpiochip_generic_free;
@@ -1607,13 +1660,6 @@ int sunxi_pinctrl_init_with_variant(stru
 			goto gpiochip_error;
 	}
 
-	ret = of_clk_get_parent_count(node);
-	clk = devm_clk_get_enabled(&pdev->dev, ret == 1 ? NULL : "apb");
-	if (IS_ERR(clk)) {
-		ret = PTR_ERR(clk);
-		goto gpiochip_error;
-	}
-
 	pctl->irq = devm_kcalloc(&pdev->dev,
 				 pctl->desc->irq_banks,
 				 sizeof(*pctl->irq),
--- a/drivers/pinctrl/sunxi/pinctrl-sunxi.h
+++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.h
@@ -80,6 +80,7 @@
 #define IO_BIAS_MASK		GENMASK(3, 0)
 
 #define SUN4I_FUNC_INPUT	0
+#define SUN4I_FUNC_OUTPUT	1
 #define SUN4I_FUNC_IRQ		6
 
 #define PINCTRL_SUN5I_A10S	BIT(1)
@@ -173,6 +174,12 @@ struct sunxi_pinctrl {
 	int				*irq;
 	unsigned			*irq_array;
 	raw_spinlock_t			lock;
+	/*
+	 * Output latch shadow, one word per bank.  Seeded lockless at
+	 * probe before the pinctrl device registers, protected by @lock
+	 * afterwards.
+	 */
+	u32				*dat_shadow;
 	struct pinctrl_dev		*pctl_dev;
 	unsigned long			variant;
 	u32				bank_mem_size;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 529/877] s390/cio: Fix NULL pointer dereference in ccw_device_get_util_str()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (527 preceding siblings ...)
  2026-09-30 15:23 ` [PATCH 6.12 528/877] pinctrl: sunxi: keep a shadow copy of the data register output latches Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 530/877] s390/cmf: Fix virtual vs physical address confusion Greg Kroah-Hartman
                   ` (355 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vineeth Vijayan, Peter Oberparleiter,
	Heiko Carstens

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Vineeth Vijayan <vneethv@linux.ibm.com>

commit 5b76268dac968612f7283d59b539036de955b7d9 upstream.

The channel path registry entry associated with a CHPID may be removed
while the subchannel's PMCW still references that CHPID. In this case,
chpid_to_chp() can return NULL, leading to a NULL pointer dereference.

Add the missing NULL check before dereferencing the returned pointer.

Fixes: 199652309a4d ("s390/cio: add helper to query utility strings per given ccw device")
Cc: stable@vger.kernel.org
Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/s390/cio/device_ops.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -517,6 +517,8 @@ u8 *ccw_device_get_util_str(struct ccw_d
 	chp_id_init(&chpid);
 	chpid.id = sch->schib.pmcw.chpid[chp_idx];
 	chp = chpid_to_chp(chpid);
+	if (!chp)
+		return NULL;
 
 	util_str = kmalloc(sizeof(chp->desc_fmt3.util_str), GFP_KERNEL);
 	if (!util_str)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 530/877] s390/cmf: Fix virtual vs physical address confusion
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (528 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 529/877] s390/cio: Fix NULL pointer dereference in ccw_device_get_util_str() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 531/877] s390/vfio-ap: fix KVM GISC and page leak when queue removed from host config Greg Kroah-Hartman
                   ` (354 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Peter Oberparleiter, Heiko Carstens

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Peter Oberparleiter <oberpar@linux.ibm.com>

commit f4d04425e66af2ecee9d1a49ae0484436f3c2fd1 upstream.

The measurement block address is an absolute address. Define the
associated schib_config and schib fields as dma64_t to enable automatic
detection of incorrect assignments. Also add the missing virt_to_dma64()
translation.

Without this fix, a wrong address will be used by firmware when storing
extended format channel measurement data on kernels built with
CONFIG_RANDOMIZE_IDENTITY_BASE=y.

Fixes: 14edd0d73bfe ("s390/cmf: fix virtual vs physical address confusion")
Cc: stable@vger.kernel.org
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/s390/cio/cio.h |    5 +++--
 drivers/s390/cio/cmf.c |    2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

--- a/drivers/s390/cio/cio.h
+++ b/drivers/s390/cio/cio.h
@@ -7,6 +7,7 @@
 #include <linux/mod_devicetable.h>
 #include <asm/chpid.h>
 #include <asm/cio.h>
+#include <asm/dma-types.h>
 #include <asm/fcx.h>
 #include <asm/schid.h>
 #include <asm/tpi.h>
@@ -49,7 +50,7 @@ struct pmcw {
 
 /* Target SCHIB configuration. */
 struct schib_config {
-	u64 mba;
+	dma64_t mba;
 	u32 intparm;
 	u16 mbi;
 	u32 isc:3;
@@ -66,7 +67,7 @@ struct schib_config {
 struct schib {
 	struct pmcw pmcw;	 /* path management control word */
 	union scsw scsw;	 /* subchannel status word */
-	__u64 mba;               /* measurement block address */
+	dma64_t mba;		 /* measurement block address */
 	__u8 mda[4];		 /* model dependent area */
 } __attribute__ ((packed,aligned(4)));
 
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -184,7 +184,7 @@ static int set_schib(struct ccw_device *
 	sch->config.mbfc = mbfc;
 	/* address can be either a block address or a block index */
 	if (mbfc)
-		sch->config.mba = address;
+		sch->config.mba = address ? virt_to_dma64((void *)address) : 0;
 	else
 		sch->config.mbi = address;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 531/877] s390/vfio-ap: fix KVM GISC and page leak when queue removed from host config
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (529 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 530/877] s390/cmf: Fix virtual vs physical address confusion Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 532/877] KVM: Ensure memory attributes xarray nodes are accounted to the callers memcg Greg Kroah-Hartman
                   ` (353 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Anthony Krowiak, Matthew Rosato,
	Halil Pasic, Claudio Imbrenda

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Anthony Krowiak <akrowiak@linux.ibm.com>

commit 65e05ec252a9b79e75930d3c4dd42d8877db04c5 upstream.

Three related problems exist in the handling of KVM interrupt and page
resources when a queue is removed from the host's AP configuration
while assigned to a mediated device (mdev).

Problem 1:
~~~~~~~~~
AP_RESPONSE_Q_NOT_AVAIL not handled in vfio_ap_mdev_reset_queue()

When the AP bus removes a queue device whose adapter or domain has
been removed from the host's AP configuration,
vfio_ap_mdev_remove_queue() is called. If the queue is still in the
host's AP configuration at that point, it calls
vfio_ap_mdev_reset_queue(), which issues a PQAP(ZAPQ). Since the
adapter is already gone from the host configuration, ap_zapq() returns
AP_RESPONSE_Q_NOT_AVAIL (0x01). This response code is not handled in
vfio_ap_mdev_reset_queue()'s switch statement and falls through to
the default case, which issues a WARN but does not call
vfio_ap_free_aqic_resources(). As a result, if IRQ handling was
enabled for the queue by the guest, the KVM GISC registration and
the pinned guest page holding the notification indicator byte (NIB)
are both leaked.

This is fixed by adding AP_RESPONSE_Q_NOT_AVAIL to the same case as
AP_RESPONSE_DECONFIGURED and AP_RESPONSE_CHECKSTOPPED in
vfio_ap_mdev_reset_queue(). Like those response codes, Q_NOT_AVAIL
indicates the queue is not operational and no further reset attempts
are possible; the correct action is to free the IRQ resources
immediately.

Problem 2:
~~~~~~~~~
 AP_RESPONSE_Q_NOT_AVAIL not handled in apq_status_check()

In vfio_ap_mdev_reset_queue(), there are four cases that indicate a queue
reset has not yet completed, in which case apq_reset_check() is queued to
a work queue to verify completion of the reset operation. This function
uses the PQAP(TAPQ) function to get the queue's status and calls
apq_status_check() to verify whether the reset has completed, failed or
needs to be executed again. As described in Problem #1 above,
apq_reset_check() does not specifically check for AP_RESPONSE_Q_NOT_AVAIL,
thereby potentially leaking KVM GISC registration and the pinned guest page
holding the NIB.

This is fixed by adding a case statement for AP_RESPONSE_Q_NOT_AVAIL to
apq_status_check() and returning -ENODEV for that case. The caller,
apq_reset_check() will then check for this return code and call
vfio_ap_free_aqic_resources() to prevent the leak.

Problem 3:
~~~~~~~~~
vfio_ap_free_aqic_resources() leaks saved_isc when kvm is NULL

vfio_ap_free_aqic_resources() guards the call to
kvm_s390_gisc_unregister() with:

    if (q->saved_isc != VFIO_AP_ISC_INVALID &&
        !WARN_ON(!(q->matrix_mdev && q->matrix_mdev->kvm)))

If matrix_mdev->kvm is NULL -- which can happen when
vfio_ap_mdev_unset_kvm() has already run and cleared kvm before a
subsequent cleanup path reaches this function -- the WARN_ON fires
and the entire block is skipped. This leaves q->saved_isc set to a
non-invalid value, creating a potential double-free on any subsequent
call to this function.

When kvm is NULL the KVM guest is already torn down, so
kvm_s390_gisc_unregister() need not and cannot be called; however,
q->saved_isc must always be cleared. Fix this by separating the
kvm_s390_gisc_unregister() call from the q->saved_isc reset. The
WARN_ON now guards only the genuinely impossible case of matrix_mdev
being NULL. A NULL kvm is handled gracefully by skipping only the
unregister call, and q->saved_isc = VFIO_AP_ISC_INVALID is set
unconditionally whenever saved_isc was not already invalid.

Additionally, add an else clause to the host-config check in
vfio_ap_mdev_remove_queue() to call vfio_ap_free_aqic_resources()
directly when the queue is not in the host's AP configuration. This
serves as a backstop: when the AP bus fires the driver .remove
callback after an adapter is removed from the host config, the queue
is by definition no longer addressable, so vfio_ap_mdev_reset_queue()
would always return Q_NOT_AVAIL. The else clause handles this case
directly without the unnecessary ap_zapq() call, and ensures cleanup
occurs even if kvm has already been set to NULL by a prior call to
vfio_ap_mdev_unset_kvm().

Fixes: b9bd10c43456d ("s390/vfio-ap: do not reset queue removed from host config")
Cc: stable@vger.kernel.org
Signed-off-by: Anthony Krowiak <akrowiak@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Acked-by: Halil Pasic <pasic@linux.ibm.com>
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Message-ID: <20260818193349.1877940-2-akrowiak@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/s390/crypto/vfio_ap_ops.c |   18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -277,9 +277,9 @@ static void vfio_ap_free_aqic_resources(
 {
 	if (!q)
 		return;
-	if (q->saved_isc != VFIO_AP_ISC_INVALID &&
-	    !WARN_ON(!(q->matrix_mdev && q->matrix_mdev->kvm))) {
-		kvm_s390_gisc_unregister(q->matrix_mdev->kvm, q->saved_isc);
+	if (q->saved_isc != VFIO_AP_ISC_INVALID) {
+		if (!WARN_ON(!q->matrix_mdev) && q->matrix_mdev->kvm)
+			kvm_s390_gisc_unregister(q->matrix_mdev->kvm, q->saved_isc);
 		q->saved_isc = VFIO_AP_ISC_INVALID;
 	}
 	if (q->saved_iova && !WARN_ON(!q->matrix_mdev)) {
@@ -1926,6 +1926,8 @@ static int apq_status_check(int apqn, st
 		 * a value indicating a reset needs to be performed again.
 		 */
 		return -EAGAIN;
+	case AP_RESPONSE_Q_NOT_AVAIL:
+		return -ENODEV;
 	default:
 		WARN(true,
 		     "failed to verify reset of queue %02x.%04x: TAPQ rc=%u\n",
@@ -1952,6 +1954,10 @@ static void apq_reset_check(struct work_
 		ret = apq_status_check(q->apqn, &status);
 		if (ret == -EIO)
 			return;
+		if (ret == -ENODEV) {
+			vfio_ap_free_aqic_resources(q);
+			return;
+		}
 		if (ret == -EBUSY) {
 			pr_notice_ratelimited(WAIT_MSG, elapsed,
 					      AP_QID_CARD(q->apqn),
@@ -1995,6 +2001,7 @@ static void vfio_ap_mdev_reset_queue(str
 		break;
 	case AP_RESPONSE_DECONFIGURED:
 	case AP_RESPONSE_CHECKSTOPPED:
+	case AP_RESPONSE_Q_NOT_AVAIL:
 		vfio_ap_free_aqic_resources(q);
 		break;
 	default:
@@ -2470,12 +2477,15 @@ void vfio_ap_mdev_remove_queue(struct ap
 	/*
 	 * If the queue is not in the host's AP configuration, then resetting
 	 * it will fail with response code 01, (APQN not valid); so, let's make
-	 * sure it is in the host's config.
+	 * sure it is in the host's config. If it is not, free the KVM GISC
+	 * resources.
 	 */
 	if (test_bit_inv(apid, (unsigned long *)matrix_dev->info.apm) &&
 	    test_bit_inv(apqi, (unsigned long *)matrix_dev->info.aqm)) {
 		vfio_ap_mdev_reset_queue(q);
 		flush_work(&q->reset_work);
+	} else {
+		vfio_ap_free_aqic_resources(q);
 	}
 
 done:



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 532/877] KVM: Ensure memory attributes xarray nodes are accounted to the callers memcg
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (530 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 531/877] s390/vfio-ap: fix KVM GISC and page leak when queue removed from host config Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 533/877] KVM: Dont treat reserved xarray entries as having memory attributes Greg Kroah-Hartman
                   ` (352 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, David Ballesteros,
	Sean Christopherson

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: David Ballesteros <davimaba.v@proton.me>

commit 382e5d514b6f35bdda2ab9044b4eed23d2ec4254 upstream.

Explicitly instantiate the memory attributes xarray with XA_FLAGS_ACCOUNT
to ensure that all allocations are accounted to the memcg.  Frustratingly,
memory allocations done in the "fastpath" do not honor the passed in gfp,
even for an explicit xa_reserve().  Only the rare, slow path __xas_nomem()
honors the original gfp.  E.g.

  xa_reserve(..., GFP_KERNEL_ACCOUNT)
  |
  -> ...
     |
     -> __xa_cmpxchg_raw()
        |
        -> xas_store()  <== does not take @gfp
           |
           -> xas_create()
              |
              -> xas_alloc()

The bug was confirmed by observing that a process in a cgroup limited to
256 MiB grew radix_tree_node slab by ~512 MiB while its memory.current
stayed near 0.

Fixes: 5a475554db1e ("KVM: Introduce per-page memory attributes")
Cc: stable@vger.kernel.org
Assisted-by: Claude-Code:claude-opus-5
Signed-off-by: David Ballesteros <davimaba.v@proton.me>
Link: https://patch.msgid.link/20260915175335.138547-4-davimaba.v@proton.me
[sean: rewrite changelog, tag for stable]
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 virt/kvm/kvm_main.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1164,7 +1164,7 @@ static struct kvm *kvm_create_vm(unsigne
 	rcuwait_init(&kvm->mn_memslots_update_rcuwait);
 	xa_init(&kvm->vcpu_array);
 #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
-	xa_init(&kvm->mem_attr_array);
+	xa_init_flags(&kvm->mem_attr_array, XA_FLAGS_ACCOUNT);
 #endif
 
 	INIT_LIST_HEAD(&kvm->gpc_list);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 533/877] KVM: Dont treat reserved xarray entries as having memory attributes
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (531 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 532/877] KVM: Ensure memory attributes xarray nodes are accounted to the callers memcg Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 534/877] KVM: arm64: Fix spurious warning for benign stage 2 teardown race Greg Kroah-Hartman
                   ` (351 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sean Christopherson,
	David Ballesteros, Zeng Chi

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Zeng Chi <zengchi@kylinos.cn>

commit 277d3623d99a4fc2623bfb7d191b649ca380605d upstream.

kvm_vm_set_mem_attributes() reserves an xarray entry for every gfn in
the range before storing the new attributes, so that the store loop
can't fail partway through.  If one of the reservations fails, e.g. with
-ENOMEM, the entries that were already reserved are left in the array.
That is harmless as far as xa_reserve() is concerned, as the reserved
entries read back as NULL via xa_load(), but it confuses the "does this
range have no attributes at all" check:

	if (!attrs)
		return !xas_find(&xas, end - 1);

A reserved entry is XA_ZERO_ENTRY, not NULL, and xas_find() returns it
as present.  So a leftover reservation makes KVM report that a fully
shared range has attributes even though kvm_get_memory_attributes()
returns none for every gfn in the range.  On x86, the next time
mixed-attribute tracking is recomputed for the range (memslot creation,
or a later attribute change that straddles the 2MiB page),
hugepage_has_attrs() treats a fully shared 2MiB range as mixed and
refuses to map it with a hugepage, until userspace happens to set
attributes on the range again.

Drop the shortcut and handle the !attrs case in the per-index loop,
using xas_next_entry() to find the next non-NULL entry.  xas_next_entry()
is essentially an optimized xas_find(), so the effective change is that
the !attrs lookup now goes through xas_retry() like the attrs != 0 case,
i.e. reserved entries are skipped and retry entries restart the walk.
Don't check the index when no entry is found, as the xarray leaves the
xas index in a bogus state in that case; no entry simply means the rest
of the range has no attributes.

KVM never stores a non-NULL entry with a value of zero (clearing stores
NULL), but such an entry would be returned by xas_next_entry() and trip
the index check, so WARN if one is ever seen.

Fixes: 5a475554db1e ("KVM: Introduce per-page memory attributes")
Cc: stable@vger.kernel.org
Suggested-by: Sean Christopherson <seanjc@google.com>
Cc: David Ballesteros <davimaba.v@proton.me>
Signed-off-by: Zeng Chi <zengchi@kylinos.cn>
Link: https://patch.msgid.link/20260921102442.1232375-1-zeng_chi911@163.com
[sean: expand comment to elaborate on xarray APIs, split optimization out]
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 virt/kvm/kvm_main.c |   28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2429,14 +2429,36 @@ bool kvm_range_has_memory_attributes(str
 		return (kvm_get_memory_attributes(kvm, start) & mask) == attrs;
 
 	guard(rcu)();
-	if (!attrs)
-		return !xas_find(&xas, end - 1);
 
+	/*
+	 * Lookup the entry for each index instead of iterating over the xarray
+	 * as KVM deletes/nullifies entries to represent "no attributes", and
+	 * the xas index is effectively invalid when no entry is found.  I.e.
+	 * matching non-zero attributes for *every* entry effectively requires
+	 * a manually lookup for each index.
+	 *
+	 * Skip pre-allocated, reserved entries, or restart the lookup if the
+	 * xarray was concurrently modified, via xas_retry() ("retry" means the
+	 * entry holds an internal xarray value, i.e. is either invalid or NULL
+	 * from the caller's perspective).
+	 *
+	 * Use xas_next() when looking for non-zero attributes to optimize for
+	 * the case where the start of the range (or the entire range) doesn't
+	 * have any attributes, as xas_next() returns literally the next entry,
+	 * whereas xas_next_entry() returns the next non-NULL entry (bounded by
+	 * a maximum index).
+	 */
 	for (index = start; index < end; index++) {
 		do {
-			entry = xas_next(&xas);
+			entry = attrs ? xas_next(&xas) :
+					xas_next_entry(&xas, end - 1);
 		} while (xas_retry(&xas, entry));
 
+		if (!entry)
+			return !attrs;
+
+		WARN_ON_ONCE(!xa_to_value(entry));
+
 		if (xas.xa_index != index ||
 		    (xa_to_value(entry) & mask) != attrs)
 			return false;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 534/877] KVM: arm64: Fix spurious warning for benign stage 2 teardown race
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (532 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 533/877] KVM: Dont treat reserved xarray entries as having memory attributes Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 535/877] RISC-V: KVM: Synchronize hrtimer callback during teardown Greg Kroah-Hartman
                   ` (350 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yuan Yao, Marc Zyngier,
	Lorenzo Stoakes (ARM), Oliver Upton

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Lorenzo Stoakes (ARM) <ljs@kernel.org>

commit 38b70fc453c3112f1a62583b89903ae41116cc27 upstream.

kvmtool was used to establish an L1 guest with 8 CPUs and 8 GiB of RAM, an
L2 guest with 4 CPUs and 4 GiB of RAM and an L3 guest with 2 CPUs and 2 GiB
of RAM, all of which was then exited.

Under memory pressure in the L0 host warnings were observed due to
migration triggered by compaction:

WARNING: arch/arm64/kvm/mmu.c:336 at __unmap_stage2_range+0x64/0x80,
CPU#5: kcompactd0/66

Which was, in turn, triggered by an MMU notifier for the host invalidation:

mmu_notifier_invalidate_range_start()
  -> ... -> kvm_mmu_notifier_invalidate_range_start()
    -> kvm_mmu_unmap_gfn_range()
      -> kvm_unmap_gfn_range()
        -> kvm_nested_s2_unmap()
          -> kvm_stage2_unmap_range()
            -> __unmap_stage2_range()
               -> stage2_apply_range()
       	       <- -EINVAL, triggering a WARN_ON()

Racing with L0's teardown of stage 2 page tables:

exit_mm()
  -> mmput()
    -> __mmput()
      -> exit_mmap()
        -> mmu_notifier_release()
	  -> ... -> kvm_mmu_notifier_release()
            -> kvm_flush_shadow_all()
              -> kvm_arch_flush_shadow_all()
	        -> kvm_free_stage2_pgd()
		  -> [ acquire kvm->mmu_lock for write ]
		  -> mmu->pgt = NULL [ among other tasks ]
		  -> [ release kvm->mmu_lock for write ]

It turns out there is a benign race resulting in a spurious warning:

	Thread A - notify: migration   | Thread B - notify: release
	-------------------------------|---------------------------------
	< kvm->mmu_lock held >         |
	stage2_apply_range()           |
	  get mmu->pgt, check !NULL    |
	  ...                          | kvm_arch_flush_shadow_all()
	  cond_resched_rwlock_write(); |   < contend, sleep kvm->mmu_lock >
	< drop kvm->mmu_lock >         |   < acquire kvm->mmu_lock>
                                       |   ...
				       |   kvm_free_stage2_pgd()
                                       |     mmu->pgt = NULL
				       |   < invalidate MMU >
				       |   ...
				       |   < release kvm->mmu_lock >
	[ scheduled ]		       |
	stage2_apply_range()           |
	  < loop to next >             |
	  get, mmu->pgt, check !NULL   |
	  is NULL, return -EINVAL      |
        __unmap_stage2_range()         |
	  WARN_ON(-EINVAL) <--- entirely spurious - the race was handled
                                 correctly.

Fix the spurious warning by updating stage2_apply_range() to no longer
treat concurrent PGT teardown on lock release as an error - whether the
walker is tearing down page tables or doing something else this is a
legitimate reason to abort the operation without error.

This keeps the warning in place for all other circumstances.

In practice only __unmap_stage2_range() actually does anything with the
error so this only impacts that.

Fixes: ec14c272408a ("KVM: arm64: nv: Unmap/flush shadow stage 2 page tables")
Cc: stable@vger.kernel.org
Reviewed-by: Yuan Yao <yaoyuan@linux.alibaba.com>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Link: https://patch.msgid.link/20260901-kvm-arm-nested-virt-fix-v3-1-b154676f7e4c@kernel.org
Signed-off-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/arm64/kvm/mmu.c |   15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -53,27 +53,36 @@ static phys_addr_t stage2_range_addr_end
  * long will also starve other vCPUs. We have to also make sure that the page
  * tables are not freed while we released the lock.
  */
-static int stage2_apply_range(struct kvm_s2_mmu *mmu, phys_addr_t addr,
+static int stage2_apply_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
 			      phys_addr_t end,
 			      int (*fn)(struct kvm_pgtable *, u64, u64),
 			      bool resched)
 {
 	struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
+	bool lock_dropped = false;
+	phys_addr_t addr = start;
 	int ret;
 	u64 next;
 
 	do {
 		struct kvm_pgtable *pgt = mmu->pgt;
+		/*
+		 * We may be raced on PGT teardown when we release the
+		 * kvm->mmu_lock. That's fine as the PGT is legitimately no
+		 * longer present.
+		 */
 		if (!pgt)
-			return -EINVAL;
+			return lock_dropped ? 0 : -EINVAL;
 
 		next = stage2_range_addr_end(addr, end);
 		ret = fn(pgt, addr, next - addr);
 		if (ret)
 			break;
 
-		if (resched && next != end)
+		if (resched && next != end) {
 			cond_resched_rwlock_write(&kvm->mmu_lock);
+			lock_dropped = true;
+		}
 	} while (addr = next, addr != end);
 
 	return ret;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 535/877] RISC-V: KVM: Synchronize hrtimer callback during teardown
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (533 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 534/877] KVM: arm64: Fix spurious warning for benign stage 2 teardown race Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 536/877] RISC-V: KVM: Fix HSM hart status error propagation Greg Kroah-Hartman
                   ` (349 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Myeonghun Pak, Anup Patel

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Myeonghun Pak <mhun512@gmail.com>

commit aaad136d56d91252517272b68cd533e5714698d5 upstream.

The non-Sstc hrtimer callback clears next_set before its final uses of
the enclosing vCPU.  If teardown observes next_set as false while the
callback is still running, kvm_riscv_vcpu_timer_cancel() skips
hrtimer_cancel() and kvm_destroy_vcpus() can free the vCPU before the
callback enters kvm_riscv_vcpu_set_interrupt().

A guest can arm the timer with SBI TIME and request shutdown with SBI
legacy shutdown or SRST.  A VMM that honors KVM_EXIT_SYSTEM_EVENT and
destroys the VM supplies the teardown side of the race; no post-launch
host ioctl is needed to arm or request teardown.

On upstream master 62cc90241548, generic KASAN reported:

  BUG: KASAN: slab-use-after-free in do_raw_spin_lock
  Write of size 4 at addr ff60000005e58898

  kvm_riscv_vcpu_set_interrupt
  kvm_riscv_vcpu_hrtimer_expired
  __hrtimer_run_queues
  hrtimer_interrupt

The object was allocated by KVM_CREATE_VCPU and freed concurrently by:

  kvm_destroy_vcpus
  kvm_arch_destroy_vm
  kvm_destroy_vm
  __fput

For deterministic validation, I added mdelay(1000) immediately after
the existing next_set = false assignment.  This only widens the
existing post-clear callback window.  A no-delay trace build naturally
reached the callback-after-teardown-start/before-deinit ordering in 12
of 200 runs, but 1,500 stock-kernel stress iterations did not produce a
KASAN report, so natural reproduction is timing-sensitive.

Always invoke hrtimer_cancel() for an initialized timer.  Preserve the
existing -EINVAL result when the timer is no longer set, but only after
synchronizing with a running callback.

With this patch, hrtimer_cancel() blocked for the full widened callback
window before vCPU destruction.  KASAN reported no error in 100
fixed-and-widened runs or 200 fix-only timing-sweep runs.

Fixes: 3a9f66cb25e1 ("RISC-V: KVM: Add timer functionality")
Cc: stable@vger.kernel.org
Assisted-by: OpenAI:GPT-5.6
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260731163550.46991-1-mhun512@gmail.com
Signed-off-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/riscv/kvm/vcpu_timer.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

--- a/arch/riscv/kvm/vcpu_timer.c
+++ b/arch/riscv/kvm/vcpu_timer.c
@@ -60,10 +60,13 @@ static enum hrtimer_restart kvm_riscv_vc
 
 static int kvm_riscv_vcpu_timer_cancel(struct kvm_vcpu_timer *t)
 {
-	if (!t->init_done || !t->next_set)
+	if (!t->init_done)
 		return -EINVAL;
 
 	hrtimer_cancel(&t->hrt);
+
+	if (!t->next_set)
+		return -EINVAL;
 	t->next_set = false;
 
 	return 0;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 536/877] RISC-V: KVM: Fix HSM hart status error propagation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (534 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 535/877] RISC-V: KVM: Synchronize hrtimer callback during teardown Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 537/877] Bluetooth: hci_conn: fix CIS hold ownership on reuse Greg Kroah-Hartman
                   ` (348 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Tan Chi, Anup Patel

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Tan Chi <tanchi25@mails.ucas.ac.cn>

commit 41e81f7e3ef96594fb840445343c0ee7723aa550 upstream.

kvm_sbi_hsm_vcpu_get_status() returns SBI_ERR_INVALID_PARAM when
the requested hart does not exist. However, the HART_STATUS case
returns from the SBI handler without storing this error in
retdata->err_val.

As a result, a guest querying the status of a non-existent hart
observes SBI_SUCCESS instead of SBI_ERR_INVALID_PARAM.

Use the common SBI error handling path for HART_STATUS after
saving a valid hart state in retdata->out_val. This preserves
the returned error when kvm_sbi_hsm_vcpu_get_status() fails.

Fixes: bae0dfd74e01 ("RISC-V: KVM: Modify SBI extension handler to return SBI error code")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Tan Chi <tanchi25@mails.ucas.ac.cn>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260914031146.446157-1-tanchi25@mails.ucas.ac.cn
Signed-off-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/riscv/kvm/vcpu_sbi_hsm.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/arch/riscv/kvm/vcpu_sbi_hsm.c
+++ b/arch/riscv/kvm/vcpu_sbi_hsm.c
@@ -106,9 +106,9 @@ static int kvm_sbi_ext_hsm_handler(struc
 		ret = kvm_sbi_hsm_vcpu_get_status(vcpu);
 		if (ret >= 0) {
 			retdata->out_val = ret;
-			retdata->err_val = 0;
+			ret = 0;
 		}
-		return 0;
+		break;
 	case SBI_EXT_HSM_HART_SUSPEND:
 		switch (lower_32_bits(cp->a0)) {
 		case SBI_HSM_SUSPEND_RET_DEFAULT:



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 537/877] Bluetooth: hci_conn: fix CIS hold ownership on reuse
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (535 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 536/877] RISC-V: KVM: Fix HSM hart status error propagation Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 538/877] Bluetooth: hci_sock: validate event length before filtering Greg Kroah-Hartman
                   ` (347 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
	Luiz Augusto von Dentz

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>

commit e06d549fcd4a0ba381ed67ddf1ab3c7a6ca4314c upstream.

Commit 69997d50ec57 ("Bluetooth: ISO: handle bound CIS cleanup via
hci_conn") made hci_bind_cis() and hci_connect_cis() return a
connection with one hold for the ISO layer.  hci_bind_cis() currently
takes that hold only after configuring a CIS, so its BT_CONNECTED and
matching BT_BOUND paths return a bare lookup result.  Its configuration
failure path can likewise call hci_conn_drop() before taking a hold.

Take the hold before any state-dependent return or configuration error
so every successful return follows the documented ownership contract
and every error drop is balanced.

hci_connect_cis() also assumes hci_conn_link() always takes a new CIS
hold before dropping the one returned by hci_bind_cis().  However, the
helper returns an existing link without taking another hold.  In that
case, preserve the CIS hold for the caller and drop the redundant LE
hold because the existing link already owns its parent hold.  Returning
early also avoids changing an existing CIS back to BT_CONNECT.

Fixes: 69997d50ec57 ("Bluetooth: ISO: handle bound CIS cleanup via hci_conn")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/bluetooth/hci_conn.c |    9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -1937,6 +1937,8 @@ struct hci_conn *hci_bind_cis(struct hci
 		cis->iso_qos.ucast.cis = BT_ISO_QOS_CIS_UNSET;
 	}
 
+	hci_conn_hold(cis);
+
 	if (cis->state == BT_CONNECTED)
 		return cis;
 
@@ -1978,7 +1980,6 @@ struct hci_conn *hci_bind_cis(struct hci
 		return ERR_PTR(-EINVAL);
 	}
 
-	hci_conn_hold(cis);
 	cis->state = BT_BOUND;
 
 	return cis;
@@ -2340,6 +2341,12 @@ struct hci_conn *hci_connect_cis(struct
 		hci_conn_drop(le);
 		return cis;
 	}
+
+	/* The existing link already owns the hold on its parent. */
+	if (cis->link) {
+		hci_conn_drop(le);
+		return cis;
+	}
 
 	link = hci_conn_link(le, cis);
 	hci_conn_drop(cis);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 538/877] Bluetooth: hci_sock: validate event length before filtering
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (536 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 537/877] Bluetooth: hci_conn: fix CIS hold ownership on reuse Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 539/877] Bluetooth: hci_sock: reject out-of-range OCF values Greg Kroah-Hartman
                   ` (346 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
	Luiz Augusto von Dentz

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>

commit b0a6cf99afd57a39598b1beca0e86ef5004980de upstream.

is_filtered_packet() reads the event code from skb->data[0] without first
checking that the skb is nonempty. When an opcode filter is configured,
it also reads the command opcode at offsets 3 or 4 without checking that
a Command Complete or Command Status event is long enough.

hci_send_to_sock() invokes the filter before hci_event_packet() validates
the event header. A malformed event supplied by a controller or a vhci
device can therefore cause an out-of-bounds read.

Keep the unmasked event code for the opcode checks. The masked value is
needed for the 64-bit event bitmap, but using it to identify command events
aliases event codes above 0x3f. In particular, Synchronous Train Complete
(0x4f) was treated as Command Status (0x0f) even though its payload has no
opcode.

Reject actual command events that are too short for the field being
inspected. A truncated command event cannot match a configured opcode.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/bluetooth/hci_sock.c |   17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -166,6 +166,7 @@ static bool is_filtered_packet(struct so
 {
 	struct hci_filter *flt;
 	int flt_type, flt_event;
+	u8 event;
 
 	/* Apply filter */
 	flt = &hci_pi(sk)->filter;
@@ -179,7 +180,11 @@ static bool is_filtered_packet(struct so
 	if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT)
 		return false;
 
-	flt_event = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
+	if (skb->len < 1)
+		return true;
+
+	event = *(__u8 *)skb->data;
+	flt_event = event & HCI_FLT_EVENT_BITS;
 
 	if (!hci_test_bit(flt_event, &flt->event_mask))
 		return true;
@@ -188,11 +193,17 @@ static bool is_filtered_packet(struct so
 	if (!flt->opcode)
 		return false;
 
-	if (flt_event == HCI_EV_CMD_COMPLETE &&
+	if (event == HCI_EV_CMD_COMPLETE && skb->len < 5)
+		return true;
+
+	if (event == HCI_EV_CMD_COMPLETE &&
 	    flt->opcode != get_unaligned((__le16 *)(skb->data + 3)))
 		return true;
 
-	if (flt_event == HCI_EV_CMD_STATUS &&
+	if (event == HCI_EV_CMD_STATUS && skb->len < 6)
+		return true;
+
+	if (event == HCI_EV_CMD_STATUS &&
 	    flt->opcode != get_unaligned((__le16 *)(skb->data + 4)))
 		return true;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 539/877] Bluetooth: hci_sock: reject out-of-range OCF values
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (537 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 538/877] Bluetooth: hci_sock: validate event length before filtering Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 540/877] Bluetooth: ISO: balance the parent hold in hci_bind_bis() Greg Kroah-Hartman
                   ` (345 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
	Luiz Augusto von Dentz

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>

commit e93fad891c72deb84cae49430163b384ebcc92b1 upstream.

The raw HCI socket security filter has 128 OCF bits per supported OGF,
but masks the 10-bit OCF with 127 before looking up the command. An
unprivileged socket can therefore submit a reserved OCF that aliases an
allowlisted command modulo 128.

A conforming controller should reject reserved opcodes. Nevertheless,
the security decision must apply to the opcode that will actually be
sent, especially since controller-specific behavior is outside the host
stack's control.

Reject OCF values that cannot be represented by the security filter
instead of aliasing them onto an unrelated command.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/bluetooth/hci_sock.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -1886,7 +1886,8 @@ static int hci_sock_sendmsg(struct socke
 		u16 ocf = hci_opcode_ocf(opcode);
 
 		if (((ogf > HCI_SFLT_MAX_OGF) ||
-		     !hci_test_bit(ocf & HCI_FLT_OCF_BITS,
+		     (ocf > HCI_FLT_OCF_BITS) ||
+		     !hci_test_bit(ocf,
 				   &hci_sec_filter.ocf_mask[ogf])) &&
 		    !capable(CAP_NET_RAW)) {
 			err = -EPERM;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 540/877] Bluetooth: ISO: balance the parent hold in hci_bind_bis()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (538 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 539/877] Bluetooth: hci_sock: reject out-of-range OCF values Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 541/877] Bluetooth: L2CAP: validate frame length before control and FCS access Greg Kroah-Hartman
                   ` (344 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
	Luiz Augusto von Dentz

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>

commit 4c94557dd02569efa6c1072a0439addaef9a5224 upstream.

hci_conn_link() takes a lifetime reference to its parent with
hci_conn_get(), but only takes an operational hold on the child.
hci_conn_unlink() later balances both a hold and a reference on the
parent.

The SCO and CIS paths pass a parent acquired from a connect helper, so
it already has a hold. For an additional BIS, hci_bind_bis() obtains the
parent from hci_conn_hash_lookup_big(), which returns a bare pointer.
Unlinking the child then drops the parent's existing hold and can
schedule it for disconnection while its socket is still using it.

Take a hold on the parent before linking it and drop that hold if linking
fails. A successful link transfers the hold to hci_conn_unlink().

Fixes: fa224d0c094a ("Bluetooth: ISO: Reassociate a socket with an active BIS")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/bluetooth/hci_conn.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -2234,10 +2234,13 @@ struct hci_conn *hci_bind_bis(struct hci
 	parent = hci_conn_hash_lookup_big(hdev,
 					  conn->iso_qos.bcast.big);
 	if (parent && parent != conn) {
+		hci_conn_hold(parent);
 		link = hci_conn_link(parent, conn);
 		hci_conn_drop(conn);
-		if (!link)
+		if (!link) {
+			hci_conn_drop(parent);
 			return ERR_PTR(-ENOLINK);
+		}
 	}
 
 	return conn;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 541/877] Bluetooth: L2CAP: validate frame length before control and FCS access
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (539 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 540/877] Bluetooth: ISO: balance the parent hold in hci_bind_bis() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 542/877] Bluetooth: mgmt: fix race in read_unconf_index_list() Greg Kroah-Hartman
                   ` (343 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
	Luiz Augusto von Dentz

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>

commit 6c78a213d9070b610c7f418af2c25b66180b7e37 upstream.

l2cap_data_rcv() unpacks either a two-byte or four-byte control field
without first ensuring that it is present. A short ERTM or streaming-mode
frame can therefore cause an out-of-bounds read.

There is a second short-frame case when CRC16 is enabled. After the
control field is pulled, l2cap_check_fcs() subtracts two from skb->len
without checking it. If fewer than two bytes remain, the subtraction
wraps; skb_trim() leaves the buffer unchanged and the subsequent FCS
load reads past the logical end of the frame.

Validate that the frame contains both its control field and, when
enabled, its FCS before either field is accessed.

Fixes: 1c2acffb76d4 ("Bluetooth: Add initial support for ERTM packets transfers")
Fixes: fcc203c30d72 ("Bluetooth: Add support for FCS option to L2CAP")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/bluetooth/l2cap_core.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -6681,9 +6681,17 @@ static int l2cap_stream_rx(struct l2cap_
 static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
 {
 	struct l2cap_ctrl *control = &bt_cb(skb)->l2cap;
-	u16 len;
+	u16 len, min_len;
 	u8 event;
 
+	min_len = test_bit(FLAG_EXT_CTRL, &chan->flags) ?
+		  L2CAP_EXT_CTRL_SIZE : L2CAP_ENH_CTRL_SIZE;
+	if (chan->fcs == L2CAP_FCS_CRC16)
+		min_len += L2CAP_FCS_SIZE;
+
+	if (skb->len < min_len)
+		goto drop;
+
 	__unpack_control(chan, skb);
 
 	len = skb->len;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 542/877] Bluetooth: mgmt: fix race in read_unconf_index_list()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (540 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 541/877] Bluetooth: L2CAP: validate frame length before control and FCS access Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 543/877] Bluetooth: RFCOMM: fix NULL dereference of dlc->session in RFCOMM_CONNINFO Greg Kroah-Hartman
                   ` (342 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Aldo Ariel Panzardo,
	Luiz Augusto von Dentz

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Aldo Ariel Panzardo <qwe.aldo@gmail.com>

commit b5dbb41b212c50c095a4dbee3017a84fe94f033b upstream.

read_unconf_index_list() counts unconfigured controllers before allocating
its response, then checks the device flags again while filling it.

hci_dev_list_lock stabilizes list membership, but it does not serialize the
per-device flags. During asynchronous controller setup, the worker can set
HCI_UNCONFIGURED and clear HCI_SETUP between the two passes. A controller
omitted from the allocation count can then become eligible for the fill
pass, causing an out-of-bounds write to rp->index[].

Allocate space for every device on hci_dev_list. Since list membership
cannot change while hci_dev_list_lock is held, the response remains large
enough regardless of flag transitions. The reported count and response
length still include only eligible unconfigured controllers.

Fixes: 73d1df2a7a10 ("Bluetooth: Add support for Read Unconfigured Index List command")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/bluetooth/mgmt.c |    8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -498,13 +498,9 @@ static int read_unconf_index_list(struct
 
 	read_lock(&hci_dev_list_lock);
 
-	count = 0;
-	list_for_each_entry(d, &hci_dev_list, list) {
-		if (hci_dev_test_flag(d, HCI_UNCONFIGURED))
-			count++;
-	}
+	count = list_count_nodes(&hci_dev_list);
 
-	rp_len = sizeof(*rp) + (2 * count);
+	rp_len = sizeof(*rp) + (sizeof(__le16) * count);
 	rp = kmalloc(rp_len, GFP_ATOMIC);
 	if (!rp) {
 		read_unlock(&hci_dev_list_lock);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 543/877] Bluetooth: RFCOMM: fix NULL dereference of dlc->session in RFCOMM_CONNINFO
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (541 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 542/877] Bluetooth: mgmt: fix race in read_unconf_index_list() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 544/877] smb: client: fix create context out-of-bounds reads Greg Kroah-Hartman
                   ` (341 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Hui Peng, Luiz Augusto von Dentz

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Hui Peng <benquike@gmail.com>

commit 46f8ffd0a1f1eb6cbc94946a92c11ef601e228a1 upstream.

The RFCOMM_CONNINFO getsockopt handler accepts a socket that is not
connected as long as deferred setup is enabled:

	if (sk->sk_state != BT_CONNECTED &&
				!rfcomm_pi(sk)->dlc->defer_setup) {
		err = -ENOTCONN;
		break;
	}
	l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk;

dlc->defer_setup is set in rfcomm_sock_init() when rfcomm_connect_ind()
creates a child socket for an incoming connection on a listening socket
that has BT_DEFER_SETUP enabled. It is never cleared afterwards. The
session, however, can go away underneath it.

rfcomm_recv_disc() forces the dlc state before tearing it down:

	d->state = BT_CLOSED;
	__rfcomm_dlc_close(d, err);

The RFCOMM_DEFER_SETUP early return in __rfcomm_dlc_close() only covers
BT_CONNECT, BT_CONFIG, BT_OPEN and BT_CONNECT2, so with the state
already BT_CLOSED that switch does not match and the function falls
through to rfcomm_dlc_unlink(), which sets d->session = NULL, while
d->defer_setup stays 1.

A getsockopt(SOL_RFCOMM, RFCOMM_CONNINFO) on the accepted socket after
that point therefore skips the -ENOTCONN path -- sk->sk_state is
BT_CLOSED, but dlc->defer_setup is still set -- and dereferences the
NULL session. No race is needed: once the DISC has been processed, the
dereference is unconditional.

Reproduced on a KASAN kernel under QEMU with a BR/EDR peer emulated over
/dev/vhci: the peer brings up an ACL link, opens L2CAP on the RFCOMM
PSM, starts a session and sends SABM for a channel bound with
BT_DEFER_SETUP, and sends DISC for that dlci after the socket has been
accepted. getsockopt(SOL_RFCOMM, RFCOMM_CONNINFO) on the accepted
socket then hits:

 Oops: general protection fault, probably for non-canonical address
 0xdffffc0000000002: 0000 [#1] SMP KASAN PTI
 KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
 CPU: 1 UID: 0 PID: 150 Comm: init Tainted: G B 7.3.0-rc3-g5dd1818b15d9
 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)
 RIP: 0010:rfcomm_sock_getsockopt+0x529/0x780
 Call Trace:
  <TASK>
  do_sock_getsockopt+0x3ad/0x7d0
  __sys_getsockopt+0x10e/0x1b0
  __x64_sys_getsockopt+0xc2/0x160
  do_syscall_64+0xda/0x4b0
  entry_SYSCALL_64_after_hwframe+0x77/0x7f
  </TASK>

0x10 is the offset of sock in struct rfcomm_session;
rfcomm_sock_getsockopt_old() is inlined into rfcomm_sock_getsockopt().

Commit 43a556b2fd43 ("Bluetooth: RFCOMM: take rfcomm_mutex for the
deferred setup accept") fixed the same "a remote DISC clears the session
while deferred setup is still flagged" problem in rfcomm_dlc_accept();
this is the remaining instance of it, in the getsockopt path.

Deferred setup only leaves a socket usable here once it has reached
BT_CONNECT2, so restrict the exception to that state and check that a
session is actually present before following it.

Fixes: bb23c0ab8246 ("Bluetooth: Add support for deferring RFCOMM connection setup")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/bluetooth/rfcomm/sock.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -785,8 +785,10 @@ static int rfcomm_sock_getsockopt_old(st
 		break;
 
 	case RFCOMM_CONNINFO:
-		if (sk->sk_state != BT_CONNECTED &&
-					!rfcomm_pi(sk)->dlc->defer_setup) {
+		if ((sk->sk_state != BT_CONNECTED &&
+		     !(sk->sk_state == BT_CONNECT2 &&
+		       rfcomm_pi(sk)->dlc->defer_setup)) ||
+		    !rfcomm_pi(sk)->dlc->session) {
 			err = -ENOTCONN;
 			break;
 		}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 544/877] smb: client: fix create context out-of-bounds reads
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (542 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 543/877] Bluetooth: RFCOMM: fix NULL dereference of dlc->session in RFCOMM_CONNINFO Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 545/877] smb: client: clean up failed cached directory opens Greg Kroah-Hartman
                   ` (340 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Luxing Yin, Zihan Xi,
	Frank Sorenson, Paulo Alcantara

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Zihan Xi <zihanx@nebusec.ai>

commit 67f4c1c6a1b51e203d986779299824d1c2c590a6 upstream.

smb2_parse_contexts() validates the complete create-context area but
does not limit each record to its Next field before dispatching it.  A
malformed chain can therefore expose bytes beyond the current context to
a handler.  The QFid handler also used a full response-structure cast
although it only reads DiskFileId.

The SMB2/SMB3 lease parsers made the same layout assumption: they read
LeaseState and LeaseFlags at canonical offsets rather than at
DataOffset.  A valid non-canonical DataOffset could therefore yield
unrelated in-bounds data, while a short DataLength was still accepted.

Limit each context to its Next value, reject offsets before the context
header, and reject malformed chains.  Bound the name range by the current
context and do not dispatch a known handler when DataLength is zero.  Read
the QFid DiskFileId only when the context data covers that field.  Parse the
lease context from DataOffset and require DataLength to match the v1 or v2
lease_context size used by ksmbd.  A size mismatch skips lease parsing
without failing the open.

Fixes: b8c32dbb0deb ("CIFS: Request SMB2.1 leases")
Fixes: f047390a097e ("CIFS: Add create lease v2 context for SMB3")
Fixes: 89a5bfa350fa ("smb3: optimize open to not send query file internal info")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Tested-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/smb2ops.c |   28 ++++++++++++++++++++--------
 fs/smb/client/smb2pdu.c |   44 ++++++++++++++++++++++++++++++++++----------
 2 files changed, 54 insertions(+), 18 deletions(-)

--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -4405,25 +4405,37 @@ smb3_create_lease_buf(u8 *lease_key, u8
 static __u8
 smb2_parse_lease_buf(void *buf, __u16 *epoch, char *lease_key)
 {
-	struct create_lease *lc = (struct create_lease *)buf;
+	struct create_context *cc = buf;
+	struct lease_context lc;
 
 	*epoch = 0; /* not used */
-	if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE)
+	if (le32_to_cpu(cc->DataLength) != sizeof(lc))
+		return 0;
+
+	memcpy(&lc, (u8 *)cc + le16_to_cpu(cc->DataOffset), sizeof(lc));
+	if (lc.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE)
 		return SMB2_OPLOCK_LEVEL_NOCHANGE;
-	return le32_to_cpu(lc->lcontext.LeaseState);
+	return le32_to_cpu(lc.LeaseState);
 }
 
 static __u8
 smb3_parse_lease_buf(void *buf, __u16 *epoch, char *lease_key)
 {
-	struct create_lease_v2 *lc = (struct create_lease_v2 *)buf;
+	struct create_context *cc = buf;
+	struct lease_context_v2 lc;
+
+	if (le32_to_cpu(cc->DataLength) != sizeof(lc)) {
+		*epoch = 0;
+		return 0;
+	}
 
-	*epoch = le16_to_cpu(lc->lcontext.Epoch);
-	if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE)
+	memcpy(&lc, (u8 *)cc + le16_to_cpu(cc->DataOffset), sizeof(lc));
+	*epoch = le16_to_cpu(lc.Epoch);
+	if (lc.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS_LE)
 		return SMB2_OPLOCK_LEVEL_NOCHANGE;
 	if (lease_key)
-		memcpy(lease_key, &lc->lcontext.LeaseKey, SMB2_LEASE_KEY_SIZE);
-	return le32_to_cpu(lc->lcontext.LeaseState);
+		memcpy(lease_key, lc.LeaseKey, SMB2_LEASE_KEY_SIZE);
+	return le32_to_cpu(lc.LeaseState);
 }
 
 static unsigned int
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -2296,11 +2296,17 @@ create_reconnect_durable_buf(struct cifs
 static void
 parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf)
 {
-	struct create_disk_id_rsp *pdisk_id = (struct create_disk_id_rsp *)cc;
+	u16 doff = le16_to_cpu(cc->DataOffset);
+	u32 dlen = le32_to_cpu(cc->DataLength);
+	u8 *beg;
 
-	cifs_dbg(FYI, "parse query id context 0x%llx 0x%llx\n",
-		pdisk_id->DiskFileId, pdisk_id->VolumeId);
-	buf->IndexNumber = pdisk_id->DiskFileId;
+	if (dlen < sizeof(__le64))
+		return;
+
+	beg = (u8 *)cc + doff;
+	memcpy(&buf->IndexNumber, beg, sizeof(__le64));
+	cifs_dbg(FYI, "parse query id context 0x%llx\n",
+		 le64_to_cpu(buf->IndexNumber));
 }
 
 static void
@@ -2348,6 +2354,7 @@ int smb2_parse_contexts(struct TCP_Serve
 	struct smb2_create_rsp *rsp = rsp_iov->iov_base;
 	struct create_context *cc;
 	size_t rem, off, len;
+	size_t cc_len;
 	size_t doff, dlen;
 	size_t noff, nlen;
 	char *name;
@@ -2370,29 +2377,41 @@ int smb2_parse_contexts(struct TCP_Serve
 		buf->IndexNumber = 0;
 
 	while (rem >= sizeof(*cc)) {
+		off = le32_to_cpu(cc->Next);
+		if (off) {
+			if ((off & 0x7) || off >= rem || off < sizeof(*cc))
+				return -EINVAL;
+			cc_len = off;
+		} else {
+			cc_len = rem;
+		}
+
 		doff = le16_to_cpu(cc->DataOffset);
 		dlen = le32_to_cpu(cc->DataLength);
-		if (check_add_overflow(doff, dlen, &len) || len > rem)
+		if (doff < sizeof(*cc) ||
+		    check_add_overflow(doff, dlen, &len) || len > cc_len)
 			return -EINVAL;
 
 		noff = le16_to_cpu(cc->NameOffset);
 		nlen = le16_to_cpu(cc->NameLength);
-		if (noff + nlen > doff)
+		if (noff < sizeof(*cc) ||
+		    check_add_overflow(noff, nlen, &len) || len > cc_len ||
+		    (dlen && len > doff))
 			return -EINVAL;
 
 		name = (char *)cc + noff;
 		switch (nlen) {
 		case 4:
-			if (!strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) {
+			if (dlen && !strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4)) {
 				*oplock = server->ops->parse_lease_buf(cc, epoch,
 								       lease_key);
-			} else if (buf &&
+			} else if (dlen && buf &&
 				   !strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4)) {
 				parse_query_id_ctxt(cc, buf);
 			}
 			break;
 		case 16:
-			if (posix && !memcmp(name, smb3_create_tag_posix, 16))
+			if (dlen && posix && !memcmp(name, smb3_create_tag_posix, 16))
 				parse_posix_ctxt(cc, buf, posix);
 			break;
 		default:
@@ -2404,13 +2423,18 @@ int smb2_parse_contexts(struct TCP_Serve
 		}
 
 		off = le32_to_cpu(cc->Next);
-		if (!off)
+		if (!off) {
+			rem = 0;
 			break;
+		}
 		if (check_sub_overflow(rem, off, &rem))
 			return -EINVAL;
 		cc = (struct create_context *)((u8 *)cc + off);
 	}
 
+	if (rem)
+		return -EINVAL;
+
 	if (rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
 		*oplock = rsp->OplockLevel;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 545/877] smb: client: clean up failed cached directory opens
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (543 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 544/877] smb: client: fix create context out-of-bounds reads Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 546/877] smb: client: validate POSIX create context length Greg Kroah-Hartman
                   ` (339 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Luxing Yin, Zihan Xi,
	Frank Sorenson, Paulo Alcantara

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Zihan Xi <zihanx@nebusec.ai>

commit d2ff5fb93ea83034025850266b5eed391f96b825 upstream.

open_cached_dir() sends CREATE and QUERY_INFO as a compound request. If
the CREATE succeeds but a later command returns an error, the function
must retain the CREATE FID so common cleanup can issue SMB2_close(). It
also must not treat a response error as a valid CREATE.

Validate the CREATE response before using its fields, record the FIDs, and
mark the handle open before handling errors from later compound commands.
Move the -EREMCHG reconnect handling before response validation so a
missing response does not hide the reconnect request. Count the handle
when it is marked open; confirmed close responses decrement the counter,
while existing close retry behavior remains best effort on transport
failures.

Fixes: b0f6df737a1c ("cifs: cache FILE_ALL_INFO for the shared root handle")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Tested-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/cached_dir.c |   32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

--- a/fs/smb/client/cached_dir.c
+++ b/fs/smb/client/cached_dir.c
@@ -8,6 +8,7 @@
 #include <linux/namei.h>
 #include "cifsglob.h"
 #include "cifsproto.h"
+#include "../common/smb2status.h"
 #include "cifs_debug.h"
 #include "smb2proto.h"
 #include "cached_dir.h"
@@ -294,25 +295,37 @@ replay_again:
 	rc = compound_send_recv(xid, ses, server,
 				flags, 2, rqst,
 				resp_buftype, rsp_iov);
-	if (rc) {
-		if (rc == -EREMCHG) {
-			tcon->need_reconnect = true;
-			pr_warn_once("server share %s deleted\n",
-				     tcon->tree_name);
-		}
-		goto oshr_free;
+	if (rc == -EREMCHG) {
+		tcon->need_reconnect = true;
+		pr_warn_once("server share %s deleted\n",
+			     tcon->tree_name);
 	}
-	cfid->is_open = true;
 
-	spin_lock(&cfids->cfid_list_lock);
+	if (!rsp_iov[0].iov_base || rsp_iov[0].iov_len < sizeof(*o_rsp)) {
+		if (!rc)
+			rc = -EIO;
+		goto oshr_free;
+	}
 
 	o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
+	if (o_rsp->hdr.Status != STATUS_SUCCESS) {
+		if (!rc)
+			rc = -EIO;
+		goto oshr_free;
+	}
+
 	oparms.fid->persistent_fid = o_rsp->PersistentFileId;
 	oparms.fid->volatile_fid = o_rsp->VolatileFileId;
 #ifdef CONFIG_CIFS_DEBUG2
 	oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId);
 #endif /* CIFS_DEBUG2 */
+	cfid->is_open = true;
+	atomic_inc(&tcon->num_remote_opens);
 
+	if (rc)
+		goto oshr_free;
+
+	spin_lock(&cfids->cfid_list_lock);
 
 	if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE) {
 		spin_unlock(&cfids->cfid_list_lock);
@@ -378,7 +391,6 @@ out:
 		close_cached_dir(cfid);
 	} else {
 		*ret_cfid = cfid;
-		atomic_inc(&tcon->num_remote_opens);
 	}
 	kfree(utf16_path);
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 546/877] smb: client: validate POSIX create context length
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (544 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 545/877] smb: client: clean up failed cached directory opens Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 547/877] xfs: dont assert when XFS_SCRUB_TYPE_HEALTHY scans return corruption Greg Kroah-Hartman
                   ` (338 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Luxing Yin, Zihan Xi,
	Frank Sorenson, Paulo Alcantara

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Zihan Xi <zihanx@nebusec.ai>

commit fa2e9900dd2a3f5a1e7ef5a8c5e8d435feedbfcc upstream.

parse_posix_ctxt() reads the fixed nlink, reparse_tag, and mode fields
before checking that the POSIX create context contains them.  A short
context can pass the generic checks and still make these fixed-width
reads run past its declared data.

The current in-tree smb2_open_file() path passes a NULL posix pointer,
so this handler is not reached on the ordinary open path.  Still require
the POSIX data to cover all three fields before reading them because the
helper performs those unguarded reads.  Keep the existing soft-failure
behavior so malformed optional metadata does not fail the open.

Fixes: 69dda3059e7a ("cifs: add SMB2_open() arg to return POSIX data")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Tested-by: Frank Sorenson <sorenson@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/smb2pdu.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -2313,12 +2313,15 @@ static void
 parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info,
 		 struct create_posix_rsp *posix)
 {
-	int sid_len;
 	u8 *beg = (u8 *)cc + le16_to_cpu(cc->DataOffset);
-	u8 *end = beg + le32_to_cpu(cc->DataLength);
+	u32 dlen = le32_to_cpu(cc->DataLength);
+	u8 *end = beg + dlen;
+	int sid_len;
 	u8 *sid;
 
 	memset(posix, 0, sizeof(*posix));
+	if (dlen < 3 * sizeof(__le32))
+		return;
 
 	posix->nlink = get_unaligned_le32(beg);
 	posix->reparse_tag = get_unaligned_le32(beg + 4);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 547/877] xfs: dont assert when XFS_SCRUB_TYPE_HEALTHY scans return corruption
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (545 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 546/877] smb: client: validate POSIX create context length Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 548/877] xfs: fix attr fork block count checks in xrep_inode_blockcounts Greg Kroah-Hartman
                   ` (337 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Darrick J. Wong <djwong@kernel.org>

commit afbccf99f7f82117cba9ad4b0b006692030f49e8 upstream.

XFS_SCRUB_TYPE_HEALTHY is a synthentic scrub type so that xfs_scrub can
tell the kernel "Hey, I finished a scan and saw no problems" and have
the kernel forget that it saw indirect evidence of corruption.

Unfortunately, as LOLLM points out, it's possible for the health system
to record a new corruption just before xfs_scrub gets to
XFS_SCRUB_TYPE_HEALTHY.  In this case, the existing logic doesn't return
early and instead wanders into unknown regions of type_to_health_flag
and trips the assert because HEALTHY doesn't have a group assignment.

Fix the logic so that we always return early for a HEALTHY scrub type,
even if we decide not to call xchk_mark_all_healthy.

Cc: stable@vger.kernel.org # v6.9
Fixes: a1f3e0cca41036 ("xfs: update health status if we get a clean bill of health")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/scrub/health.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

--- a/fs/xfs/scrub/health.c
+++ b/fs/xfs/scrub/health.c
@@ -192,9 +192,9 @@ xchk_update_health(
 	 * there's no sick flag defined for it, so we branch here ahead of the
 	 * mask check.
 	 */
-	if (sc->sm->sm_type == XFS_SCRUB_TYPE_HEALTHY &&
-	    !(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) {
-		xchk_mark_all_healthy(sc->mp);
+	if (sc->sm->sm_type == XFS_SCRUB_TYPE_HEALTHY) {
+		if (!(sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
+			xchk_mark_all_healthy(sc->mp);
 		return;
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 548/877] xfs: fix attr fork block count checks in xrep_inode_blockcounts
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (546 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 547/877] xfs: dont assert when XFS_SCRUB_TYPE_HEALTHY scans return corruption Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 549/877] xfs: release orphanage dir inode if chown fails Greg Kroah-Hartman
                   ` (336 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Darrick J. Wong <djwong@kernel.org>

commit bb991b7f79dd34cc5f24db0f736bf75630c970e7 upstream.

LOLLM points out that a file has an attr fork, it will call
xchk_inode_count_blocks to set @ablocks to the number of fsblocks mapped
by the attr fork; but then it'll compare @blocks (aka the count of
fsblocks mapped by the data fork).  We already checked that and we never
do anything with @acount, so I think this is clearly a bug.  Fix the
comparison.

Cc: stable@vger.kernel.org # v6.8
Fixes: 2d295fe65776d1 ("xfs: repair inode records")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/scrub/inode_repair.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/xfs/scrub/inode_repair.c
+++ b/fs/xfs/scrub/inode_repair.c
@@ -1513,7 +1513,7 @@ xrep_inode_blockcounts(
 				&nextents, &acount);
 		if (error)
 			return error;
-		if (count >= sc->mp->m_sb.sb_dblocks)
+		if (acount >= sc->mp->m_sb.sb_dblocks)
 			return -EFSCORRUPTED;
 		error = xrep_ino_ensure_extent_count(sc, XFS_ATTR_FORK,
 				nextents);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 549/877] xfs: release orphanage dir inode if chown fails
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (547 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 548/877] xfs: fix attr fork block count checks in xrep_inode_blockcounts Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 550/877] xfs: use correct jiffies comparison function in xchk_maybe_relax Greg Kroah-Hartman
                   ` (335 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Darrick J. Wong <djwong@kernel.org>

commit 1c32cdc986467eaffeedb6c5334852809555b82d upstream.

LOLLM points out that we leak the igrab'd reference to the orphanage
directory inode if chowning it fails.  Fix that.

Cc: stable@vger.kernel.org # v6.10
Fixes: 1e58a8ccf2597c ("xfs: move orphan files to the orphanage")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/scrub/orphanage.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

--- a/fs/xfs/scrub/orphanage.c
+++ b/fs/xfs/scrub/orphanage.c
@@ -193,12 +193,16 @@ xrep_orphanage_create(
 	/* Make sure the orphanage is owned by root. */
 	error = xrep_chown_orphanage(sc, XFS_I(orphanage_inode));
 	if (error)
-		goto out_dput_orphanage;
+		goto out_rele_orphanage;
 
 	/* Stash the reference for later and bail out. */
 	sc->orphanage = XFS_I(orphanage_inode);
 	sc->orphanage_ilock_flags = 0;
+	orphanage_inode = NULL;
 
+out_rele_orphanage:
+	if (orphanage_inode)
+		xchk_irele(sc, XFS_I(orphanage_inode));
 out_dput_orphanage:
 	dput(orphanage_dentry);
 out_unlock_root:



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 550/877] xfs: use correct jiffies comparison function in xchk_maybe_relax
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (548 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 549/877] xfs: release orphanage dir inode if chown fails Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 551/877] xfs: check padding field in xfs_ioc_commit_range Greg Kroah-Hartman
                   ` (334 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Darrick J. Wong <djwong@kernel.org>

commit 984aab2d905a8557fafb27cd9e8713d6d12b3437 upstream.

LOLLM points out that we're supposed to use time_after_eq, not a raw >=
operation here, or else jiffies wraps can go unnoticed.  Fix this.

Cc: stable@vger.kernel.org # v6.10
Fixes: 271557de7cbfde ("xfs: reduce the rate of cond_resched calls inside scrub")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/scrub/scrub.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/xfs/scrub/scrub.h b/fs/xfs/scrub/scrub.h
index 737a5d6db15f..b093945f3631 100644
--- a/fs/xfs/scrub/scrub.h
+++ b/fs/xfs/scrub/scrub.h
@@ -40,7 +40,7 @@ static inline int xchk_maybe_relax(struct xchk_relax *widget)
 		return 0;
 	widget->resched_nr = 0;
 
-	if (unlikely(widget->next_resched <= jiffies)) {
+	if (unlikely(time_after_eq(jiffies, widget->next_resched))) {
 		cond_resched();
 		widget->next_resched = XCHK_RELAX_NEXT;
 	}
-- 
2.55.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 551/877] xfs: check padding field in xfs_ioc_commit_range
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (549 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 550/877] xfs: use correct jiffies comparison function in xchk_maybe_relax Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 552/877] xfs: dont call xfs_exchange_range_finish for a dry run Greg Kroah-Hartman
                   ` (333 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Darrick J. Wong <djwong@kernel.org>

commit 3083ba8dde765a9ab2337f3db68d00724a6b1202 upstream.

LOLLM points out that we don't check the ioctl padding field here, so
let's do that.  I don't think there are many users yet since exchrange
requires a new feature flag, so it's a good time to try to plug this
hole.

Cc: stable@vger.kernel.org # v6.12
Fixes: 398597c3ef7fb1 ("xfs: introduce new file range commit ioctls")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/xfs_exchrange.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/xfs/xfs_exchrange.c
+++ b/fs/xfs/xfs_exchrange.c
@@ -905,7 +905,7 @@ xfs_ioc_commit_range(
 
 	if (copy_from_user(&args, argp, sizeof(args)))
 		return -EFAULT;
-	if (args.flags & ~XFS_EXCHANGE_RANGE_ALL_FLAGS)
+	if (args.pad || (args.flags & ~XFS_EXCHANGE_RANGE_ALL_FLAGS))
 		return -EINVAL;
 	if (kern_f->magic != XCR_FRESH_MAGIC)
 		return -EBUSY;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 552/877] xfs: dont call xfs_exchange_range_finish for a dry run
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (550 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 551/877] xfs: check padding field in xfs_ioc_commit_range Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 553/877] xfs: check di_forkoff correctly in scrub Greg Kroah-Hartman
                   ` (332 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Darrick J. Wong <djwong@kernel.org>

commit 8fc18580ec17f90beac4c933fbe4c74dcd3b7f36 upstream.

LOLLM noticed that we strip file privileges and whatnot even for a dry
run.  We also shouldn't flush dirty data to disk or trim COW staging
events for a dry run.  Neither of those behaviors are allowed by the
manpage, so fix that by exiting early on DRY_RUN in various functions.

Cc: stable@vger.kernel.org # v6.10
Fixes: 42672471f938cd ("xfs: bind together the front and back ends of the file range exchange code")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/xfs_exchrange.c |   11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

--- a/fs/xfs/xfs_exchrange.c
+++ b/fs/xfs/xfs_exchrange.c
@@ -630,6 +630,9 @@ xfs_exchrange_prep(
 	if (error)
 		return error;
 
+	if (fxr->flags & XFS_EXCHANGE_RANGE_DRY_RUN)
+		return 0;
+
 	trace_xfs_exchrange_flush(fxr, ip1, ip2);
 
 	/* Flush the relevant ranges of both files. */
@@ -706,9 +709,11 @@ xfs_exchrange_contents(
 	 * other file write would do.  This may involve turning on support for
 	 * logged xattrs if either file has security capabilities.
 	 */
-	error = xfs_exchange_range_finish(fxr);
-	if (error)
-		goto out_unlock;
+	if (!(fxr->flags & XFS_EXCHANGE_RANGE_DRY_RUN)) {
+		error = xfs_exchange_range_finish(fxr);
+		if (error)
+			goto out_unlock;
+	}
 
 out_unlock:
 	xfs_iunlock2_io_mmap(ip1, ip2);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 553/877] xfs: check di_forkoff correctly in scrub
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (551 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 552/877] xfs: dont call xfs_exchange_range_finish for a dry run Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush Greg Kroah-Hartman
                   ` (331 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Darrick J. Wong <djwong@kernel.org>

commit e9193f2f1ce32d02b9230094ffdbfab715ab6137 upstream.

The di_forkoff check in xchk_dinode is incorrect, according to LOLLM.
XFS_DFORK_BOFF returns a byte count relative to the start of the literal
area, not the start of the inode.  Therefore, this check won't flag
di_forkoff values that are larger than the literal area but not the
inode size itself.  Fix this check; sadly the old APTR code was correct.

Cc: stable@vger.kernel.org # v6.8
Fixes: 6b5d917780219d ("xfs: dont cast to char * for XFS_DFORK_*PTR macros")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/scrub/inode.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/xfs/scrub/inode.c
+++ b/fs/xfs/scrub/inode.c
@@ -560,7 +560,7 @@ xchk_dinode(
 	}
 
 	/* di_forkoff */
-	if (XFS_DFORK_BOFF(dip) >= mp->m_sb.sb_inodesize)
+	if (dip->di_forkoff >= (XFS_LITINO(mp) >> 3))
 		xchk_ino_set_corrupt(sc, ino);
 	if (naextents != 0 && dip->di_forkoff == 0)
 		xchk_ino_set_corrupt(sc, ino);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (552 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 553/877] xfs: check di_forkoff correctly in scrub Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-10-01 20:21   ` Harshit Mogalapalli
  2026-09-30 15:24 ` [PATCH 6.12 555/877] xfs: fix blockgc group quota scanning when usrquota isnt enforced Greg Kroah-Hartman
                   ` (330 subsequent siblings)
  884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Darrick J. Wong <djwong@kernel.org>

commit ffb48dccce1960a9ea24463a2f3c21d124d6b672 upstream.

LOLLM noticed that xfs_qm_flush_one fails to drop the dquot flush lock
if it can't grab the buffer associated with the dquot.  Since there's no
buffer, nobody else is going to drop the dqflock, so we need to do it
ourselves.

Cc: stable@vger.kernel.org # v6.13
Fixes: ca378189fdfa89 ("xfs: convert quotacheck to attach dquot buffers")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/xfs_qm.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

--- a/fs/xfs/xfs_qm.c
+++ b/fs/xfs/xfs_qm.c
@@ -1317,16 +1317,22 @@ xfs_qm_flush_one(
 
 	error = xfs_dquot_use_attached_buf(dqp, &bp);
 	if (error)
-		goto out_unlock;
+		goto out_dqflock;
 	if (!bp) {
 		error = -EFSCORRUPTED;
-		goto out_unlock;
+		goto out_dqflock;
 	}
 
 	error = xfs_qm_dqflush(dqp, bp);
 	if (!error)
 		xfs_buf_delwri_queue(bp, buffer_list);
 	xfs_buf_relse(bp);
+	mutex_unlock(&dqp->q_qlock);
+	xfs_qm_dqrele(dqp);
+	return error;
+
+out_dqflock:
+	xfs_dqfunlock(dqp);
 out_unlock:
 	xfs_dqunlock(dqp);
 	return error;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 555/877] xfs: fix blockgc group quota scanning when usrquota isnt enforced
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (553 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 556/877] net: tls: fix silent data drop under pipe back-pressure Greg Kroah-Hartman
                   ` (329 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Darrick J. Wong <djwong@kernel.org>

commit f8f6382ff13109e19d0fc1d0224ff7d29641e56a upstream.

LOLLM noticed the copy-paste error here -- if user quotas aren't
enforced but we're near the group quota limit, we fail to set FLAG_GID
and hence we might not actually free any preallocations, causing
unnecessary EDQUOT.  Fix that.

Cc: stable@vger.kernel.org # v5.12
Fixes: c237dd7c709432 ("xfs: flush eof/cowblocks if we can't reserve quota for inode creation")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/xfs_icache.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1593,7 +1593,7 @@ xfs_blockgc_free_dquots(
 		do_work = true;
 	}
 
-	if (XFS_IS_UQUOTA_ENFORCED(mp) && gdqp && xfs_dquot_lowsp(gdqp)) {
+	if (XFS_IS_GQUOTA_ENFORCED(mp) && gdqp && xfs_dquot_lowsp(gdqp)) {
 		icw.icw_gid = make_kgid(mp->m_super->s_user_ns, gdqp->q_id);
 		icw.icw_flags |= XFS_ICWALK_FLAG_GID;
 		do_work = true;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 556/877] net: tls: fix silent data drop under pipe back-pressure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (554 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 555/877] xfs: fix blockgc group quota scanning when usrquota isnt enforced Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 557/877] perf test: Change all remaining #!/bin/sh to #!/bin/bash Greg Kroah-Hartman
                   ` (328 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jakub Kicinski <kuba@kernel.org>

[ Upstream commit 7e7be31bfdb066c1c780dcd6b1224078fc54063f ]

tls_sw_splice_read() uses len when advancing rxm->offset / rxm->full_len
after skb_splice_bits(), rather than copied (the actual number of bytes
successfully spliced into the pipe). When the destination pipe cannot
accept all the requested bytes, splice_to_pipe() returns fewer bytes
than len, and 'len - copied' of data is effectively skipped over.

Fixes: e062fe99cccd ("tls: splice_read: fix accessing pre-processed records")
Link: https://patch.msgid.link/20260429222944.2139041-2-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 net/tls/tls_sw.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index a41fd85279bcd..323ac8b1ad0c8 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -2337,9 +2337,9 @@ ssize_t tls_sw_splice_read(struct socket *sock,  loff_t *ppos,
 	if (copied < 0)
 		goto splice_requeue;
 
-	if (chunk < rxm->full_len) {
-		rxm->offset += len;
-		rxm->full_len -= len;
+	if (copied < rxm->full_len) {
+		rxm->offset += copied;
+		rxm->full_len -= copied;
 		goto splice_requeue;
 	}
 
-- 
2.53.0




^ permalink raw reply related	[flat|nested] 922+ messages in thread

* [PATCH 6.12 557/877] perf test: Change all remaining #!/bin/sh to #!/bin/bash
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (555 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 556/877] net: tls: fix silent data drop under pipe back-pressure Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 558/877] ring-buffer: Add helper functions for allocations Greg Kroah-Hartman
                   ` (327 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, James Clark, Collin Funk,
	Arnaldo Carvalho de Melo, Namhyung Kim, Salvatore Bonaccorso

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: James Clark <james.clark@linaro.org>

commit 2f5d370dec3f800b44bbf7b68875d521e0af43cd upstream.

There are 43 instances of posix shell tests and 35 instances of bash. To
give us a single consistent language for testing in, replace
all #!/bin/sh to #!/bin/bash. Common sources that are included in both
different shells will now work as expected. And we no longer have to fix
up bashisms that appear to work when someone's system has sh symlinked
to bash, but don't work on other systems that have both shells
installed.

Although we could have chosen sh, it's not backwards compatible so it
wouldn't be possible to bulk convert without re-writing the existing
bash tests.

Choosing bash also gives us some nicer features including 'local'
variable definitions and regexes in if statements that are already
widely used in the tests.

It's not expected that there are any users with only sh available due to
the large number of bash tests that exist.

Discussed in relation to running shellcheck here:
https://lore.kernel.org/linux-perf-users/e3751a74be34bbf3781c4644f518702a7270220b.1749785642.git.collin.funk1@gmail.com/

Signed-off-by: James Clark <james.clark@linaro.org>
Reviewed-by: Collin Funk <collin.funk1@gmail.com>
Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Link: https://lore.kernel.org/r/20250623-james-perf-bash-tests-v1-1-f572f54d4559@linaro.org
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

When commit b02027776ac5 ("perf tests: Fix flakiness in BPF counters
test on hybrid systems") was backported to several stable series
(v5.15.221, v6.1.188, v6.6.157, v6.12.110, v6.18.52, v7.2.6) it
introduced specific bash syntax. For versions after 2f5d370dec3f ("perf
test: Change all remaining #!/bin/sh to #!/bin/bash") in v6.17-rc1 this
is not a problem as the shebang was already hanged to #!/bin/bash. For
the older stable series this introduced invalid syntax if #!/bin/sh is
not bash:

	$ sh -n tools/perf/tests/shell/stat_bpf_counters.sh
	tools/perf/tests/shell/stat_bpf_counters.sh: 12: Syntax error: "(" unexpected

	$ checkbashism tools/perf/tests/shell/stat_bpf_counters.sh
	possible bashism in tools/perf/tests/shell/stat_bpf_counters.sh line 52 (bash arrays, ${name[0|*|@]}):
		base_instructions=$(perf stat --no-big-num -e instructions:u -- "${workload[@]}" 2>&1 | \
					awk -v i=0 -v c=0 '/instructions/ { \
						if ($1 != "<not") { i++; c += $1 } \
					} END { if (i > 0) printf "%.0f", c; else print "<not" }')
	possible bashism in tools/perf/tests/shell/stat_bpf_counters.sh line 57 (bash arrays, ${name[0|*|@]}):
		bpf_instructions=$(perf stat --no-big-num --bpf-counters -e instructions:u \
					-- "${workload[@]}"  2>&1 | \
					awk -v i=0 -v c=0 '/instructions/ { \
						if ($1 != "<not") { i++; c += $1 } \
					} END { if (i > 0) printf "%.0f", c; else print "<not" }')
	possible bashism in tools/perf/tests/shell/stat_bpf_counters.sh line 68 (bash arrays, ${name[0|*|@]}):
		stat_output=$(perf stat --no-big-num \
			-e instructions/name=base_instructions/u,instructions/name=bpf_instructions/bu \
			-- "${workload[@]}" 2>&1)

Change shebang for the stat_bpf_counters.sh script.

No upstream commit exists for this change as for versions post 6.17-rc1
the scripts were converted to #!/bin/bash already.

Signed-off-by: Salvatore Bonaccorso <carnil@debian.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 tools/perf/tests/shell/stat_bpf_counters.sh |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/tools/perf/tests/shell/stat_bpf_counters.sh
+++ b/tools/perf/tests/shell/stat_bpf_counters.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 # perf stat --bpf-counters test
 # SPDX-License-Identifier: GPL-2.0
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 558/877] ring-buffer: Add helper functions for allocations
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (556 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 557/877] perf test: Change all remaining #!/bin/sh to #!/bin/bash Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 559/877] ring-buffer: Fix subbuf resize race with ring_buffer_alloc_read_page() Greg Kroah-Hartman
                   ` (326 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Masami Hiramatsu, Mathieu Desnoyers,
	Linus Torvalds, Steven Rostedt (Google), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Steven Rostedt <rostedt@goodmis.org>

[ Upstream commit b1e7a590a0133606d3efd41aee38cdeac630b52f ]

The allocation of the per CPU buffer descriptor, the buffer page
descriptors and the buffer page data itself can be pretty ugly:

  kzalloc_node(ALIGN(sizeof(struct buffer_page), cache_line_size()),
               GFP_KERNEL, cpu_to_node(cpu));

And the data pages:

  page = alloc_pages_node(cpu_to_node(cpu),
                          GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_COMP | __GFP_ZERO, order);
  if (!page)
	return NULL;
  bpage->page = page_address(page);
  rb_init_page(bpage->page);

Add helper functions to make the code easier to read.

This does make all allocations of the data page (bpage->page) allocated
with the __GFP_RETRY_MAYFAIL flag (and not just the bulk allocator). Which
is actually better, as allocating the data page for the ring buffer tracing
should try hard but not trigger the OOM killer.

Link: https://lore.kernel.org/all/CAHk-=wjMMSAaqTjBSfYenfuzE1bMjLj+2DLtLWJuGt07UGCH_Q@mail.gmail.com/

Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://patch.msgid.link/20251125121153.35c07461@gandalf.local.home
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

Stable backport adjustment for e743527c5bfd:

Keep only the read-page allocation refactor needed by the target. Express
alloc_cpu_data as a statement-expression macro instead of adding a C
function, retaining NUMA allocation, __GFP_RETRY_MAYFAIL, compound/zeroed
pages, NULL failure handling, and data-page initialization.

Rename the existing rb_init_page initializer to rb_init_data_page, without
changing its implementation, and update its callers. This supplies the
context expected by the target without importing the unrelated cleanup
from 7cf02d0aa6bd or introducing additional functions.

Drop the CPU-buffer and buffer-page descriptor refactors and the bulk and
internal reader-page allocator conversions. These are not needed by the
target; leaving them intact preserves this tree's ring_buffer_meta type,
__GFP_RETRY_MAYFAIL descriptor allocations, and the existing bpage->order
and resize-disabled fixes. Only newly allocated external read pages switch
from __GFP_NORETRY to __GFP_RETRY_MAYFAIL in this backport.

The target's change to allocate using the saved bpage->order is deliberately
left for e743527c5bfd itself.

Stable-dep-of: e743527c5bfd ("ring-buffer: Fix subbuf resize race with ring_buffer_alloc_read_page()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/ring_buffer.c |   50 ++++++++++++++++++++++++++-------------------
 1 file changed, 29 insertions(+), 21 deletions(-)

--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -382,7 +382,7 @@ struct buffer_page {
 #define RB_WRITE_MASK		0xfffff
 #define RB_WRITE_INTCNT		(1 << 20)
 
-static void rb_init_page(struct buffer_data_page *bpage)
+static void rb_init_data_page(struct buffer_data_page *bpage)
 {
 	local_set(&bpage->commit, 0);
 }
@@ -411,6 +411,21 @@ static void free_buffer_page(struct buff
 	kfree(bpage);
 }
 
+/* Try hard to allocate data pages without invoking the OOM killer. */
+#define alloc_cpu_data(cpu, order) ({						\
+	struct buffer_data_page *__rb_data = NULL;				\
+	struct page *__rb_page;							\
+										\
+	__rb_page = alloc_pages_node(cpu_to_node(cpu),				\
+		GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_COMP | __GFP_ZERO,	\
+		(order));							\
+	if (__rb_page) {							\
+		__rb_data = page_address(__rb_page);				\
+		rb_init_data_page(__rb_data);					\
+	}									\
+	__rb_data;								\
+})
+
 /*
  * We need to fit the time_stamp delta into 27 bits.
  */
@@ -2016,7 +2031,7 @@ static void rb_range_meta_init(struct tr
 		 */
 		for (i = 0; i < meta->nr_subbufs; i++) {
 			meta->buffers[i] = i;
-			rb_init_page(subbuf);
+			rb_init_data_page(subbuf);
 			subbuf += meta->subbuf_size;
 		}
 	}
@@ -2187,7 +2202,7 @@ static int __rb_allocate_pages(struct ri
 			if (!page)
 				goto free_pages;
 			bpage->page = page_address(page);
-			rb_init_page(bpage->page);
+			rb_init_data_page(bpage->page);
 		}
 		bpage->order = cpu_buffer->buffer->subbuf_order;
 
@@ -2293,7 +2308,7 @@ rb_allocate_cpu_buffer(struct trace_buff
 		if (!page)
 			goto fail_free_reader;
 		bpage->page = page_address(page);
-		rb_init_page(bpage->page);
+		rb_init_data_page(bpage->page);
 	}
 
 	INIT_LIST_HEAD(&cpu_buffer->reader_page->list);
@@ -6008,7 +6023,7 @@ static void rb_clear_buffer_page(struct
 {
 	local_set(&page->write, 0);
 	local_set(&page->entries, 0);
-	rb_init_page(page->page);
+	rb_init_data_page(page->page);
 	page->read = 0;
 }
 
@@ -6394,7 +6409,6 @@ ring_buffer_alloc_read_page(struct trace
 	struct ring_buffer_per_cpu *cpu_buffer;
 	struct buffer_data_read_page *bpage = NULL;
 	unsigned long flags;
-	struct page *page;
 
 	if (!cpumask_test_cpu(cpu, buffer->cpumask))
 		return ERR_PTR(-ENODEV);
@@ -6416,22 +6430,16 @@ ring_buffer_alloc_read_page(struct trace
 	arch_spin_unlock(&cpu_buffer->lock);
 	local_irq_restore(flags);
 
-	if (bpage->data)
-		goto out;
-
-	page = alloc_pages_node(cpu_to_node(cpu),
-				GFP_KERNEL | __GFP_NORETRY | __GFP_COMP | __GFP_ZERO,
-				cpu_buffer->buffer->subbuf_order);
-	if (!page) {
-		kfree(bpage);
-		return ERR_PTR(-ENOMEM);
+	if (bpage->data) {
+		rb_init_data_page(bpage->data);
+	} else {
+		bpage->data = alloc_cpu_data(cpu, cpu_buffer->buffer->subbuf_order);
+		if (!bpage->data) {
+			kfree(bpage);
+			return ERR_PTR(-ENOMEM);
+		}
 	}
 
-	bpage->data = page_address(page);
-
- out:
-	rb_init_page(bpage->data);
-
 	return bpage;
 }
 EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page);
@@ -6640,7 +6648,7 @@ int ring_buffer_read_page(struct trace_b
 		cpu_buffer->read_bytes += rb_page_size(reader);
 
 		/* swap the pages */
-		rb_init_page(bpage);
+		rb_init_data_page(bpage);
 		bpage = reader->page;
 		reader->page = data_page->data;
 		local_set(&reader->write, 0);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 559/877] ring-buffer: Fix subbuf resize race with ring_buffer_alloc_read_page()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (557 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 558/877] ring-buffer: Add helper functions for allocations Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 560/877] sched: Rework prev_balance() to avoid stale prev references Greg Kroah-Hartman
                   ` (325 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Vincent Donnefort,
	Steven Rostedt, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Vincent Donnefort <vdonnefort@google.com>

[ Upstream commit e743527c5bfdceda1095bc0a9e596e2aebb6a9c3 ]

ring_buffer_alloc_read_page() is racy with ring_buffer_subbuf_order_set,
it can allocate a reader page with an outdated order. This isn't a big
issue, the user can still re-allocate a new reader page and try again.

However, what is more problematic is if the value of subbuf_order
changes in the middle of ring_buffer_alloc_read_page(). In that case,
bpage->order might not match the actual allocated memory.

Use bpage->order for the allocation to prevent this race.

Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260813131152.3589632-6-vdonnefort@google.com
Fixes: bce761d75745 ("ring-buffer: Read and write to ring buffers with custom sub buffer size")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/ring_buffer.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -6433,7 +6433,7 @@ ring_buffer_alloc_read_page(struct trace
 	if (bpage->data) {
 		rb_init_data_page(bpage->data);
 	} else {
-		bpage->data = alloc_cpu_data(cpu, cpu_buffer->buffer->subbuf_order);
+		bpage->data = alloc_cpu_data(cpu, bpage->order);
 		if (!bpage->data) {
 			kfree(bpage);
 			return ERR_PTR(-ENOMEM);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 560/877] sched: Rework prev_balance() to avoid stale prev references
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (558 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 559/877] ring-buffer: Fix subbuf resize race with ring_buffer_alloc_read_page() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 561/877] sched/core: Make core-sched flips wait for in-flight selections Greg Kroah-Hartman
                   ` (324 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, John Stultz, Peter Zijlstra (Intel),
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: John Stultz <jstultz@google.com>

[ Upstream commit 7a3a6bfbd62a2ba3e0ef1e92d6b71abb66890825 ]

Historically, the prev value from __schedule() was the rq->curr.
This prev value is passed down through numerous functions, and
used in the class scheduler implementations. The fact that
prev was on_cpu until the end of __schedule(), meant it was
stable across the rq lock drops that the class->balance()
implementations often do.

However, with proxy-exec, the prev passed to functions called
by __schedule() is rq->donor, which may not be the same as
rq->curr and may not be on_cpu, this makes the prev value
potentially unstable across rq lock drops.

A recently found issue with proxy-exec, is when we begin doing
return migration from try_to_wake_up(), its possible we may be
waking up the rq->donor.  When we do this, we proxy_resched_idle()
to put_prev_set_next() setting the rq->donor to rq->idle, allowing
the rq->donor to be return migrated and allowed to run.

This however runs into trouble, as on another cpu we might be in
the middle of calling __schedule(). Conceptually the rq lock is
held for the majority of the time, but in calling prev_balance()
its possible the class->balance() handler call may briefly drop the rq lock.
This opens a window for try_to_wake_up() to wake and return migrate the
rq->donor before the class logic reacquires the rq lock.

Unfortunately prev_balance() pass in a prev argument, to which we pass
rq->donor. However this prev value can now become stale and incorrect across a
rq lock drop.

So, to correct this, rework the prev_balance() call so that it does not take a
"prev" argument.

Signed-off-by: John Stultz <jstultz@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260512025635.2840817-2-jstultz@google.com

Backport adaptation for Linux 6.12, as a dependency of f3629c63a4af
("sched/core: Make core-sched flips wait for in-flight selections"):

This tree has no proxy execution. Alias rq->donor and rq->curr in a union,
as upstream does without CONFIG_SCHED_PROXY_EXEC, so the existing curr
updates also provide the scheduling context without separate state.
Remove the prev parameter from prev_balance(), __pick_next_task(), and
both pick_next_task() variants, and read rq->donor at their call sites.

Keep the stable sched_class balance and pick_next_task interfaces and the
fair and sched_ext selection paths. Pass rq->donor to these existing
callbacks; it aliases the on-CPU current task and remains stable across
lock drops here. Drop the upstream deadline, RT, idle, and stop callback
signature changes, along with assumptions about newer selection APIs,
proxy execution, and lock annotations. No functions are added.

Label the CONFIG_SCHED_CORE closing directive in struct rq to match the
target's patch context. The unmodified target patch applies cleanly after
this adaptation. The core-selection counter fix remains in the target.

[ sashal: Reduced backport -- upstream 7a3a6bfbd62a2 touches 6 file(s), this
  backport carries 2. Not backported here:
  kernel/sched/deadline.c
  kernel/sched/idle.c
  kernel/sched/rt.c
  kernel/sched/stop_task.c
  This note is generated from the file lists only; see the resolution record
  for the reasoning. ]

Stable-dep-of: f3629c63a4af ("sched/core: Make core-sched flips wait for in-flight selections")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/sched/core.c  |   39 +++++++++++++++++++--------------------
 kernel/sched/sched.h |    8 ++++++--
 2 files changed, 25 insertions(+), 22 deletions(-)

--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5936,10 +5936,9 @@ static inline void schedule_debug(struct
 	schedstat_inc(this_rq()->sched_count);
 }
 
-static void prev_balance(struct rq *rq, struct task_struct *prev,
-			 struct rq_flags *rf)
+static void prev_balance(struct rq *rq, struct rq_flags *rf)
 {
-	const struct sched_class *start_class = prev->sched_class;
+	const struct sched_class *start_class = rq->donor->sched_class;
 	const struct sched_class *class;
 
 #ifdef CONFIG_SCHED_CLASS_EXT
@@ -5964,7 +5963,7 @@ static void prev_balance(struct rq *rq,
 	 * a runnable task of @class priority or higher.
 	 */
 	for_active_class_range(class, start_class, &idle_sched_class) {
-		if (class->balance && class->balance(rq, prev, rf))
+		if (class->balance && class->balance(rq, rq->donor, rf))
 			break;
 	}
 }
@@ -5973,7 +5972,7 @@ static void prev_balance(struct rq *rq,
  * Pick up the highest-prio task:
  */
 static inline struct task_struct *
-__pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
+__pick_next_task(struct rq *rq, struct rq_flags *rf)
 {
 	const struct sched_class *class;
 	struct task_struct *p;
@@ -5985,38 +5984,38 @@ __pick_next_task(struct rq *rq, struct t
 
 	/*
 	 * Optimization: we know that if all tasks are in the fair class we can
-	 * call that function directly, but only if the @prev task wasn't of a
+	 * call that function directly, but only if the current task wasn't of a
 	 * higher scheduling class, because otherwise those lose the
 	 * opportunity to pull in more work from other CPUs.
 	 */
-	if (likely(!sched_class_above(prev->sched_class, &fair_sched_class) &&
+	if (likely(!sched_class_above(rq->donor->sched_class, &fair_sched_class) &&
 		   rq->nr_running == rq->cfs.h_nr_queued)) {
 
-		p = pick_next_task_fair(rq, prev, rf);
+		p = pick_next_task_fair(rq, rq->donor, rf);
 		if (unlikely(p == RETRY_TASK))
 			goto restart;
 
 		/* Assume the next prioritized class is idle_sched_class */
 		if (!p) {
 			p = pick_task_idle(rq);
-			put_prev_set_next_task(rq, prev, p);
+			put_prev_set_next_task(rq, rq->donor, p);
 		}
 
 		return p;
 	}
 
 restart:
-	prev_balance(rq, prev, rf);
+	prev_balance(rq, rf);
 
 	for_each_active_class(class) {
 		if (class->pick_next_task) {
-			p = class->pick_next_task(rq, prev);
+			p = class->pick_next_task(rq, rq->donor);
 			if (p)
 				return p;
 		} else {
 			p = class->pick_task(rq);
 			if (p) {
-				put_prev_set_next_task(rq, prev, p);
+				put_prev_set_next_task(rq, rq->donor, p);
 				return p;
 			}
 		}
@@ -6065,7 +6064,7 @@ extern void task_vruntime_update(struct
 static void queue_core_balance(struct rq *rq);
 
 static struct task_struct *
-pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
+pick_next_task(struct rq *rq, struct rq_flags *rf)
 {
 	struct task_struct *next, *p, *max = NULL;
 	const struct cpumask *smt_mask;
@@ -6077,7 +6076,7 @@ pick_next_task(struct rq *rq, struct tas
 	bool need_sync;
 
 	if (!sched_core_enabled(rq))
-		return __pick_next_task(rq, prev, rf);
+		return __pick_next_task(rq, rf);
 
 	cpu = cpu_of(rq);
 
@@ -6090,7 +6089,7 @@ pick_next_task(struct rq *rq, struct tas
 		 */
 		rq->core_pick = NULL;
 		rq->core_dl_server = NULL;
-		return __pick_next_task(rq, prev, rf);
+		return __pick_next_task(rq, rf);
 	}
 
 	/*
@@ -6114,7 +6113,7 @@ pick_next_task(struct rq *rq, struct tas
 		goto out_set_next;
 	}
 
-	prev_balance(rq, prev, rf);
+	prev_balance(rq, rf);
 
 	smt_mask = cpu_smt_mask(cpu);
 	need_sync = !!rq->core->core_cookie;
@@ -6287,7 +6286,7 @@ pick_next_task(struct rq *rq, struct tas
 	}
 
 out_set_next:
-	put_prev_set_next_task(rq, prev, next);
+	put_prev_set_next_task(rq, rq->donor, next);
 	if (rq->core->core_forceidle_count && next == rq->idle)
 		queue_core_balance(rq);
 
@@ -6512,9 +6511,9 @@ static inline void sched_core_cpu_deacti
 static inline void sched_core_cpu_dying(unsigned int cpu) {}
 
 static struct task_struct *
-pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
+pick_next_task(struct rq *rq, struct rq_flags *rf)
 {
-	return __pick_next_task(rq, prev, rf);
+	return __pick_next_task(rq, rf);
 }
 
 #endif /* CONFIG_SCHED_CORE */
@@ -6682,7 +6681,7 @@ static void __sched notrace __schedule(i
 		switch_count = &prev->nvcsw;
 	}
 
-	next = pick_next_task(rq, prev, &rf);
+	next = pick_next_task(rq, &rf);
 picked:
 	clear_tsk_need_resched(prev);
 	clear_preempt_need_resched();
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1184,7 +1184,11 @@ struct rq {
 	 */
 	unsigned long 		nr_uninterruptible;
 
-	struct task_struct __rcu	*curr;
+	/* Scheduling and execution contexts coincide without proxy execution. */
+	union {
+		struct task_struct __rcu *donor;
+		struct task_struct __rcu *curr;
+	};
 	struct sched_dl_entity	*dl_server;
 	struct task_struct	*idle;
 	struct task_struct	*stop;
@@ -1326,7 +1330,7 @@ struct rq {
 	unsigned int		core_forceidle_seq;
 	unsigned int		core_forceidle_occupation;
 	u64			core_forceidle_start;
-#endif
+#endif /* CONFIG_SCHED_CORE */
 
 	/* Scratch cpumask to be temporarily used under rq_lock */
 	cpumask_var_t		scratch_mask;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 561/877] sched/core: Make core-sched flips wait for in-flight selections
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (559 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 560/877] sched: Rework prev_balance() to avoid stale prev references Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 562/877] ASoC: codecs: aw88261: reduce log spam Greg Kroah-Hartman
                   ` (323 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Tejun Heo, Peter Zijlstra (Intel),
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Tejun Heo <tj@kernel.org>

[ Upstream commit f3629c63a4af3e491381780bc6c123cb498c4c40 ]

Core scheduling's pick_next_task() operates on all sibling rqs under one
acquisition of the shared core-wide lock. A ->pick_task() that releases the
rq lock leaves every sibling __lock momentarily free, letting
__sched_core_flip(false) complete mid-selection and rebind rq_lockp() under
it. The selection resumes on the split locks, touching sibling state it no
longer protects, and __schedule() finally releases a lock that was never
taken while leaking the one that was.

Count in-flight core-wide selections in the leader's rq->core_pick_in_flight
and make __sched_core_flip() wait for the count to drain. The count only
changes under the shared lock, which the flip holds while sampling, so no
other ordering is needed. The wait can repeat while selections overlap, but
the flip backs off between samples and flips are rare cookie-lifetime
events.

sched_core_cpu_deactivate() moves the count to the new leader - a stale copy
left behind would bias it forever if that CPU later returns as its own
leader.

Fixes: 539f65125d20 ("sched: Add core wide task selection and scheduling")
Cc: stable@vger.kernel.org # v5.14+
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/sched/core.c  |   22 ++++++++++++++++++++++
 kernel/sched/sched.h |    1 +
 2 files changed, 23 insertions(+)

--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -401,6 +401,17 @@ static void __sched_core_flip(bool enabl
 
 		sched_core_lock(cpu, &flags);
 
+		/*
+		 * A core-wide selection may have the shared rq lock temporarily
+		 * released by a lock-dropping ->pick_task(). Flipping would
+		 * rebind rq_lockp() under it. Wait it out.
+		 */
+		while (cpu_rq(cpu)->core->core_pick_in_flight) {
+			sched_core_unlock(cpu, &flags);
+			cpu_relax();
+			sched_core_lock(cpu, &flags);
+		}
+
 		for_each_cpu(t, smt_mask)
 			cpu_rq(t)->core_enabled = enabled;
 
@@ -6092,6 +6103,8 @@ pick_next_task(struct rq *rq, struct rq_
 		return __pick_next_task(rq, rf);
 	}
 
+	rq->core->core_pick_in_flight++;
+
 	/*
 	 * If there were no {en,de}queues since we picked (IOW, the task
 	 * pointers are all still valid), and we haven't scheduled the last
@@ -6286,6 +6299,7 @@ pick_next_task(struct rq *rq, struct rq_
 	}
 
 out_set_next:
+	rq->core->core_pick_in_flight--;
 	put_prev_set_next_task(rq, rq->donor, next);
 	if (rq->core->core_forceidle_count && next == rq->idle)
 		queue_core_balance(rq);
@@ -6483,6 +6497,13 @@ static void sched_core_cpu_deactivate(un
 	core_rq->core_forceidle_occupation = rq->core_forceidle_occupation;
 
 	/*
+	 * A stale leftover would bias the count forever if this CPU later
+	 * returns as its own leader. Move, don't copy.
+	 */
+	core_rq->core_pick_in_flight       = rq->core_pick_in_flight;
+	rq->core_pick_in_flight            = 0;
+
+	/*
 	 * Accounting edge for forced idle is handled in pick_next_task().
 	 * Don't need another one here, since the hotplug thread shouldn't
 	 * have a cookie.
@@ -8553,6 +8574,7 @@ void __init sched_init(void)
 		rq->core_forceidle_count = 0;
 		rq->core_forceidle_occupation = 0;
 		rq->core_forceidle_start = 0;
+		rq->core_pick_in_flight = 0;
 
 		rq->core_cookie = 0UL;
 #endif
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1330,6 +1330,7 @@ struct rq {
 	unsigned int		core_forceidle_seq;
 	unsigned int		core_forceidle_occupation;
 	u64			core_forceidle_start;
+	unsigned int		core_pick_in_flight;
 #endif /* CONFIG_SCHED_CORE */
 
 	/* Scratch cpumask to be temporarily used under rq_lock */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 562/877] ASoC: codecs: aw88261: reduce log spam
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (560 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 561/877] sched/core: Make core-sched flips wait for in-flight selections Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 563/877] ASoC: codecs: aw88261: only check PLL and clock state at power-up Greg Kroah-Hartman
                   ` (322 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Val Packett, Luca Weiss, Mark Brown,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Val Packett <val@packett.cool>

[ Upstream commit d90c361af215a9fa2a986d9f47d554d0cf3401dd ]

This driver would create a wall of logspam during initialization due to
e.g. the PLL not being ready while waiting for it to stabilize. Change
intermediate dev_err() calls to dev_dbg() to reduce the noise.

While here, log the detected chip ID when that check fails.

Signed-off-by: Val Packett <val@packett.cool>
Tested-by: Luca Weiss <luca.weiss@fairphone.com>
Link: https://patch.msgid.link/20260529200550.529719-4-val@packett.cool
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 06b6f1245567 ("ASoC: codecs: aw88261: only check PLL and clock state at power-up")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 sound/soc/codecs/aw88261.c |   24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

--- a/sound/soc/codecs/aw88261.c
+++ b/sound/soc/codecs/aw88261.c
@@ -150,7 +150,7 @@ static int aw88261_dev_get_iis_status(st
 	if (ret)
 		return ret;
 	if ((reg_val & AW88261_BIT_PLL_CHECK) != AW88261_BIT_PLL_CHECK) {
-		dev_err(aw_dev->dev, "check pll lock fail,reg_val:0x%04x", reg_val);
+		dev_dbg(aw_dev->dev, "check pll lock fail,reg_val:0x%04x", reg_val);
 		return -EINVAL;
 	}
 
@@ -164,7 +164,7 @@ static int aw88261_dev_check_mode1_pll(s
 	for (i = 0; i < AW88261_DEV_SYSST_CHECK_MAX; i++) {
 		ret = aw88261_dev_get_iis_status(aw_dev);
 		if (ret) {
-			dev_err(aw_dev->dev, "mode1 iis signal check error");
+			dev_dbg(aw_dev->dev, "mode1 iis signal check error");
 			usleep_range(AW88261_2000_US, AW88261_2000_US + 10);
 		} else {
 			return ret;
@@ -255,7 +255,7 @@ static int aw88261_dev_check_sysst(struc
 		check_val = reg_val & (~AW88261_BIT_SYSST_CHECK_MASK)
 							& AW88261_BIT_SYSST_CHECK;
 		if (check_val != AW88261_BIT_SYSST_CHECK) {
-			dev_err(aw_dev->dev, "check sysst fail, reg_val=0x%04x, check:0x%x",
+			dev_dbg(aw_dev->dev, "check sysst fail, reg_val=0x%04x, check:0x%x",
 				reg_val, AW88261_BIT_SYSST_CHECK);
 			usleep_range(AW88261_2000_US, AW88261_2000_US + 10);
 		} else {
@@ -549,7 +549,7 @@ static int aw88261_dev_start(struct aw88
 	int ret;
 
 	if (aw_dev->status == AW88261_DEV_PW_ON) {
-		dev_info(aw_dev->dev, "already power on");
+		dev_dbg(aw_dev->dev, "already power on");
 		return 0;
 	}
 
@@ -559,7 +559,7 @@ static int aw88261_dev_start(struct aw88
 
 	ret = aw88261_dev_check_syspll(aw_dev);
 	if (ret) {
-		dev_err(aw_dev->dev, "pll check failed cannot start");
+		dev_dbg(aw_dev->dev, "pll check failed");
 		goto pll_check_fail;
 	}
 
@@ -570,7 +570,7 @@ static int aw88261_dev_start(struct aw88
 	/* check i2s status */
 	ret = aw88261_dev_check_sysst(aw_dev);
 	if (ret) {
-		dev_err(aw_dev->dev, "sysst check failed");
+		dev_dbg(aw_dev->dev, "sysst check failed");
 		goto sysst_check_fail;
 	}
 
@@ -671,18 +671,22 @@ static void aw88261_start_pa(struct aw88
 	for (i = 0; i < AW88261_START_RETRIES; i++) {
 		ret = aw88261_reg_update(aw88261, aw88261->phase_sync);
 		if (ret) {
-			dev_err(aw88261->aw_pa->dev, "fw update failed, cnt:%d\n", i);
+			dev_dbg(aw88261->aw_pa->dev,
+				"aw88261_reg_update failed, cnt:%d, ret:%d\n", i, ret);
 			continue;
 		}
 		ret = aw88261_dev_start(aw88261);
 		if (ret) {
-			dev_err(aw88261->aw_pa->dev, "aw88261 device start failed. retry = %d", i);
+			dev_dbg(aw88261->aw_pa->dev,
+				"aw88261_dev_start failed, cnt:%d, ret:%d\n", i, ret);
 			continue;
 		} else {
-			dev_info(aw88261->aw_pa->dev, "start success\n");
+			dev_dbg(aw88261->aw_pa->dev, "start success\n");
 			break;
 		}
 	}
+	if (ret != 0)
+		dev_err(aw88261->aw_pa->dev, "start failure (%d)\n", ret);
 }
 
 static void aw88261_startup_work(struct work_struct *work)
@@ -1200,7 +1204,7 @@ static int aw88261_init(struct aw88261 *
 		return ret;
 	}
 	if (chip_id != AW88261_CHIP_ID) {
-		dev_err(&i2c->dev, "unsupported device");
+		dev_err(&i2c->dev, "unsupported device id = %x", chip_id);
 		return -ENXIO;
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 563/877] ASoC: codecs: aw88261: only check PLL and clock state at power-up
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (561 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 562/877] ASoC: codecs: aw88261: reduce log spam Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 564/877] ring-buffer: Make cpu_buffer::free_page a buffer_data_read_page Greg Kroah-Hartman
                   ` (321 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jorijn van der Graaf, Mark Brown,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>

[ Upstream commit 06b6f1245567a4be862c3e1cc74577922ceb05fb ]

The SYSST check performed during device start requires SWS (amplifier
switching, bit 8) and BSTS (boost finished, bit 9) on top of PLL lock
and clock stability. Those bits cannot be asserted at this point in the
sequence: the check runs after amppd release but before the
hmute/ULS-hmute release, and the amplifier neither switches nor
finishes ramping its boost converter while it is still muted. With the
Fairphone (Gen. 6) firmware profile, aw88261_dev_start() therefore
always fails with

  check sysst fail, reg_val=0x0011, check:0x311

and playback aborts, even though the amplifier is fine and PLL lock
and stable clocks are present.

Check only PLL lock and clock stability, for which a definition
already exists; this still re-validates the clocks after amppd release
(aw88261_dev_check_syspll() checked them before it). This matches the
vendor aw882xx driver, which only validates PLL lock and clock
stability at this stage, and the in-tree aw88399 driver, which skips
the SWS check whenever the amplifier may legitimately not be switching
(AW88399_BIT_SYSST_NOSWS_CHECK).

Fixes: 028a2ae25691 ("ASoC: codecs: Add aw88261 amplifier driver")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-fable-5
Signed-off-by: Jorijn van der Graaf <jorijnvdgraaf@catcrafts.net>
Link: https://patch.msgid.link/20260704192857.88366-1-jorijnvdgraaf@catcrafts.net
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 sound/soc/codecs/aw88261.c |    6 +++---
 sound/soc/codecs/aw88261.h |    6 ------
 2 files changed, 3 insertions(+), 9 deletions(-)

--- a/sound/soc/codecs/aw88261.c
+++ b/sound/soc/codecs/aw88261.c
@@ -253,10 +253,10 @@ static int aw88261_dev_check_sysst(struc
 			return ret;
 
 		check_val = reg_val & (~AW88261_BIT_SYSST_CHECK_MASK)
-							& AW88261_BIT_SYSST_CHECK;
-		if (check_val != AW88261_BIT_SYSST_CHECK) {
+							& AW88261_BIT_PLL_CHECK;
+		if (check_val != AW88261_BIT_PLL_CHECK) {
 			dev_dbg(aw_dev->dev, "check sysst fail, reg_val=0x%04x, check:0x%x",
-				reg_val, AW88261_BIT_SYSST_CHECK);
+				reg_val, AW88261_BIT_PLL_CHECK);
 			usleep_range(AW88261_2000_US, AW88261_2000_US + 10);
 		} else {
 			return 0;
--- a/sound/soc/codecs/aw88261.h
+++ b/sound/soc/codecs/aw88261.h
@@ -181,12 +181,6 @@
 		AW88261_OTHS_OT_VALUE | \
 		AW88261_PLLS_LOCKED_VALUE))
 
-#define AW88261_BIT_SYSST_CHECK \
-		(AW88261_BSTS_FINISHED_VALUE | \
-		AW88261_SWS_SWITCHING_VALUE | \
-		AW88261_CLKS_STABLE_VALUE | \
-		AW88261_PLLS_LOCKED_VALUE)
-
 #define AW88261_ULS_HMUTE_START_BIT	(14)
 #define AW88261_ULS_HMUTE_BITS_LEN	(1)
 #define AW88261_ULS_HMUTE_MASK		\



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 564/877] ring-buffer: Make cpu_buffer::free_page a buffer_data_read_page
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (562 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 563/877] ASoC: codecs: aw88261: only check PLL and clock state at power-up Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 565/877] dmaengine: Add devm_dma_request_chan() Greg Kroah-Hartman
                   ` (320 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vincent Donnefort, Steven Rostedt,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Vincent Donnefort <vdonnefort@google.com>

[ Upstream commit 7a1fb95de5404134f8758c1295ce88986bdf117c ]

Discarding a cached reader page after a concurrent ring buffer resize
uses the new global subbuf_order for the free_pages() call. This
mismatched order may crashes the kernel or leaks memory because the cached
page was allocated under the old size.

Save the actual free_page order alongside the page address to ensure we
always refer to the correct value and do not rely on the potentially
stalled cpu_buffer->subbuf_order value. The simplest is to make
free_page a buffer_data_read_page which already covers exactly what we
need: a page address and a page order.

Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260813131152.3589632-4-vdonnefort@google.com
Fixes: 8e7b58c27b3c ("ring-buffer: Just update the subbuffers when changing their allocation order")
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
[ Changed upstream’s dpage variable to bpage in ring_buffer_free_read_page(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/ring_buffer.c |   20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -507,7 +507,7 @@ struct ring_buffer_per_cpu {
 	raw_spinlock_t			reader_lock;	/* serialize readers */
 	arch_spinlock_t			lock;
 	struct lock_class_key		lock_key;
-	struct buffer_data_page		*free_page;
+	struct buffer_data_read_page	free_page;
 	unsigned long			nr_pages;
 	unsigned int			current_context;
 	struct list_head		*pages;
@@ -2376,7 +2376,7 @@ static void rb_free_cpu_buffer(struct ri
 		free_buffer_page(bpage);
 	}
 
-	free_pages((unsigned long)cpu_buffer->free_page, cpu_buffer->buffer->subbuf_order);
+	free_pages((unsigned long)cpu_buffer->free_page.data, cpu_buffer->free_page.order);
 
 	kfree(cpu_buffer);
 }
@@ -6422,9 +6422,9 @@ ring_buffer_alloc_read_page(struct trace
 	local_irq_save(flags);
 	arch_spin_lock(&cpu_buffer->lock);
 
-	if (cpu_buffer->free_page) {
-		bpage->data = cpu_buffer->free_page;
-		cpu_buffer->free_page = NULL;
+	if (cpu_buffer->free_page.data) {
+		*bpage = cpu_buffer->free_page;
+		cpu_buffer->free_page.data = NULL;
 	}
 
 	arch_spin_unlock(&cpu_buffer->lock);
@@ -6476,8 +6476,8 @@ void ring_buffer_free_read_page(struct t
 	local_irq_save(flags);
 	arch_spin_lock(&cpu_buffer->lock);
 
-	if (!cpu_buffer->free_page) {
-		cpu_buffer->free_page = bpage;
+	if (!cpu_buffer->free_page.data) {
+		cpu_buffer->free_page = *data_page;
 		bpage = NULL;
 	}
 
@@ -6838,7 +6838,7 @@ int ring_buffer_subbuf_order_set(struct
 	}
 
 	for_each_buffer_cpu(buffer, cpu) {
-		struct buffer_data_page *old_free_data_page;
+		struct buffer_data_read_page old_free_data_page;
 		struct list_head old_pages;
 		unsigned long flags;
 
@@ -6881,7 +6881,7 @@ int ring_buffer_subbuf_order_set(struct
 
 		arch_spin_lock(&cpu_buffer->lock);
 		old_free_data_page = cpu_buffer->free_page;
-		cpu_buffer->free_page = NULL;
+		cpu_buffer->free_page.data = NULL;
 		arch_spin_unlock(&cpu_buffer->lock);
 
 		rb_head_page_activate(cpu_buffer);
@@ -6893,7 +6893,7 @@ int ring_buffer_subbuf_order_set(struct
 			list_del_init(&bpage->list);
 			free_buffer_page(bpage);
 		}
-		free_pages((unsigned long)old_free_data_page, old_order);
+		free_pages((unsigned long)old_free_data_page.data, old_free_data_page.order);
 
 		rb_check_pages(cpu_buffer);
 	}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 565/877] dmaengine: Add devm_dma_request_chan()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (563 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 564/877] ring-buffer: Make cpu_buffer::free_page a buffer_data_read_page Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 566/877] i2c: mxs: fix DMA channel leak on probe error Greg Kroah-Hartman
                   ` (319 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bence Csókás, Vinod Koul,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bence Csókás <csokas.bence@prolan.hu>

[ Upstream commit 08bf1663c21a3e815eda28fa242d84c945ca3b94 ]

Expand the arsenal of devm functions for DMA devices, this time for
requesting channels.

Signed-off-by: Bence Csókás <csokas.bence@prolan.hu>
Link: https://lore.kernel.org/r/20250610082256.400492-2-csokas.bence@prolan.hu
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Stable-dep-of: 777979e62711 ("i2c: mxs: fix DMA channel leak on probe error")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/dma/dmaengine.c   |   30 ++++++++++++++++++++++++++++++
 include/linux/dmaengine.h |    7 +++++++
 2 files changed, 37 insertions(+)

--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -933,6 +933,36 @@ void dma_release_channel(struct dma_chan
 }
 EXPORT_SYMBOL_GPL(dma_release_channel);
 
+static void dmaenginem_release_channel(void *chan)
+{
+	dma_release_channel(chan);
+}
+
+/**
+ * devm_dma_request_chan - try to allocate an exclusive slave channel
+ * @dev:	pointer to client device structure
+ * @name:	slave channel name
+ *
+ * Returns pointer to appropriate DMA channel on success or an error pointer.
+ *
+ * The operation is managed and will be undone on driver detach.
+ */
+
+struct dma_chan *devm_dma_request_chan(struct device *dev, const char *name)
+{
+	struct dma_chan *chan = dma_request_chan(dev, name);
+	int ret = 0;
+
+	if (!IS_ERR(chan))
+		ret = devm_add_action_or_reset(dev, dmaenginem_release_channel, chan);
+
+	if (ret)
+		return ERR_PTR(ret);
+
+	return chan;
+}
+EXPORT_SYMBOL_GPL(devm_dma_request_chan);
+
 /**
  * dmaengine_get - register interest in dma_channels
  */
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -1521,6 +1521,7 @@ struct dma_chan *__dma_request_channel(c
 
 struct dma_chan *dma_request_chan(struct device *dev, const char *name);
 struct dma_chan *dma_request_chan_by_mask(const dma_cap_mask_t *mask);
+struct dma_chan *devm_dma_request_chan(struct device *dev, const char *name);
 
 void dma_release_channel(struct dma_chan *chan);
 int dma_get_slave_caps(struct dma_chan *chan, struct dma_slave_caps *caps);
@@ -1557,6 +1558,12 @@ static inline struct dma_chan *dma_reque
 {
 	return ERR_PTR(-ENODEV);
 }
+
+static inline struct dma_chan *devm_dma_request_chan(struct device *dev, const char *name)
+{
+	return ERR_PTR(-ENODEV);
+}
+
 static inline void dma_release_channel(struct dma_chan *chan)
 {
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 566/877] i2c: mxs: fix DMA channel leak on probe error
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (564 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 565/877] dmaengine: Add devm_dma_request_chan() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 567/877] lockd: fix swapped arguments in nlmsvc_match_ip() Greg Kroah-Hartman
                   ` (318 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ruoyu Wang, Frank Li, Andi Shyti,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ruoyu Wang <ruoyuw560@gmail.com>

[ Upstream commit 777979e627115734052b323d2721cdb500e81dcf ]

mxs_i2c_probe() requests an exclusive DMA channel before resetting the
controller and registering the I2C adapter. If either later operation
fails, probe returns without releasing the channel because the remove
callback is not invoked after a failed probe.

Use devm_dma_request_chan() so the device core releases the channel on
probe failure and driver detach. Remove the manual release from the
remove callback because the channel is now device-managed.

This issue was found by a static analysis checker and confirmed by
manual source review.

Fixes: 62885f59a261 ("MXS: Implement DMA support into mxs-i2c")
Assisted-by: unnamed:claude-opus-4.8 typestate
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Cc: <stable@vger.kernel.org> # v3.7+
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260815151720.3757460-1-ruoyuw560@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/i2c/busses/i2c-mxs.c |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -831,7 +831,7 @@ static int mxs_i2c_probe(struct platform
 	}
 
 	/* Setup the DMA */
-	i2c->dmach = dma_request_chan(dev, "rx-tx");
+	i2c->dmach = devm_dma_request_chan(dev, "rx-tx");
 	if (IS_ERR(i2c->dmach)) {
 		return dev_err_probe(dev, PTR_ERR(i2c->dmach),
 				     "Failed to request dma\n");
@@ -869,9 +869,6 @@ static void mxs_i2c_remove(struct platfo
 
 	i2c_del_adapter(&i2c->adapter);
 
-	if (i2c->dmach)
-		dma_release_channel(i2c->dmach);
-
 	writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET);
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 567/877] lockd: fix swapped arguments in nlmsvc_match_ip()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (565 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 566/877] i2c: mxs: fix DMA channel leak on probe error Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 568/877] firmware: qcom_scm: Rename peripheral as pas_id Greg Kroah-Hartman
                   ` (317 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Oscar Ou, Chuck Lever, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Oscar Ou <oscarou@synology.com>

[ Upstream commit b9060689f49dc663e9a3d069c4a65ff63a836e66 ]

When releasing locks by server IP address via /proc/fs/nfsd/unlock_ip,
nlmsvc_unlock_all_by_ip() calls nlm_traverse_files() with the server
sockaddr as the opaque @data argument:

	nlm_traverse_files(server_addr, nlmsvc_match_ip, NULL);

The match callback is later invoked from nlm_traverse_locks() as:

	match(lockhost, host);

where the first argument is the nlm_host that owns the lock, and the
second argument is the @data that was originally passed down (here the
server sockaddr).  This is the convention every other match callback
relies on (nlmsvc_mark_host(), nlmsvc_same_host(), nlmsvc_is_client()):
arg1 is the real nlm_host, arg2 is the caller-supplied reference value.

nlmsvc_match_ip() has had these two arguments reversed ever since the
unlock-by-IP feature was introduced in commit 4373ea84c84d ("lockd:
unlock lockd locks associated with a given server ip"):

	return rpc_cmp_addr(nlm_srcaddr(host), datap);

Here @host is actually the server sockaddr, so nlm_srcaddr(host)
dereferences a struct sockaddr as a struct nlm_host and reads garbage
at the offset of h_srcaddr; meanwhile @datap is actually the lock
owner's nlm_host but is compared as a sockaddr.  As a result the
comparison practically never matches and locks are not released for the
requested IP.

Swap the arguments so the lock owner's source address is compared
against the requested server address:

	return rpc_cmp_addr(nlm_srcaddr(datap), (struct sockaddr *)host);

Fixes: 4373ea84c84d ("lockd: unlock lockd locks associated with a given server ip")
Cc: stable@vger.kernel.org
Signed-off-by: Oscar Ou <oscarou@synology.com>
[ cel: fix the misleading typedef parameter names too ]
Link: https://patch.msgid.link/20260617075738.1151797-1-oscarou@synology.com
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/lockd/svcsubs.c          |    2 +-
 include/linux/lockd/lockd.h |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -493,7 +493,7 @@ EXPORT_SYMBOL_GPL(nlmsvc_unlock_all_by_s
 static int
 nlmsvc_match_ip(void *datap, struct nlm_host *host)
 {
-	return rpc_cmp_addr(nlm_srcaddr(host), datap);
+	return rpc_cmp_addr(nlm_srcaddr(datap), (struct sockaddr *)host);
 }
 
 /**
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -268,7 +268,7 @@ void		  nsm_release(struct nsm_handle *n
  * This is used in garbage collection and resource reclaim
  * A return value != 0 means destroy the lock/block/share
  */
-typedef int	  (*nlm_host_match_fn_t)(void *cur, struct nlm_host *ref);
+typedef int	  (*nlm_host_match_fn_t)(void *owner, struct nlm_host *ref);
 
 /*
  * Server-side lock handling



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 568/877] firmware: qcom_scm: Rename peripheral as pas_id
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (566 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 567/877] lockd: fix swapped arguments in nlmsvc_match_ip() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 569/877] remoteproc: pas: Replace metadata context with PAS context structure Greg Kroah-Hartman
                   ` (316 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bryan ODonoghue, Konrad Dybcio,
	Mukesh Ojha, Bjorn Andersson, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>

[ Upstream commit 69054348cc1c2d87acad90aec5e6e0d191012aff ]

Peripheral and pas_id refers to unique id for a subsystem and used only
when peripheral authentication service from secure world is utilized.

Lets rename peripheral to pas_id to reflect closer to its meaning.

Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-3-022e96815380@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Stable-dep-of: c06c5ab49453 ("remoteproc: qcom: pas: Guard dtb metadata release with dtb_pas_id check")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/firmware/qcom/qcom_scm.c       |   30 +++++++++++++++---------------
 include/linux/firmware/qcom/qcom_scm.h |   10 +++++-----
 2 files changed, 20 insertions(+), 20 deletions(-)

--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -572,7 +572,7 @@ static void qcom_scm_set_download_mode(u
  * qcom_scm_pas_init_image() - Initialize peripheral authentication service
  *			       state machine for a given peripheral, using the
  *			       metadata
- * @peripheral: peripheral id
+ * @pas_id:	peripheral authentication service id
  * @metadata:	pointer to memory containing ELF header, program header table
  *		and optional blob of data used for authenticating the metadata
  *		and the rest of the firmware
@@ -585,7 +585,7 @@ static void qcom_scm_set_download_mode(u
  * track the metadata allocation, this needs to be released by invoking
  * qcom_scm_pas_metadata_release() by the caller.
  */
-int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
+int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
 			    struct qcom_scm_pas_metadata *ctx)
 {
 	dma_addr_t mdata_phys;
@@ -595,7 +595,7 @@ int qcom_scm_pas_init_image(u32 peripher
 		.svc = QCOM_SCM_SVC_PIL,
 		.cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE,
 		.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW),
-		.args[0] = peripheral,
+		.args[0] = pas_id,
 		.owner = ARM_SMCCC_OWNER_SIP,
 	};
 	struct qcom_scm_res res;
@@ -668,20 +668,20 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_
 /**
  * qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral
  *			      for firmware loading
- * @peripheral:	peripheral id
+ * @pas_id:	peripheral authentication service id
  * @addr:	start address of memory area to prepare
  * @size:	size of the memory area to prepare
  *
  * Returns 0 on success.
  */
-int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size)
+int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
 {
 	int ret;
 	struct qcom_scm_desc desc = {
 		.svc = QCOM_SCM_SVC_PIL,
 		.cmd = QCOM_SCM_PIL_PAS_MEM_SETUP,
 		.arginfo = QCOM_SCM_ARGS(3),
-		.args[0] = peripheral,
+		.args[0] = pas_id,
 		.args[1] = addr,
 		.args[2] = size,
 		.owner = ARM_SMCCC_OWNER_SIP,
@@ -709,18 +709,18 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_mem_setup
 /**
  * qcom_scm_pas_auth_and_reset() - Authenticate the given peripheral firmware
  *				   and reset the remote processor
- * @peripheral:	peripheral id
+ * @pas_id:	peripheral authentication service id
  *
  * Return 0 on success.
  */
-int qcom_scm_pas_auth_and_reset(u32 peripheral)
+int qcom_scm_pas_auth_and_reset(u32 pas_id)
 {
 	int ret;
 	struct qcom_scm_desc desc = {
 		.svc = QCOM_SCM_SVC_PIL,
 		.cmd = QCOM_SCM_PIL_PAS_AUTH_AND_RESET,
 		.arginfo = QCOM_SCM_ARGS(1),
-		.args[0] = peripheral,
+		.args[0] = pas_id,
 		.owner = ARM_SMCCC_OWNER_SIP,
 	};
 	struct qcom_scm_res res;
@@ -745,18 +745,18 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_auth_and_
 
 /**
  * qcom_scm_pas_shutdown() - Shut down the remote processor
- * @peripheral: peripheral id
+ * @pas_id:	peripheral authentication service id
  *
  * Returns 0 on success.
  */
-int qcom_scm_pas_shutdown(u32 peripheral)
+int qcom_scm_pas_shutdown(u32 pas_id)
 {
 	int ret;
 	struct qcom_scm_desc desc = {
 		.svc = QCOM_SCM_SVC_PIL,
 		.cmd = QCOM_SCM_PIL_PAS_SHUTDOWN,
 		.arginfo = QCOM_SCM_ARGS(1),
-		.args[0] = peripheral,
+		.args[0] = pas_id,
 		.owner = ARM_SMCCC_OWNER_SIP,
 	};
 	struct qcom_scm_res res;
@@ -782,18 +782,18 @@ EXPORT_SYMBOL_GPL(qcom_scm_pas_shutdown)
 /**
  * qcom_scm_pas_supported() - Check if the peripheral authentication service is
  *			      available for the given peripherial
- * @peripheral:	peripheral id
+ * @pas_id:	peripheral authentication service id
  *
  * Returns true if PAS is supported for this peripheral, otherwise false.
  */
-bool qcom_scm_pas_supported(u32 peripheral)
+bool qcom_scm_pas_supported(u32 pas_id)
 {
 	int ret;
 	struct qcom_scm_desc desc = {
 		.svc = QCOM_SCM_SVC_PIL,
 		.cmd = QCOM_SCM_PIL_PAS_IS_SUPPORTED,
 		.arginfo = QCOM_SCM_ARGS(1),
-		.args[0] = peripheral,
+		.args[0] = pas_id,
 		.owner = ARM_SMCCC_OWNER_SIP,
 	};
 	struct qcom_scm_res res;
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -72,13 +72,13 @@ struct qcom_scm_pas_metadata {
 	ssize_t size;
 };
 
-int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
+int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
 			    struct qcom_scm_pas_metadata *ctx);
 void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
-int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size);
-int qcom_scm_pas_auth_and_reset(u32 peripheral);
-int qcom_scm_pas_shutdown(u32 peripheral);
-bool qcom_scm_pas_supported(u32 peripheral);
+int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
+int qcom_scm_pas_auth_and_reset(u32 pas_id);
+int qcom_scm_pas_shutdown(u32 pas_id);
+bool qcom_scm_pas_supported(u32 pas_id);
 
 int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
 int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 569/877] remoteproc: pas: Replace metadata context with PAS context structure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (567 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 568/877] firmware: qcom_scm: Rename peripheral as pas_id Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 570/877] remoteproc: qcom: pas: Guard dtb metadata release with dtb_pas_id check Greg Kroah-Hartman
                   ` (315 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mukesh Ojha, Bjorn Andersson,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>

[ Upstream commit b13d8baf56016e7eec29395b52d18b91df081d48 ]

As a superset of the existing metadata context, the PAS context
structure enables both remoteproc and non-remoteproc subsystems to
better support scenarios where the SoC runs with or without the Gunyah
hypervisor. To reflect this, relevant SCM and metadata functions are
updated to incorporate PAS context awareness and remove metadata context
data structure completely.

Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260105-kvmrprocv10-v10-5-022e96815380@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>

Stable adaptation for c06c5ab4945392d2c2aded6d832ab6b58cabe351:

This tree has neither the PAS context allocator nor the later generic
PAS service and context-aware MDT loader. Define the PAS context in the
existing SCM header and allocate and initialize it in adsp_probe() using
devm_kzalloc(), without adding any functions. Keep the stable MDT loader
interfaces and update their existing context arguments and declarations.

Rename the existing metadata release implementation and its callers to
qcom_pas_metadata_release(), as used by the target fix. Keep the driver's
adsp names except for the local PAS pointer in adsp_load(). Handle DTB
initialization failure inline, preserving its existing cleanup behavior,
so that the target can remove the shared load-failure cleanup label. The
remaining load-failure path and its context now support a clean three-way
cherry-pick of the target without importing the newer loader helper.

Stable-dep-of: c06c5ab49453 ("remoteproc: qcom: pas: Guard dtb metadata release with dtb_pas_id check")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/firmware/qcom/qcom_scm.c       |   14 ++---
 drivers/remoteproc/qcom_q6v5_pas.c     |   84 ++++++++++++++++++++-------------
 drivers/soc/qcom/mdt_loader.c          |    4 -
 include/linux/firmware/qcom/qcom_scm.h |   10 ++-
 include/linux/soc/qcom/mdt_loader.h    |    6 +-
 5 files changed, 72 insertions(+), 46 deletions(-)

--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -577,16 +577,16 @@ static void qcom_scm_set_download_mode(u
  *		and optional blob of data used for authenticating the metadata
  *		and the rest of the firmware
  * @size:	size of the metadata
- * @ctx:	optional metadata context
+ * @ctx:	optional pas context
  *
  * Return: 0 on success.
  *
  * Upon successful return, the PAS metadata context (@ctx) will be used to
  * track the metadata allocation, this needs to be released by invoking
- * qcom_scm_pas_metadata_release() by the caller.
+ * qcom_pas_metadata_release() by the caller.
  */
 int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
-			    struct qcom_scm_pas_metadata *ctx)
+			    struct qcom_scm_pas_context *ctx)
 {
 	dma_addr_t mdata_phys;
 	void *mdata_buf;
@@ -649,10 +649,10 @@ out:
 EXPORT_SYMBOL_GPL(qcom_scm_pas_init_image);
 
 /**
- * qcom_scm_pas_metadata_release() - release metadata context
- * @ctx:	metadata context
+ * qcom_pas_metadata_release() - release metadata context
+ * @ctx:	pas context
  */
-void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx)
+void qcom_pas_metadata_release(struct qcom_scm_pas_context *ctx)
 {
 	if (!ctx->ptr)
 		return;
@@ -663,7 +663,7 @@ void qcom_scm_pas_metadata_release(struc
 	ctx->phys = 0;
 	ctx->size = 0;
 }
-EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_release);
+EXPORT_SYMBOL_GPL(qcom_pas_metadata_release);
 
 /**
  * qcom_scm_pas_mem_setup() - Prepare the memory related to a given peripheral
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -115,8 +115,8 @@ struct qcom_adsp {
 	struct qcom_rproc_ssr ssr_subdev;
 	struct qcom_sysmon *sysmon;
 
-	struct qcom_scm_pas_metadata pas_metadata;
-	struct qcom_scm_pas_metadata dtb_pas_metadata;
+	struct qcom_scm_pas_context *pas_ctx;
+	struct qcom_scm_pas_context *dtb_pas_ctx;
 };
 
 static void adsp_segment_dump(struct rproc *rproc, struct rproc_dump_segment *segment,
@@ -203,47 +203,50 @@ static int adsp_unprepare(struct rproc *
 	struct qcom_adsp *adsp = rproc->priv;
 
 	/*
-	 * adsp_load() did pass pas_metadata to the SCM driver for storing
+	 * adsp_load() did pass the PAS context to the SCM driver for storing
 	 * metadata context. It might have been released already if
 	 * auth_and_reset() was successful, but in other cases clean it up
 	 * here.
 	 */
-	qcom_scm_pas_metadata_release(&adsp->pas_metadata);
+	qcom_pas_metadata_release(adsp->pas_ctx);
 	if (adsp->dtb_pas_id)
-		qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
+		qcom_pas_metadata_release(adsp->dtb_pas_ctx);
 
 	return 0;
 }
 
 static int adsp_load(struct rproc *rproc, const struct firmware *fw)
 {
-	struct qcom_adsp *adsp = rproc->priv;
+	struct qcom_adsp *pas = rproc->priv;
 	int ret;
 
 	/* Store firmware handle to be used in adsp_start() */
-	adsp->firmware = fw;
+	pas->firmware = fw;
 
-	if (adsp->lite_pas_id)
-		ret = qcom_scm_pas_shutdown(adsp->lite_pas_id);
+	if (pas->lite_pas_id)
+		ret = qcom_scm_pas_shutdown(pas->lite_pas_id);
 
-	if (adsp->dtb_pas_id) {
-		ret = request_firmware(&adsp->dtb_firmware, adsp->dtb_firmware_name, adsp->dev);
+	if (pas->dtb_pas_id) {
+		ret = request_firmware(&pas->dtb_firmware, pas->dtb_firmware_name, pas->dev);
 		if (ret) {
-			dev_err(adsp->dev, "request_firmware failed for %s: %d\n",
-				adsp->dtb_firmware_name, ret);
+			dev_err(pas->dev, "request_firmware failed for %s: %d\n",
+				pas->dtb_firmware_name, ret);
 			return ret;
 		}
 
-		ret = qcom_mdt_pas_init(adsp->dev, adsp->dtb_firmware, adsp->dtb_firmware_name,
-					adsp->dtb_pas_id, adsp->dtb_mem_phys,
-					&adsp->dtb_pas_metadata);
-		if (ret)
-			goto release_dtb_firmware;
+		ret = qcom_mdt_pas_init(pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
+					pas->dtb_pas_id, pas->dtb_mem_phys,
+					pas->dtb_pas_ctx);
+		if (ret) {
+			release_firmware(pas->dtb_firmware);
+			return ret;
+		}
 
-		ret = qcom_mdt_load_no_init(adsp->dev, adsp->dtb_firmware, adsp->dtb_firmware_name,
-					    adsp->dtb_pas_id, adsp->dtb_mem_region,
-					    adsp->dtb_mem_phys, adsp->dtb_mem_size,
-					    &adsp->dtb_mem_reloc);
+		ret = qcom_mdt_load_no_init(
+					pas->dev, pas->dtb_firmware, pas->dtb_firmware_name,
+					pas->dtb_pas_id, pas->dtb_mem_region,
+					pas->dtb_mem_phys, pas->dtb_mem_size,
+					&pas->dtb_mem_reloc);
 		if (ret)
 			goto release_dtb_metadata;
 	}
@@ -251,10 +254,8 @@ static int adsp_load(struct rproc *rproc
 	return 0;
 
 release_dtb_metadata:
-	qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
-
-release_dtb_firmware:
-	release_firmware(adsp->dtb_firmware);
+	qcom_pas_metadata_release(pas->dtb_pas_ctx);
+	release_firmware(pas->dtb_firmware);
 
 	return ret;
 }
@@ -302,7 +303,7 @@ static int adsp_start(struct rproc *rpro
 	}
 
 	ret = qcom_mdt_pas_init(adsp->dev, adsp->firmware, rproc->firmware, adsp->pas_id,
-				adsp->mem_phys, &adsp->pas_metadata);
+				adsp->mem_phys, adsp->pas_ctx);
 	if (ret)
 		goto disable_px_supply;
 
@@ -328,9 +329,9 @@ static int adsp_start(struct rproc *rpro
 		goto release_pas_metadata;
 	}
 
-	qcom_scm_pas_metadata_release(&adsp->pas_metadata);
+	qcom_pas_metadata_release(adsp->pas_ctx);
 	if (adsp->dtb_pas_id)
-		qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
+		qcom_pas_metadata_release(adsp->dtb_pas_ctx);
 
 	/* Remove pointer to the loaded firmware, only valid in adsp_load() & adsp_start() */
 	adsp->firmware = NULL;
@@ -338,9 +339,9 @@ static int adsp_start(struct rproc *rpro
 	return 0;
 
 release_pas_metadata:
-	qcom_scm_pas_metadata_release(&adsp->pas_metadata);
+	qcom_pas_metadata_release(adsp->pas_ctx);
 	if (adsp->dtb_pas_id)
-		qcom_scm_pas_metadata_release(&adsp->dtb_pas_metadata);
+		qcom_pas_metadata_release(adsp->dtb_pas_ctx);
 disable_px_supply:
 	if (adsp->px_supply)
 		regulator_disable(adsp->px_supply);
@@ -788,6 +789,27 @@ static int adsp_probe(struct platform_de
 	}
 
 	qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
+
+	adsp->pas_ctx = devm_kzalloc(adsp->dev, sizeof(*adsp->pas_ctx), GFP_KERNEL);
+	if (!adsp->pas_ctx) {
+		ret = -ENOMEM;
+		goto remove_ssr_sysmon;
+	}
+	adsp->pas_ctx->dev = adsp->dev;
+	adsp->pas_ctx->pas_id = adsp->pas_id;
+	adsp->pas_ctx->mem_phys = adsp->mem_phys;
+	adsp->pas_ctx->mem_size = adsp->mem_size;
+
+	adsp->dtb_pas_ctx = devm_kzalloc(adsp->dev, sizeof(*adsp->dtb_pas_ctx), GFP_KERNEL);
+	if (!adsp->dtb_pas_ctx) {
+		ret = -ENOMEM;
+		goto remove_ssr_sysmon;
+	}
+	adsp->dtb_pas_ctx->dev = adsp->dev;
+	adsp->dtb_pas_ctx->pas_id = adsp->dtb_pas_id;
+	adsp->dtb_pas_ctx->mem_phys = adsp->dtb_mem_phys;
+	adsp->dtb_pas_ctx->mem_size = adsp->dtb_mem_size;
+
 	ret = rproc_add(rproc);
 	if (ret)
 		goto remove_ssr_sysmon;
--- a/drivers/soc/qcom/mdt_loader.c
+++ b/drivers/soc/qcom/mdt_loader.c
@@ -234,13 +234,13 @@ EXPORT_SYMBOL_GPL(qcom_mdt_read_metadata
  * @fw_name:	name of the firmware, for construction of segment file names
  * @pas_id:	PAS identifier
  * @mem_phys:	physical address of allocated memory region
- * @ctx:	PAS metadata context, to be released by caller
+ * @ctx:	PAS context, metadata to be released by caller
  *
  * Returns 0 on success, negative errno otherwise.
  */
 int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
 		      const char *fw_name, int pas_id, phys_addr_t mem_phys,
-		      struct qcom_scm_pas_metadata *ctx)
+		      struct qcom_scm_pas_context *ctx)
 {
 	const struct elf32_phdr *phdrs;
 	const struct elf32_phdr *phdr;
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -66,15 +66,19 @@ int qcom_scm_set_warm_boot_addr(void *en
 void qcom_scm_cpu_power_down(u32 flags);
 int qcom_scm_set_remote_state(u32 state, u32 id);
 
-struct qcom_scm_pas_metadata {
+struct qcom_scm_pas_context {
+	struct device *dev;
+	u32 pas_id;
+	phys_addr_t mem_phys;
+	size_t mem_size;
 	void *ptr;
 	dma_addr_t phys;
 	ssize_t size;
 };
 
 int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
-			    struct qcom_scm_pas_metadata *ctx);
-void qcom_scm_pas_metadata_release(struct qcom_scm_pas_metadata *ctx);
+			    struct qcom_scm_pas_context *ctx);
+void qcom_pas_metadata_release(struct qcom_scm_pas_context *ctx);
 int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
 int qcom_scm_pas_auth_and_reset(u32 pas_id);
 int qcom_scm_pas_shutdown(u32 pas_id);
--- a/include/linux/soc/qcom/mdt_loader.h
+++ b/include/linux/soc/qcom/mdt_loader.h
@@ -10,14 +10,14 @@
 
 struct device;
 struct firmware;
-struct qcom_scm_pas_metadata;
+struct qcom_scm_pas_context;
 
 #if IS_ENABLED(CONFIG_QCOM_MDT_LOADER)
 
 ssize_t qcom_mdt_get_size(const struct firmware *fw);
 int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
 		      const char *fw_name, int pas_id, phys_addr_t mem_phys,
-		      struct qcom_scm_pas_metadata *pas_metadata_ctx);
+		      struct qcom_scm_pas_context *pas_ctx);
 int qcom_mdt_load(struct device *dev, const struct firmware *fw,
 		  const char *fw_name, int pas_id, void *mem_region,
 		  phys_addr_t mem_phys, size_t mem_size,
@@ -39,7 +39,7 @@ static inline ssize_t qcom_mdt_get_size(
 
 static inline int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw,
 				    const char *fw_name, int pas_id, phys_addr_t mem_phys,
-				    struct qcom_scm_pas_metadata *pas_metadata_ctx)
+				    struct qcom_scm_pas_context *pas_ctx)
 {
 	return -ENODEV;
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 570/877] remoteproc: qcom: pas: Guard dtb metadata release with dtb_pas_id check
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (568 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 569/877] remoteproc: pas: Replace metadata context with PAS context structure Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 571/877] power: supply: ab8500_fg: Remove redundant dev_err()/dev_err_probe() Greg Kroah-Hartman
                   ` (314 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Konrad Dybcio, Dmitry Baryshkov,
	Mukesh Ojha, Bjorn Andersson, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>

[ Upstream commit c06c5ab4945392d2c2aded6d832ab6b58cabe351 ]

All other call sites of qcom_scm_pas_metadata_release() for the DTB
context are guarded by a check on pas->dtb_pas_id, but the call inside
qcom_pas_load() was not. Fix this by moving the call to the guarded
block.

Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Fixes: 29814986b82e ("remoteproc: qcom_q6v5_pas: add support for dtb co-firmware loading")
Cc: stable@vger.kernel.org
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260724182858.1868271-3-mukesh.ojha@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/remoteproc/qcom_q6v5_pas.c |   13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -247,17 +247,14 @@ static int adsp_load(struct rproc *rproc
 					pas->dtb_pas_id, pas->dtb_mem_region,
 					pas->dtb_mem_phys, pas->dtb_mem_size,
 					&pas->dtb_mem_reloc);
-		if (ret)
-			goto release_dtb_metadata;
+		if (ret) {
+			qcom_pas_metadata_release(pas->dtb_pas_ctx);
+			release_firmware(pas->dtb_firmware);
+			return ret;
+		}
 	}
 
 	return 0;
-
-release_dtb_metadata:
-	qcom_pas_metadata_release(pas->dtb_pas_ctx);
-	release_firmware(pas->dtb_firmware);
-
-	return ret;
 }
 
 static int adsp_start(struct rproc *rproc)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 571/877] power: supply: ab8500_fg: Remove redundant dev_err()/dev_err_probe()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (569 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 570/877] remoteproc: qcom: pas: Guard dtb metadata release with dtb_pas_id check Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 572/877] power: supply: ab8500_fg: fix use-after-free on remove Greg Kroah-Hartman
                   ` (313 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Pan Chuang, Linus Walleij,
	Sebastian Reichel, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pan Chuang <panchuang@vivo.com>

[ Upstream commit aa5f4decedfb4fc5cd0fe49ab256ad4304d192e4 ]

The devm_request_threaded_irq() and devm_request_irq() now automatically
log detailed error messages on failure. This eliminates the need for
driver-specific dev_err() and dev_err_probe() calls that previously
printed generic messages.

Signed-off-by: Pan Chuang <panchuang@vivo.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260709033428.362970-7-panchuang@vivo.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Stable-dep-of: 75b1e88d3425 ("power: supply: ab8500_fg: fix use-after-free on remove")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/power/supply/ab8500_fg.c |    2 --
 1 file changed, 2 deletions(-)

--- a/drivers/power/supply/ab8500_fg.c
+++ b/drivers/power/supply/ab8500_fg.c
@@ -3179,8 +3179,6 @@ static int ab8500_fg_probe(struct platfo
 				  ab8500_fg_irq[i].name, di);
 
 		if (ret != 0) {
-			dev_err(dev, "failed to request %s IRQ %d: %d\n",
-				ab8500_fg_irq[i].name, irq, ret);
 			destroy_workqueue(di->fg_wq);
 			return ret;
 		}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 572/877] power: supply: ab8500_fg: fix use-after-free on remove
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (570 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 571/877] power: supply: ab8500_fg: Remove redundant dev_err()/dev_err_probe() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 573/877] PCI: starfive: Use regulator APIs to control the 3v3 power supply of PCIe slots Greg Kroah-Hartman
                   ` (312 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Fan Wu, Linus Walleij,
	Sebastian Reichel, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Fan Wu <fanwu01@zju.edu.cn>

[ Upstream commit 75b1e88d34254f4fb7753345e21bfee47abddd7f ]

ab8500_fg_remove() destroys the driver workqueue while the threaded
interrupt handlers are still armed; they are devm-managed and freed
only after ->remove() returns, so a handler that fires in that
window queues work on the freed workqueue.

Tear the workqueue down through devm instead, registering its cleanup
after the power supply and before the interrupt requests.  devm then
frees the interrupts first, so the handlers can no longer queue work,
before disabling the delayed and plain work items and destroying the
workqueue.  Disabling the items, rather than cancelling them, keeps
them disabled so no producer (including the power-supply
external_power_changed callback) can requeue them.

Found by an in-house static analysis tool.

Fixes: 13151631b5bd ("ab8500-fg: A8500 fuel gauge driver")
Cc: stable@vger.kernel.org # v6.10+
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260802020316.417757-1-fanwu01@zju.edu.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/power/supply/ab8500_fg.c |   30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

--- a/drivers/power/supply/ab8500_fg.c
+++ b/drivers/power/supply/ab8500_fg.c
@@ -3055,6 +3055,20 @@ static void ab8500_fg_unbind(struct devi
 	flush_workqueue(di->fg_wq);
 }
 
+/* Disable, not cancel: works stay disabled so nothing can re-arm them. */
+static void ab8500_fg_destroy_workqueue(void *data)
+{
+	struct ab8500_fg *di = data;
+
+	disable_work_sync(&di->fg_acc_cur_work);
+	disable_work_sync(&di->fg_work);
+	disable_delayed_work_sync(&di->fg_reinit_work);
+	disable_delayed_work_sync(&di->fg_low_bat_work);
+	disable_delayed_work_sync(&di->fg_check_hw_failure_work);
+	disable_delayed_work_sync(&di->fg_periodic_work);
+	destroy_workqueue(di->fg_wq);
+}
+
 static const struct component_ops ab8500_fg_component_ops = {
 	.bind = ab8500_fg_bind,
 	.unbind = ab8500_fg_unbind,
@@ -3156,6 +3170,11 @@ static int ab8500_fg_probe(struct platfo
 		return PTR_ERR(di->fg_psy);
 	}
 
+	/* Registered after fg_psy, before the IRQs: devm frees IRQ -> workqueue -> fg_psy. */
+	ret = devm_add_action_or_reset(dev, ab8500_fg_destroy_workqueue, di);
+	if (ret)
+		return ret;
+
 	di->fg_samples = SEC_TO_SAMPLE(di->bm->fg_params->init_timer);
 
 	/*
@@ -3168,20 +3187,16 @@ static int ab8500_fg_probe(struct platfo
 	/* Register primary interrupt handlers */
 	for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq); i++) {
 		irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name);
-		if (irq < 0) {
-			destroy_workqueue(di->fg_wq);
+		if (irq < 0)
 			return irq;
-		}
 
 		ret = devm_request_threaded_irq(dev, irq, NULL,
 				  ab8500_fg_irq[i].isr,
 				  IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT,
 				  ab8500_fg_irq[i].name, di);
 
-		if (ret != 0) {
-			destroy_workqueue(di->fg_wq);
+		if (ret != 0)
 			return ret;
-		}
 		dev_dbg(dev, "Requested %s IRQ %d: %d\n",
 			ab8500_fg_irq[i].name, irq, ret);
 	}
@@ -3195,7 +3210,6 @@ static int ab8500_fg_probe(struct platfo
 	ret = ab8500_fg_sysfs_init(di);
 	if (ret) {
 		dev_err(dev, "failed to create sysfs entry\n");
-		destroy_workqueue(di->fg_wq);
 		return ret;
 	}
 
@@ -3203,7 +3217,6 @@ static int ab8500_fg_probe(struct platfo
 	if (ret) {
 		dev_err(dev, "failed to create FG psy\n");
 		ab8500_fg_sysfs_exit(di);
-		destroy_workqueue(di->fg_wq);
 		return ret;
 	}
 
@@ -3223,7 +3236,6 @@ static void ab8500_fg_remove(struct plat
 {
 	struct ab8500_fg *di = platform_get_drvdata(pdev);
 
-	destroy_workqueue(di->fg_wq);
 	component_del(&pdev->dev, &ab8500_fg_component_ops);
 	list_del(&di->node);
 	ab8500_fg_sysfs_exit(di);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 573/877] PCI: starfive: Use regulator APIs to control the 3v3 power supply of PCIe slots
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (571 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 572/877] power: supply: ab8500_fg: fix use-after-free on remove Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 574/877] PCI: starfive: Fix resource leaks on error paths in host_init() Greg Kroah-Hartman
                   ` (311 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Hal Feng, Manivannan Sadhasivam,
	Kevin Xie, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Hal Feng <hal.feng@starfivetech.com>

[ Upstream commit 05a75df4182e301a1b0059606f77b65c74deaa9b ]

The driver has been using the "enable-gpios" property to control the 3v3
power supply of PCIe slots. But it is not documented in the dt-bindings and
also using GPIO APIs is not a standard way to control PCIe slot power, so
use the documented "vpcie3v3-supply" property and regulator APIs to control
the slot supply.

This change will break the DTs which used "enable-gpio" or "enable-gpios"
property under the controller node. Since these properties were not defined
in the bindings, it is safe to switch to "vpcie3v3-supply". Any out-of-tree
DTS impacted by this change should migrate to "vpcie3v3-supply" instead.

Signed-off-by: Hal Feng <hal.feng@starfivetech.com>
[mani: reworded description]
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Acked-by: Kevin Xie <kevin.xie@starfivetech.com>
Link: https://patch.msgid.link/20251218102149.28062-1-hal.feng@starfivetech.com
Stable-dep-of: 22877a061f81 ("PCI: starfive: Fix resource leaks on error paths in host_init()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/pci/controller/plda/pcie-starfive.c |   25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

--- a/drivers/pci/controller/plda/pcie-starfive.c
+++ b/drivers/pci/controller/plda/pcie-starfive.c
@@ -55,7 +55,7 @@ struct starfive_jh7110_pcie {
 	struct reset_control *resets;
 	struct clk_bulk_data *clks;
 	struct regmap *reg_syscon;
-	struct gpio_desc *power_gpio;
+	struct regulator *vpcie3v3;
 	struct gpio_desc *reset_gpio;
 	struct phy *phy;
 
@@ -153,11 +153,13 @@ static int starfive_pcie_parse_dt(struct
 		return dev_err_probe(dev, PTR_ERR(pcie->reset_gpio),
 				     "failed to get perst-gpio\n");
 
-	pcie->power_gpio = devm_gpiod_get_optional(dev, "enable",
-						   GPIOD_OUT_LOW);
-	if (IS_ERR(pcie->power_gpio))
-		return dev_err_probe(dev, PTR_ERR(pcie->power_gpio),
-				     "failed to get power-gpio\n");
+	pcie->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3");
+	if (IS_ERR(pcie->vpcie3v3)) {
+		if (PTR_ERR(pcie->vpcie3v3) != -ENODEV)
+			return dev_err_probe(dev, PTR_ERR(pcie->vpcie3v3),
+					     "failed to get vpcie3v3 regulator\n");
+		pcie->vpcie3v3 = NULL;
+	}
 
 	return 0;
 }
@@ -270,8 +272,8 @@ static void starfive_pcie_host_deinit(st
 		container_of(plda, struct starfive_jh7110_pcie, plda);
 
 	starfive_pcie_clk_rst_deinit(pcie);
-	if (pcie->power_gpio)
-		gpiod_set_value_cansleep(pcie->power_gpio, 0);
+	if (pcie->vpcie3v3)
+		regulator_disable(pcie->vpcie3v3);
 	starfive_pcie_disable_phy(pcie);
 }
 
@@ -304,8 +306,11 @@ static int starfive_pcie_host_init(struc
 	if (ret)
 		return ret;
 
-	if (pcie->power_gpio)
-		gpiod_set_value_cansleep(pcie->power_gpio, 1);
+	if (pcie->vpcie3v3) {
+		ret = regulator_enable(pcie->vpcie3v3);
+		if (ret)
+			dev_err_probe(dev, ret, "failed to enable vpcie3v3 regulator\n");
+	}
 
 	if (pcie->reset_gpio)
 		gpiod_set_value_cansleep(pcie->reset_gpio, 1);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 574/877] PCI: starfive: Fix resource leaks on error paths in host_init()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (572 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 573/877] PCI: starfive: Use regulator APIs to control the 3v3 power supply of PCIe slots Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 575/877] iommu/msm: Use helper function devm_clk_get_prepared() Greg Kroah-Hartman
                   ` (310 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ali Tariq, Manivannan Sadhasivam,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ali Tariq <alitariq45892@gmail.com>

[ Upstream commit 22877a061f81c5d58041e384b3131684bec636b9 ]

starfive_pcie_host_init() acquires the PHY, clocks/resets, and an
optional regulator in sequence, but does not correctly unwind these
resources when a later step fails.

If starfive_pcie_clk_rst_init() fails after the PHY has already been
successfully enabled, the function returns directly without disabling
the PHY, leaking it and leaving it powered.

If regulator_enable() fails for the optional vpcie3v3 regulator, the
failure is only logged; the function falls through and returns
success, leaving the driver believing the regulator is enabled while
continuing to configure PCIe hardware that may be unpowered. This
also leaves the clocks and PHY enabled with nothing to clean them up.

Disable the PHY on the clk/reset failure path, and disable the
clocks/resets and PHY, then return the error, if the regulator fails
to enable.

Build-tested and boot-tested on StarFive VisionFive 2 v1.2A

Fixes: 05a75df4182e ("PCI: starfive: Use regulator APIs to control the 3v3 power supply of PCIe slots")
Fixes: 39b91eb40c6a ("PCI: starfive: Add JH7110 PCIe controller")
Signed-off-by: Ali Tariq <alitariq45892@gmail.com>
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260716102053.185276-1-alitariq45892@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/pci/controller/plda/pcie-starfive.c |   13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

--- a/drivers/pci/controller/plda/pcie-starfive.c
+++ b/drivers/pci/controller/plda/pcie-starfive.c
@@ -304,12 +304,14 @@ static int starfive_pcie_host_init(struc
 
 	ret = starfive_pcie_clk_rst_init(pcie);
 	if (ret)
-		return ret;
+		goto err_disable_phy;
 
 	if (pcie->vpcie3v3) {
 		ret = regulator_enable(pcie->vpcie3v3);
-		if (ret)
+		if (ret) {
 			dev_err_probe(dev, ret, "failed to enable vpcie3v3 regulator\n");
+			goto err_clk_rst;
+		}
 	}
 
 	if (pcie->reset_gpio)
@@ -379,6 +381,13 @@ static int starfive_pcie_host_init(struc
 		dev_info(dev, "port link down\n");
 
 	return 0;
+
+err_clk_rst:
+	starfive_pcie_clk_rst_deinit(pcie);
+err_disable_phy:
+	starfive_pcie_disable_phy(pcie);
+
+	return ret;
 }
 
 static const struct plda_pcie_host_ops sf_host_ops = {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 575/877] iommu/msm: Use helper function devm_clk_get_prepared()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (573 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 574/877] PCI: starfive: Fix resource leaks on error paths in host_init() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 576/877] iommu/msm: Unwind probe state on registration failure Greg Kroah-Hartman
                   ` (309 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Zhang Heng, Dmitry Baryshkov,
	Joerg Roedel, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Zhang Heng <zhangheng@kylinos.cn>

[ Upstream commit afc0cbc6e25b37dc9ba11d415ea6858902a7f04b ]

Since commit 7ef9651e9792 ("clk: Provide new devm_clk helpers for prepared
and enabled clocks"), devm_clk_get() and clk_prepare() can now be replaced
by devm_clk_get_prepared() when driver prepares the clocks for the whole
lifetime of the device. Moreover, it is no longer necessary to unprepare
the clocks explicitly.

Signed-off-by: Zhang Heng <zhangheng@kylinos.cn>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://lore.kernel.org/r/20250103113059.463033-1-zhangheng@kylinos.cn
Signed-off-by: Joerg Roedel <jroedel@suse.de>

Backport to 6.12: remove the .remove_new callback entry used by this
stable tree instead of the upstream .remove entry. The callback only
unprepares clocks, which devm_clk_get_prepared() now handles. Keep
the remaining upstream changes to prepare the probe error paths for
535a200220ca ("iommu/msm: Unwind probe state on registration failure").

Stable-dep-of: 535a200220ca ("iommu/msm: Unwind probe state on registration failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/iommu/msm_iommu.c |   51 +++++++++-------------------------------------
 1 file changed, 11 insertions(+), 40 deletions(-)

--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -725,47 +725,32 @@ static int msm_iommu_probe(struct platfo
 	iommu->dev = &pdev->dev;
 	INIT_LIST_HEAD(&iommu->ctx_list);
 
-	iommu->pclk = devm_clk_get(iommu->dev, "smmu_pclk");
+	iommu->pclk = devm_clk_get_prepared(iommu->dev, "smmu_pclk");
 	if (IS_ERR(iommu->pclk))
 		return dev_err_probe(iommu->dev, PTR_ERR(iommu->pclk),
 				     "could not get smmu_pclk\n");
 
-	ret = clk_prepare(iommu->pclk);
-	if (ret)
-		return dev_err_probe(iommu->dev, ret,
-				     "could not prepare smmu_pclk\n");
-
-	iommu->clk = devm_clk_get(iommu->dev, "iommu_clk");
-	if (IS_ERR(iommu->clk)) {
-		clk_unprepare(iommu->pclk);
+	iommu->clk = devm_clk_get_prepared(iommu->dev, "iommu_clk");
+	if (IS_ERR(iommu->clk))
 		return dev_err_probe(iommu->dev, PTR_ERR(iommu->clk),
 				     "could not get iommu_clk\n");
-	}
-
-	ret = clk_prepare(iommu->clk);
-	if (ret) {
-		clk_unprepare(iommu->pclk);
-		return dev_err_probe(iommu->dev, ret, "could not prepare iommu_clk\n");
-	}
 
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	iommu->base = devm_ioremap_resource(iommu->dev, r);
 	if (IS_ERR(iommu->base)) {
 		ret = dev_err_probe(iommu->dev, PTR_ERR(iommu->base), "could not get iommu base\n");
-		goto fail;
+		return ret;
 	}
 	ioaddr = r->start;
 
 	iommu->irq = platform_get_irq(pdev, 0);
-	if (iommu->irq < 0) {
-		ret = -ENODEV;
-		goto fail;
-	}
+	if (iommu->irq < 0)
+		return -ENODEV;
 
 	ret = of_property_read_u32(iommu->dev->of_node, "qcom,ncb", &val);
 	if (ret) {
 		dev_err(iommu->dev, "could not get ncb\n");
-		goto fail;
+		return ret;
 	}
 	iommu->ncb = val;
 
@@ -780,8 +765,7 @@ static int msm_iommu_probe(struct platfo
 
 	if (!par) {
 		pr_err("Invalid PAR value detected\n");
-		ret = -ENODEV;
-		goto fail;
+		return -ENODEV;
 	}
 
 	ret = devm_request_threaded_irq(iommu->dev, iommu->irq, NULL,
@@ -791,7 +775,7 @@ static int msm_iommu_probe(struct platfo
 					iommu);
 	if (ret) {
 		pr_err("Request IRQ %d failed with ret=%d\n", iommu->irq, ret);
-		goto fail;
+		return ret;
 	}
 
 	list_add(&iommu->dev_node, &qcom_iommu_devices);
@@ -800,23 +784,19 @@ static int msm_iommu_probe(struct platfo
 				     "msm-smmu.%pa", &ioaddr);
 	if (ret) {
 		pr_err("Could not add msm-smmu at %pa to sysfs\n", &ioaddr);
-		goto fail;
+		return ret;
 	}
 
 	ret = iommu_device_register(&iommu->iommu, &msm_iommu_ops, &pdev->dev);
 	if (ret) {
 		pr_err("Could not register msm-smmu at %pa\n", &ioaddr);
-		goto fail;
+		return ret;
 	}
 
 	pr_info("device mapped at %p, irq %d with %d ctx banks\n",
 		iommu->base, iommu->irq, iommu->ncb);
 
 	return ret;
-fail:
-	clk_unprepare(iommu->clk);
-	clk_unprepare(iommu->pclk);
-	return ret;
 }
 
 static const struct of_device_id msm_iommu_dt_match[] = {
@@ -824,20 +804,11 @@ static const struct of_device_id msm_iom
 	{}
 };
 
-static void msm_iommu_remove(struct platform_device *pdev)
-{
-	struct msm_iommu_dev *iommu = platform_get_drvdata(pdev);
-
-	clk_unprepare(iommu->clk);
-	clk_unprepare(iommu->pclk);
-}
-
 static struct platform_driver msm_iommu_driver = {
 	.driver = {
 		.name	= "msm_iommu",
 		.of_match_table = msm_iommu_dt_match,
 	},
 	.probe		= msm_iommu_probe,
-	.remove_new	= msm_iommu_remove,
 };
 builtin_platform_driver(msm_iommu_driver);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 576/877] iommu/msm: Unwind probe state on registration failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (574 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 575/877] iommu/msm: Use helper function devm_clk_get_prepared() Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 577/877] iommufd: Pass @pasid through the device attach/replace path Greg Kroah-Hartman
                   ` (308 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mukesh Ojha, Weimin Xiong,
	Will Deacon, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Weimin Xiong <xiongwm2026@163.com>

[ Upstream commit 535a200220ca2c83bc8bf54bd2cbe045d6ee70c4 ]

msm_iommu_probe() adds its devm-managed IOMMU object to
qcom_iommu_devices before adding the IOMMU sysfs device and registering
it with the IOMMU core.

If iommu_device_sysfs_add() fails, probe returns with the object still on
qcom_iommu_devices. The driver core then releases the devm allocation,
leaving a dangling list entry that later list walks may dereference.

If iommu_device_register() fails, the same dangling list entry remains
and the sysfs device is left registered as well.

Unwind the sysfs device and global list entry in reverse setup order on
the corresponding failure paths.

Fixes: 42df43b36163 ("iommu/msm: Make use of iommu_device_register interface")
Cc: stable@vger.kernel.org
Reviewed-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Signed-off-by: Weimin Xiong <xiongwm2026@163.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/iommu/msm_iommu.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

--- a/drivers/iommu/msm_iommu.c
+++ b/drivers/iommu/msm_iommu.c
@@ -784,19 +784,25 @@ static int msm_iommu_probe(struct platfo
 				     "msm-smmu.%pa", &ioaddr);
 	if (ret) {
 		pr_err("Could not add msm-smmu at %pa to sysfs\n", &ioaddr);
-		return ret;
+		goto err_remove_list;
 	}
 
 	ret = iommu_device_register(&iommu->iommu, &msm_iommu_ops, &pdev->dev);
 	if (ret) {
 		pr_err("Could not register msm-smmu at %pa\n", &ioaddr);
-		return ret;
+		goto err_remove_sysfs;
 	}
 
 	pr_info("device mapped at %p, irq %d with %d ctx banks\n",
 		iommu->base, iommu->irq, iommu->ncb);
 
 	return ret;
+
+err_remove_sysfs:
+	iommu_device_sysfs_remove(&iommu->iommu);
+err_remove_list:
+	list_del(&iommu->dev_node);
+	return ret;
 }
 
 static const struct of_device_id msm_iommu_dt_match[] = {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 577/877] iommufd: Pass @pasid through the device attach/replace path
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (575 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 576/877] iommu/msm: Unwind probe state on registration failure Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 578/877] iommufd: Fix UAF in selftest IOPF reporting Greg Kroah-Hartman
                   ` (307 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kevin Tian, Jason Gunthorpe,
	Nicolin Chen, Lu Baolu, Yi Liu, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Yi Liu <yi.l.liu@intel.com>

[ Upstream commit 03c9b102bea6f4f0b517c841fe1d2f9c616c95b9 ]

Most of the core logic before conducting the actual device attach/
replace operation can be shared with pasid attach/replace. So pass
@pasid through the device attach/replace helpers to prepare adding
pasid attach/replace.

So far the @pasid should only be IOMMU_NO_PASID. No functional change.

Link: https://patch.msgid.link/r/20250321171940.7213-4-yi.l.liu@intel.com
Signed-off-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Stable-dep-of: 8c07df7cdfcf ("iommufd: Fix UAF in selftest IOPF reporting")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/iommu/iommufd/device.c          |   70 ++++++++++++++++++--------------
 drivers/iommu/iommufd/hw_pagetable.c    |   13 +++--
 drivers/iommu/iommufd/iommufd_private.h |    8 +--
 3 files changed, 52 insertions(+), 39 deletions(-)

--- a/drivers/iommu/iommufd/device.c
+++ b/drivers/iommu/iommufd/device.c
@@ -367,7 +367,8 @@ static bool iommufd_device_is_attached(s
 }
 
 static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,
-				      struct iommufd_device *idev)
+				      struct iommufd_device *idev,
+				      ioasid_t pasid)
 {
 	struct iommufd_attach_handle *handle;
 	int rc;
@@ -385,6 +386,7 @@ static int iommufd_hwpt_attach_device(st
 	}
 
 	handle->idev = idev;
+	WARN_ON(pasid != IOMMU_NO_PASID);
 	rc = iommu_attach_group_handle(hwpt->domain, idev->igroup->group,
 				       &handle->handle);
 	if (rc)
@@ -401,25 +403,28 @@ out_free_handle:
 }
 
 static struct iommufd_attach_handle *
-iommufd_device_get_attach_handle(struct iommufd_device *idev)
+iommufd_device_get_attach_handle(struct iommufd_device *idev, ioasid_t pasid)
 {
 	struct iommu_attach_handle *handle;
 
 	lockdep_assert_held(&idev->igroup->lock);
 
 	handle =
-		iommu_attach_handle_get(idev->igroup->group, IOMMU_NO_PASID, 0);
+		iommu_attach_handle_get(idev->igroup->group, pasid, 0);
 	if (IS_ERR(handle))
 		return NULL;
 	return to_iommufd_handle(handle);
 }
 
 static void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt,
-				       struct iommufd_device *idev)
+				       struct iommufd_device *idev,
+				       ioasid_t pasid)
 {
 	struct iommufd_attach_handle *handle;
 
-	handle = iommufd_device_get_attach_handle(idev);
+	WARN_ON(pasid != IOMMU_NO_PASID);
+
+	handle = iommufd_device_get_attach_handle(idev, pasid);
 	iommu_detach_group_handle(hwpt->domain, idev->igroup->group);
 	if (hwpt->fault) {
 		iommufd_auto_response_faults(hwpt, handle);
@@ -429,13 +434,17 @@ static void iommufd_hwpt_detach_device(s
 }
 
 static int iommufd_hwpt_replace_device(struct iommufd_device *idev,
+				       ioasid_t pasid,
 				       struct iommufd_hw_pagetable *hwpt,
 				       struct iommufd_hw_pagetable *old)
 {
-	struct iommufd_attach_handle *handle, *old_handle =
-		iommufd_device_get_attach_handle(idev);
+	struct iommufd_attach_handle *handle, *old_handle;
 	int rc;
 
+	WARN_ON(pasid != IOMMU_NO_PASID);
+
+	old_handle = iommufd_device_get_attach_handle(idev, pasid);
+
 	handle = kzalloc(sizeof(*handle), GFP_KERNEL);
 	if (!handle)
 		return -ENOMEM;
@@ -470,7 +479,7 @@ out_free_handle:
 }
 
 int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
-				struct iommufd_device *idev)
+				struct iommufd_device *idev, ioasid_t pasid)
 {
 	struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt);
 	int rc;
@@ -496,7 +505,7 @@ int iommufd_hw_pagetable_attach(struct i
 	 * attachment.
 	 */
 	if (list_empty(&idev->igroup->device_list)) {
-		rc = iommufd_hwpt_attach_device(hwpt, idev);
+		rc = iommufd_hwpt_attach_device(hwpt, idev, pasid);
 		if (rc)
 			goto err_unresv;
 		idev->igroup->hwpt = hwpt;
@@ -514,7 +523,7 @@ err_unlock:
 }
 
 struct iommufd_hw_pagetable *
-iommufd_hw_pagetable_detach(struct iommufd_device *idev)
+iommufd_hw_pagetable_detach(struct iommufd_device *idev, ioasid_t pasid)
 {
 	struct iommufd_hw_pagetable *hwpt = idev->igroup->hwpt;
 	struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt);
@@ -522,7 +531,7 @@ iommufd_hw_pagetable_detach(struct iommu
 	mutex_lock(&idev->igroup->lock);
 	list_del(&idev->group_item);
 	if (list_empty(&idev->igroup->device_list)) {
-		iommufd_hwpt_detach_device(hwpt, idev);
+		iommufd_hwpt_detach_device(hwpt, idev, pasid);
 		idev->igroup->hwpt = NULL;
 	}
 	if (hwpt_paging)
@@ -534,12 +543,12 @@ iommufd_hw_pagetable_detach(struct iommu
 }
 
 static struct iommufd_hw_pagetable *
-iommufd_device_do_attach(struct iommufd_device *idev,
+iommufd_device_do_attach(struct iommufd_device *idev, ioasid_t pasid,
 			 struct iommufd_hw_pagetable *hwpt)
 {
 	int rc;
 
-	rc = iommufd_hw_pagetable_attach(hwpt, idev);
+	rc = iommufd_hw_pagetable_attach(hwpt, idev, pasid);
 	if (rc)
 		return ERR_PTR(rc);
 	return NULL;
@@ -588,7 +597,7 @@ err_unresv:
 }
 
 static struct iommufd_hw_pagetable *
-iommufd_device_do_replace(struct iommufd_device *idev,
+iommufd_device_do_replace(struct iommufd_device *idev, ioasid_t pasid,
 			  struct iommufd_hw_pagetable *hwpt)
 {
 	struct iommufd_hwpt_paging *hwpt_paging = find_hwpt_paging(hwpt);
@@ -622,7 +631,7 @@ iommufd_device_do_replace(struct iommufd
 			goto err_unlock;
 	}
 
-	rc = iommufd_hwpt_replace_device(idev, hwpt, old_hwpt);
+	rc = iommufd_hwpt_replace_device(idev, pasid, hwpt, old_hwpt);
 	if (rc)
 		goto err_unresv;
 
@@ -655,7 +664,8 @@ err_unlock:
 }
 
 typedef struct iommufd_hw_pagetable *(*attach_fn)(
-	struct iommufd_device *idev, struct iommufd_hw_pagetable *hwpt);
+	struct iommufd_device *idev, ioasid_t pasid,
+	struct iommufd_hw_pagetable *hwpt);
 
 /*
  * When automatically managing the domains we search for a compatible domain in
@@ -663,7 +673,7 @@ typedef struct iommufd_hw_pagetable *(*a
  * Automatic domain selection will never pick a manually created domain.
  */
 static struct iommufd_hw_pagetable *
-iommufd_device_auto_get_domain(struct iommufd_device *idev,
+iommufd_device_auto_get_domain(struct iommufd_device *idev, ioasid_t pasid,
 			       struct iommufd_ioas *ioas, u32 *pt_id,
 			       attach_fn do_attach)
 {
@@ -692,7 +702,7 @@ iommufd_device_auto_get_domain(struct io
 		hwpt = &hwpt_paging->common;
 		if (!iommufd_lock_obj(&hwpt->obj))
 			continue;
-		destroy_hwpt = (*do_attach)(idev, hwpt);
+		destroy_hwpt = (*do_attach)(idev, pasid, hwpt);
 		if (IS_ERR(destroy_hwpt)) {
 			iommufd_put_object(idev->ictx, &hwpt->obj);
 			/*
@@ -710,8 +720,8 @@ iommufd_device_auto_get_domain(struct io
 		goto out_unlock;
 	}
 
-	hwpt_paging = iommufd_hwpt_paging_alloc(idev->ictx, ioas, idev, 0,
-						immediate_attach, NULL);
+	hwpt_paging = iommufd_hwpt_paging_alloc(idev->ictx, ioas, idev, pasid,
+						0, immediate_attach, NULL);
 	if (IS_ERR(hwpt_paging)) {
 		destroy_hwpt = ERR_CAST(hwpt_paging);
 		goto out_unlock;
@@ -719,7 +729,7 @@ iommufd_device_auto_get_domain(struct io
 	hwpt = &hwpt_paging->common;
 
 	if (!immediate_attach) {
-		destroy_hwpt = (*do_attach)(idev, hwpt);
+		destroy_hwpt = (*do_attach)(idev, pasid, hwpt);
 		if (IS_ERR(destroy_hwpt))
 			goto out_abort;
 	} else {
@@ -740,8 +750,9 @@ out_unlock:
 	return destroy_hwpt;
 }
 
-static int iommufd_device_change_pt(struct iommufd_device *idev, u32 *pt_id,
-				    attach_fn do_attach)
+static int iommufd_device_change_pt(struct iommufd_device *idev,
+				    ioasid_t pasid,
+				    u32 *pt_id, attach_fn do_attach)
 {
 	struct iommufd_hw_pagetable *destroy_hwpt;
 	struct iommufd_object *pt_obj;
@@ -756,7 +767,7 @@ static int iommufd_device_change_pt(stru
 		struct iommufd_hw_pagetable *hwpt =
 			container_of(pt_obj, struct iommufd_hw_pagetable, obj);
 
-		destroy_hwpt = (*do_attach)(idev, hwpt);
+		destroy_hwpt = (*do_attach)(idev, pasid, hwpt);
 		if (IS_ERR(destroy_hwpt))
 			goto out_put_pt_obj;
 		break;
@@ -765,8 +776,8 @@ static int iommufd_device_change_pt(stru
 		struct iommufd_ioas *ioas =
 			container_of(pt_obj, struct iommufd_ioas, obj);
 
-		destroy_hwpt = iommufd_device_auto_get_domain(idev, ioas, pt_id,
-							      do_attach);
+		destroy_hwpt = iommufd_device_auto_get_domain(idev, pasid, ioas,
+							      pt_id, do_attach);
 		if (IS_ERR(destroy_hwpt))
 			goto out_put_pt_obj;
 		break;
@@ -803,7 +814,8 @@ int iommufd_device_attach(struct iommufd
 {
 	int rc;
 
-	rc = iommufd_device_change_pt(idev, pt_id, &iommufd_device_do_attach);
+	rc = iommufd_device_change_pt(idev, IOMMU_NO_PASID, pt_id,
+				      &iommufd_device_do_attach);
 	if (rc)
 		return rc;
 
@@ -833,7 +845,7 @@ EXPORT_SYMBOL_NS_GPL(iommufd_device_atta
  */
 int iommufd_device_replace(struct iommufd_device *idev, u32 *pt_id)
 {
-	return iommufd_device_change_pt(idev, pt_id,
+	return iommufd_device_change_pt(idev, IOMMU_NO_PASID, pt_id,
 					&iommufd_device_do_replace);
 }
 EXPORT_SYMBOL_NS_GPL(iommufd_device_replace, IOMMUFD);
@@ -849,7 +861,7 @@ void iommufd_device_detach(struct iommuf
 {
 	struct iommufd_hw_pagetable *hwpt;
 
-	hwpt = iommufd_hw_pagetable_detach(idev);
+	hwpt = iommufd_hw_pagetable_detach(idev, IOMMU_NO_PASID);
 	iommufd_hw_pagetable_put(idev->ictx, hwpt);
 	refcount_dec(&idev->obj.users);
 }
--- a/drivers/iommu/iommufd/hw_pagetable.c
+++ b/drivers/iommu/iommufd/hw_pagetable.c
@@ -87,6 +87,7 @@ iommufd_hwpt_paging_enforce_cc(struct io
  * @ictx: iommufd context
  * @ioas: IOAS to associate the domain with
  * @idev: Device to get an iommu_domain for
+ * @pasid: PASID to get an iommu_domain for
  * @flags: Flags from userspace
  * @immediate_attach: True if idev should be attached to the hwpt
  * @user_data: The user provided driver specific data describing the domain to
@@ -102,8 +103,8 @@ iommufd_hwpt_paging_enforce_cc(struct io
  */
 struct iommufd_hwpt_paging *
 iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
-			  struct iommufd_device *idev, u32 flags,
-			  bool immediate_attach,
+			  struct iommufd_device *idev, ioasid_t pasid,
+			  u32 flags, bool immediate_attach,
 			  const struct iommu_user_data *user_data)
 {
 	const u32 valid_flags = IOMMU_HWPT_ALLOC_NEST_PARENT |
@@ -183,7 +184,7 @@ iommufd_hwpt_paging_alloc(struct iommufd
 	 * sequence. Once those drivers are fixed this should be removed.
 	 */
 	if (immediate_attach) {
-		rc = iommufd_hw_pagetable_attach(hwpt, idev);
+		rc = iommufd_hw_pagetable_attach(hwpt, idev, pasid);
 		if (rc)
 			goto out_abort;
 	}
@@ -196,7 +197,7 @@ iommufd_hwpt_paging_alloc(struct iommufd
 
 out_detach:
 	if (immediate_attach)
-		iommufd_hw_pagetable_detach(idev);
+		iommufd_hw_pagetable_detach(idev, pasid);
 out_abort:
 	iommufd_object_abort_and_destroy(ictx, &hwpt->obj);
 	return ERR_PTR(rc);
@@ -299,8 +300,8 @@ int iommufd_hwpt_alloc(struct iommufd_uc
 		ioas = container_of(pt_obj, struct iommufd_ioas, obj);
 		mutex_lock(&ioas->mutex);
 		hwpt_paging = iommufd_hwpt_paging_alloc(
-			ucmd->ictx, ioas, idev, cmd->flags, false,
-			user_data.len ? &user_data : NULL);
+			ucmd->ictx, ioas, idev, IOMMU_NO_PASID, cmd->flags,
+			false, user_data.len ? &user_data : NULL);
 		if (IS_ERR(hwpt_paging)) {
 			rc = PTR_ERR(hwpt_paging);
 			goto out_unlock;
--- a/drivers/iommu/iommufd/iommufd_private.h
+++ b/drivers/iommu/iommufd/iommufd_private.h
@@ -365,13 +365,13 @@ int iommufd_hwpt_get_dirty_bitmap(struct
 
 struct iommufd_hwpt_paging *
 iommufd_hwpt_paging_alloc(struct iommufd_ctx *ictx, struct iommufd_ioas *ioas,
-			  struct iommufd_device *idev, u32 flags,
-			  bool immediate_attach,
+			  struct iommufd_device *idev, ioasid_t pasid,
+			  u32 flags, bool immediate_attach,
 			  const struct iommu_user_data *user_data);
 int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
-				struct iommufd_device *idev);
+				struct iommufd_device *idev, ioasid_t pasid);
 struct iommufd_hw_pagetable *
-iommufd_hw_pagetable_detach(struct iommufd_device *idev);
+iommufd_hw_pagetable_detach(struct iommufd_device *idev, ioasid_t pasid);
 void iommufd_hwpt_paging_destroy(struct iommufd_object *obj);
 void iommufd_hwpt_paging_abort(struct iommufd_object *obj);
 void iommufd_hwpt_nested_destroy(struct iommufd_object *obj);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 578/877] iommufd: Fix UAF in selftest IOPF reporting
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (576 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 577/877] iommufd: Pass @pasid through the device attach/replace path Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 579/877] platform/x86: ISST: Check for admin capability for write commands Greg Kroah-Hartman
                   ` (306 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jason Gunthorpe, Peiyang He,
	Jason Gunthorpe, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Peiyang He <peiyang_he@smail.nju.edu.cn>

[ Upstream commit 8c07df7cdfcf52f1ff276c588612aabc6c6b8399 ]

IOMMUFD selftest TRIGGER_IOPF borrows an attach handle from
group->pasid_array without synchronizing against PASID detach,
then a concurrent iommu_report_device_fault() can dereference
that borrowed handle's domain pointer after the detach erases
the handle and frees the backing struct iommufd_attach_handle.
TRIGGER_IOPF then dereferences the freed handle, causing a UAF.

Fix by adding a iopf_rwsem in mock_dev to follow the expected design
of a real driver. Hold its read side across the whole
iommu_report_device_fault() call, and its write side around every
path that attaches, detaches, or replaces a device domain.
This can block new reports and drains in-flight reports before an old
attach handle or the IOPF fault parameter can be removed.
Also take the write side while registering a mock device, since
it can invoke the mock driver's default-domain attach callback.

Closes: https://lore.kernel.org/all/D5E3AA41600B2056+f4e15662-bd2b-43ea-91cb-518de429e72c@smail.nju.edu.cn/
Fixes: ddee19971081 ("iommufd/selftest: Add IOPF support for mock device")
Cc: stable@vger.kernel.org
Suggested-by: Jason Gunthorpe <jgg@ziepe.ca>
Assisted-by: Codex:gpt-5.6-terra
Signed-off-by: Peiyang He <peiyang_he@smail.nju.edu.cn>
Link: https://patch.msgid.link/38C8DF0A118B7176+20260811095551.2756745-1-peiyang_he@smail.nju.edu.cn
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[ adapted locking to the older non-PASID selftest device APIs. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/iommu/iommufd/selftest.c |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

--- a/drivers/iommu/iommufd/selftest.c
+++ b/drivers/iommu/iommufd/selftest.c
@@ -139,6 +139,7 @@ enum selftest_obj_type {
 
 struct mock_dev {
 	struct device dev;
+	struct rw_semaphore iopf_rwsem;
 	unsigned long flags;
 	int id;
 };
@@ -702,6 +703,7 @@ static struct mock_dev *mock_dev_create(
 	if (!mdev)
 		return ERR_PTR(-ENOMEM);
 
+	init_rwsem(&mdev->iopf_rwsem);
 	device_initialize(&mdev->dev);
 	mdev->flags = dev_flags;
 	mdev->dev.release = mock_dev_release;
@@ -716,7 +718,9 @@ static struct mock_dev *mock_dev_create(
 	if (rc)
 		goto err_put;
 
+	down_write(&mdev->iopf_rwsem);
 	rc = device_add(&mdev->dev);
+	up_write(&mdev->iopf_rwsem);
 	if (rc)
 		goto err_put;
 	return mdev;
@@ -771,7 +775,9 @@ static int iommufd_test_mock_domain(stru
 	}
 	sobj->idev.idev = idev;
 
+	down_write(&sobj->idev.mock_dev->iopf_rwsem);
 	rc = iommufd_device_attach(idev, &pt_id);
+	up_write(&sobj->idev.mock_dev->iopf_rwsem);
 	if (rc)
 		goto out_unbind;
 
@@ -786,7 +792,9 @@ static int iommufd_test_mock_domain(stru
 	return 0;
 
 out_detach:
+	down_write(&sobj->idev.mock_dev->iopf_rwsem);
 	iommufd_device_detach(idev);
+	up_write(&sobj->idev.mock_dev->iopf_rwsem);
 out_unbind:
 	iommufd_device_unbind(idev);
 out_mdev:
@@ -820,7 +828,9 @@ static int iommufd_test_mock_domain_repl
 		goto out_dev_obj;
 	}
 
+	down_write(&sobj->idev.mock_dev->iopf_rwsem);
 	rc = iommufd_device_replace(sobj->idev.idev, &pt_id);
+	up_write(&sobj->idev.mock_dev->iopf_rwsem);
 	if (rc)
 		goto out_dev_obj;
 
@@ -1418,10 +1428,16 @@ static int iommufd_test_trigger_iopf(str
 {
 	struct iopf_fault event = { };
 	struct iommufd_device *idev;
+	struct mock_dev *mdev;
 
 	idev = iommufd_get_device(ucmd, cmd->trigger_iopf.dev_id);
 	if (IS_ERR(idev))
 		return PTR_ERR(idev);
+	if (!iommufd_selftest_is_mock_dev(idev->dev)) {
+		iommufd_put_object(ucmd->ictx, &idev->obj);
+		return -EINVAL;
+	}
+	mdev = container_of(idev->dev, struct mock_dev, dev);
 
 	event.fault.prm.flags = IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE;
 	if (cmd->trigger_iopf.pasid != IOMMU_NO_PASID)
@@ -1432,7 +1448,9 @@ static int iommufd_test_trigger_iopf(str
 	event.fault.prm.grpid = cmd->trigger_iopf.grpid;
 	event.fault.prm.perm = cmd->trigger_iopf.perm;
 
+	down_read(&mdev->iopf_rwsem);
 	iommu_report_device_fault(idev->dev, &event);
+	up_read(&mdev->iopf_rwsem);
 	iommufd_put_object(ucmd->ictx, &idev->obj);
 
 	return 0;
@@ -1444,7 +1462,9 @@ void iommufd_selftest_destroy(struct iom
 
 	switch (sobj->type) {
 	case TYPE_IDEV:
+		down_write(&sobj->idev.mock_dev->iopf_rwsem);
 		iommufd_device_detach(sobj->idev.idev);
+		up_write(&sobj->idev.mock_dev->iopf_rwsem);
 		iommufd_device_unbind(sobj->idev.idev);
 		mock_dev_destroy(sobj->idev.mock_dev);
 		break;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 579/877] platform/x86: ISST: Check for admin capability for write commands
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (577 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 578/877] iommufd: Fix UAF in selftest IOPF reporting Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 580/877] platform/x86: ISST: Validate max level for set feature Greg Kroah-Hartman
                   ` (305 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Srinivas Pandruvada,
	Ilpo Järvinen, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>

[ Upstream commit 69cd1ca440a96c85dcedcddfa5e0af6012f60b8b ]

In some SST deployments, administrators want to allow reading SST
capabilities for non-root users. This can be achieved by changing file
permissions for "/dev/isst_interface", but they still want to prevent
any changes to the SST configuration by non-root users.

This capability was available before for non-TPMI SST. Extend the same
capability for TPMI SST by adding a check for CAP_SYS_ADMIN for all
write commands.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/20260107060729.1634420-1-srinivas.pandruvada@linux.intel.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Stable-dep-of: e45d6b847286 ("platform/x86: ISST: Validate max level for set feature")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

--- a/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c
+++ b/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c
@@ -620,7 +620,7 @@ static long isst_if_core_power_state(voi
 		return -EINVAL;
 
 	if (core_power.get_set) {
-		if (power_domain_info->write_blocked)
+		if (power_domain_info->write_blocked || !capable(CAP_SYS_ADMIN))
 			return -EPERM;
 
 		if (core_power.enable > SST_CP_MAX_ENABLE ||
@@ -679,7 +679,7 @@ static long isst_if_clos_param(void __us
 		return -EINVAL;
 
 	if (clos_param.get_set) {
-		if (power_domain_info->write_blocked)
+		if (power_domain_info->write_blocked || !capable(CAP_SYS_ADMIN))
 			return -EPERM;
 
 		if (!in_range(clos_param.min_freq_mhz / SST_MUL_FACTOR_FREQ, 0, SST_MAX_FREQ + 1))
@@ -790,7 +790,8 @@ static long isst_if_clos_assoc(void __us
 
 		power_domain_info = &sst_inst->power_domain_info[part][punit_id];
 
-		if (assoc_cmds.get_set && power_domain_info->write_blocked)
+		if (assoc_cmds.get_set && (power_domain_info->write_blocked ||
+					   !capable(CAP_SYS_ADMIN)))
 			return -EPERM;
 
 		offset = SST_CLOS_ASSOC_0_OFFSET +
@@ -968,7 +969,7 @@ static int isst_if_set_perf_level(void _
 	if (!power_domain_info)
 		return -EINVAL;
 
-	if (power_domain_info->write_blocked)
+	if (power_domain_info->write_blocked || !capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
 	if (!(power_domain_info->pp_header.allowed_level_mask & BIT(perf_level.level)))
@@ -1028,7 +1029,7 @@ static int isst_if_set_perf_feature(void
 	if (!power_domain_info)
 		return -EINVAL;
 
-	if (power_domain_info->write_blocked)
+	if (power_domain_info->write_blocked || !capable(CAP_SYS_ADMIN))
 		return -EPERM;
 
 	if (perf_feature.feature & ~SST_PP_FEATURE_STATE_VALID_MASK)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 580/877] platform/x86: ISST: Validate max level for set feature
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (578 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 579/877] platform/x86: ISST: Check for admin capability for write commands Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 581/877] mmc: via-sdmmc: cancel card-detect work on remove Greg Kroah-Hartman
                   ` (304 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Srinivas Pandruvada,
	Ilpo Järvinen, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>

[ Upstream commit e45d6b8472861d3bac86bb37f8556a7c5aca3266 ]

Validate the level before setting, so that it fails early instead of
failing later when checking the bit mask for allowed levels.

Fixes: ea009e4769fa3 ("platform/x86: ISST: Add SST-PP support via TPMI")
Cc: stable@vger.kernel.org
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/20260811221514.3905817-3-srinivas.pandruvada@linux.intel.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c
+++ b/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c
@@ -969,6 +969,9 @@ static int isst_if_set_perf_level(void _
 	if (!power_domain_info)
 		return -EINVAL;
 
+	if (perf_level.level > power_domain_info->max_level)
+		return -EINVAL;
+
 	if (power_domain_info->write_blocked || !capable(CAP_SYS_ADMIN))
 		return -EPERM;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 581/877] mmc: via-sdmmc: cancel card-detect work on remove
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (579 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 580/877] platform/x86: ISST: Validate max level for set feature Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 582/877] PCI: Introduce PCI_SLOT_PLACEHOLDER constant for slot_nr placeholder value Greg Kroah-Hartman
                   ` (303 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Ulf Hansson, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Fan Wu <fanwu01@zju.edu.cn>

[ Upstream commit 57e5d877f898d5e5c9d672a77bb6bdd24f0d9bf5 ]

Disabling the device interrupt and freeing the IRQ prevents new card-detect
work from being queued, but carddet_work already queued by the handler can
still run after via_sd_remove() returns. via_sdc_card_detect() recovers the
host through container_of() and dereferences its MMIO base; once remove()
returns the host can be freed, so that work would touch freed memory.

Cancel carddet_work after freeing the IRQ and before cancelling
finish_bh_work, which the card-detect handler can also queue. carddet_work
can re-enable the interrupt through via_reset_pcictrl(); mask it again
afterwards.

This issue was found by an in-house static analysis tool and confirmed by
manual code review.

Fixes: f0bf7f61b840 ("mmc: Add new via-sdmmc host controller driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
[ adjusted context to retain del_timer_sync() instead of timer_delete_sync(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mmc/host/via-sdmmc.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/drivers/mmc/host/via-sdmmc.c
+++ b/drivers/mmc/host/via-sdmmc.c
@@ -1208,6 +1208,10 @@ static void via_sd_remove(struct pci_dev
 
 	free_irq(pcidev->irq, sdhost);
 
+	cancel_work_sync(&sdhost->carddet_work);
+	/* carddet_work may re-enable the interrupt via via_reset_pcictrl(). */
+	writeb(0x0, sdhost->pcictrl_mmiobase + VIA_CRDR_PCIINTCTRL);
+
 	del_timer_sync(&sdhost->timer);
 
 	cancel_work_sync(&sdhost->finish_bh_work);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 582/877] PCI: Introduce PCI_SLOT_PLACEHOLDER constant for slot_nr placeholder value
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (580 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 581/877] mmc: via-sdmmc: cancel card-detect work on remove Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 583/877] PCI: Allow per function PCI slots to fix slot reset on s390 Greg Kroah-Hartman
                   ` (302 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bjorn Helgaas, Farhan Ali,
	Madhavan Srinivasan, Tyrel Datwyler, linuxppc-dev, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Farhan Ali <alifm@linux.ibm.com>

[ Upstream commit c243e6c470c4695965cc8287767925bc1d9a7867 ]

Introduce a constant for placeholder value and update the kerneldoc for
pci_create_slot() to reference PCI_SLOT_PLACEHOLDER instead of -1
throughout. No functional change.

Suggested-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Tyrel Datwyler <tyreld@linux.ibm.com>
Cc: linuxppc-dev@lists.ozlabs.org
Link: https://patch.msgid.link/20260805165518.794-2-alifm@linux.ibm.com

Stable backport: this tree predates 102c8b26b54e ("PCI: Allow all bus
devices to use the same slot"). Include its PCI_SLOT_ALL_DEVICES definition,
slot-number documentation, and core matching/address handling so that
subsequent commit dcc5bec09e23 ("PCI: Allow per function PCI slots to fix
slot reset on s390") applies without conflicts. Keep the PCIe hotplug
callers unchanged; enabling bus-wide slots there is outside this dependency.

Retain the stable tree's kzalloc() and ATTRIBUTE_GROUPS() implementations.
The placeholder conversion covers both PowerPC hotplug callers and the
PCI core. All code changes stay within existing functions.

Stable-dep-of: dcc5bec09e23 ("PCI: Allow per function PCI slots to fix slot reset on s390")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/pci/hotplug/pnv_php.c     |    2 -
 drivers/pci/hotplug/rpaphp_slot.c |    2 -
 drivers/pci/slot.c                |   50 ++++++++++++++++++++++++++++----------
 include/linux/pci.h               |   13 +++++++++
 4 files changed, 51 insertions(+), 16 deletions(-)

--- a/drivers/pci/hotplug/pnv_php.c
+++ b/drivers/pci/hotplug/pnv_php.c
@@ -800,7 +800,7 @@ static struct pnv_php_slot *pnv_php_allo
 	if (dn->child && PCI_DN(dn->child))
 		php_slot->slot_no = PCI_SLOT(PCI_DN(dn->child)->devfn);
 	else
-		php_slot->slot_no = -1;   /* Placeholder slot */
+		php_slot->slot_no = PCI_SLOT_PLACEHOLDER;   /* Placeholder slot */
 
 	kref_init(&php_slot->kref);
 	php_slot->state	                = PNV_PHP_STATE_INITIALIZED;
--- a/drivers/pci/hotplug/rpaphp_slot.c
+++ b/drivers/pci/hotplug/rpaphp_slot.c
@@ -85,7 +85,7 @@ int rpaphp_register_slot(struct slot *sl
 	struct device_node *child;
 	u32 my_index;
 	int retval;
-	int slotno = -1;
+	int slotno = PCI_SLOT_PLACEHOLDER;
 
 	dbg("%s registering slot:path[%pOF] index[%x], name[%s] pdomain[%x] type[%d]\n",
 		__func__, slot->dn, slot->index, slot->name,
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -38,11 +38,20 @@ static const struct sysfs_ops pci_slot_s
 
 static ssize_t address_read_file(struct pci_slot *slot, char *buf)
 {
-	if (slot->number == 0xff)
+	if (slot->number == PCI_SLOT_PLACEHOLDER)
 		return sysfs_emit(buf, "%04x:%02x\n",
 				  pci_domain_nr(slot->bus),
 				  slot->bus->number);
 
+	/*
+	 * Preserve legacy ABI expectations that hotplug drivers that manage
+	 * multiple devices per slot emit 0 for the device number.
+	 */
+	if (slot->number == PCI_SLOT_ALL_DEVICES)
+		return sysfs_emit(buf, "%04x:%02x:00\n",
+				  pci_domain_nr(slot->bus),
+				  slot->bus->number);
+
 	return sysfs_emit(buf, "%04x:%02x:%02x\n",
 			  pci_domain_nr(slot->bus),
 			  slot->bus->number,
@@ -74,7 +83,8 @@ static void pci_slot_release(struct kobj
 
 	down_read(&pci_bus_sem);
 	list_for_each_entry(dev, &slot->bus->devices, bus_list)
-		if (PCI_SLOT(dev->devfn) == slot->number)
+		if (slot->number == PCI_SLOT_ALL_DEVICES ||
+		    PCI_SLOT(dev->devfn) == slot->number)
 			dev->slot = NULL;
 	up_read(&pci_bus_sem);
 
@@ -167,7 +177,8 @@ void pci_dev_assign_slot(struct pci_dev
 
 	mutex_lock(&pci_slot_mutex);
 	list_for_each_entry(slot, &dev->bus->slots, list)
-		if (PCI_SLOT(dev->devfn) == slot->number)
+		if (slot->number == PCI_SLOT_ALL_DEVICES ||
+		    PCI_SLOT(dev->devfn) == slot->number)
 			dev->slot = slot;
 	mutex_unlock(&pci_slot_mutex);
 }
@@ -189,7 +200,8 @@ static struct pci_slot *get_slot(struct
 /**
  * pci_create_slot - create or increment refcount for physical PCI slot
  * @parent: struct pci_bus of parent bridge
- * @slot_nr: PCI_SLOT(pci_dev->devfn) or -1 for placeholder
+ * @slot_nr: PCI_SLOT(pci_dev->devfn), PCI_SLOT_PLACEHOLDER for placeholder, or
+ *	PCI_SLOT_ALL_DEVICES
  * @name: user visible string presented in /sys/bus/pci/slots/<name>
  * @hotplug: set if caller is hotplug driver, NULL otherwise
  *
@@ -214,15 +226,26 @@ static struct pci_slot *get_slot(struct
  * In most cases, @pci_bus, @slot_nr will be sufficient to uniquely identify
  * a slot. There is one notable exception - pSeries (rpaphp), where the
  * @slot_nr cannot be determined until a device is actually inserted into
- * the slot. In this scenario, the caller may pass -1 for @slot_nr.
+ * the slot. In this scenario, the caller may pass PCI_SLOT_PLACEHOLDER for @slot_nr.
  *
  * The following semantics are imposed when the caller passes @slot_nr ==
- * -1. First, we no longer check for an existing %struct pci_slot, as there
- * may be many slots with @slot_nr of -1.  The other change in semantics is
- * user-visible, which is the 'address' parameter presented in sysfs will
- * consist solely of a dddd:bb tuple, where dddd is the PCI domain of the
- * %struct pci_bus and bb is the bus number. In other words, the devfn of
- * the 'placeholder' slot will not be displayed.
+ * PCI_SLOT_PLACEHOLDER. First, we no longer check for an existing %struct
+ * pci_slot, as there may be many slots with @slot_nr of
+ * PCI_SLOT_PLACEHOLDER. The other change in semantics is user-visible,
+ * which is the 'address' parameter presented in sysfs will consist solely
+ * of a dddd:bb tuple, where dddd is the PCI domain of the %struct pci_bus
+ * and bb is the bus number. In other words, the devfn of the 'placeholder'
+ * slot will not be displayed.
+ *
+ * Bus-wide slots:
+ * For PCIe hotplug, the physical slot encompasses the entire secondary
+ * bus, not just a single device number. If the device supports ARI and ARI
+ * Forwarding is enabled in the upstream bridge, a multi-function device
+ * may include functions that appear to have several different device
+ * numbers, i.e., PCI_SLOT() values.  Pass @slot_nr == PCI_SLOT_ALL_DEVICES
+ * to create a slot that matches all devices on the bus. Unlike placeholder
+ * slots, bus-wide slots go through normal slot lookup and reuse existing
+ * slots if present.
  */
 struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
 				 const char *name,
@@ -235,7 +258,7 @@ struct pci_slot *pci_create_slot(struct
 
 	mutex_lock(&pci_slot_mutex);
 
-	if (slot_nr == -1)
+	if (slot_nr == PCI_SLOT_PLACEHOLDER)
 		goto placeholder;
 
 	/*
@@ -287,7 +310,8 @@ placeholder:
 
 	down_read(&pci_bus_sem);
 	list_for_each_entry(dev, &parent->devices, bus_list)
-		if (PCI_SLOT(dev->devfn) == slot_nr)
+		if (slot_nr == PCI_SLOT_ALL_DEVICES ||
+		    PCI_SLOT(dev->devfn) == slot_nr)
 			dev->slot = slot;
 	up_read(&pci_bus_sem);
 
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -72,12 +72,23 @@
 /* return bus from PCI devid = ((u16)bus_number) << 8) | devfn */
 #define PCI_BUS_NUM(x) (((x) >> 8) & 0xff)
 
+/*
+ * PCI_SLOT_ALL_DEVICES indicates a slot that covers all devices on the bus.
+ * Used for PCIe hotplug where the physical slot is the entire secondary bus,
+ * and, if ARI Forwarding is enabled, functions may appear to be on multiple
+ * devices.
+ */
+#define PCI_SLOT_ALL_DEVICES	0xfe
+
+/* Used to identify a slot as a placeholder */
+#define PCI_SLOT_PLACEHOLDER	0xff
+
 /* pci_slot represents a physical slot */
 struct pci_slot {
 	struct pci_bus		*bus;		/* Bus this slot is on */
 	struct list_head	list;		/* Node in list of slots */
 	struct hotplug_slot	*hotplug;	/* Hotplug info (move here) */
-	unsigned char		number;		/* PCI_SLOT(pci_dev->devfn) */
+	unsigned char		number;		/* Device nr, or PCI_SLOT_ALL_DEVICES */
 	struct kobject		kobj;
 };
 




^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 583/877] PCI: Allow per function PCI slots to fix slot reset on s390
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (581 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 582/877] PCI: Introduce PCI_SLOT_PLACEHOLDER constant for slot_nr placeholder value Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 584/877] platform/x86: think-lmi: Fix current password length check Greg Kroah-Hartman
                   ` (301 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Niklas Schnelle, Farhan Ali,
	Bjorn Helgaas, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Farhan Ali <alifm@linux.ibm.com>

[ Upstream commit dcc5bec09e23bbc4f9de055a11fce9937244f2c8 ]

On s390 systems, which use a machine level hypervisor, PCI devices are
always accessed through a form of PCI pass-through which fundamentally
operates on a per PCI function granularity. This is also reflected in the
s390 PCI hotplug driver which creates hotplug slots for individual PCI
functions. Its reset_slot() function, which is a wrapper for
zpci_hot_reset_device(), thus also resets individual functions.

Currently, the pci_create_slot() assigns the same pci_slot object to
multifunction devices. This approach worked fine on s390 systems that only
exposed virtual functions as individual PCI domains to the operating
system.  Since commit 44510d6fa0c0 ("s390/pci: Handling multifunctions")
s390 supports exposing the topology of multifunction PCI devices by
grouping them in a shared PCI domain. This creates a problem when resetting
a function through the hotplug driver's slot_reset() interface.

When attempting to reset a function through the hotplug driver, the shared
slot assignment causes the wrong function to be reset instead of the
intended one. It also leaks memory as we do create a pci_slot object for
the function, but don't correctly free it in pci_slot_release().

Add a flag for struct pci_slot to allow per function PCI slots for
functions managed through a hypervisor, which exposes individual PCI
functions while retaining the topology. Since we can use all 8 bits for
slot 'number' (for ARI devices), change slot 'number' u16 to account for
special values PCI_SLOT_PLACEHOLDER and PCI_SLOT_ALL_DEVICES.

Fixes: 44510d6fa0c0 ("s390/pci: Handling multifunctions")
Suggested-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Farhan Ali <alifm@linux.ibm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260805165518.794-3-alifm@linux.ibm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/pci/pci.c   |    5 +++--
 drivers/pci/slot.c  |   29 +++++++++++++++++++++++------
 include/linux/pci.h |    7 ++++---
 3 files changed, 30 insertions(+), 11 deletions(-)

--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4919,8 +4919,9 @@ static int pci_reset_hotplug_slot(struct
 
 static int pci_dev_reset_slot_function(struct pci_dev *dev, bool probe)
 {
-	if (dev->multifunction || dev->subordinate || !dev->slot ||
-	    dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET)
+	if (dev->subordinate || !dev->slot ||
+	    dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET ||
+	    (dev->multifunction && !dev->slot->per_func_slot))
 		return -ENOTTY;
 
 	return pci_reset_hotplug_slot(dev->slot->hotplug, probe);
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -73,6 +73,23 @@ static ssize_t cur_speed_read_file(struc
 	return bus_speed_read(slot->bus->cur_bus_speed, buf);
 }
 
+static bool pci_dev_matches_slot(struct pci_dev *dev, struct pci_slot *slot)
+{
+	if (slot->per_func_slot)
+		return dev->devfn == slot->number;
+
+	return slot->number == PCI_SLOT_ALL_DEVICES ||
+		PCI_SLOT(dev->devfn) == slot->number;
+}
+
+static bool pci_slot_enabled_per_func(void)
+{
+	if (IS_ENABLED(CONFIG_S390))
+		return true;
+
+	return false;
+}
+
 static void pci_slot_release(struct kobject *kobj)
 {
 	struct pci_dev *dev;
@@ -83,8 +100,7 @@ static void pci_slot_release(struct kobj
 
 	down_read(&pci_bus_sem);
 	list_for_each_entry(dev, &slot->bus->devices, bus_list)
-		if (slot->number == PCI_SLOT_ALL_DEVICES ||
-		    PCI_SLOT(dev->devfn) == slot->number)
+		if (pci_dev_matches_slot(dev, slot))
 			dev->slot = NULL;
 	up_read(&pci_bus_sem);
 
@@ -177,8 +193,7 @@ void pci_dev_assign_slot(struct pci_dev
 
 	mutex_lock(&pci_slot_mutex);
 	list_for_each_entry(slot, &dev->bus->slots, list)
-		if (slot->number == PCI_SLOT_ALL_DEVICES ||
-		    PCI_SLOT(dev->devfn) == slot->number)
+		if (pci_dev_matches_slot(dev, slot))
 			dev->slot = slot;
 	mutex_unlock(&pci_slot_mutex);
 }
@@ -288,6 +303,9 @@ placeholder:
 	slot->bus = pci_bus_get(parent);
 	slot->number = slot_nr;
 
+	if (pci_slot_enabled_per_func())
+		slot->per_func_slot = 1;
+
 	slot->kobj.kset = pci_slots_kset;
 
 	slot_name = make_slot_name(name);
@@ -310,8 +328,7 @@ placeholder:
 
 	down_read(&pci_bus_sem);
 	list_for_each_entry(dev, &parent->devices, bus_list)
-		if (slot_nr == PCI_SLOT_ALL_DEVICES ||
-		    PCI_SLOT(dev->devfn) == slot_nr)
+		if (pci_dev_matches_slot(dev, slot))
 			dev->slot = slot;
 	up_read(&pci_bus_sem);
 
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -78,17 +78,18 @@
  * and, if ARI Forwarding is enabled, functions may appear to be on multiple
  * devices.
  */
-#define PCI_SLOT_ALL_DEVICES	0xfe
+#define PCI_SLOT_ALL_DEVICES	0xfeff
 
 /* Used to identify a slot as a placeholder */
-#define PCI_SLOT_PLACEHOLDER	0xff
+#define PCI_SLOT_PLACEHOLDER	0xffff
 
 /* pci_slot represents a physical slot */
 struct pci_slot {
 	struct pci_bus		*bus;		/* Bus this slot is on */
 	struct list_head	list;		/* Node in list of slots */
 	struct hotplug_slot	*hotplug;	/* Hotplug info (move here) */
-	unsigned char		number;		/* Device nr, or PCI_SLOT_ALL_DEVICES */
+	u16			number;		/* Device nr, or PCI_SLOT_ALL_DEVICES */
+	unsigned int		per_func_slot:1; /* Allow per function slot */
 	struct kobject		kobj;
 };
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 584/877] platform/x86: think-lmi: Fix current password length check
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (582 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 583/877] PCI: Allow per function PCI slots to fix slot reset on s390 Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 585/877] platform/x86: think-lmi: improve check if BIOS account security enabled Greg Kroah-Hartman
                   ` (300 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mark Pearson, Thorsten Blum,
	Ilpo Järvinen, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Thorsten Blum <thorsten.blum@linux.dev>

[ Upstream commit 54745d563114b74f6fecebce68cd020d06c1772b ]

current_password_store() checks the password length before removing the
trailing newline, which can reject valid passwords that are exactly
->maxlen bytes long.

It also passes ->maxlen to strscpy(), which truncates passwords without
a newline.

Use strchrnul() to measure the password length up to the newline, then
copy that many bytes and add a trailing NUL terminator using strscpy().

Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms")
Cc: stable@vger.kernel.org
Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Link: https://patch.msgid.link/20260818151635.37094-2-thorsten.blum@linux.dev
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/platform/x86/think-lmi.c |    7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

--- a/drivers/platform/x86/think-lmi.c
+++ b/drivers/platform/x86/think-lmi.c
@@ -402,14 +402,13 @@ static ssize_t current_password_store(st
 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
 	size_t pwdlen;
 
-	pwdlen = strlen(buf);
+	/* Strip newline; setting password won't work if one is present. */
+	pwdlen = strchrnul(buf, '\n') - buf;
 	/* pwdlen == 0 is allowed to clear the password */
 	if (pwdlen && ((pwdlen < setting->minlen) || (pwdlen > setting->maxlen)))
 		return -EINVAL;
 
-	strscpy(setting->password, buf, setting->maxlen);
-	/* Strip out CR if one is present, setting password won't work if it is present */
-	strreplace(setting->password, '\n', '\0');
+	strscpy(setting->password, buf, pwdlen + 1);
 	return count;
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 585/877] platform/x86: think-lmi: improve check if BIOS account security enabled
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (583 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 584/877] platform/x86: think-lmi: Fix current password length check Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 586/877] platform/x86: think-lmi: Fix certificate thumbprint sysfs output Greg Kroah-Hartman
                   ` (299 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mark Pearson, Ilpo Järvinen,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mark Pearson <mpearson-lenovo@squebb.ca>

[ Upstream commit b39e8ece931a4b4f64cdf9e75fffd6e82828e471 ]

Improve determination of whether authentication account is enabled by
checking if either password or certificate is enabled.

Renamed valid to pwd_enabled for better readability.

Signed-off-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Link: https://lore.kernel.org/r/20241024195536.6992-1-mpearson-lenovo@squebb.ca
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Stable-dep-of: 4f3183f5ae9b ("platform/x86: think-lmi: Fix certificate thumbprint sysfs output")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/platform/x86/think-lmi.c |   26 +++++++++++++-------------
 drivers/platform/x86/think-lmi.h |    2 +-
 2 files changed, 14 insertions(+), 14 deletions(-)

--- a/drivers/platform/x86/think-lmi.c
+++ b/drivers/platform/x86/think-lmi.c
@@ -390,7 +390,7 @@ static ssize_t is_enabled_show(struct ko
 {
 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
 
-	return sysfs_emit(buf, "%d\n", setting->valid);
+	return sysfs_emit(buf, "%d\n", setting->pwd_enabled || setting->cert_installed);
 }
 
 static struct kobj_attribute auth_is_pass_set = __ATTR_RO(is_enabled);
@@ -467,7 +467,7 @@ static ssize_t new_password_store(struct
 		if (ret)
 			goto out;
 
-		if (tlmi_priv.pwd_admin->valid) {
+		if (tlmi_priv.pwd_admin->pwd_enabled) {
 			ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin",
 					tlmi_priv.pwd_admin->password);
 			if (ret)
@@ -775,7 +775,7 @@ static ssize_t certificate_store(struct
 				new_cert, setting->signature);
 	} else {
 		/* This is a fresh install */
-		if (!setting->valid || !setting->password[0]) {
+		if (!setting->pwd_enabled || !setting->password[0]) {
 			kfree(new_cert);
 			return -EACCES;
 		}
@@ -1018,7 +1018,7 @@ static ssize_t current_value_store(struc
 		 * Workstation's require the opcode to be set before changing the
 		 * attribute.
 		 */
-		if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
+		if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
 			ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin",
 						  tlmi_priv.pwd_admin->password);
 			if (ret)
@@ -1041,7 +1041,7 @@ static ssize_t current_value_store(struc
 		else
 			ret = tlmi_save_bios_settings("");
 	} else { /* old non-opcode based authentication method (deprecated) */
-		if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
+		if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
 			auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
 					tlmi_priv.pwd_admin->password,
 					encoding_options[tlmi_priv.pwd_admin->encoding],
@@ -1217,7 +1217,7 @@ static ssize_t save_settings_store(struc
 			if (ret)
 				goto out;
 		} else if (tlmi_priv.opcode_support) {
-			if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
+			if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
 				ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin",
 							  tlmi_priv.pwd_admin->password);
 				if (ret)
@@ -1225,7 +1225,7 @@ static ssize_t save_settings_store(struc
 			}
 			ret = tlmi_save_bios_settings("");
 		} else { /* old non-opcode based authentication method (deprecated) */
-			if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
+			if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
 				auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
 						     tlmi_priv.pwd_admin->password,
 						     encoding_options[tlmi_priv.pwd_admin->encoding],
@@ -1275,7 +1275,7 @@ static ssize_t debug_cmd_store(struct ko
 	if (!new_setting)
 		return -ENOMEM;
 
-	if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
+	if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
 		auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
 				tlmi_priv.pwd_admin->password,
 				encoding_options[tlmi_priv.pwd_admin->encoding],
@@ -1602,14 +1602,14 @@ static int tlmi_analyze(void)
 		goto fail_clear_attr;
 
 	if (tlmi_priv.pwdcfg.core.password_state & TLMI_PAP_PWD)
-		tlmi_priv.pwd_admin->valid = true;
+		tlmi_priv.pwd_admin->pwd_enabled = true;
 
 	tlmi_priv.pwd_power = tlmi_create_auth("pop", "power-on");
 	if (!tlmi_priv.pwd_power)
 		goto fail_clear_attr;
 
 	if (tlmi_priv.pwdcfg.core.password_state & TLMI_POP_PWD)
-		tlmi_priv.pwd_power->valid = true;
+		tlmi_priv.pwd_power->pwd_enabled = true;
 
 	if (tlmi_priv.opcode_support) {
 		tlmi_priv.pwd_system = tlmi_create_auth("smp", "system");
@@ -1617,7 +1617,7 @@ static int tlmi_analyze(void)
 			goto fail_clear_attr;
 
 		if (tlmi_priv.pwdcfg.core.password_state & TLMI_SMP_PWD)
-			tlmi_priv.pwd_system->valid = true;
+			tlmi_priv.pwd_system->pwd_enabled = true;
 
 		tlmi_priv.pwd_hdd = tlmi_create_auth("hdd", "hdd");
 		if (!tlmi_priv.pwd_hdd)
@@ -1635,7 +1635,7 @@ static int tlmi_analyze(void)
 			/* Check if PWD is configured and set index to first drive found */
 			if (tlmi_priv.pwdcfg.ext.hdd_user_password ||
 					tlmi_priv.pwdcfg.ext.hdd_master_password) {
-				tlmi_priv.pwd_hdd->valid = true;
+				tlmi_priv.pwd_hdd->pwd_enabled = true;
 				if (tlmi_priv.pwdcfg.ext.hdd_master_password)
 					tlmi_priv.pwd_hdd->index =
 						ffs(tlmi_priv.pwdcfg.ext.hdd_master_password) - 1;
@@ -1645,7 +1645,7 @@ static int tlmi_analyze(void)
 			}
 			if (tlmi_priv.pwdcfg.ext.nvme_user_password ||
 					tlmi_priv.pwdcfg.ext.nvme_master_password) {
-				tlmi_priv.pwd_nvme->valid = true;
+				tlmi_priv.pwd_nvme->pwd_enabled = true;
 				if (tlmi_priv.pwdcfg.ext.nvme_master_password)
 					tlmi_priv.pwd_nvme->index =
 						ffs(tlmi_priv.pwdcfg.ext.nvme_master_password) - 1;
--- a/drivers/platform/x86/think-lmi.h
+++ b/drivers/platform/x86/think-lmi.h
@@ -65,7 +65,7 @@ struct tlmi_pwdcfg {
 /* password setting details */
 struct tlmi_pwd_setting {
 	struct kobject kobj;
-	bool valid;
+	bool pwd_enabled;
 	char password[TLMI_PWD_BUFSIZE];
 	const char *pwd_type;
 	const char *role;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 586/877] platform/x86: think-lmi: Fix certificate thumbprint sysfs output
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (584 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 585/877] platform/x86: think-lmi: improve check if BIOS account security enabled Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 587/877] platform/x86: intel_sar: Check ACPI_HANDLE() against NULL Greg Kroah-Hartman
                   ` (298 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Thorsten Blum, Mark Pearson,
	Ilpo Järvinen, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Thorsten Blum <thorsten.blum@linux.dev>

[ Upstream commit 4f3183f5ae9b8ddfe338d79a96146a05342bbe50 ]

cert_thumbprint() already returns the accumulated output length, but
certificate_thumbprint_show() adds that value to count again, making the
next line use the wrong offset. Errors returned by cert_thumbprint() are
also ignored and their negative values added to count.

Assign the total length to count instead and propagate errors correctly.

Fixes: b49f72e7f96d ("platform/x86: think-lmi: Certificate authentication support")
Cc: stable@vger.kernel.org
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Link: https://patch.msgid.link/20260810120556.149416-2-thorsten.blum@linux.dev
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
[ adapted upstream loop changes to the older driver's three direct cert_thumbprint() calls. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/platform/x86/think-lmi.c |   12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

--- a/drivers/platform/x86/think-lmi.c
+++ b/drivers/platform/x86/think-lmi.c
@@ -671,14 +671,18 @@ static ssize_t certificate_thumbprint_sh
 			 char *buf)
 {
 	struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
-	int count = 0;
+	ssize_t count = 0;
 
 	if (!tlmi_priv.certificate_support || !setting->cert_installed)
 		return -EOPNOTSUPP;
 
-	count += cert_thumbprint(buf, "Md5", count);
-	count += cert_thumbprint(buf, "Sha1", count);
-	count += cert_thumbprint(buf, "Sha256", count);
+	count = cert_thumbprint(buf, "Md5", count);
+	if (count < 0)
+		return count;
+	count = cert_thumbprint(buf, "Sha1", count);
+	if (count < 0)
+		return count;
+	count = cert_thumbprint(buf, "Sha256", count);
 	return count;
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 587/877] platform/x86: intel_sar: Check ACPI_HANDLE() against NULL
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (585 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 586/877] platform/x86: think-lmi: Fix certificate thumbprint sysfs output Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:24 ` [PATCH 6.12 588/877] platform/x86: int1092: Fix potential memory leak in sar_probe() Greg Kroah-Hartman
                   ` (297 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Rafael J. Wysocki, Andy Shevchenko,
	Ilpo Järvinen, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

[ Upstream commit 2765f16c12af7c2533763e46b8113b727354012d ]

Every platform driver can be forced to match a device that doesn't match
its list of device IDs because of device_match_driver_override(), so
platform drivers that rely on the existence of a device's ACPI companion
object need to verify its presence.

Accordingly, add a requisite ACPI_HANDLE() check against NULL to the
platform/x86 intel_sar driver.

Fixes: dcfbd31ef4bc ("platform/x86: BIOS SAR driver for Intel M.2 Modem")
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/14023870.uLZWGnKmhe@rafael.j.wysocki
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

For this stable dependency, also convert the existing allocations in
parse_package() and sar_probe() to kmalloc_objs() and kzalloc_obj().
Both helpers are already available in this tree and retain the same
allocation sizes and GFP_KERNEL flags. This makes intel_sar.c match
the parent of 30c906cff490 ("platform/x86: int1092: Fix potential
memory leak in sar_probe()"), allowing that target to apply unchanged.
No new functions or allocation helpers are introduced.

Stable-dep-of: 30c906cff490 ("platform/x86: int1092: Fix potential memory leak in sar_probe()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/platform/x86/intel/int1092/intel_sar.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

--- a/drivers/platform/x86/intel/int1092/intel_sar.c
+++ b/drivers/platform/x86/intel/int1092/intel_sar.c
@@ -91,8 +91,8 @@ static acpi_status parse_package(struct
 	    item->package.count <= data->total_dev_mode)
 		return AE_ERROR;
 
-	data->device_mode_info = kmalloc_array(data->total_dev_mode,
-					       sizeof(struct wwan_device_mode_info), GFP_KERNEL);
+	data->device_mode_info = kmalloc_objs(struct wwan_device_mode_info,
+					      data->total_dev_mode);
 	if (!data->device_mode_info)
 		return AE_ERROR;
 
@@ -245,15 +245,20 @@ static void sar_get_data(int reg, struct
 static int sar_probe(struct platform_device *device)
 {
 	struct wwan_sar_context *context;
+	acpi_handle handle;
 	int reg;
 	int result;
 
-	context = kzalloc(sizeof(*context), GFP_KERNEL);
+	handle = ACPI_HANDLE(&device->dev);
+	if (!handle)
+		return -ENODEV;
+
+	context = kzalloc_obj(*context);
 	if (!context)
 		return -ENOMEM;
 
 	context->sar_device = device;
-	context->handle = ACPI_HANDLE(&device->dev);
+	context->handle = handle;
 	dev_set_drvdata(&device->dev, context);
 
 	result = guid_parse(SAR_DSM_UUID, &context->guid);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 588/877] platform/x86: int1092: Fix potential memory leak in sar_probe()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (586 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 587/877] platform/x86: intel_sar: Check ACPI_HANDLE() against NULL Greg Kroah-Hartman
@ 2026-09-30 15:24 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 589/877] platform/x86/amd/pmc: Move STB block into amd_pmc_s2d_init() Greg Kroah-Hartman
                   ` (296 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:24 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Abdun Nihaal, Ilpo Järvinen,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Abdun Nihaal <nihaal@cse.iitm.ac.in>

[ Upstream commit 30c906cff490c3601ee9ff110fe8115fabe75fd4 ]

The memory allocated for device_mode_info in parse_package() called by
sar_get_data() is not freed in some of the error paths in sar_probe().
Fix that by converting to use device managed allocations.

Fixes: dcfbd31ef4bc ("platform/x86: BIOS SAR driver for Intel M.2 Modem")
Cc: stable@vger.kernel.org
Signed-off-by: Abdun Nihaal <nihaal@cse.iitm.ac.in>
Link: https://patch.msgid.link/20260723-platx86-v4-1-93b4a178b595@cse.iitm.ac.in
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/platform/x86/intel/int1092/intel_sar.c |   32 +++++++------------------
 1 file changed, 10 insertions(+), 22 deletions(-)

--- a/drivers/platform/x86/intel/int1092/intel_sar.c
+++ b/drivers/platform/x86/intel/int1092/intel_sar.c
@@ -91,8 +91,10 @@ static acpi_status parse_package(struct
 	    item->package.count <= data->total_dev_mode)
 		return AE_ERROR;
 
-	data->device_mode_info = kmalloc_objs(struct wwan_device_mode_info,
-					      data->total_dev_mode);
+	data->device_mode_info = devm_kmalloc_array(&context->sar_device->dev,
+						    data->total_dev_mode,
+						    sizeof(*data->device_mode_info),
+						    GFP_KERNEL);
 	if (!data->device_mode_info)
 		return AE_ERROR;
 
@@ -253,7 +255,7 @@ static int sar_probe(struct platform_dev
 	if (!handle)
 		return -ENODEV;
 
-	context = kzalloc_obj(*context);
+	context = devm_kzalloc(&device->dev, sizeof(*context), GFP_KERNEL);
 	if (!context)
 		return -ENOMEM;
 
@@ -264,7 +266,7 @@ static int sar_probe(struct platform_dev
 	result = guid_parse(SAR_DSM_UUID, &context->guid);
 	if (result) {
 		dev_err(&device->dev, "SAR UUID parse error: %d\n", result);
-		goto r_free;
+		return result;
 	}
 
 	for (reg = 0; reg < MAX_REGULATORY; reg++)
@@ -272,43 +274,29 @@ static int sar_probe(struct platform_dev
 
 	if (sar_get_device_mode(device) != AE_OK) {
 		dev_err(&device->dev, "Failed to get device mode\n");
-		result = -EIO;
-		goto r_free;
+		return -EIO;
 	}
 
 	result = sysfs_create_group(&device->dev.kobj, &intcsar_group);
 	if (result) {
 		dev_err(&device->dev, "sysfs creation failed\n");
-		goto r_free;
+		return result;
 	}
 
 	if (acpi_install_notify_handler(ACPI_HANDLE(&device->dev), ACPI_DEVICE_NOTIFY,
 					sar_notify, (void *)device) != AE_OK) {
 		dev_err(&device->dev, "Failed acpi_install_notify_handler\n");
-		result = -EIO;
-		goto r_sys;
+		sysfs_remove_group(&device->dev.kobj, &intcsar_group);
+		return -EIO;
 	}
 	return 0;
-
-r_sys:
-	sysfs_remove_group(&device->dev.kobj, &intcsar_group);
-r_free:
-	kfree(context);
-	return result;
 }
 
 static void sar_remove(struct platform_device *device)
 {
-	struct wwan_sar_context *context = dev_get_drvdata(&device->dev);
-	int reg;
-
 	acpi_remove_notify_handler(ACPI_HANDLE(&device->dev),
 				   ACPI_DEVICE_NOTIFY, sar_notify);
 	sysfs_remove_group(&device->dev.kobj, &intcsar_group);
-	for (reg = 0; reg < MAX_REGULATORY; reg++)
-		kfree(context->config_data[reg].device_mode_info);
-
-	kfree(context);
 }
 
 static struct platform_driver sar_driver = {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 589/877] platform/x86/amd/pmc: Move STB block into amd_pmc_s2d_init()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (587 preceding siblings ...)
  2026-09-30 15:24 ` [PATCH 6.12 588/877] platform/x86: int1092: Fix potential memory leak in sar_probe() Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 590/877] platform/x86/amd/pmc: Move STB functionality to a new file for better code organization Greg Kroah-Hartman
                   ` (295 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mario Limonciello, Sanket Goswami,
	Shyam Sundar S K, Ilpo Järvinen, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>

[ Upstream commit 83ad6974dd3bf34c080b3c08d36d02ebc3bd6da8 ]

Transfer the support for STB-related file operations to the
amd_pmc_s2d_init() function, thereby consolidating the STB and S2D
(Spill to DRAM) functionality in one location. Also, relocate the
call to amd_pmc_s2d_init() to occur after the creation of the
"amd_pmc" debugfs directory. This ensures that the driver's root debugfs
directory is established beforehand.

For older platforms that supported S2D, exit immediately after creating
debugfs. These platforms may not support the PMFW messages available on
newer platforms. This adjustment is necessary due to the relocation of
debugfs creation into amd_pmc_s2d_init().

Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Co-developed-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Link: https://lore.kernel.org/r/20241108070822.3912689-2-Shyam-sundar.S-k@amd.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Stable-dep-of: 9cef693bce96 ("platform/x86/amd/pmc: Restore msg_port on amd_stb_s2d_init() error paths")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/platform/x86/amd/pmc/pmc.c |   31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

--- a/drivers/platform/x86/amd/pmc/pmc.c
+++ b/drivers/platform/x86/amd/pmc/pmc.c
@@ -657,15 +657,6 @@ static void amd_pmc_dbgfs_register(struc
 			    &s0ix_stats_fops);
 	debugfs_create_file("amd_pmc_idlemask", 0644, dev->dbgfs_dir, dev,
 			    &amd_pmc_idlemask_fops);
-	/* Enable STB only when the module_param is set */
-	if (enable_stb) {
-		if (amd_pmc_is_stb_supported(dev))
-			debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
-					    &amd_pmc_stb_debugfs_fops_v2);
-		else
-			debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
-					    &amd_pmc_stb_debugfs_fops);
-	}
 }
 
 static void amd_pmc_dump_registers(struct amd_pmc_dev *dev)
@@ -1069,6 +1060,18 @@ static int amd_pmc_s2d_init(struct amd_p
 	u32 size = 0;
 	int ret;
 
+	if (!enable_stb)
+		return 0;
+
+	if (amd_pmc_is_stb_supported(dev)) {
+		debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
+				    &amd_pmc_stb_debugfs_fops_v2);
+	} else {
+		debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
+				    &amd_pmc_stb_debugfs_fops);
+		return 0;
+	}
+
 	/* Spill to DRAM feature uses separate SMU message port */
 	dev->msg_port = 1;
 
@@ -1187,12 +1190,6 @@ static int amd_pmc_probe(struct platform
 	/* Get num of IP blocks within the SoC */
 	amd_pmc_get_ip_info(dev);
 
-	if (enable_stb && amd_pmc_is_stb_supported(dev)) {
-		err = amd_pmc_s2d_init(dev);
-		if (err)
-			goto err_pci_dev_put;
-	}
-
 	platform_set_drvdata(pdev, dev);
 	if (IS_ENABLED(CONFIG_SUSPEND)) {
 		err = acpi_register_lps0_dev(&amd_pmc_s2idle_dev_ops);
@@ -1203,6 +1200,10 @@ static int amd_pmc_probe(struct platform
 	}
 
 	amd_pmc_dbgfs_register(dev);
+	err = amd_pmc_s2d_init(dev);
+	if (err)
+		goto err_pci_dev_put;
+
 	if (IS_ENABLED(CONFIG_AMD_MP2_STB))
 		amd_mp2_stb_init(dev);
 	pm_report_max_hw_sleep(U64_MAX);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 590/877] platform/x86/amd/pmc: Move STB functionality to a new file for better code organization
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (588 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 589/877] platform/x86/amd/pmc: Move STB block into amd_pmc_s2d_init() Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 591/877] platform/x86/amd/pmc: Define enum for S2D/PMC msg_port and add helper function Greg Kroah-Hartman
                   ` (294 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sanket Goswami, Shyam Sundar S K,
	Ilpo Järvinen, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>

[ Upstream commit 0e914063ddd135407c0550b77a6f5bf779bf8384 ]

As the SoC evolves with each generation, the dynamics between the PMC and
STB layers within the PMC driver are becoming increasingly complex, making
it challenging to manage both in a single file and maintain code
readability.

Additionally, during silicon bringup, the PMC functionality is often
enabled first, with STB functionality added later. This can lead to missed
updates in the driver, potentially causing issues.

To address these challenges, it's beneficial to move all STB-related
changes to a separate file. This approach will better accommodate newer
SoCs, provide improved flexibility for desktop variants, and facilitate
the collection of additional debug information through STB mechanisms.

Also the additional checks for entering s2d_init have been moved from
the PMC probe to amd_pmc_s2d_init(). This adjustment makes more sense
following the transfer of code to the separate mp1_stb.c file.

Co-developed-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Link: https://lore.kernel.org/r/20241108070822.3912689-3-Shyam-sundar.S-k@amd.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

Stable backport adaptation:
Preserve the delay_suspend module parameter and the existing stable PMC
workarounds while moving the STB implementation out of pmc.c.

Rename the existing initializer to amd_stb_s2d_init(), define the two
message-port constants, and move s2d_msg_id into a minimal struct stb_arg.
These are the interfaces needed for 9cef693bce96 to apply unchanged; the
later upstream helper functions and unrelated platform changes are not
needed here. No new functions are introduced.

Retain the existing zero STB physical-address check omitted by the upstream
move, and restore MSG_PORT_PMC before its -EINVAL return. This preserves
the stable validation without leaving an extra mailbox error path outside
the target fix.

Stable-dep-of: 9cef693bce96 ("platform/x86/amd/pmc: Restore msg_port on amd_stb_s2d_init() error paths")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/platform/x86/amd/pmc/Makefile  |    2 
 drivers/platform/x86/amd/pmc/mp1_stb.c |  302 +++++++++++++++++++++++++++++++++
 drivers/platform/x86/amd/pmc/pmc.c     |  285 -------------------------------
 drivers/platform/x86/amd/pmc/pmc.h     |   16 +
 4 files changed, 320 insertions(+), 285 deletions(-)
 create mode 100644 drivers/platform/x86/amd/pmc/mp1_stb.c

--- a/drivers/platform/x86/amd/pmc/Makefile
+++ b/drivers/platform/x86/amd/pmc/Makefile
@@ -4,6 +4,6 @@
 # AMD Power Management Controller Driver
 #
 
-amd-pmc-objs := pmc.o pmc-quirks.o
+amd-pmc-objs := pmc.o pmc-quirks.o mp1_stb.o
 obj-$(CONFIG_AMD_PMC) += amd-pmc.o
 amd-pmc-$(CONFIG_AMD_MP2_STB) += mp2_stb.o
--- /dev/null
+++ b/drivers/platform/x86/amd/pmc/mp1_stb.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * AMD MP1 Smart Trace Buffer (STB) Layer
+ *
+ * Copyright (c) 2024, Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+ *          Sanket Goswami <Sanket.Goswami@amd.com>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <asm/amd_nb.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/uaccess.h>
+
+#include "pmc.h"
+
+/* STB Spill to DRAM Parameters */
+#define S2D_TELEMETRY_DRAMBYTES_MAX	0x1000000
+#define S2D_TELEMETRY_BYTES_MAX		0x100000U
+#define S2D_RSVD_RAM_SPACE		0x100000
+
+/* STB Registers */
+#define AMD_PMC_STB_PMI_0		0x03E30600
+#define AMD_PMC_STB_DUMMY_PC	0xC6000007
+
+/* STB Spill to DRAM Message Definition */
+#define STB_FORCE_FLUSH_DATA		0xCF
+#define FIFO_SIZE		4096
+
+static bool enable_stb;
+module_param(enable_stb, bool, 0644);
+MODULE_PARM_DESC(enable_stb, "Enable the STB debug mechanism");
+
+static bool dump_custom_stb;
+module_param(dump_custom_stb, bool, 0644);
+MODULE_PARM_DESC(dump_custom_stb, "Enable to dump full STB buffer");
+
+enum s2d_arg {
+	S2D_TELEMETRY_SIZE = 0x01,
+	S2D_PHYS_ADDR_LOW,
+	S2D_PHYS_ADDR_HIGH,
+	S2D_NUM_SAMPLES,
+	S2D_DRAM_SIZE,
+};
+
+struct amd_pmc_stb_v2_data {
+	size_t size;
+	u8 data[] __counted_by(size);
+};
+
+int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data)
+{
+	int err;
+
+	err = amd_smn_write(0, AMD_PMC_STB_PMI_0, data);
+	if (err) {
+		dev_err(dev->dev, "failed to write data in stb: 0x%X\n", AMD_PMC_STB_PMI_0);
+		return pcibios_err_to_errno(err);
+	}
+
+	return 0;
+}
+
+int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf)
+{
+	int i, err;
+
+	for (i = 0; i < FIFO_SIZE; i++) {
+		err = amd_smn_read(0, AMD_PMC_STB_PMI_0, buf++);
+		if (err) {
+			dev_err(dev->dev, "error reading data from stb: 0x%X\n", AMD_PMC_STB_PMI_0);
+			return pcibios_err_to_errno(err);
+		}
+	}
+
+	return 0;
+}
+
+static int amd_pmc_stb_debugfs_open(struct inode *inode, struct file *filp)
+{
+	struct amd_pmc_dev *dev = filp->f_inode->i_private;
+	u32 size = FIFO_SIZE * sizeof(u32);
+	u32 *buf;
+	int rc;
+
+	buf = kzalloc(size, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	rc = amd_pmc_read_stb(dev, buf);
+	if (rc) {
+		kfree(buf);
+		return rc;
+	}
+
+	filp->private_data = buf;
+	return rc;
+}
+
+static ssize_t amd_pmc_stb_debugfs_read(struct file *filp, char __user *buf, size_t size,
+					loff_t *pos)
+{
+	if (!filp->private_data)
+		return -EINVAL;
+
+	return simple_read_from_buffer(buf, size, pos, filp->private_data,
+				       FIFO_SIZE * sizeof(u32));
+}
+
+static int amd_pmc_stb_debugfs_release(struct inode *inode, struct file *filp)
+{
+	kfree(filp->private_data);
+	return 0;
+}
+
+static const struct file_operations amd_pmc_stb_debugfs_fops = {
+	.owner = THIS_MODULE,
+	.open = amd_pmc_stb_debugfs_open,
+	.read = amd_pmc_stb_debugfs_read,
+	.release = amd_pmc_stb_debugfs_release,
+};
+
+/* Enhanced STB Firmware Reporting Mechanism */
+static int amd_pmc_stb_handle_efr(struct file *filp)
+{
+	struct amd_pmc_dev *dev = filp->f_inode->i_private;
+	struct amd_pmc_stb_v2_data *stb_data_arr;
+	u32 fsize;
+
+	fsize = dev->dram_size - S2D_RSVD_RAM_SPACE;
+	stb_data_arr = kmalloc(struct_size(stb_data_arr, data, fsize), GFP_KERNEL);
+	if (!stb_data_arr)
+		return -ENOMEM;
+
+	stb_data_arr->size = fsize;
+	memcpy_fromio(stb_data_arr->data, dev->stb_virt_addr, fsize);
+	filp->private_data = stb_data_arr;
+
+	return 0;
+}
+
+static int amd_pmc_stb_debugfs_open_v2(struct inode *inode, struct file *filp)
+{
+	struct amd_pmc_dev *dev = filp->f_inode->i_private;
+	u32 fsize, num_samples, val, stb_rdptr_offset = 0;
+	struct amd_pmc_stb_v2_data *stb_data_arr;
+	int ret;
+
+	/* Write dummy postcode while reading the STB buffer */
+	ret = amd_pmc_write_stb(dev, AMD_PMC_STB_DUMMY_PC);
+	if (ret)
+		dev_err(dev->dev, "error writing to STB: %d\n", ret);
+
+	/* Spill to DRAM num_samples uses separate SMU message port */
+	dev->msg_port = MSG_PORT_S2D;
+
+	ret = amd_pmc_send_cmd(dev, 0, &val, STB_FORCE_FLUSH_DATA, 1);
+	if (ret)
+		dev_dbg_once(dev->dev, "S2D force flush not supported: %d\n", ret);
+
+	/*
+	 * We have a custom stb size and the PMFW is supposed to give
+	 * the enhanced dram size. Note that we land here only for the
+	 * platforms that support enhanced dram size reporting.
+	 */
+	if (dump_custom_stb)
+		return amd_pmc_stb_handle_efr(filp);
+
+	/* Get the num_samples to calculate the last push location */
+	ret = amd_pmc_send_cmd(dev, S2D_NUM_SAMPLES, &num_samples, dev->stb_arg.s2d_msg_id, true);
+	/* Clear msg_port for other SMU operation */
+	dev->msg_port = MSG_PORT_PMC;
+	if (ret) {
+		dev_err(dev->dev, "error: S2D_NUM_SAMPLES not supported : %d\n", ret);
+		return ret;
+	}
+
+	fsize = min(num_samples, S2D_TELEMETRY_BYTES_MAX);
+	stb_data_arr = kmalloc(struct_size(stb_data_arr, data, fsize), GFP_KERNEL);
+	if (!stb_data_arr)
+		return -ENOMEM;
+
+	stb_data_arr->size = fsize;
+
+	/*
+	 * Start capturing data from the last push location.
+	 * This is for general cases, where the stb limits
+	 * are meant for standard usage.
+	 */
+	if (num_samples > S2D_TELEMETRY_BYTES_MAX) {
+		/* First read oldest data starting 1 behind last write till end of ringbuffer */
+		stb_rdptr_offset = num_samples % S2D_TELEMETRY_BYTES_MAX;
+		fsize = S2D_TELEMETRY_BYTES_MAX - stb_rdptr_offset;
+
+		memcpy_fromio(stb_data_arr->data, dev->stb_virt_addr + stb_rdptr_offset, fsize);
+		/* Second copy the newer samples from offset 0 - last write */
+		memcpy_fromio(stb_data_arr->data + fsize, dev->stb_virt_addr, stb_rdptr_offset);
+	} else {
+		memcpy_fromio(stb_data_arr->data, dev->stb_virt_addr, fsize);
+	}
+
+	filp->private_data = stb_data_arr;
+
+	return 0;
+}
+
+static ssize_t amd_pmc_stb_debugfs_read_v2(struct file *filp, char __user *buf, size_t size,
+					   loff_t *pos)
+{
+	struct amd_pmc_stb_v2_data *data = filp->private_data;
+
+	return simple_read_from_buffer(buf, size, pos, data->data, data->size);
+}
+
+static int amd_pmc_stb_debugfs_release_v2(struct inode *inode, struct file *filp)
+{
+	kfree(filp->private_data);
+	return 0;
+}
+
+static const struct file_operations amd_pmc_stb_debugfs_fops_v2 = {
+	.owner = THIS_MODULE,
+	.open = amd_pmc_stb_debugfs_open_v2,
+	.read = amd_pmc_stb_debugfs_read_v2,
+	.release = amd_pmc_stb_debugfs_release_v2,
+};
+
+static bool amd_pmc_is_stb_supported(struct amd_pmc_dev *dev)
+{
+	switch (dev->cpu_id) {
+	case AMD_CPU_ID_YC:
+	case AMD_CPU_ID_CB:
+		dev->stb_arg.s2d_msg_id = 0xBE;
+		return true;
+	case AMD_CPU_ID_PS:
+		dev->stb_arg.s2d_msg_id = 0x85;
+		return true;
+	case PCI_DEVICE_ID_AMD_1AH_M20H_ROOT:
+	case PCI_DEVICE_ID_AMD_1AH_M60H_ROOT:
+		dev->stb_arg.s2d_msg_id = 0xDE;
+		return true;
+	default:
+		return false;
+	}
+}
+
+int amd_stb_s2d_init(struct amd_pmc_dev *dev)
+{
+	u32 phys_addr_low, phys_addr_hi;
+	u64 stb_phys_addr;
+	u32 size = 0;
+	int ret;
+
+	if (!enable_stb)
+		return 0;
+
+	if (amd_pmc_is_stb_supported(dev)) {
+		debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
+				    &amd_pmc_stb_debugfs_fops_v2);
+	} else {
+		debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
+				    &amd_pmc_stb_debugfs_fops);
+		return 0;
+	}
+
+	/* Spill to DRAM feature uses separate SMU message port */
+	dev->msg_port = MSG_PORT_S2D;
+
+	amd_pmc_send_cmd(dev, S2D_TELEMETRY_SIZE, &size, dev->stb_arg.s2d_msg_id, true);
+	if (size != S2D_TELEMETRY_BYTES_MAX)
+		return -EIO;
+
+	/* Get DRAM size */
+	ret = amd_pmc_send_cmd(dev, S2D_DRAM_SIZE, &dev->dram_size, dev->stb_arg.s2d_msg_id, true);
+	if (ret || !dev->dram_size)
+		dev->dram_size = S2D_TELEMETRY_DRAMBYTES_MAX;
+
+	/* Get STB DRAM address */
+	amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_LOW, &phys_addr_low, dev->stb_arg.s2d_msg_id, true);
+	amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_HIGH, &phys_addr_hi, dev->stb_arg.s2d_msg_id, true);
+
+	if (!phys_addr_hi && !phys_addr_low) {
+		dev_err(dev->dev, "STB is not enabled on the system; disable enable_stb or contact system vendor\n");
+		dev->msg_port = MSG_PORT_PMC;
+		return -EINVAL;
+	}
+
+	stb_phys_addr = ((u64)phys_addr_hi << 32 | phys_addr_low);
+
+	/* Clear msg_port for other SMU operation */
+	dev->msg_port = MSG_PORT_PMC;
+
+	dev->stb_virt_addr = devm_ioremap(dev->dev, stb_phys_addr, dev->dram_size);
+	if (!dev->stb_virt_addr)
+		return -ENOMEM;
+
+	return 0;
+}
--- a/drivers/platform/x86/amd/pmc/pmc.c
+++ b/drivers/platform/x86/amd/pmc/pmc.c
@@ -41,25 +41,15 @@
 #define AMD_PMC_SCRATCH_REG_1AH		0xF14
 
 /* STB Registers */
-#define AMD_PMC_STB_PMI_0		0x03E30600
 #define AMD_PMC_STB_S2IDLE_PREPARE	0xC6000001
 #define AMD_PMC_STB_S2IDLE_RESTORE	0xC6000002
 #define AMD_PMC_STB_S2IDLE_CHECK	0xC6000003
-#define AMD_PMC_STB_DUMMY_PC		0xC6000007
 
 /* STB S2D(Spill to DRAM) has different message port offset */
 #define AMD_S2D_REGISTER_MESSAGE	0xA20
 #define AMD_S2D_REGISTER_RESPONSE	0xA80
 #define AMD_S2D_REGISTER_ARGUMENT	0xA88
 
-/* STB Spill to DRAM Parameters */
-#define S2D_TELEMETRY_BYTES_MAX		0x100000U
-#define S2D_RSVD_RAM_SPACE		0x100000
-#define S2D_TELEMETRY_DRAMBYTES_MAX	0x1000000
-
-/* STB Spill to DRAM Message Definition */
-#define STB_FORCE_FLUSH_DATA		0xCF
-
 /* Base address of SMU for mapping physical address to virtual address */
 #define AMD_PMC_MAPPING_SIZE		0x01000
 #define AMD_PMC_BASE_ADDR_OFFSET	0x10000
@@ -98,7 +88,6 @@
 
 #define DELAY_MIN_US		2000
 #define DELAY_MAX_US		3000
-#define FIFO_SIZE		4096
 
 enum amd_pmc_def {
 	MSG_TEST = 0x01,
@@ -106,19 +95,6 @@ enum amd_pmc_def {
 	MSG_OS_HINT_RN,
 };
 
-enum s2d_arg {
-	S2D_TELEMETRY_SIZE = 0x01,
-	S2D_PHYS_ADDR_LOW,
-	S2D_PHYS_ADDR_HIGH,
-	S2D_NUM_SAMPLES,
-	S2D_DRAM_SIZE,
-};
-
-struct amd_pmc_stb_v2_data {
-	size_t size;
-	u8 data[] __counted_by(size);
-};
-
 struct amd_pmc_bit_map {
 	const char *name;
 	u32 bit_mask;
@@ -150,27 +126,16 @@ static const struct amd_pmc_bit_map soc1
 	{}
 };
 
-static bool enable_stb;
-module_param(enable_stb, bool, 0644);
-MODULE_PARM_DESC(enable_stb, "Enable the STB debug mechanism");
-
 static bool disable_workarounds;
 module_param(disable_workarounds, bool, 0644);
 MODULE_PARM_DESC(disable_workarounds, "Disable workarounds for platform bugs");
 
-static bool dump_custom_stb;
-module_param(dump_custom_stb, bool, 0644);
-MODULE_PARM_DESC(dump_custom_stb, "Enable to dump full STB buffer");
-
 static int delay_suspend = -1;
 module_param(delay_suspend, int, 0644);
 MODULE_PARM_DESC(delay_suspend,
 		 "Delays s2idle by 2.5 seconds to work around buggy ECs, often causing keyboard issues after suspend. 0: don't delay, 1: do delay, -1 (default): let amd_pmc decide. If you need this please report this to: platform-driver-x86@vger.kernel.org");
 
 static struct amd_pmc_dev pmc;
-static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret);
-static int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf);
-static int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data);
 
 static inline u32 amd_pmc_reg_read(struct amd_pmc_dev *dev, int reg_offset)
 {
@@ -199,155 +164,6 @@ struct smu_metrics {
 	u64 timecondition_notmet_totaltime[32];
 } __packed;
 
-static int amd_pmc_stb_debugfs_open(struct inode *inode, struct file *filp)
-{
-	struct amd_pmc_dev *dev = filp->f_inode->i_private;
-	u32 size = FIFO_SIZE * sizeof(u32);
-	u32 *buf;
-	int rc;
-
-	buf = kzalloc(size, GFP_KERNEL);
-	if (!buf)
-		return -ENOMEM;
-
-	rc = amd_pmc_read_stb(dev, buf);
-	if (rc) {
-		kfree(buf);
-		return rc;
-	}
-
-	filp->private_data = buf;
-	return rc;
-}
-
-static ssize_t amd_pmc_stb_debugfs_read(struct file *filp, char __user *buf, size_t size,
-					loff_t *pos)
-{
-	if (!filp->private_data)
-		return -EINVAL;
-
-	return simple_read_from_buffer(buf, size, pos, filp->private_data,
-				       FIFO_SIZE * sizeof(u32));
-}
-
-static int amd_pmc_stb_debugfs_release(struct inode *inode, struct file *filp)
-{
-	kfree(filp->private_data);
-	return 0;
-}
-
-static const struct file_operations amd_pmc_stb_debugfs_fops = {
-	.owner = THIS_MODULE,
-	.open = amd_pmc_stb_debugfs_open,
-	.read = amd_pmc_stb_debugfs_read,
-	.release = amd_pmc_stb_debugfs_release,
-};
-
-/* Enhanced STB Firmware Reporting Mechanism */
-static int amd_pmc_stb_handle_efr(struct file *filp)
-{
-	struct amd_pmc_dev *dev = filp->f_inode->i_private;
-	struct amd_pmc_stb_v2_data *stb_data_arr;
-	u32 fsize;
-
-	fsize = dev->dram_size - S2D_RSVD_RAM_SPACE;
-	stb_data_arr = kmalloc(struct_size(stb_data_arr, data, fsize), GFP_KERNEL);
-	if (!stb_data_arr)
-		return -ENOMEM;
-
-	stb_data_arr->size = fsize;
-	memcpy_fromio(stb_data_arr->data, dev->stb_virt_addr, fsize);
-	filp->private_data = stb_data_arr;
-
-	return 0;
-}
-
-static int amd_pmc_stb_debugfs_open_v2(struct inode *inode, struct file *filp)
-{
-	struct amd_pmc_dev *dev = filp->f_inode->i_private;
-	u32 fsize, num_samples, val, stb_rdptr_offset = 0;
-	struct amd_pmc_stb_v2_data *stb_data_arr;
-	int ret;
-
-	/* Write dummy postcode while reading the STB buffer */
-	ret = amd_pmc_write_stb(dev, AMD_PMC_STB_DUMMY_PC);
-	if (ret)
-		dev_err(dev->dev, "error writing to STB: %d\n", ret);
-
-	/* Spill to DRAM num_samples uses separate SMU message port */
-	dev->msg_port = 1;
-
-	ret = amd_pmc_send_cmd(dev, 0, &val, STB_FORCE_FLUSH_DATA, 1);
-	if (ret)
-		dev_dbg_once(dev->dev, "S2D force flush not supported: %d\n", ret);
-
-	/*
-	 * We have a custom stb size and the PMFW is supposed to give
-	 * the enhanced dram size. Note that we land here only for the
-	 * platforms that support enhanced dram size reporting.
-	 */
-	if (dump_custom_stb)
-		return amd_pmc_stb_handle_efr(filp);
-
-	/* Get the num_samples to calculate the last push location */
-	ret = amd_pmc_send_cmd(dev, S2D_NUM_SAMPLES, &num_samples, dev->s2d_msg_id, true);
-	/* Clear msg_port for other SMU operation */
-	dev->msg_port = 0;
-	if (ret) {
-		dev_err(dev->dev, "error: S2D_NUM_SAMPLES not supported : %d\n", ret);
-		return ret;
-	}
-
-	fsize = min(num_samples, S2D_TELEMETRY_BYTES_MAX);
-	stb_data_arr = kmalloc(struct_size(stb_data_arr, data, fsize), GFP_KERNEL);
-	if (!stb_data_arr)
-		return -ENOMEM;
-
-	stb_data_arr->size = fsize;
-
-	/*
-	 * Start capturing data from the last push location.
-	 * This is for general cases, where the stb limits
-	 * are meant for standard usage.
-	 */
-	if (num_samples > S2D_TELEMETRY_BYTES_MAX) {
-		/* First read oldest data starting 1 behind last write till end of ringbuffer */
-		stb_rdptr_offset = num_samples % S2D_TELEMETRY_BYTES_MAX;
-		fsize = S2D_TELEMETRY_BYTES_MAX - stb_rdptr_offset;
-
-		memcpy_fromio(stb_data_arr->data, dev->stb_virt_addr + stb_rdptr_offset, fsize);
-		/* Second copy the newer samples from offset 0 - last write */
-		memcpy_fromio(stb_data_arr->data + fsize, dev->stb_virt_addr, stb_rdptr_offset);
-	} else {
-		memcpy_fromio(stb_data_arr->data, dev->stb_virt_addr, fsize);
-	}
-
-	filp->private_data = stb_data_arr;
-
-	return 0;
-}
-
-static ssize_t amd_pmc_stb_debugfs_read_v2(struct file *filp, char __user *buf, size_t size,
-					   loff_t *pos)
-{
-	struct amd_pmc_stb_v2_data *data = filp->private_data;
-
-	return simple_read_from_buffer(buf, size, pos, data->data, data->size);
-}
-
-static int amd_pmc_stb_debugfs_release_v2(struct inode *inode, struct file *filp)
-{
-	kfree(filp->private_data);
-	return 0;
-}
-
-static const struct file_operations amd_pmc_stb_debugfs_fops_v2 = {
-	.owner = THIS_MODULE,
-	.open = amd_pmc_stb_debugfs_open_v2,
-	.read = amd_pmc_stb_debugfs_read_v2,
-	.release = amd_pmc_stb_debugfs_release_v2,
-};
-
 static void amd_pmc_get_ip_info(struct amd_pmc_dev *dev)
 {
 	switch (dev->cpu_id) {
@@ -357,18 +173,15 @@ static void amd_pmc_get_ip_info(struct a
 	case AMD_CPU_ID_YC:
 	case AMD_CPU_ID_CB:
 		dev->num_ips = 12;
-		dev->s2d_msg_id = 0xBE;
 		dev->smu_msg = 0x538;
 		break;
 	case AMD_CPU_ID_PS:
 		dev->num_ips = 21;
-		dev->s2d_msg_id = 0x85;
 		dev->smu_msg = 0x538;
 		break;
 	case PCI_DEVICE_ID_AMD_1AH_M20H_ROOT:
 	case PCI_DEVICE_ID_AMD_1AH_M60H_ROOT:
 		dev->num_ips = 22;
-		dev->s2d_msg_id = 0xDE;
 		dev->smu_msg = 0x938;
 		break;
 	}
@@ -634,20 +447,6 @@ static void amd_pmc_dbgfs_unregister(str
 	debugfs_remove_recursive(dev->dbgfs_dir);
 }
 
-static bool amd_pmc_is_stb_supported(struct amd_pmc_dev *dev)
-{
-	switch (dev->cpu_id) {
-	case AMD_CPU_ID_YC:
-	case AMD_CPU_ID_CB:
-	case AMD_CPU_ID_PS:
-	case PCI_DEVICE_ID_AMD_1AH_M20H_ROOT:
-	case PCI_DEVICE_ID_AMD_1AH_M60H_ROOT:
-		return true;
-	default:
-		return false;
-	}
-}
-
 static void amd_pmc_dbgfs_register(struct amd_pmc_dev *dev)
 {
 	dev->dbgfs_dir = debugfs_create_dir("amd_pmc", NULL);
@@ -683,7 +482,7 @@ static void amd_pmc_dump_registers(struc
 	dev_dbg(dev->dev, "AMD_%s_REGISTER_MESSAGE:%x\n", dev->msg_port ? "S2D" : "PMC", value);
 }
 
-static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret)
+int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret)
 {
 	int rc;
 	u32 val, message, argument, response;
@@ -1053,86 +852,6 @@ static const struct pci_device_id pmc_pc
 	{ }
 };
 
-static int amd_pmc_s2d_init(struct amd_pmc_dev *dev)
-{
-	u32 phys_addr_low, phys_addr_hi;
-	u64 stb_phys_addr;
-	u32 size = 0;
-	int ret;
-
-	if (!enable_stb)
-		return 0;
-
-	if (amd_pmc_is_stb_supported(dev)) {
-		debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
-				    &amd_pmc_stb_debugfs_fops_v2);
-	} else {
-		debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
-				    &amd_pmc_stb_debugfs_fops);
-		return 0;
-	}
-
-	/* Spill to DRAM feature uses separate SMU message port */
-	dev->msg_port = 1;
-
-	amd_pmc_send_cmd(dev, S2D_TELEMETRY_SIZE, &size, dev->s2d_msg_id, true);
-	if (size != S2D_TELEMETRY_BYTES_MAX)
-		return -EIO;
-
-	/* Get DRAM size */
-	ret = amd_pmc_send_cmd(dev, S2D_DRAM_SIZE, &dev->dram_size, dev->s2d_msg_id, true);
-	if (ret || !dev->dram_size)
-		dev->dram_size = S2D_TELEMETRY_DRAMBYTES_MAX;
-
-	/* Get STB DRAM address */
-	amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_LOW, &phys_addr_low, dev->s2d_msg_id, true);
-	amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_HIGH, &phys_addr_hi, dev->s2d_msg_id, true);
-
-	if (!phys_addr_hi && !phys_addr_low) {
-		dev_err(dev->dev, "STB is not enabled on the system; disable enable_stb or contact system vendor\n");
-		return -EINVAL;
-	}
-
-	stb_phys_addr = ((u64)phys_addr_hi << 32 | phys_addr_low);
-
-	/* Clear msg_port for other SMU operation */
-	dev->msg_port = 0;
-
-	dev->stb_virt_addr = devm_ioremap(dev->dev, stb_phys_addr, dev->dram_size);
-	if (!dev->stb_virt_addr)
-		return -ENOMEM;
-
-	return 0;
-}
-
-static int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data)
-{
-	int err;
-
-	err = amd_smn_write(0, AMD_PMC_STB_PMI_0, data);
-	if (err) {
-		dev_err(dev->dev, "failed to write data in stb: 0x%X\n", AMD_PMC_STB_PMI_0);
-		return pcibios_err_to_errno(err);
-	}
-
-	return 0;
-}
-
-static int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf)
-{
-	int i, err;
-
-	for (i = 0; i < FIFO_SIZE; i++) {
-		err = amd_smn_read(0, AMD_PMC_STB_PMI_0, buf++);
-		if (err) {
-			dev_err(dev->dev, "error reading data from stb: 0x%X\n", AMD_PMC_STB_PMI_0);
-			return pcibios_err_to_errno(err);
-		}
-	}
-
-	return 0;
-}
-
 static int amd_pmc_probe(struct platform_device *pdev)
 {
 	struct amd_pmc_dev *dev = &pmc;
@@ -1200,7 +919,7 @@ static int amd_pmc_probe(struct platform
 	}
 
 	amd_pmc_dbgfs_register(dev);
-	err = amd_pmc_s2d_init(dev);
+	err = amd_stb_s2d_init(dev);
 	if (err)
 		goto err_pci_dev_put;
 
--- a/drivers/platform/x86/amd/pmc/pmc.h
+++ b/drivers/platform/x86/amd/pmc/pmc.h
@@ -14,6 +14,11 @@
 #include <linux/types.h>
 #include <linux/mutex.h>
 
+enum s2d_msg_port {
+	MSG_PORT_PMC,
+	MSG_PORT_S2D,
+};
+
 struct amd_mp2_dev {
 	void __iomem *mmio;
 	void __iomem *vslbase;
@@ -25,6 +30,10 @@ struct amd_mp2_dev {
 	bool is_stb_data;
 };
 
+struct stb_arg {
+	u32 s2d_msg_id;
+};
+
 struct amd_pmc_dev {
 	void __iomem *regbase;
 	void __iomem *smu_virt_addr;
@@ -36,7 +45,6 @@ struct amd_pmc_dev {
 	u32 active_ips;
 	u32 dram_size;
 	u32 num_ips;
-	u32 s2d_msg_id;
 	u32 smu_msg;
 /* SMU version information */
 	u8 smu_program;
@@ -51,6 +59,7 @@ struct amd_pmc_dev {
 	bool disable_8042_wakeup;
 	bool is_first_check_after_suspend;
 	struct amd_mp2_dev *mp2;
+	struct stb_arg stb_arg;
 };
 
 void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev);
@@ -73,4 +82,9 @@ void amd_mp2_stb_deinit(struct amd_pmc_d
 #define PCI_DEVICE_ID_AMD_1AH_M60H_ROOT 0x1122
 #define PCI_DEVICE_ID_AMD_MP2_STB	0x172c
 
+int amd_stb_s2d_init(struct amd_pmc_dev *dev);
+int amd_pmc_read_stb(struct amd_pmc_dev *dev, u32 *buf);
+int amd_pmc_write_stb(struct amd_pmc_dev *dev, u32 data);
+int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret);
+
 #endif /* PMC_H */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 591/877] platform/x86/amd/pmc: Define enum for S2D/PMC msg_port and add helper function
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (589 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 590/877] platform/x86/amd/pmc: Move STB functionality to a new file for better code organization Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 592/877] platform/x86/amd/pmc: Restore msg_port on amd_stb_s2d_init() error paths Greg Kroah-Hartman
                   ` (293 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mario Limonciello, Sanket Goswami,
	Shyam Sundar S K, Ilpo Järvinen, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>

[ Upstream commit 2851f4f8ed4e130d864c5478c6da933a4427ae52 ]

To distinguish between the PMC message port and the S2D (Spill to DRAM)
message port, replace the use of 0 and 1 with an enum.

To avoid printing the S2D or PMC port multiple times in debug print,
add new routine to retrieve the message port information, which can be
used to print the right msg_port getting used.

Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Co-developed-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Link: https://lore.kernel.org/r/20241108070822.3912689-5-Shyam-sundar.S-k@amd.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Stable-dep-of: 9cef693bce96 ("platform/x86/amd/pmc: Restore msg_port on amd_stb_s2d_init() error paths")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/platform/x86/amd/pmc/pmc.c |   22 +++++++++++++++++-----
 drivers/platform/x86/amd/pmc/pmc.h |    2 +-
 2 files changed, 18 insertions(+), 6 deletions(-)

--- a/drivers/platform/x86/amd/pmc/pmc.c
+++ b/drivers/platform/x86/amd/pmc/pmc.c
@@ -458,11 +458,23 @@ static void amd_pmc_dbgfs_register(struc
 			    &amd_pmc_idlemask_fops);
 }
 
+static char *amd_pmc_get_msg_port(struct amd_pmc_dev *dev)
+{
+	switch (dev->msg_port) {
+	case MSG_PORT_PMC:
+		return "PMC";
+	case MSG_PORT_S2D:
+		return "S2D";
+	default:
+		return "Invalid message port";
+	}
+}
+
 static void amd_pmc_dump_registers(struct amd_pmc_dev *dev)
 {
 	u32 value, message, argument, response;
 
-	if (dev->msg_port) {
+	if (dev->msg_port == MSG_PORT_S2D) {
 		message = AMD_S2D_REGISTER_MESSAGE;
 		argument = AMD_S2D_REGISTER_ARGUMENT;
 		response = AMD_S2D_REGISTER_RESPONSE;
@@ -473,13 +485,13 @@ static void amd_pmc_dump_registers(struc
 	}
 
 	value = amd_pmc_reg_read(dev, response);
-	dev_dbg(dev->dev, "AMD_%s_REGISTER_RESPONSE:%x\n", dev->msg_port ? "S2D" : "PMC", value);
+	dev_dbg(dev->dev, "AMD_%s_REGISTER_RESPONSE:%x\n", amd_pmc_get_msg_port(dev), value);
 
 	value = amd_pmc_reg_read(dev, argument);
-	dev_dbg(dev->dev, "AMD_%s_REGISTER_ARGUMENT:%x\n", dev->msg_port ? "S2D" : "PMC", value);
+	dev_dbg(dev->dev, "AMD_%s_REGISTER_ARGUMENT:%x\n", amd_pmc_get_msg_port(dev), value);
 
 	value = amd_pmc_reg_read(dev, message);
-	dev_dbg(dev->dev, "AMD_%s_REGISTER_MESSAGE:%x\n", dev->msg_port ? "S2D" : "PMC", value);
+	dev_dbg(dev->dev, "AMD_%s_REGISTER_MESSAGE:%x\n", amd_pmc_get_msg_port(dev), value);
 }
 
 int amd_pmc_send_cmd(struct amd_pmc_dev *dev, u32 arg, u32 *data, u8 msg, bool ret)
@@ -489,7 +501,7 @@ int amd_pmc_send_cmd(struct amd_pmc_dev
 
 	mutex_lock(&dev->lock);
 
-	if (dev->msg_port) {
+	if (dev->msg_port == MSG_PORT_S2D) {
 		message = AMD_S2D_REGISTER_MESSAGE;
 		argument = AMD_S2D_REGISTER_ARGUMENT;
 		response = AMD_S2D_REGISTER_RESPONSE;
--- a/drivers/platform/x86/amd/pmc/pmc.h
+++ b/drivers/platform/x86/amd/pmc/pmc.h
@@ -39,7 +39,6 @@ struct amd_pmc_dev {
 	void __iomem *smu_virt_addr;
 	void __iomem *stb_virt_addr;
 	void __iomem *fch_virt_addr;
-	bool msg_port;
 	u32 base_addr;
 	u32 cpu_id;
 	u32 active_ips;
@@ -51,6 +50,7 @@ struct amd_pmc_dev {
 	u8 major;
 	u8 minor;
 	u8 rev;
+	u8 msg_port;
 	struct device *dev;
 	struct pci_dev *rdev;
 	struct mutex lock; /* generic mutex lock */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 592/877] platform/x86/amd/pmc: Restore msg_port on amd_stb_s2d_init() error paths
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (590 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 591/877] platform/x86/amd/pmc: Define enum for S2D/PMC msg_port and add helper function Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 593/877] platform/x86/amd/pmc: Propagate SMU errors and validate S2D address Greg Kroah-Hartman
                   ` (292 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mario Limonciello,
	Ilpo Järvinen, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mario Limonciello <mario.limonciello@amd.com>

[ Upstream commit 9cef693bce96bb4c6952f48d855284cf7fa4f367 ]

dev->msg_port is switched to MSG_PORT_S2D before issuing the S2D SMU
commands but is only restored to MSG_PORT_PMC on the success path.  The
early "return -EIO" and "return -ENOMEM" leave the port stuck on
MSG_PORT_S2D, so all subsequent SMU communication - including the s2idle
prepare/restore handlers - is directed at the wrong mailbox.

Consolidate the exit path through a single label so the message port is
always restored.

Fixes: 3d7d407dfb05 ("platform/x86: amd-pmc: Add support for AMD Spill to DRAM STB feature")
Cc: stable@vger.kernel.org
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://patch.msgid.link/20260721181756.143084-2-mario.limonciello@amd.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/platform/x86/amd/pmc/mp1_stb.c |   24 +++++++++++++++---------
 1 file changed, 15 insertions(+), 9 deletions(-)

--- a/drivers/platform/x86/amd/pmc/mp1_stb.c
+++ b/drivers/platform/x86/amd/pmc/mp1_stb.c
@@ -253,7 +253,7 @@ int amd_stb_s2d_init(struct amd_pmc_dev
 	u32 phys_addr_low, phys_addr_hi;
 	u64 stb_phys_addr;
 	u32 size = 0;
-	int ret;
+	int ret = 0;
 
 	if (!enable_stb)
 		return 0;
@@ -271,8 +271,10 @@ int amd_stb_s2d_init(struct amd_pmc_dev
 	dev->msg_port = MSG_PORT_S2D;
 
 	amd_pmc_send_cmd(dev, S2D_TELEMETRY_SIZE, &size, dev->stb_arg.s2d_msg_id, true);
-	if (size != S2D_TELEMETRY_BYTES_MAX)
-		return -EIO;
+	if (size != S2D_TELEMETRY_BYTES_MAX) {
+		ret = -EIO;
+		goto out;
+	}
 
 	/* Get DRAM size */
 	ret = amd_pmc_send_cmd(dev, S2D_DRAM_SIZE, &dev->dram_size, dev->stb_arg.s2d_msg_id, true);
@@ -291,12 +293,16 @@ int amd_stb_s2d_init(struct amd_pmc_dev
 
 	stb_phys_addr = ((u64)phys_addr_hi << 32 | phys_addr_low);
 
-	/* Clear msg_port for other SMU operation */
-	dev->msg_port = MSG_PORT_PMC;
-
 	dev->stb_virt_addr = devm_ioremap(dev->dev, stb_phys_addr, dev->dram_size);
-	if (!dev->stb_virt_addr)
-		return -ENOMEM;
+	if (!dev->stb_virt_addr) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	ret = 0;
 
-	return 0;
+out:
+	/* Restore the default message port for subsequent SMU operations */
+	dev->msg_port = MSG_PORT_PMC;
+	return ret;
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 593/877] platform/x86/amd/pmc: Propagate SMU errors and validate S2D address
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (591 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 592/877] platform/x86/amd/pmc: Restore msg_port on amd_stb_s2d_init() error paths Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 594/877] io_uring/waitid: have io_waitid_complete() remove wait queue entry Greg Kroah-Hartman
                   ` (291 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Francis De Brabandere,
	Mario Limonciello, Ilpo Järvinen, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mario Limonciello <mario.limonciello@amd.com>

[ Upstream commit 0225c1d637687b03726f00ac65b6def843d2c464 ]

amd_stb_s2d_init() discards the return value of several S2D SMU commands.
When the SMU refuses a command (e.g. "SMU cmd failed. err: 0xff") the
failure is only noticed indirectly - if at all - and reported as -EIO,
masking the real error.

More seriously, the S2D_PHYS_ADDR_LOW/HIGH return values are ignored, so
on failure phys_addr_low/hi are left uninitialised and the assembled
address is passed straight to devm_ioremap().  When the SMU leaves them at
zero this maps physical address 0 and trips the ioremap-on-RAM warning:

  amd_pmc AMDI000B:00: SMU cmd failed. err: 0xff
  ioremap on RAM at 0x0000000000000000 - 0x0000000000ffffff
  WARNING: CPU: 13 PID: 4592 at arch/x86/mm/ioremap.c:...

Check the return value of each SMU command and propagate it, and reject a
zero physical address before calling devm_ioremap().

Reported-by: Francis De Brabandere <francisdb@gmail.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221759
Tested-by: Francis De Brabandere <francisdb@gmail.com>
Fixes: 3d7d407dfb05 ("platform/x86: amd-pmc: Add support for AMD Spill to DRAM STB feature")
Cc: stable@vger.kernel.org
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://patch.msgid.link/20260721181756.143084-4-mario.limonciello@amd.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/platform/x86/amd/pmc/mp1_stb.c |   14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

--- a/drivers/platform/x86/amd/pmc/mp1_stb.c
+++ b/drivers/platform/x86/amd/pmc/mp1_stb.c
@@ -270,7 +270,9 @@ int amd_stb_s2d_init(struct amd_pmc_dev
 	/* Spill to DRAM feature uses separate SMU message port */
 	dev->msg_port = MSG_PORT_S2D;
 
-	amd_pmc_send_cmd(dev, S2D_TELEMETRY_SIZE, &size, dev->stb_arg.s2d_msg_id, true);
+	ret = amd_pmc_send_cmd(dev, S2D_TELEMETRY_SIZE, &size, dev->stb_arg.s2d_msg_id, true);
+	if (ret)
+		goto out;
 	if (size != S2D_TELEMETRY_BYTES_MAX) {
 		ret = -EIO;
 		goto out;
@@ -282,8 +284,14 @@ int amd_stb_s2d_init(struct amd_pmc_dev
 		dev->dram_size = S2D_TELEMETRY_DRAMBYTES_MAX;
 
 	/* Get STB DRAM address */
-	amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_LOW, &phys_addr_low, dev->stb_arg.s2d_msg_id, true);
-	amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_HIGH, &phys_addr_hi, dev->stb_arg.s2d_msg_id, true);
+	ret = amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_LOW, &phys_addr_low,
+			       dev->stb_arg.s2d_msg_id, true);
+	if (ret)
+		goto out;
+	ret = amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_HIGH, &phys_addr_hi,
+			       dev->stb_arg.s2d_msg_id, true);
+	if (ret)
+		goto out;
 
 	if (!phys_addr_hi && !phys_addr_low) {
 		dev_err(dev->dev, "STB is not enabled on the system; disable enable_stb or contact system vendor\n");



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 594/877] io_uring/waitid: have io_waitid_complete() remove wait queue entry
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (592 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 593/877] platform/x86/amd/pmc: Propagate SMU errors and validate S2D address Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 595/877] io_uring/waitid: avoid siginfo copy during ring teardown Greg Kroah-Hartman
                   ` (290 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Jens Axboe, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jens Axboe <axboe@kernel.dk>

[ Upstream commit a48c0cbf28c03f6c590a14ceb31bf6e619c2f6da ]

Both callers of this need the entry potentially removed, so shift the
removal into the completion side and kill it from the two callers.

While at it, add a helper for removing the wait_queue_entry based
on the passed in io_kiocb.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
Stable-dep-of: 2cf20c4e0f72 ("io_uring/waitid: avoid siginfo copy during ring teardown")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 io_uring/waitid.c |   26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

--- a/io_uring/waitid.c
+++ b/io_uring/waitid.c
@@ -115,6 +115,22 @@ static int io_waitid_finish(struct io_ki
 	return ret;
 }
 
+static void io_waitid_remove_wq(struct io_kiocb *req)
+{
+	struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
+	struct wait_queue_head *head;
+
+	head = READ_ONCE(iw->head);
+	if (head) {
+		struct io_waitid_async *iwa = req->async_data;
+
+		iw->head = NULL;
+		spin_lock_irq(&head->lock);
+		list_del_init(&iwa->wo.child_wait.entry);
+		spin_unlock_irq(&head->lock);
+	}
+}
+
 static void io_waitid_complete(struct io_kiocb *req, int ret)
 {
 	struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
@@ -125,6 +141,7 @@ static void io_waitid_complete(struct io
 	lockdep_assert_held(&req->ctx->uring_lock);
 
 	hlist_del_init(&req->hash_node);
+	io_waitid_remove_wq(req);
 
 	ret = io_waitid_finish(req, ret);
 	if (ret < 0)
@@ -135,7 +152,8 @@ static void io_waitid_complete(struct io
 static bool __io_waitid_cancel(struct io_ring_ctx *ctx, struct io_kiocb *req)
 {
 	struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
-	struct io_waitid_async *iwa = req->async_data;
+
+	lockdep_assert_held(&req->ctx->uring_lock);
 
 	/*
 	 * Mark us canceled regardless of ownership. This will prevent a
@@ -147,9 +165,6 @@ static bool __io_waitid_cancel(struct io
 	if (atomic_fetch_inc(&iw->refs) & IO_WAITID_REF_MASK)
 		return false;
 
-	spin_lock_irq(&iw->head->lock);
-	list_del_init(&iwa->wo.child_wait.entry);
-	spin_unlock_irq(&iw->head->lock);
 	io_waitid_complete(req, -ECANCELED);
 	io_req_queue_tw_complete(req, -ECANCELED);
 	return true;
@@ -251,8 +266,7 @@ static void io_waitid_cb(struct io_kiocb
 				io_waitid_drop_issue_ref(req);
 				return;
 			}
-
-			remove_wait_queue(iw->head, &iwa->wo.child_wait);
+			/* fall through to complete, will kill waitqueue */
 		}
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 595/877] io_uring/waitid: avoid siginfo copy during ring teardown
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (593 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 594/877] io_uring/waitid: have io_waitid_complete() remove wait queue entry Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 596/877] power: supply: qcom_battmgr: fix use-after-free Greg Kroah-Hartman
                   ` (289 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Hui Su, Jens Axboe, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Hui Su <sh_def@163.com>

[ Upstream commit 2cf20c4e0f72d523b8673053e7120d092ff1f074 ]

During ring teardown, io_ring_exit_work() cancels outstanding requests
from a kworker with a NULL tctx. The waitid cancellation path eventually
reaches io_waitid_finish(), which copies the stored siginfo to the
userspace pointer supplied with the request.

Ring-wide teardown does not run in the task context that submitted the
request, so it must not access that task's userspace pointer. Depending
on the address and mm state, the copy may fail with -EFAULT, but the
uaccess itself is inappropriate from the teardown kworker.

Use a no-copy cancellation callback when io_waitid_remove_all() is
called without an owning task context. Complete the request with
-ECANCELED while releasing the waitid state without touching siginfo.

Keep the existing siginfo handling for explicit async cancellation and
task-scoped cancellation.

Fixes: f31ecf671ddc ("io_uring: add IORING_OP_WAITID support")
Cc: stable@vger.kernel.org
Signed-off-by: Hui Su <sh_def@163.com>
Link: https://patch.msgid.link/20260818103336.1922818-3-sh_def@163.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
[ adapted copy_si handling to older direct cancellation helpers using task instead of tctx. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 io_uring/waitid.c |   18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

--- a/io_uring/waitid.c
+++ b/io_uring/waitid.c
@@ -131,7 +131,7 @@ static void io_waitid_remove_wq(struct i
 	}
 }
 
-static void io_waitid_complete(struct io_kiocb *req, int ret)
+static void io_waitid_complete(struct io_kiocb *req, int ret, bool copy_si)
 {
 	struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
 
@@ -143,13 +143,17 @@ static void io_waitid_complete(struct io
 	hlist_del_init(&req->hash_node);
 	io_waitid_remove_wq(req);
 
-	ret = io_waitid_finish(req, ret);
+	if (copy_si)
+		ret = io_waitid_finish(req, ret);
+	else
+		io_waitid_free(req);
 	if (ret < 0)
 		req_set_fail(req);
 	io_req_set_res(req, ret, 0);
 }
 
-static bool __io_waitid_cancel(struct io_ring_ctx *ctx, struct io_kiocb *req)
+static bool __io_waitid_cancel(struct io_ring_ctx *ctx, struct io_kiocb *req,
+			       bool copy_si)
 {
 	struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
 
@@ -165,7 +169,7 @@ static bool __io_waitid_cancel(struct io
 	if (atomic_fetch_inc(&iw->refs) & IO_WAITID_REF_MASK)
 		return false;
 
-	io_waitid_complete(req, -ECANCELED);
+	io_waitid_complete(req, -ECANCELED, copy_si);
 	io_req_queue_tw_complete(req, -ECANCELED);
 	return true;
 }
@@ -185,7 +189,7 @@ int io_waitid_cancel(struct io_ring_ctx
 		if (req->cqe.user_data != cd->data &&
 		    !(cd->flags & IORING_ASYNC_CANCEL_ANY))
 			continue;
-		if (__io_waitid_cancel(ctx, req))
+		if (__io_waitid_cancel(ctx, req, true))
 			nr++;
 		if (!(cd->flags & IORING_ASYNC_CANCEL_ALL))
 			break;
@@ -211,7 +215,7 @@ bool io_waitid_remove_all(struct io_ring
 		if (!io_match_task_safe(req, task, cancel_all))
 			continue;
 		hlist_del_init(&req->hash_node);
-		__io_waitid_cancel(ctx, req);
+		__io_waitid_cancel(ctx, req, task != NULL);
 		found = true;
 	}
 
@@ -270,7 +274,7 @@ static void io_waitid_cb(struct io_kiocb
 		}
 	}
 
-	io_waitid_complete(req, ret);
+	io_waitid_complete(req, ret, true);
 	io_req_task_complete(req, ts);
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 596/877] power: supply: qcom_battmgr: fix use-after-free
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (594 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 595/877] io_uring/waitid: avoid siginfo copy during ring teardown Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 597/877] net/smc: Address spelling errors Greg Kroah-Hartman
                   ` (288 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Sebastian Reichel,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Fan Wu <fanwu01@zju.edu.cn>

[ Upstream commit 4e40befedfc8ed86f44e1f81df92d13c149c9f8d ]

qcom_battmgr_pdr_notify() queues enable_work when the PMIC GLINK service
comes up, and the worker recovers battmgr through container_of() to issue
firmware requests. The PMIC GLINK client stays on the client list until
its devres release action runs, so a PDR notification can keep queueing
the work, and a pending or running worker can access battmgr after devres
frees it.

Make enable_work device-managed with devm_work_autocancel(), registered
before the PMIC GLINK client is allocated. The devres cleanup then
releases the client first, so no further notification can queue the work,
and cancels the work before battmgr is freed.

This issue was found by an in-house static analysis tool.

Fixes: 29e8142b5623 ("power: supply: Introduce Qualcomm PMIC GLINK power supply")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260731022006.317192-1-fanwu01@zju.edu.cn
Link: https://patch.msgid.link/20260801051923.354496-1-fanwu01@zju.edu.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
[ added the missing int ret declaration in qcom_battmgr_probe() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/power/supply/qcom_battmgr.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

--- a/drivers/power/supply/qcom_battmgr.c
+++ b/drivers/power/supply/qcom_battmgr.c
@@ -4,6 +4,7 @@
  * Copyright (c) 2022, Linaro Ltd
  */
 #include <linux/auxiliary_bus.h>
+#include <linux/devm-helpers.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/of_device.h>
@@ -1335,6 +1336,7 @@ static int qcom_battmgr_probe(struct aux
 	const struct of_device_id *match;
 	struct qcom_battmgr *battmgr;
 	struct device *dev = &adev->dev;
+	int ret;
 
 	battmgr = devm_kzalloc(dev, sizeof(*battmgr), GFP_KERNEL);
 	if (!battmgr)
@@ -1350,7 +1352,6 @@ static int qcom_battmgr_probe(struct aux
 	psy_cfg_supply.supplied_to = qcom_battmgr_battery;
 	psy_cfg_supply.num_supplicants = 1;
 
-	INIT_WORK(&battmgr->enable_work, qcom_battmgr_enable_worker);
 	mutex_init(&battmgr->lock);
 	init_completion(&battmgr->ack);
 
@@ -1397,6 +1398,11 @@ static int qcom_battmgr_probe(struct aux
 					     "failed to register wireless charing power supply\n");
 	}
 
+	ret = devm_work_autocancel(dev, &battmgr->enable_work,
+				   qcom_battmgr_enable_worker);
+	if (ret)
+		return ret;
+
 	battmgr->client = devm_pmic_glink_client_alloc(dev, PMIC_GLINK_OWNER_BATTMGR,
 						       qcom_battmgr_callback,
 						       qcom_battmgr_pdr_notify,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 597/877] net/smc: Address spelling errors
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (595 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 596/877] power: supply: qcom_battmgr: fix use-after-free Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 598/877] net/smc: stop killed, freed and out_of_sync sharing a byte Greg Kroah-Hartman
                   ` (287 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Simon Horman, D. Wythe,
	Guangguan Wang, Randy Dunlap, Wenjia Zhang, Jakub Kicinski,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Simon Horman <horms@kernel.org>

[ Upstream commit cd959bf7c3bbaf64a29750c5e36776078a18a8fe ]

Address spelling errors flagged by codespell.

This patch is intended to cover all files under drivers/smc

Signed-off-by: Simon Horman <horms@kernel.org>
Reviewed-by: D. Wythe <alibuda@linux.alibaba.com>
Reviewed-by: Guangguan Wang <guangguan.wang@linux.alibaba.com>
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
Reviewed-by: Wenjia Zhang <wenjia@linux.ibm.com>
Link: https://patch.msgid.link/20241009-smc-starspell-v1-1-b8b395bbaf82@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: db51a8658c11 ("net/smc: stop killed, freed and out_of_sync sharing a byte")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/smc/smc.h      |    2 +-
 net/smc/smc_clc.h  |    2 +-
 net/smc/smc_core.c |    2 +-
 net/smc/smc_core.h |    4 ++--
 4 files changed, 5 insertions(+), 5 deletions(-)

--- a/net/smc/smc.h
+++ b/net/smc/smc.h
@@ -278,7 +278,7 @@ struct smc_connection {
 						 */
 	u64			peer_token;	/* SMC-D token of peer */
 	u8			killed : 1;	/* abnormal termination */
-	u8			freed : 1;	/* normal termiation */
+	u8			freed : 1;	/* normal termination */
 	u8			out_of_sync : 1; /* out of sync with peer */
 };
 
--- a/net/smc/smc_clc.h
+++ b/net/smc/smc_clc.h
@@ -156,7 +156,7 @@ struct smc_clc_msg_proposal_prefix {	/*
 } __aligned(4);
 
 struct smc_clc_msg_smcd {	/* SMC-D GID information */
-	struct smc_clc_smcd_gid_chid ism; /* ISM native GID+CHID of requestor */
+	struct smc_clc_smcd_gid_chid ism; /* ISM native GID+CHID of requester */
 	__be16 v2_ext_offset;	/* SMC Version 2 Extension Offset */
 	u8 vendor_oui[3];	/* vendor organizationally unique identifier */
 	u8 vendor_exp_options[5];
--- a/net/smc/smc_core.c
+++ b/net/smc/smc_core.c
@@ -2326,7 +2326,7 @@ static struct smc_buf_desc *smcr_new_buf
 		}
 		if (lgr->buf_type == SMCR_PHYS_CONT_BUFS)
 			goto out;
-		fallthrough;	// try virtually continguous buf
+		fallthrough;	// try virtually contiguous buf
 	case SMCR_VIRT_CONT_BUFS:
 		buf_desc->order = get_order(bufsize);
 		buf_desc->cpu_addr = vzalloc(PAGE_SIZE << buf_desc->order);
--- a/net/smc/smc_core.h
+++ b/net/smc/smc_core.h
@@ -30,7 +30,7 @@
 					 */
 #define SMC_CONN_PER_LGR_PREFER	255	/* Preferred connections per link group used for
 					 * SMC-R v2.1 and later negotiation, vendors or
-					 * distrubutions may modify it to a value between
+					 * distributions may modify it to a value between
 					 * 16-255 as needed.
 					 */
 
@@ -181,7 +181,7 @@ struct smc_link {
 					 */
 #define SMC_LINKS_PER_LGR_MAX_PREFER	2	/* Preferred max links per link group used for
 						 * SMC-R v2.1 and later negotiation, vendors or
-						 * distrubutions may modify it to a value between
+						 * distributions may modify it to a value between
 						 * 1-2 as needed.
 						 */
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 598/877] net/smc: stop killed, freed and out_of_sync sharing a byte
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (596 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 597/877] net/smc: Address spelling errors Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 599/877] net/mlx5e: SHAMPO, Always calculate page size Greg Kroah-Hartman
                   ` (286 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mahanta Jambigi, Hidayath Khan,
	Simon Horman, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Hidayath Khan <hidayath@linux.ibm.com>

[ Upstream commit db51a8658c11a82432b64999519a269c3aabb447 ]

The three connection state flags are single-bit bitfields, so they occupy
one byte of struct smc_connection and every store to one is a
read-modify-write of the other two:

    u8  killed : 1;
    u8  freed : 1;
    u8  out_of_sync : 1;

They are not written under a common lock. smc_cdc_msg_validate() sets
out_of_sync from the receive tasklet, while smc_conn_kill() sets killed
from process context under lock_sock(), and the receive path does not defer
to the backlog when the socket is owned -- smc_cdc_msg_recv() takes only
bh_lock_sock().

Give each flag its own byte so a store no longer touches its neighbours.
All readers test them as booleans and are unchanged. struct smc_connection
grows by two bytes.

Fixes: b286a0651e44 ("net/smc: handle incoming CDC validation message")
Cc: stable@vger.kernel.org
Reviewed-by: Mahanta Jambigi <mjambigi@linux.ibm.com>
Signed-off-by: Hidayath Khan <hidayath@linux.ibm.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260820074642.966856-2-hidayath@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/smc/smc.h |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

--- a/net/smc/smc.h
+++ b/net/smc/smc.h
@@ -277,9 +277,9 @@ struct smc_connection {
 						 * 0 for SMC-R, 32 for SMC-D
 						 */
 	u64			peer_token;	/* SMC-D token of peer */
-	u8			killed : 1;	/* abnormal termination */
-	u8			freed : 1;	/* normal termination */
-	u8			out_of_sync : 1; /* out of sync with peer */
+	u8			killed;		/* abnormal termination */
+	u8			freed;		/* normal termination */
+	u8			out_of_sync;	/* out of sync with peer */
 };
 
 struct smc_sock {				/* smc sock container */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 599/877] net/mlx5e: SHAMPO, Always calculate page size
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (597 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 598/877] net/smc: stop killed, freed and out_of_sync sharing a byte Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 600/877] net/mlx5e: do not HW-GRO coalesce small frames Greg Kroah-Hartman
                   ` (285 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Dragos Tatulea, Cosmin Ratiu,
	Tariq Toukan, Paolo Abeni, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dragos Tatulea <dtatulea@nvidia.com>

[ Upstream commit dff1c3164a69284ac9fedb1c25d4c008139e9fb8 ]

Adapt the rx path in SHAMPO mode to calculate page size based on
configured page_shift when dealing with payload data.

This is necessary as an upcoming patch will add support for using
different page sizes.

This change has no functional changes.

Signed-off-by: Dragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260223204155.1783580-9-tariqt@nvidia.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Stable-dep-of: e2466392a0b8 ("net/mlx5e: do not HW-GRO coalesce small frames")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/mellanox/mlx5/core/en_rx.c |   34 +++++++++++++++---------
 1 file changed, 22 insertions(+), 12 deletions(-)

--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -1983,11 +1983,14 @@ mlx5e_shampo_fill_skb_data(struct sk_buf
 			   struct mlx5e_frag_page *frag_page,
 			   u32 data_bcnt, u32 data_offset)
 {
+	u32 page_size = BIT(rq->mpwqe.page_shift);
+
 	net_prefetchw(skb->data);
 
 	do {
 		/* Non-linear mode, hence non-XSK, which always uses PAGE_SIZE. */
-		u32 pg_consumed_bytes = min_t(u32, PAGE_SIZE - data_offset, data_bcnt);
+		u32 pg_consumed_bytes = min_t(u32, page_size - data_offset,
+					      data_bcnt);
 		unsigned int truesize = pg_consumed_bytes;
 
 		mlx5e_add_skb_frag(rq, skb, frag_page, data_offset,
@@ -2008,6 +2011,7 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struc
 	u16 headlen = min_t(u16, MLX5E_RX_MAX_HEAD, cqe_bcnt);
 	struct mlx5e_frag_page *head_page = frag_page;
 	struct mlx5e_xdp_buff *mxbuf = &rq->mxbuf;
+	u32 page_size = BIT(rq->mpwqe.page_shift);
 	u32 frag_offset    = head_offset;
 	u32 byte_cnt       = cqe_bcnt;
 	struct skb_shared_info *sinfo;
@@ -2051,9 +2055,9 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struc
 		linear_hr = skb_headroom(skb);
 		linear_data_len = headlen;
 		linear_frame_sz = MLX5_SKB_FRAG_SZ(skb_end_offset(skb));
-		if (unlikely(frag_offset >= PAGE_SIZE)) {
+		if (unlikely(frag_offset >= page_size)) {
 			frag_page++;
-			frag_offset -= PAGE_SIZE;
+			frag_offset -= page_size;
 		}
 	}
 
@@ -2065,7 +2069,7 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struc
 	while (byte_cnt) {
 		/* Non-linear mode, hence non-XSK, which always uses PAGE_SIZE. */
 		pg_consumed_bytes =
-			min_t(u32, PAGE_SIZE - frag_offset, byte_cnt);
+			min_t(u32, page_size - frag_offset, byte_cnt);
 
 		if (test_bit(MLX5E_RQ_STATE_SHAMPO, &rq->state))
 			truesize += pg_consumed_bytes;
@@ -2102,7 +2106,7 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struc
 		nr_frags_free = old_nr_frags - sinfo->nr_frags;
 		if (unlikely(nr_frags_free)) {
 			frag_page -= nr_frags_free;
-			truesize -= (nr_frags_free - 1) * PAGE_SIZE +
+			truesize -= (nr_frags_free - 1) * page_size +
 				ALIGN(pg_consumed_bytes,
 				      BIT(rq->mpwqe.log_stride_sz));
 		}
@@ -2311,15 +2315,16 @@ mlx5e_shampo_flush_skb(struct mlx5e_rq *
 	rq->hw_gro_data->skb = NULL;
 }
 
-static bool
-mlx5e_hw_gro_skb_has_enough_space(struct sk_buff *skb, u16 data_bcnt)
+static bool mlx5e_hw_gro_skb_has_enough_space(struct sk_buff *skb,
+					      u16 data_bcnt,
+					      u32 page_size)
 {
 	int nr_frags = skb_shinfo(skb)->nr_frags;
 
-	if (PAGE_SIZE >= GRO_LEGACY_MAX_SIZE)
+	if (page_size >= GRO_LEGACY_MAX_SIZE)
 		return skb->len + data_bcnt <= GRO_LEGACY_MAX_SIZE;
 	else
-		return PAGE_SIZE * nr_frags + data_bcnt <= GRO_LEGACY_MAX_SIZE;
+		return page_size * nr_frags + data_bcnt <= GRO_LEGACY_MAX_SIZE;
 }
 
 static void mlx5e_handle_rx_cqe_mpwrq_shampo(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe)
@@ -2328,18 +2333,19 @@ static void mlx5e_handle_rx_cqe_mpwrq_sh
 	u16 header_index	= mlx5e_shampo_get_cqe_header_index(rq, cqe);
 	u32 wqe_offset		= be32_to_cpu(cqe->shampo.data_offset);
 	u16 cstrides		= mpwrq_get_cqe_consumed_strides(cqe);
-	u32 data_offset		= wqe_offset & (PAGE_SIZE - 1);
 	u32 cqe_bcnt		= mpwrq_get_cqe_byte_cnt(cqe);
 	u16 wqe_id		= be16_to_cpu(cqe->wqe_id);
-	u32 page_idx		= wqe_offset >> PAGE_SHIFT;
 	u16 head_size		= cqe->shampo.header_size;
 	struct sk_buff **skb	= &rq->hw_gro_data->skb;
 	bool flush		= cqe->shampo.flush;
 	bool match		= cqe->shampo.match;
+	u32 page_size = BIT(rq->mpwqe.page_shift);
 	struct mlx5e_rq_stats *stats = rq->stats;
 	struct mlx5e_rx_wqe_ll *wqe;
 	struct mlx5e_mpw_info *wi;
 	struct mlx5_wq_ll *wq;
+	u32 data_offset;
+	u32 page_idx;
 
 	wi = mlx5e_get_mpw_info(rq, wqe_id);
 	wi->consumed_strides += cstrides;
@@ -2355,7 +2361,11 @@ static void mlx5e_handle_rx_cqe_mpwrq_sh
 		goto mpwrq_cqe_out;
 	}
 
-	if (*skb && (!match || !(mlx5e_hw_gro_skb_has_enough_space(*skb, data_bcnt)))) {
+	data_offset = wqe_offset & (page_size - 1);
+	page_idx = wqe_offset >> rq->mpwqe.page_shift;
+	if (*skb &&
+	    !(match && mlx5e_hw_gro_skb_has_enough_space(*skb, data_bcnt,
+							 page_size))) {
 		match = false;
 		mlx5e_shampo_flush_skb(rq, cqe, match);
 	}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 600/877] net/mlx5e: do not HW-GRO coalesce small frames
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (598 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 599/877] net/mlx5e: SHAMPO, Always calculate page size Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 601/877] ALSA: hda/ext: preserve PPLCCTL bits when clearing reset Greg Kroah-Hartman
                   ` (284 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Glenn Judd, Tariq Toukan,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Glenn Judd <gmj@meta.com>

[ Upstream commit e2466392a0b8496000e12181cb1ee1535eb0da25 ]

When hardware GRO (SHAMPO) coalesces a small IPv4/TCP segment that was
padded up to the 60-byte minimum Ethernet frame, the trailing padding is
folded into the merged payload causing padding to be delivered
to the user as payload.

Detecting and reproducing the issue: the selftest
tools/testing/selftests/drivers/net/gro.py subtest
hw_ipv4_data_lrg_1byte sends {100, 1} expecting to receive {101}.
In current code, it receives {106} (100 + 1 payload + 5 pad) instead.

This patch avoids giving the user padding as payload by simply not
coalescing small packets (which fails the subtest; the same approach
and behavior as sw gro). This gains code simplicity at the cost of
more computation (passing an extra skb up the stack) for small packets
that could be coalesced.

The threshold is chosen as ETH_ZLEN + 2 * VLAN_HLEN. This is the largest
frame that may still contain minimum-frame padding (+ 2 VLAN tags), so
anything larger is safe to consider for coalesce. (We do not include
ETH_FCS_LEN in that threshold computation as netdev_fix_features()
drops NETIF_F_GRO_HW whenever NETIF_F_RXFCS is set, so retained FCS
can't reach this path.)

Fixes: 92552d3abd32 ("net/mlx5e: HW_GRO cqe handler implementation")
Cc: stable@vger.kernel.org
Signed-off-by: Glenn Judd <gmj@meta.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260816064259.3279548-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/mellanox/mlx5/core/en_rx.c |    5 +++++
 1 file changed, 5 insertions(+)

--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
@@ -2363,6 +2363,11 @@ static void mlx5e_handle_rx_cqe_mpwrq_sh
 
 	data_offset = wqe_offset & (page_size - 1);
 	page_idx = wqe_offset >> rq->mpwqe.page_shift;
+	if (unlikely(cqe_bcnt <= ETH_ZLEN + 2 * VLAN_HLEN)) {
+		match = false;
+		flush = true;
+	}
+
 	if (*skb &&
 	    !(match && mlx5e_hw_gro_skb_has_enough_space(*skb, data_bcnt,
 							 page_size))) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 601/877] ALSA: hda/ext: preserve PPLCCTL bits when clearing reset
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (599 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 600/877] net/mlx5e: do not HW-GRO coalesce small frames Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 602/877] hwrng: drivers - Switch back to struct platform_driver::remove() Greg Kroah-Hartman
                   ` (283 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Xu Rao, Takashi Iwai, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Xu Rao <raoxu@uniontech.com>

[ Upstream commit 36aa66de481d29edd63cbad9b5c4dc18c340fdf6 ]

snd_hdac_ext_stream_reset() polls PPLCCTL for STRST by masking the
register value with AZX_PPLCCTL_STRST:

	val = readl(...) & AZX_PPLCCTL_STRST;

The same masked value is then used when clearing STRST. Since val
contains no bits other than STRST, clearing STRST from it always
produces zero. The subsequent writel() therefore writes zero to the
entire PPLCCTL register instead of clearing only the reset bit.

PPLCCTL contains other stream control fields, including the stream tag
in AZX_PPLCCTL_STRM_MASK. Those fields must not be modified as a side
effect of clearing stream reset.

Use snd_hdac_updatel() to clear STRST, matching the existing set-reset
path and preserving all unrelated PPLCCTL bits.

Fixes: df203a4e46f4 ("ALSA: hdac_ext: add extended stream capabilities")
Cc: stable@vger.kernel.org
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Link: https://patch.msgid.link/43BB7930B0F07C09+20260813065524.1955696-1-raoxu@uniontech.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 sound/hda/ext/hdac_ext_stream.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/sound/hda/ext/hdac_ext_stream.c
+++ b/sound/hda/ext/hdac_ext_stream.c
@@ -212,8 +212,8 @@ void snd_hdac_ext_stream_reset(struct hd
 			break;
 		udelay(3);
 	} while (--timeout);
-	val &= ~AZX_PPLCCTL_STRST;
-	writel(val, hext_stream->pplc_addr + AZX_REG_PPLCCTL);
+	snd_hdac_updatel(hext_stream->pplc_addr, AZX_REG_PPLCCTL,
+			 AZX_PPLCCTL_STRST, 0);
 	udelay(3);
 
 	timeout = 50;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 602/877] hwrng: drivers - Switch back to struct platform_driver::remove()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (600 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 601/877] ALSA: hda/ext: preserve PPLCCTL bits when clearing reset Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 603/877] hwrng: stm32 - Fix runtime PM cleanup on registration failure Greg Kroah-Hartman
                   ` (282 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Uwe Kleine-König, Herbert Xu,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Uwe Kleine-König <u.kleine-koenig@baylibre.com>

[ Upstream commit d11c8b87a36267a2861b9010ce0393de8ff3d278 ]

After commit 0edb555a65d1 ("platform: Make platform_driver::remove()
return void") .remove() is (again) the right callback to implement for
platform drivers.

Convert all platform drivers below drivers/char/hw_random to use
.remove(), with the eventual goal to drop struct
platform_driver::remove_new(). As .remove() and .remove_new() have the
same prototypes, conversion is done by just changing the structure
member name in the driver initializer.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Stable-dep-of: 1163a476a568 ("hwrng: stm32 - Fix runtime PM cleanup on registration failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/char/hw_random/atmel-rng.c      |    2 +-
 drivers/char/hw_random/cctrng.c         |    2 +-
 drivers/char/hw_random/exynos-trng.c    |    2 +-
 drivers/char/hw_random/ingenic-rng.c    |    2 +-
 drivers/char/hw_random/ks-sa-rng.c      |    2 +-
 drivers/char/hw_random/mxc-rnga.c       |    2 +-
 drivers/char/hw_random/n2-drv.c         |    2 +-
 drivers/char/hw_random/npcm-rng.c       |    2 +-
 drivers/char/hw_random/omap-rng.c       |    2 +-
 drivers/char/hw_random/stm32-rng.c      |    2 +-
 drivers/char/hw_random/timeriomem-rng.c |    2 +-
 drivers/char/hw_random/xgene-rng.c      |    2 +-
 12 files changed, 12 insertions(+), 12 deletions(-)

--- a/drivers/char/hw_random/atmel-rng.c
+++ b/drivers/char/hw_random/atmel-rng.c
@@ -216,7 +216,7 @@ MODULE_DEVICE_TABLE(of, atmel_trng_dt_id
 
 static struct platform_driver atmel_trng_driver = {
 	.probe		= atmel_trng_probe,
-	.remove_new	= atmel_trng_remove,
+	.remove		= atmel_trng_remove,
 	.driver		= {
 		.name	= "atmel-trng",
 		.pm	= pm_ptr(&atmel_trng_pm_ops),
--- a/drivers/char/hw_random/cctrng.c
+++ b/drivers/char/hw_random/cctrng.c
@@ -653,7 +653,7 @@ static struct platform_driver cctrng_dri
 		.pm = &cctrng_pm,
 	},
 	.probe = cctrng_probe,
-	.remove_new = cctrng_remove,
+	.remove = cctrng_remove,
 };
 
 module_platform_driver(cctrng_driver);
--- a/drivers/char/hw_random/exynos-trng.c
+++ b/drivers/char/hw_random/exynos-trng.c
@@ -335,7 +335,7 @@ static struct platform_driver exynos_trn
 		.of_match_table = exynos_trng_dt_match,
 	},
 	.probe = exynos_trng_probe,
-	.remove_new = exynos_trng_remove,
+	.remove = exynos_trng_remove,
 };
 
 module_platform_driver(exynos_trng_driver);
--- a/drivers/char/hw_random/ingenic-rng.c
+++ b/drivers/char/hw_random/ingenic-rng.c
@@ -132,7 +132,7 @@ MODULE_DEVICE_TABLE(of, ingenic_rng_of_m
 
 static struct platform_driver ingenic_rng_driver = {
 	.probe		= ingenic_rng_probe,
-	.remove_new	= ingenic_rng_remove,
+	.remove		= ingenic_rng_remove,
 	.driver		= {
 		.name	= "ingenic-rng",
 		.of_match_table = ingenic_rng_of_match,
--- a/drivers/char/hw_random/ks-sa-rng.c
+++ b/drivers/char/hw_random/ks-sa-rng.c
@@ -272,7 +272,7 @@ static struct platform_driver ks_sa_rng_
 		.of_match_table = ks_sa_rng_dt_match,
 	},
 	.probe		= ks_sa_rng_probe,
-	.remove_new	= ks_sa_rng_remove,
+	.remove		= ks_sa_rng_remove,
 };
 
 module_platform_driver(ks_sa_rng_driver);
--- a/drivers/char/hw_random/mxc-rnga.c
+++ b/drivers/char/hw_random/mxc-rnga.c
@@ -188,7 +188,7 @@ static struct platform_driver mxc_rnga_d
 		.of_match_table = mxc_rnga_of_match,
 	},
 	.probe = mxc_rnga_probe,
-	.remove_new = mxc_rnga_remove,
+	.remove = mxc_rnga_remove,
 };
 
 module_platform_driver(mxc_rnga_driver);
--- a/drivers/char/hw_random/n2-drv.c
+++ b/drivers/char/hw_random/n2-drv.c
@@ -858,7 +858,7 @@ static struct platform_driver n2rng_driv
 		.of_match_table = n2rng_match,
 	},
 	.probe		= n2rng_probe,
-	.remove_new	= n2rng_remove,
+	.remove		= n2rng_remove,
 };
 
 module_platform_driver(n2rng_driver);
--- a/drivers/char/hw_random/npcm-rng.c
+++ b/drivers/char/hw_random/npcm-rng.c
@@ -176,7 +176,7 @@ static struct platform_driver npcm_rng_d
 		.of_match_table = of_match_ptr(rng_dt_id),
 	},
 	.probe		= npcm_rng_probe,
-	.remove_new	= npcm_rng_remove,
+	.remove		= npcm_rng_remove,
 };
 
 module_platform_driver(npcm_rng_driver);
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -558,7 +558,7 @@ static struct platform_driver omap_rng_d
 		.of_match_table = of_match_ptr(omap_rng_of_match),
 	},
 	.probe		= omap_rng_probe,
-	.remove_new	= omap_rng_remove,
+	.remove		= omap_rng_remove,
 };
 
 module_platform_driver(omap_rng_driver);
--- a/drivers/char/hw_random/stm32-rng.c
+++ b/drivers/char/hw_random/stm32-rng.c
@@ -565,7 +565,7 @@ static struct platform_driver stm32_rng_
 		.of_match_table = stm32_rng_match,
 	},
 	.probe = stm32_rng_probe,
-	.remove_new = stm32_rng_remove,
+	.remove = stm32_rng_remove,
 };
 
 module_platform_driver(stm32_rng_driver);
--- a/drivers/char/hw_random/timeriomem-rng.c
+++ b/drivers/char/hw_random/timeriomem-rng.c
@@ -193,7 +193,7 @@ static struct platform_driver timeriomem
 		.of_match_table	= timeriomem_rng_match,
 	},
 	.probe		= timeriomem_rng_probe,
-	.remove_new	= timeriomem_rng_remove,
+	.remove		= timeriomem_rng_remove,
 };
 
 module_platform_driver(timeriomem_rng_driver);
--- a/drivers/char/hw_random/xgene-rng.c
+++ b/drivers/char/hw_random/xgene-rng.c
@@ -375,7 +375,7 @@ MODULE_DEVICE_TABLE(of, xgene_rng_of_mat
 
 static struct platform_driver xgene_rng_driver = {
 	.probe = xgene_rng_probe,
-	.remove_new = xgene_rng_remove,
+	.remove = xgene_rng_remove,
 	.driver = {
 		.name		= "xgene-rng",
 		.of_match_table = xgene_rng_of_match,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 603/877] hwrng: stm32 - Fix runtime PM cleanup on registration failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (601 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 602/877] hwrng: drivers - Switch back to struct platform_driver::remove() Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 604/877] i3c: master: Do not treat master device as a duplicate target Greg Kroah-Hartman
                   ` (281 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Can Peng, Linus Walleij, Herbert Xu,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Can Peng <pengcan@kylinos.cn>

[ Upstream commit 1163a476a568f6c0f852d469c8e4c5a5f805adac ]

stm32_rng_probe() enables autosuspend and runtime PM before registering the
hwrng. If devm_hwrng_register() fails, probe returns with runtime PM left
enabled and autosuspend still selected.

The remove callback also only disables runtime PM and does not undo
pm_runtime_use_autosuspend().

Use devm_pm_runtime_enable() so runtime PM is unwound automatically on
probe failure and driver detach. Since the managed cleanup also disables
runtime PM,drop the remove callback.

Fixes: c6a97c42e399 ("hwrng: stm32 - add support for STM32 HW RNG")
Cc: stable@vger.kernel.org
Signed-off-by: Can Peng <pengcan@kylinos.cn>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
[ added the missing int ret declaration in stm32_rng_probe(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/char/hw_random/stm32-rng.c |   11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

--- a/drivers/char/hw_random/stm32-rng.c
+++ b/drivers/char/hw_random/stm32-rng.c
@@ -366,11 +366,6 @@ static int stm32_rng_init(struct hwrng *
 	return 0;
 }
 
-static void stm32_rng_remove(struct platform_device *ofdev)
-{
-	pm_runtime_disable(&ofdev->dev);
-}
-
 static int __maybe_unused stm32_rng_runtime_suspend(struct device *dev)
 {
 	struct stm32_rng_private *priv = dev_get_drvdata(dev);
@@ -516,6 +511,7 @@ static int stm32_rng_probe(struct platfo
 	struct device_node *np = ofdev->dev.of_node;
 	struct stm32_rng_private *priv;
 	struct resource *res;
+	int ret;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
@@ -553,7 +549,9 @@ static int stm32_rng_probe(struct platfo
 
 	pm_runtime_set_autosuspend_delay(dev, 100);
 	pm_runtime_use_autosuspend(dev);
-	pm_runtime_enable(dev);
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
 
 	return devm_hwrng_register(dev, &priv->rng);
 }
@@ -565,7 +563,6 @@ static struct platform_driver stm32_rng_
 		.of_match_table = stm32_rng_match,
 	},
 	.probe = stm32_rng_probe,
-	.remove = stm32_rng_remove,
 };
 
 module_platform_driver(stm32_rng_driver);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 604/877] i3c: master: Do not treat master device as a duplicate target
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (602 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 603/877] hwrng: stm32 - Fix runtime PM cleanup on registration failure Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 605/877] wifi: mt76: mt7915: set correct background radar capability Greg Kroah-Hartman
                   ` (280 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Adrian Hunter, Frank Li,
	Mukesh Savaliya, Alexandre Belloni, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Adrian Hunter <adrian.hunter@intel.com>

[ Upstream commit 4dc1b3eeba7991905a5b5b8129ebea51be7d87b7 ]

i3c_master_search_i3c_dev_duplicate() searches the bus for another I3C
device with the same PID as the reference device.  The search can match
master->this, causing the controller itself to be returned as a
duplicate.

Since the controller is not a target device, it cannot be a duplicate of
one.  Exclude master->this from matching so that the function only
returns real duplicate target devices.

Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure")
Cc: stable@vger.kernel.org
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Acked-by: Mukesh Savaliya <mukesh.savaliya@oss.qualcomm.com>
Link: https://patch.msgid.link/20260807145638.168865-4-adrian.hunter@intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
[ adjusted the duplicate-device comparison to match the older branch’s PID handling without nonzero-PID checks. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/i3c/master.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -2024,7 +2024,8 @@ i3c_master_search_i3c_dev_duplicate(stru
 	struct i3c_dev_desc *i3cdev;
 
 	i3c_bus_for_each_i3cdev(&master->bus, i3cdev) {
-		if (i3cdev != refdev && i3cdev->info.pid == refdev->info.pid)
+		if (i3cdev != refdev && i3cdev->info.pid == refdev->info.pid &&
+		    i3cdev != master->this)
 			return i3cdev;
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 605/877] wifi: mt76: mt7915: set correct background radar capability
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (603 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 604/877] i3c: master: Do not treat master device as a duplicate target Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 606/877] wifi: mt76: mt7915: bound the device EEPROM address before the EFUSE copy Greg Kroah-Hartman
                   ` (279 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, StanleyYP Wang, Shayne Chen,
	Felix Fietkau, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>

[ Upstream commit 888208d1ccc41bebe97744445787183b17bb3ea4 ]

Some of the variants do not support background radar, so add a
helper to report background radar capability.
For mt7916, only the variant of 5G 2T2R + 1R supports background
radar.

Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Reviewed-by: Shayne Chen <shayne.chen@mediatek.com>
Link: https://patch.msgid.link/20250320015909.3948612-1-StanleyYP.Wang@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Stable-dep-of: 44b5adfe4949 ("wifi: mt76: mt7915: bound the device EEPROM address before the EFUSE copy")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c |    5 +++
 drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c  |   33 +++++++++++++++++++-
 drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h  |    1 
 drivers/net/wireless/mediatek/mt76/mt7915/init.c    |    7 ++--
 drivers/net/wireless/mediatek/mt76/mt7915/mcu.c     |    8 +++-
 drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h  |    3 +
 6 files changed, 49 insertions(+), 8 deletions(-)

--- a/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/debugfs.c
@@ -444,6 +444,11 @@ mt7915_rdd_monitor(struct seq_file *s, v
 
 	mutex_lock(&dev->mt76.mutex);
 
+	if (!mt7915_eeprom_has_background_radar(dev)) {
+		seq_puts(s, "no background radar capability\n");
+		goto out;
+	}
+
 	if (!cfg80211_chandef_valid(chandef)) {
 		ret = -EINVAL;
 		goto out;
--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
@@ -147,7 +147,7 @@ static int mt7915_eeprom_load(struct mt7
 		/* read eeprom data from efuse */
 		block_num = DIV_ROUND_UP(eeprom_size, eeprom_blk_size);
 		for (i = 0; i < block_num; i++) {
-			ret = mt7915_mcu_get_eeprom(dev, i * eeprom_blk_size);
+			ret = mt7915_mcu_get_eeprom(dev, i * eeprom_blk_size, NULL);
 			if (ret < 0)
 				return ret;
 		}
@@ -359,6 +359,37 @@ s8 mt7915_eeprom_get_power_delta(struct
 	return val & MT_EE_RATE_DELTA_SIGN ? delta : -delta;
 }
 
+bool
+mt7915_eeprom_has_background_radar(struct mt7915_dev *dev)
+{
+	u8 val, buf[MT7915_EEPROM_BLOCK_SIZE];
+	u8 band_sel, tx_path, rx_path;
+	int offs = MT_EE_WIFI_CONF + 1;
+
+	switch (mt76_chip(&dev->mt76)) {
+	case 0x7915:
+		return true;
+	case 0x7906:
+		/* read efuse to check background radar capability */
+		if (mt7915_mcu_get_eeprom(dev, offs, buf))
+			break;
+
+		val = buf[offs % MT7915_EEPROM_BLOCK_SIZE];
+		band_sel = u8_get_bits(val, MT_EE_WIFI_CONF0_BAND_SEL);
+		tx_path = u8_get_bits(val, MT_EE_WIFI_CONF0_TX_PATH);
+		rx_path = u8_get_bits(val, MT_EE_WIFI_CONF0_RX_PATH);
+
+		return (band_sel == MT_EE_V2_BAND_SEL_5GHZ &&
+			tx_path == rx_path && rx_path == 2);
+	case 0x7981:
+	case 0x7986:
+	default:
+		break;
+	}
+
+	return false;
+}
+
 const u8 mt7915_sku_group_len[] = {
 	[SKU_CCK] = 4,
 	[SKU_OFDM] = 8,
--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.h
@@ -55,6 +55,7 @@ enum mt7915_eeprom_field {
 #define MT_EE_CAL_DPD_SIZE_V2			(300 * MT_EE_CAL_UNIT)
 
 #define MT_EE_WIFI_CONF0_TX_PATH		GENMASK(2, 0)
+#define MT_EE_WIFI_CONF0_RX_PATH		GENMASK(5, 3)
 #define MT_EE_WIFI_CONF0_BAND_SEL		GENMASK(7, 6)
 #define MT_EE_WIFI_CONF1_BAND_SEL		GENMASK(7, 6)
 #define MT_EE_WIFI_CONF_STREAM_NUM		GENMASK(7, 5)
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -389,9 +389,10 @@ mt7915_init_wiphy(struct mt7915_phy *phy
 	if (!is_mt7915(&dev->mt76))
 		wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_STA_TX_PWR);
 
-	if (!mdev->dev->of_node ||
-	    !of_property_read_bool(mdev->dev->of_node,
-				   "mediatek,disable-radar-background"))
+	if (mt7915_eeprom_has_background_radar(phy->dev) &&
+	    (!mdev->dev->of_node ||
+	     !of_property_read_bool(mdev->dev->of_node,
+				    "mediatek,disable-radar-background")))
 		wiphy_ext_feature_set(wiphy,
 				      NL80211_EXT_FEATURE_RADAR_BACKGROUND);
 
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -2853,7 +2853,7 @@ int mt7915_mcu_set_eeprom(struct mt7915_
 				 &req, sizeof(req), true);
 }
 
-int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset)
+int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset, u8 *read_buf)
 {
 	struct mt7915_mcu_eeprom_info req = {
 		.addr = cpu_to_le32(round_down(offset,
@@ -2861,8 +2861,8 @@ int mt7915_mcu_get_eeprom(struct mt7915_
 	};
 	struct mt7915_mcu_eeprom_info *res;
 	struct sk_buff *skb;
+	u8 *buf = read_buf;
 	int ret;
-	u8 *buf;
 
 	ret = mt76_mcu_send_and_get_msg(&dev->mt76,
 					MCU_EXT_QUERY(EFUSE_ACCESS),
@@ -2871,8 +2871,10 @@ int mt7915_mcu_get_eeprom(struct mt7915_
 		return ret;
 
 	res = (struct mt7915_mcu_eeprom_info *)skb->data;
-	buf = dev->mt76.eeprom.data + le32_to_cpu(res->addr);
+	if (!buf)
+		buf = dev->mt76.eeprom.data + le32_to_cpu(res->addr);
 	memcpy(buf, res->data, MT7915_EEPROM_BLOCK_SIZE);
+
 	dev_kfree_skb(skb);
 
 	return 0;
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -445,6 +445,7 @@ int mt7915_eeprom_get_target_power(struc
 				   struct ieee80211_channel *chan,
 				   u8 chain_idx);
 s8 mt7915_eeprom_get_power_delta(struct mt7915_dev *dev, int band);
+bool mt7915_eeprom_has_background_radar(struct mt7915_dev *dev);
 int mt7915_dma_init(struct mt7915_dev *dev, struct mt7915_phy *phy2);
 void mt7915_dma_prefetch(struct mt7915_dev *dev);
 void mt7915_dma_cleanup(struct mt7915_dev *dev);
@@ -495,7 +496,7 @@ int mt7915_mcu_set_fixed_rate_ctrl(struc
 				   struct ieee80211_sta *sta,
 				   void *data, u32 field);
 int mt7915_mcu_set_eeprom(struct mt7915_dev *dev);
-int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset);
+int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset, u8 *read_buf);
 int mt7915_mcu_get_eeprom_free_block(struct mt7915_dev *dev, u8 *block_num);
 int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band, bool enable,
 		       bool hdr_trans);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 606/877] wifi: mt76: mt7915: bound the device EEPROM address before the EFUSE copy
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (604 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 605/877] wifi: mt76: mt7915: set correct background radar capability Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 607/877] i3c: master: Fix use-after-free of master->this Greg Kroah-Hartman
                   ` (278 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bryam Vargas, Felix Fietkau,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bryam Vargas <hexlabsecurity@proton.me>

[ Upstream commit 44b5adfe49499f53002737f5fe81d608c08122fc ]

mt7915_mcu_get_eeprom() copies a fixed EFUSE block into the driver's
dev->mt76.eeprom.data buffer at the offset reported by the MCU response
(res->addr, a device-controlled __le32) without checking it against the
buffer size. A malicious or malfunctioning device can report an arbitrary
address and drive a 16-byte out-of-bounds write past eeprom.data.

Reject a response whose address would place the copy outside eeprom.data
before deriving the destination pointer. Devices that echo the requested
in-bounds offset are unaffected.

Fixes: e57b7901469f ("mt76: add mac80211 driver for MT7915 PCIe-based chipsets")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Link: https://patch.msgid.link/20260625-b4-disp-16f99062-v1-1-aee52ecf61b9@proton.me
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/mediatek/mt76/mt7915/mcu.c |   11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -2871,8 +2871,15 @@ int mt7915_mcu_get_eeprom(struct mt7915_
 		return ret;
 
 	res = (struct mt7915_mcu_eeprom_info *)skb->data;
-	if (!buf)
-		buf = dev->mt76.eeprom.data + le32_to_cpu(res->addr);
+	if (!buf) {
+		u32 addr = le32_to_cpu(res->addr);
+
+		if (addr > dev->mt76.eeprom.size - MT7915_EEPROM_BLOCK_SIZE) {
+			dev_kfree_skb(skb);
+			return -EINVAL;
+		}
+		buf = dev->mt76.eeprom.data + addr;
+	}
 	memcpy(buf, res->data, MT7915_EEPROM_BLOCK_SIZE);
 
 	dev_kfree_skb(skb);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 607/877] i3c: master: Fix use-after-free of master->this
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (605 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 606/877] wifi: mt76: mt7915: bound the device EEPROM address before the EFUSE copy Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 608/877] udf: Move udf_map_block() up Greg Kroah-Hartman
                   ` (277 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Adrian Hunter, Frank Li,
	Alexandre Belloni, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Adrian Hunter <adrian.hunter@intel.com>

[ Upstream commit feb0ed76601f3c2f91f08688c5a7d8b9d382f720 ]

sysfs attribute callbacks for the master controller device dereference
master->this.  However, master->this is freed in
i3c_master_detach_free_devs() before the master device itself is
released.

As a result, sysfs accesses can dereference a freed master->this
pointer, leading to a use-after-free.

Keep master->this alive until i3c_masterdev_release(), which is called
after the master device and its sysfs state are being torn down. Do not
free master->this as part of the normal device detach path.

On the error path in i3c_master_set_info(), reset master->this and
bus.cur_master to NULL before freeing the allocated device.

Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure")
Cc: stable@vger.kernel.org
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260807145638.168865-5-adrian.hunter@intel.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
[ retained of_node_put(dev->of_node) instead of upstream’s fwnode_handle_put(dev->fwnode). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/i3c/master.c |   17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -700,6 +700,11 @@ static struct attribute *i3c_masterdev_a
 };
 ATTRIBUTE_GROUPS(i3c_masterdev);
 
+static void i3c_master_free_i3c_dev(struct i3c_dev_desc *dev)
+{
+	kfree(dev);
+}
+
 static void i3c_masterdev_release(struct device *dev)
 {
 	struct i3c_master_controller *master = dev_to_i3cmaster(dev);
@@ -712,6 +717,8 @@ static void i3c_masterdev_release(struct
 	i3c_bus_cleanup(bus);
 
 	of_node_put(dev->of_node);
+
+	i3c_master_free_i3c_dev(master->this);
 }
 
 static const struct device_type i3c_masterdev_type = {
@@ -899,11 +906,6 @@ static void i3c_device_release(struct de
 	kfree(i3cdev);
 }
 
-static void i3c_master_free_i3c_dev(struct i3c_dev_desc *dev)
-{
-	kfree(dev);
-}
-
 static struct i3c_dev_desc *
 i3c_master_alloc_i3c_dev(struct i3c_master_controller *master,
 			 const struct i3c_device_info *info)
@@ -1784,6 +1786,8 @@ int i3c_master_set_info(struct i3c_maste
 	return 0;
 
 err_free_dev:
+	master->bus.cur_master = NULL;
+	master->this = NULL;
 	i3c_master_free_i3c_dev(i3cdev);
 
 	return ret;
@@ -1804,7 +1808,8 @@ static void i3c_master_detach_free_devs(
 					i3cdev->boardinfo->init_dyn_addr,
 					I3C_ADDR_SLOT_FREE);
 
-		i3c_master_free_i3c_dev(i3cdev);
+		if (i3cdev != master->this)
+			i3c_master_free_i3c_dev(i3cdev);
 	}
 
 	list_for_each_entry_safe(i2cdev, i2ctmp, &master->bus.devs.i2c,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 608/877] udf: Move udf_map_block() up
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (606 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 607/877] i3c: master: Fix use-after-free of master->this Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 609/877] udf: Fix data loss when converting inline inodes to out of line Greg Kroah-Hartman
                   ` (276 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Jan Kara, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jan Kara <jack@suse.cz>

[ Upstream commit 97e9d759a4193eabe4d8b6ecac093aac664c16e3 ]

Move udf_map_block() in the file to avoid forward declarations.

Link: https://patch.msgid.link/20260730104232.4086759-3-jack@suse.cz
Signed-off-by: Jan Kara <jack@suse.cz>
Stable-dep-of: 62333e480d12 ("udf: Fix data loss when converting inline inodes to out of line")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/udf/inode.c |  118 ++++++++++++++++++++++++++++-----------------------------
 1 file changed, 59 insertions(+), 59 deletions(-)

--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -330,65 +330,6 @@ const struct address_space_operations ud
 	.migrate_folio	= buffer_migrate_folio,
 };
 
-/*
- * Expand file stored in ICB to a normal one-block-file
- *
- * This function requires i_mutex held
- */
-int udf_expand_file_adinicb(struct inode *inode)
-{
-	struct folio *folio;
-	struct udf_inode_info *iinfo = UDF_I(inode);
-	int err;
-
-	WARN_ON_ONCE(!inode_is_locked(inode));
-	if (!iinfo->i_lenAlloc) {
-		down_write(&iinfo->i_data_sem);
-		if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
-			iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT;
-		else
-			iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
-		up_write(&iinfo->i_data_sem);
-		mark_inode_dirty(inode);
-		return 0;
-	}
-
-	folio = __filemap_get_folio(inode->i_mapping, 0,
-			FGP_LOCK | FGP_ACCESSED | FGP_CREAT, GFP_KERNEL);
-	if (IS_ERR(folio))
-		return PTR_ERR(folio);
-
-	if (!folio_test_uptodate(folio))
-		udf_adinicb_read_folio(folio);
-	down_write(&iinfo->i_data_sem);
-	memset(iinfo->i_data + iinfo->i_lenEAttr, 0x00,
-	       iinfo->i_lenAlloc);
-	iinfo->i_lenAlloc = 0;
-	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
-		iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT;
-	else
-		iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
-	folio_mark_dirty(folio);
-	folio_unlock(folio);
-	up_write(&iinfo->i_data_sem);
-	err = filemap_fdatawrite(inode->i_mapping);
-	if (err) {
-		/* Restore everything back so that we don't lose data... */
-		folio_lock(folio);
-		down_write(&iinfo->i_data_sem);
-		memcpy_from_folio(iinfo->i_data + iinfo->i_lenEAttr,
-				folio, 0, inode->i_size);
-		folio_unlock(folio);
-		iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
-		iinfo->i_lenAlloc = inode->i_size;
-		up_write(&iinfo->i_data_sem);
-	}
-	folio_put(folio);
-	mark_inode_dirty(inode);
-
-	return err;
-}
-
 #define UDF_MAP_CREATE		0x01	/* Mapping can allocate new blocks */
 #define UDF_MAP_NOPREALLOC	0x02	/* Do not preallocate blocks */
 
@@ -449,6 +390,65 @@ out_read:
 	return ret;
 }
 
+/*
+ * Expand file stored in ICB to a normal one-block-file
+ *
+ * This function requires i_mutex held
+ */
+int udf_expand_file_adinicb(struct inode *inode)
+{
+	struct folio *folio;
+	struct udf_inode_info *iinfo = UDF_I(inode);
+	int err;
+
+	WARN_ON_ONCE(!inode_is_locked(inode));
+	if (!iinfo->i_lenAlloc) {
+		down_write(&iinfo->i_data_sem);
+		if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
+			iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT;
+		else
+			iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
+		up_write(&iinfo->i_data_sem);
+		mark_inode_dirty(inode);
+		return 0;
+	}
+
+	folio = __filemap_get_folio(inode->i_mapping, 0,
+			FGP_LOCK | FGP_ACCESSED | FGP_CREAT, GFP_KERNEL);
+	if (IS_ERR(folio))
+		return PTR_ERR(folio);
+
+	if (!folio_test_uptodate(folio))
+		udf_adinicb_read_folio(folio);
+	down_write(&iinfo->i_data_sem);
+	memset(iinfo->i_data + iinfo->i_lenEAttr, 0x00,
+	       iinfo->i_lenAlloc);
+	iinfo->i_lenAlloc = 0;
+	if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
+		iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT;
+	else
+		iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
+	folio_mark_dirty(folio);
+	folio_unlock(folio);
+	up_write(&iinfo->i_data_sem);
+	err = filemap_fdatawrite(inode->i_mapping);
+	if (err) {
+		/* Restore everything back so that we don't lose data... */
+		folio_lock(folio);
+		down_write(&iinfo->i_data_sem);
+		memcpy_from_folio(iinfo->i_data + iinfo->i_lenEAttr,
+				folio, 0, inode->i_size);
+		folio_unlock(folio);
+		iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
+		iinfo->i_lenAlloc = inode->i_size;
+		up_write(&iinfo->i_data_sem);
+	}
+	folio_put(folio);
+	mark_inode_dirty(inode);
+
+	return err;
+}
+
 static int __udf_get_block(struct inode *inode, sector_t block,
 			   struct buffer_head *bh_result, int flags)
 {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 609/877] udf: Fix data loss when converting inline inodes to out of line
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (607 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 608/877] udf: Move udf_map_block() up Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 610/877] usb: dwc3: gadget: Reinitiate stream for all host NoStream behavior Greg Kroah-Hartman
                   ` (275 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Jan Kara, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jan Kara <jack@suse.cz>

[ Upstream commit 62333e480d12ab186f89fe2725b372d12f72d5eb ]

When udf_expand_file_adinicb() converts file from inline format to out
of line, we use filemap_fdatawrite() to writeout the data to the new
blocks. However since 36580ed08776 ("udf: Do not allocate blocks on page
writeback") the writeback actually doesn't allocate the new block and
the folio dirty bit is just silently cleared. Thus unless the file is
written to after the conversion (as it can easily happen in case of
truncate up), the data is just lost. Fix the problem by explicitely
allocating the block underlying the data before starting writeback.

Fixes: 36580ed08776 ("udf: Do not allocate blocks on page writeback")
CC: stable@vger.kernel.org
Link: https://patch.msgid.link/20260730104232.4086759-4-jack@suse.cz
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/udf/inode.c |   15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -399,6 +399,10 @@ int udf_expand_file_adinicb(struct inode
 {
 	struct folio *folio;
 	struct udf_inode_info *iinfo = UDF_I(inode);
+	struct udf_map_rq map = {
+		.lblk = 0,
+		.iflags = UDF_MAP_CREATE,
+	};
 	int err;
 
 	WARN_ON_ONCE(!inode_is_locked(inode));
@@ -428,20 +432,27 @@ int udf_expand_file_adinicb(struct inode
 		iinfo->i_alloc_type = ICBTAG_FLAG_AD_SHORT;
 	else
 		iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
+	up_write(&iinfo->i_data_sem);
+
+	/* Allocate the block underlying the data */
+	err = udf_map_block(inode, &map);
+	if (err < 0)
+		goto restore;
+
 	folio_mark_dirty(folio);
 	folio_unlock(folio);
-	up_write(&iinfo->i_data_sem);
 	err = filemap_fdatawrite(inode->i_mapping);
 	if (err) {
 		/* Restore everything back so that we don't lose data... */
 		folio_lock(folio);
+restore:
 		down_write(&iinfo->i_data_sem);
 		memcpy_from_folio(iinfo->i_data + iinfo->i_lenEAttr,
 				folio, 0, inode->i_size);
-		folio_unlock(folio);
 		iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
 		iinfo->i_lenAlloc = inode->i_size;
 		up_write(&iinfo->i_data_sem);
+		folio_unlock(folio);
 	}
 	folio_put(folio);
 	mark_inode_dirty(inode);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 610/877] usb: dwc3: gadget: Reinitiate stream for all host NoStream behavior
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (608 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 609/877] udf: Fix data loss when converting inline inodes to out of line Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 611/877] usb: dwc3: clear forceRM when issuing EndTransfer Greg Kroah-Hartman
                   ` (274 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Thinh Nguyen, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>

[ Upstream commit dcfe437492e27d54f3ac491aed024da760f5c43c ]

There are too many different host behaviors when it comes to NoStream
handling, and not everyone follows the USB and xHCI spec. The DWC3
driver attempts to do some guess work to interop with different hosts,
but it can't cover everything. Let's keep it simple and treat every host
the same: just retry on NoStream after a 100ms of no response delay.
Note that some hosts cannot handle frequent retries. This may affect
performance on certain defective hosts, but NoStream is a rare
occurrence and interoperability is more important.

Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://lore.kernel.org/r/b92ae94c86f01f165d5f178b7767898573b6dc75.1736819308.git.Thinh.Nguyen@synopsys.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: b58e6200450d ("usb: dwc3: clear forceRM when issuing EndTransfer")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/dwc3/core.h   |    3 -
 drivers/usb/dwc3/gadget.c |  109 ++++++++++++++++++++++++----------------------
 2 files changed, 59 insertions(+), 53 deletions(-)

--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -742,6 +742,7 @@ struct dwc3_event_buffer {
  */
 struct dwc3_ep {
 	struct usb_ep		endpoint;
+	struct delayed_work	nostream_work;
 	struct list_head	cancelled_list;
 	struct list_head	pending_list;
 	struct list_head	started_list;
@@ -764,7 +765,7 @@ struct dwc3_ep {
 #define DWC3_EP_WAIT_TRANSFER_COMPLETE	BIT(7)
 #define DWC3_EP_IGNORE_NEXT_NOSTREAM	BIT(8)
 #define DWC3_EP_FORCE_RESTART_STREAM	BIT(9)
-#define DWC3_EP_FIRST_STREAM_PRIMED	BIT(10)
+#define DWC3_EP_STREAM_PRIMED		BIT(10)
 #define DWC3_EP_PENDING_CLEAR_STALL	BIT(11)
 #define DWC3_EP_TXFIFO_RESIZED		BIT(12)
 #define DWC3_EP_DELAY_STOP             BIT(13)
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -995,8 +995,7 @@ static int __dwc3_gadget_ep_enable(struc
 
 			/*
 			 * All stream eps will reinitiate stream on NoStream
-			 * rejection until we can determine that the host can
-			 * prime after the first transfer.
+			 * rejection.
 			 *
 			 * However, if the controller is capable of
 			 * TXF_FLUSH_BYPASS, then IN direction endpoints will
@@ -3309,6 +3308,50 @@ static int dwc3_gadget_init_out_endpoint
 	return dwc3_alloc_trb_pool(dep);
 }
 
+#define nostream_work_to_dep(w) (container_of(to_delayed_work(w), struct dwc3_ep, nostream_work))
+static void dwc3_nostream_work(struct work_struct *work)
+{
+	struct dwc3_ep	*dep = nostream_work_to_dep(work);
+	struct dwc3	*dwc = dep->dwc;
+	unsigned long   flags;
+
+	spin_lock_irqsave(&dwc->lock, flags);
+	if (dep->flags & DWC3_EP_STREAM_PRIMED)
+		goto out;
+
+	if ((dep->flags & DWC3_EP_IGNORE_NEXT_NOSTREAM) ||
+	    (!DWC3_MST_CAPABLE(&dwc->hwparams) &&
+	     !(dep->flags & DWC3_EP_WAIT_TRANSFER_COMPLETE)))
+		goto out;
+	/*
+	 * If the host rejects a stream due to no active stream, by the
+	 * USB and xHCI spec, the endpoint will be put back to idle
+	 * state. When the host is ready (buffer added/updated), it will
+	 * prime the endpoint to inform the usb device controller. This
+	 * triggers the device controller to issue ERDY to restart the
+	 * stream. However, some hosts don't follow this and keep the
+	 * endpoint in the idle state. No prime will come despite host
+	 * streams are updated, and the device controller will not be
+	 * triggered to generate ERDY to move the next stream data. To
+	 * workaround this and maintain compatibility with various
+	 * hosts, force to reinitiate the stream until the host is ready
+	 * instead of waiting for the host to prime the endpoint.
+	 */
+	if (DWC3_VER_IS_WITHIN(DWC32, 100A, ANY)) {
+		unsigned int cmd = DWC3_DGCMD_SET_ENDPOINT_PRIME;
+
+		dwc3_send_gadget_generic_command(dwc, cmd, dep->number);
+	} else {
+		dep->flags |= DWC3_EP_DELAY_START;
+		dwc3_stop_active_transfer(dep, true, true);
+		spin_unlock_irqrestore(&dwc->lock, flags);
+		return;
+	}
+out:
+	dep->flags &= ~DWC3_EP_IGNORE_NEXT_NOSTREAM;
+	spin_unlock_irqrestore(&dwc->lock, flags);
+}
+
 static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum)
 {
 	struct dwc3_ep			*dep;
@@ -3354,6 +3397,7 @@ static int dwc3_gadget_init_endpoint(str
 	INIT_LIST_HEAD(&dep->pending_list);
 	INIT_LIST_HEAD(&dep->started_list);
 	INIT_LIST_HEAD(&dep->cancelled_list);
+	INIT_DELAYED_WORK(&dep->nostream_work, dwc3_nostream_work);
 
 	dwc3_debugfs_create_endpoint_dir(dep);
 
@@ -3789,66 +3833,27 @@ static void dwc3_gadget_endpoint_command
 static void dwc3_gadget_endpoint_stream_event(struct dwc3_ep *dep,
 		const struct dwc3_event_depevt *event)
 {
-	struct dwc3 *dwc = dep->dwc;
-
 	if (event->status == DEPEVT_STREAMEVT_FOUND) {
-		dep->flags |= DWC3_EP_FIRST_STREAM_PRIMED;
-		goto out;
+		cancel_delayed_work(&dep->nostream_work);
+		dep->flags |= DWC3_EP_STREAM_PRIMED;
+		dep->flags &= ~DWC3_EP_IGNORE_NEXT_NOSTREAM;
+		return;
 	}
 
 	/* Note: NoStream rejection event param value is 0 and not 0xFFFF */
 	switch (event->parameters) {
 	case DEPEVT_STREAM_PRIME:
-		/*
-		 * If the host can properly transition the endpoint state from
-		 * idle to prime after a NoStream rejection, there's no need to
-		 * force restarting the endpoint to reinitiate the stream. To
-		 * simplify the check, assume the host follows the USB spec if
-		 * it primed the endpoint more than once.
-		 */
-		if (dep->flags & DWC3_EP_FORCE_RESTART_STREAM) {
-			if (dep->flags & DWC3_EP_FIRST_STREAM_PRIMED)
-				dep->flags &= ~DWC3_EP_FORCE_RESTART_STREAM;
-			else
-				dep->flags |= DWC3_EP_FIRST_STREAM_PRIMED;
-		}
-
+		cancel_delayed_work(&dep->nostream_work);
+		dep->flags |= DWC3_EP_STREAM_PRIMED;
+		dep->flags &= ~DWC3_EP_IGNORE_NEXT_NOSTREAM;
 		break;
 	case DEPEVT_STREAM_NOSTREAM:
-		if ((dep->flags & DWC3_EP_IGNORE_NEXT_NOSTREAM) ||
-		    !(dep->flags & DWC3_EP_FORCE_RESTART_STREAM) ||
-		    (!DWC3_MST_CAPABLE(&dwc->hwparams) &&
-		     !(dep->flags & DWC3_EP_WAIT_TRANSFER_COMPLETE)))
-			break;
-
-		/*
-		 * If the host rejects a stream due to no active stream, by the
-		 * USB and xHCI spec, the endpoint will be put back to idle
-		 * state. When the host is ready (buffer added/updated), it will
-		 * prime the endpoint to inform the usb device controller. This
-		 * triggers the device controller to issue ERDY to restart the
-		 * stream. However, some hosts don't follow this and keep the
-		 * endpoint in the idle state. No prime will come despite host
-		 * streams are updated, and the device controller will not be
-		 * triggered to generate ERDY to move the next stream data. To
-		 * workaround this and maintain compatibility with various
-		 * hosts, force to reinitiate the stream until the host is ready
-		 * instead of waiting for the host to prime the endpoint.
-		 */
-		if (DWC3_VER_IS_WITHIN(DWC32, 100A, ANY)) {
-			unsigned int cmd = DWC3_DGCMD_SET_ENDPOINT_PRIME;
-
-			dwc3_send_gadget_generic_command(dwc, cmd, dep->number);
-		} else {
-			dep->flags |= DWC3_EP_DELAY_START;
-			dwc3_stop_active_transfer(dep, true, true);
-			return;
-		}
+		dep->flags &= ~DWC3_EP_STREAM_PRIMED;
+		if (dep->flags & DWC3_EP_FORCE_RESTART_STREAM)
+			queue_delayed_work(system_wq, &dep->nostream_work,
+					   msecs_to_jiffies(100));
 		break;
 	}
-
-out:
-	dep->flags &= ~DWC3_EP_IGNORE_NEXT_NOSTREAM;
 }
 
 static void dwc3_endpoint_interrupt(struct dwc3 *dwc,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 611/877] usb: dwc3: clear forceRM when issuing EndTransfer
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (609 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 610/877] usb: dwc3: gadget: Reinitiate stream for all host NoStream behavior Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 612/877] wifi: rtw89: cleanup unused rtwdev::roc_work Greg Kroah-Hartman
                   ` (273 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, stable, Elson Serrao, Thinh Nguyen,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Elson Serrao <elson.serrao@oss.qualcomm.com>

[ Upstream commit b58e6200450d350314db0ecda7d6d1bde3281e80 ]

The forceRM bit of the DEPCMD register controls the behavior of the
EndTransfer command used to stop an active transfer. Older DWC3
programming guide revisions recommended setting forceRM=1 when
issuing EndTransfer. Newer programming guide revisions recommend
issuing EndTransfer with forceRM cleared.

With forceRM=1 on DWC_usb31 v2.00a and v2.10a controllers, a transfer
aborted through the ep_dequeue path was observed to remain active
after EndTransfer completion. A subsequent StartTransfer issued on the
same endpoint triggered writes associated with the aborted transfer.
This resulted in an SMMU fault because the transfer buffer had already
been unmapped during EndTransfer command-completion cleanup.

Using forceRM=0 eliminates the issue. Although older DWC3 programming
guide revisions recommended setting forceRM=1, no issues are known
from using forceRM=0. Clear forceRM when issuing EndTransfer to provide
consistent EndTransfer behavior and align with newer programming guide
recommendations.

Fixes: 1e43c86d84fb ("usb: dwc3: core: Add DWC31 version 2.00a controller")
Cc: stable <stable@kernel.org>
Signed-off-by: Elson Serrao <elson.serrao@oss.qualcomm.com>
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://patch.msgid.link/20260813151456.867008-1-elson.serrao@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/dwc3/ep0.c    |    2 +-
 drivers/usb/dwc3/gadget.c |   21 +++++++++++++--------
 2 files changed, 14 insertions(+), 9 deletions(-)

--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -304,7 +304,7 @@ void dwc3_ep0_out_start(struct dwc3 *dwc
 
 		dwc3_ep->flags &= ~DWC3_EP_DELAY_STOP;
 		if (dwc->connected)
-			dwc3_stop_active_transfer(dwc3_ep, true, true);
+			dwc3_stop_active_transfer(dwc3_ep, false, true);
 		else
 			dwc3_remove_requests(dwc, dwc3_ep, -ESHUTDOWN);
 	}
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -991,7 +991,7 @@ static int __dwc3_gadget_ep_enable(struc
 			 * controller to generate an ERDY to initiate the
 			 * stream.
 			 */
-			dwc3_stop_active_transfer(dep, true, true);
+			dwc3_stop_active_transfer(dep, false, true);
 
 			/*
 			 * All stream eps will reinitiate stream on NoStream
@@ -1019,7 +1019,7 @@ void dwc3_remove_requests(struct dwc3 *d
 {
 	struct dwc3_request		*req;
 
-	dwc3_stop_active_transfer(dep, true, false);
+	dwc3_stop_active_transfer(dep, false, false);
 
 	/* If endxfer is delayed, avoid unmapping requests */
 	if (dep->flags & DWC3_EP_DELAY_STOP)
@@ -1709,7 +1709,7 @@ static int __dwc3_gadget_kick_transfer(s
 		if (ret == -EAGAIN)
 			return ret;
 
-		dwc3_stop_active_transfer(dep, true, true);
+		dwc3_stop_active_transfer(dep, false, true);
 
 		list_for_each_entry_safe(req, tmp, &dep->started_list, list)
 			dwc3_gadget_move_cancelled_request(req, DWC3_REQUEST_STATUS_DEQUEUED);
@@ -1746,6 +1746,11 @@ static int __dwc3_gadget_get_frame(struc
  * the controller won't update the TRB progress on command
  * completion. It also won't clear the HWO bit in the TRB.
  * The command will also not complete immediately in that case.
+ *
+ * Older programming guide revisions recommended setting ForceRM to 1
+ * when ending a transfer. Newer programming guide revisions now
+ * recommend keeping ForceRM cleared, and TRBs are properly updated
+ * on command completion.
  */
 static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt)
 {
@@ -1871,7 +1876,7 @@ static int dwc3_gadget_start_isoc_quirk(
 		 * to wait for the next XferNotReady to test the command again
 		 */
 		if (cmd_status == 0) {
-			dwc3_stop_active_transfer(dep, true, true);
+			dwc3_stop_active_transfer(dep, false, true);
 			return 0;
 		}
 	}
@@ -2154,7 +2159,7 @@ static int dwc3_gadget_ep_dequeue(struct
 			struct dwc3_request *t;
 
 			/* wait until it is processed */
-			dwc3_stop_active_transfer(dep, true, true);
+			dwc3_stop_active_transfer(dep, false, true);
 
 			/*
 			 * Remove any started request if the transfer is
@@ -2231,7 +2236,7 @@ int __dwc3_gadget_ep_set_halt(struct dwc
 			return 0;
 		}
 
-		dwc3_stop_active_transfer(dep, true, true);
+		dwc3_stop_active_transfer(dep, false, true);
 
 		list_for_each_entry_safe(req, tmp, &dep->started_list, list)
 			dwc3_gadget_move_cancelled_request(req, DWC3_REQUEST_STATUS_STALLED);
@@ -3343,7 +3348,7 @@ static void dwc3_nostream_work(struct wo
 		dwc3_send_gadget_generic_command(dwc, cmd, dep->number);
 	} else {
 		dep->flags |= DWC3_EP_DELAY_START;
-		dwc3_stop_active_transfer(dep, true, true);
+		dwc3_stop_active_transfer(dep, false, true);
 		spin_unlock_irqrestore(&dwc->lock, flags);
 		return;
 	}
@@ -3687,7 +3692,7 @@ static bool dwc3_gadget_endpoint_trbs_co
 	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
 		list_empty(&dep->started_list) &&
 		(list_empty(&dep->pending_list) || status == -EXDEV))
-		dwc3_stop_active_transfer(dep, true, true);
+		dwc3_stop_active_transfer(dep, false, true);
 	else if (dwc3_gadget_ep_should_continue(dep))
 		if (__dwc3_gadget_kick_transfer(dep) == 0)
 			no_started_trb = false;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 612/877] wifi: rtw89: cleanup unused rtwdev::roc_work
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (610 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 611/877] usb: dwc3: clear forceRM when issuing EndTransfer Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 613/877] wifi: rtw89: Hide some errors when the device is unplugged Greg Kroah-Hartman
                   ` (272 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Zong-Zhe Yang, Ping-Ke Shih,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Zong-Zhe Yang <kevin_yang@realtek.com>

[ Upstream commit c281bdb8821461047d3e74206afbff190d1f7846 ]

The needed one was moved to rtwvif::roc_work. And, rtwdev::roc_work is
unused. So, remove it.

Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20250120034004.21135-1-pkshih@realtek.com
Stable-dep-of: 667c12782aaf ("wifi: rtw89: pci: add .shutdown callback to stop rfkill polling on reboot")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/realtek/rtw89/core.h |    1 -
 1 file changed, 1 deletion(-)

--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -5604,7 +5604,6 @@ struct rtw89_dev {
 	struct delayed_work coex_rfk_chk_work;
 	struct delayed_work cfo_track_work;
 	struct delayed_work forbid_ba_work;
-	struct delayed_work roc_work;
 	struct delayed_work antdiv_work;
 	struct rtw89_ppdu_sts_info ppdu_sts;
 	u8 total_sta_assoc;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 613/877] wifi: rtw89: Hide some errors when the device is unplugged
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (611 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 612/877] wifi: rtw89: cleanup unused rtwdev::roc_work Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 614/877] wifi: rtw89: pci: add .shutdown callback to stop rfkill polling on reboot Greg Kroah-Hartman
                   ` (271 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bitterblue Smith, Ping-Ke Shih,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bitterblue Smith <rtl8821cerfe2@gmail.com>

[ Upstream commit 0740c6beefae03066a562e3047959528d8893709 ]

A few unnecessary error messages are printed when the device is
unplugged. "read swsi busy" in particular can appear ~1000 times when
RTL8851BU is unplugged.

Add a new flag RTW89_FLAG_UNPLUGGED and print some error messages only
when this flag is not set. The new USB driver will set the flag when
the device is unplugged.

Signed-off-by: Bitterblue Smith <rtl8821cerfe2@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/cc18b739-6f38-4c1a-a681-1e2a0d4ed60d@gmail.com
Stable-dep-of: 667c12782aaf ("wifi: rtw89: pci: add .shutdown callback to stop rfkill polling on reboot")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/realtek/rtw89/core.h |    1 +
 drivers/net/wireless/realtek/rtw89/mac.c  |   13 ++++++++-----
 drivers/net/wireless/realtek/rtw89/phy.c  |    3 ++-
 3 files changed, 11 insertions(+), 6 deletions(-)

--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4724,6 +4724,7 @@ enum rtw89_flags {
 	RTW89_FLAG_FORBIDDEN_TRACK_WROK,
 	RTW89_FLAG_CHANGING_INTERFACE,
 	RTW89_FLAG_HW_RFKILL_STATE,
+	RTW89_FLAG_UNPLUGGED,
 
 	NUM_OF_RTW89_FLAGS,
 };
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -88,7 +88,7 @@ int rtw89_mac_write_lte(struct rtw89_dev
 
 	ret = read_poll_timeout(rtw89_read8, lte_ctrl, (lte_ctrl & BIT(5)) != 0,
 				50, 50000, false, rtwdev, R_AX_LTE_CTRL + 3);
-	if (ret)
+	if (ret && !test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
 		rtw89_err(rtwdev, "[ERR]lte not ready(W)\n");
 
 	rtw89_write32(rtwdev, R_AX_LTE_WDATA, val);
@@ -104,7 +104,7 @@ int rtw89_mac_read_lte(struct rtw89_dev
 
 	ret = read_poll_timeout(rtw89_read8, lte_ctrl, (lte_ctrl & BIT(5)) != 0,
 				50, 50000, false, rtwdev, R_AX_LTE_CTRL + 3);
-	if (ret)
+	if (ret && !test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
 		rtw89_err(rtwdev, "[ERR]lte not ready(W)\n");
 
 	rtw89_write32(rtwdev, R_AX_LTE_CTRL, 0x800F0000 | offset);
@@ -5666,13 +5666,15 @@ int rtw89_mac_coex_init(struct rtw89_dev
 
 	ret = rtw89_mac_read_lte(rtwdev, R_AX_LTE_SW_CFG_2, &val32);
 	if (ret) {
-		rtw89_err(rtwdev, "Read R_AX_LTE_SW_CFG_2 fail!\n");
+		if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
+			rtw89_err(rtwdev, "Read R_AX_LTE_SW_CFG_2 fail!\n");
 		return ret;
 	}
 	val32 = val32 & B_AX_WL_RX_CTRL;
 	ret = rtw89_mac_write_lte(rtwdev, R_AX_LTE_SW_CFG_2, val32);
 	if (ret) {
-		rtw89_err(rtwdev, "Write R_AX_LTE_SW_CFG_2 fail!\n");
+		if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
+			rtw89_err(rtwdev, "Write R_AX_LTE_SW_CFG_2 fail!\n");
 		return ret;
 	}
 
@@ -5796,7 +5798,8 @@ int rtw89_mac_cfg_gnt(struct rtw89_dev *
 
 	ret = rtw89_mac_write_lte(rtwdev, R_AX_LTE_SW_CFG_1, val);
 	if (ret) {
-		rtw89_err(rtwdev, "Write LTE fail!\n");
+		if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
+			rtw89_err(rtwdev, "Write LTE fail!\n");
 		return ret;
 	}
 
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -881,7 +881,8 @@ static u32 rtw89_phy_read_rf_a(struct rt
 				       30, false, rtwdev, R_SWSI_V1,
 				       B_SWSI_R_DATA_DONE_V1);
 	if (ret) {
-		rtw89_err(rtwdev, "read swsi busy\n");
+		if (!test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags))
+			rtw89_err(rtwdev, "read swsi busy\n");
 		return INV_RF_DATA;
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 614/877] wifi: rtw89: pci: add .shutdown callback to stop rfkill polling on reboot
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (612 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 613/877] wifi: rtw89: Hide some errors when the device is unplugged Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 615/877] usb: typec: tcpm: fix debug accessory mode detection for sink ports Greg Kroah-Hartman
                   ` (270 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Ping-Ke Shih, Yuhang.chen,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Yuhang.chen" <yhchen312@gmail.com>

[ Upstream commit 667c12782aaf8dd3cb2213e528fe63a73cb63345 ]

Since the hardware rfkill polling was introduced, arm64 platforms can
panic with an asynchronous SError during warm reboot:

  SError Interrupt on CPU8, code 0x00000000be000011 -- SError
  Workqueue: events_power_efficient rfkill_poll [rfkill]
    rtw89_pci_ops_read8+0x94/0x160 [rtw89_pci]
    rtw89_core_rfkill_poll+0x50/0x1e0 [rtw89_core]
    rtw89_ops_rfkill_poll+0x40/0x68 [rtw89_core]
    ieee80211_rfkill_poll+0x3c/0x70 [mac80211]
    cfg80211_rfkill_poll+0x40/0x2a0 [cfg80211]
    rfkill_poll+0x30/0x88 [rfkill]
  Kernel panic - not syncing: Asynchronous SError Interrupt

On the reboot path the kernel only runs device_shutdown(), which calls
each driver's .shutdown callback; .remove is not invoked.  The rtw89 PCI
driver had no .shutdown callback, so nothing stopped the rfkill polling
work while the platform was tearing the PCIe link down.  Once the link
is gone, the next MMIO read from the poll handler targets a
non-responding device and is reported as a fatal asynchronous SError on
arm64.

Add rtw89_pci_shutdown(), wired to all rtw89 PCI device drivers, which
sets a new RTW89_FLAG_SHUTDOWN flag (mirroring the USB
RTW89_FLAG_UNPLUGGED pattern).  When the flag is set,
rtw89_ops_rfkill_poll() returns early, so no MMIO read is issued to the
chip after shutdown begins and the SError no longer occurs.

This does not call the full .remove path from .shutdown, to keep the
shutdown handler minimal and avoid running the non-idempotent teardown
twice.

Fixes: 0b38e6277aed ("wifi: rtw89: add support for hardware rfkill")
Cc: stable@vger.kernel.org
Suggested-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Yuhang.chen <yhchen312@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260729014142.2746777-1-yhchen312@gmail.com
[ Adapted the shutdown check to use the existing goto out path for mutex unlocking. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/realtek/rtw89/core.h       |    1 +
 drivers/net/wireless/realtek/rtw89/mac80211.c   |    3 ++-
 drivers/net/wireless/realtek/rtw89/pci.c        |   13 +++++++++++++
 drivers/net/wireless/realtek/rtw89/pci.h        |    1 +
 drivers/net/wireless/realtek/rtw89/rtw8851be.c  |    1 +
 drivers/net/wireless/realtek/rtw89/rtw8852ae.c  |    1 +
 drivers/net/wireless/realtek/rtw89/rtw8852be.c  |    1 +
 drivers/net/wireless/realtek/rtw89/rtw8852bte.c |    1 +
 drivers/net/wireless/realtek/rtw89/rtw8852ce.c  |    1 +
 drivers/net/wireless/realtek/rtw89/rtw8922ae.c  |    1 +
 10 files changed, 23 insertions(+), 1 deletion(-)

--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4725,6 +4725,7 @@ enum rtw89_flags {
 	RTW89_FLAG_CHANGING_INTERFACE,
 	RTW89_FLAG_HW_RFKILL_STATE,
 	RTW89_FLAG_UNPLUGGED,
+	RTW89_FLAG_SHUTDOWN,
 
 	NUM_OF_RTW89_FLAGS,
 };
--- a/drivers/net/wireless/realtek/rtw89/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c
@@ -1550,7 +1550,8 @@ static void rtw89_ops_rfkill_poll(struct
 	mutex_lock(&rtwdev->mutex);
 
 	/* wl_disable GPIO get floating when entering LPS */
-	if (test_bit(RTW89_FLAG_RUNNING, rtwdev->flags))
+	if (test_bit(RTW89_FLAG_RUNNING, rtwdev->flags) ||
+	    test_bit(RTW89_FLAG_SHUTDOWN, rtwdev->flags))
 		goto out;
 
 	rtw89_core_rfkill_poll(rtwdev, false);
--- a/drivers/net/wireless/realtek/rtw89/pci.c
+++ b/drivers/net/wireless/realtek/rtw89/pci.c
@@ -4465,6 +4465,19 @@ void rtw89_pci_remove(struct pci_dev *pd
 }
 EXPORT_SYMBOL(rtw89_pci_remove);
 
+void rtw89_pci_shutdown(struct pci_dev *pdev)
+{
+	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+	struct rtw89_dev *rtwdev;
+
+	if (!hw)
+		return;
+
+	rtwdev = hw->priv;
+	set_bit(RTW89_FLAG_SHUTDOWN, rtwdev->flags);
+}
+EXPORT_SYMBOL(rtw89_pci_shutdown);
+
 MODULE_AUTHOR("Realtek Corporation");
 MODULE_DESCRIPTION("Realtek PCI 802.11ax wireless driver");
 MODULE_LICENSE("Dual BSD/GPL");
--- a/drivers/net/wireless/realtek/rtw89/pci.h
+++ b/drivers/net/wireless/realtek/rtw89/pci.h
@@ -1602,6 +1602,7 @@ struct pci_device_id;
 
 int rtw89_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id);
 void rtw89_pci_remove(struct pci_dev *pdev);
+void rtw89_pci_shutdown(struct pci_dev *pdev);
 void rtw89_pci_ops_reset(struct rtw89_dev *rtwdev);
 int rtw89_pci_ltr_set(struct rtw89_dev *rtwdev, bool en);
 int rtw89_pci_ltr_set_v1(struct rtw89_dev *rtwdev, bool en);
--- a/drivers/net/wireless/realtek/rtw89/rtw8851be.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851be.c
@@ -84,6 +84,7 @@ static struct pci_driver rtw89_8851be_dr
 	.id_table	= rtw89_8851be_id_table,
 	.probe		= rtw89_pci_probe,
 	.remove		= rtw89_pci_remove,
+	.shutdown	= rtw89_pci_shutdown,
 	.driver.pm	= &rtw89_pm_ops,
 };
 module_pci_driver(rtw89_8851be_driver);
--- a/drivers/net/wireless/realtek/rtw89/rtw8852ae.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852ae.c
@@ -86,6 +86,7 @@ static struct pci_driver rtw89_8852ae_dr
 	.id_table	= rtw89_8852ae_id_table,
 	.probe		= rtw89_pci_probe,
 	.remove		= rtw89_pci_remove,
+	.shutdown	= rtw89_pci_shutdown,
 	.driver.pm	= &rtw89_pm_ops,
 };
 module_pci_driver(rtw89_8852ae_driver);
--- a/drivers/net/wireless/realtek/rtw89/rtw8852be.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852be.c
@@ -88,6 +88,7 @@ static struct pci_driver rtw89_8852be_dr
 	.id_table	= rtw89_8852be_id_table,
 	.probe		= rtw89_pci_probe,
 	.remove		= rtw89_pci_remove,
+	.shutdown	= rtw89_pci_shutdown,
 	.driver.pm	= &rtw89_pm_ops,
 };
 module_pci_driver(rtw89_8852be_driver);
--- a/drivers/net/wireless/realtek/rtw89/rtw8852bte.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bte.c
@@ -84,6 +84,7 @@ static struct pci_driver rtw89_8852bte_d
 	.id_table	= rtw89_8852bte_id_table,
 	.probe		= rtw89_pci_probe,
 	.remove		= rtw89_pci_remove,
+	.shutdown	= rtw89_pci_shutdown,
 	.driver.pm	= &rtw89_pm_ops,
 };
 module_pci_driver(rtw89_8852bte_driver);
--- a/drivers/net/wireless/realtek/rtw89/rtw8852ce.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852ce.c
@@ -113,6 +113,7 @@ static struct pci_driver rtw89_8852ce_dr
 	.id_table	= rtw89_8852ce_id_table,
 	.probe		= rtw89_pci_probe,
 	.remove		= rtw89_pci_remove,
+	.shutdown	= rtw89_pci_shutdown,
 	.driver.pm	= &rtw89_pm_ops,
 };
 module_pci_driver(rtw89_8852ce_driver);
--- a/drivers/net/wireless/realtek/rtw89/rtw8922ae.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922ae.c
@@ -82,6 +82,7 @@ static struct pci_driver rtw89_8922ae_dr
 	.id_table	= rtw89_8922ae_id_table,
 	.probe		= rtw89_pci_probe,
 	.remove		= rtw89_pci_remove,
+	.shutdown	= rtw89_pci_shutdown,
 	.driver.pm	= &rtw89_pm_ops_be,
 };
 module_pci_driver(rtw89_8922ae_driver);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 615/877] usb: typec: tcpm: fix debug accessory mode detection for sink ports
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (613 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 614/877] wifi: rtw89: pci: add .shutdown callback to stop rfkill polling on reboot Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 616/877] usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling Greg Kroah-Hartman
                   ` (269 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, stable, Xu Yang, Heikki Krogerus,
	Amit Sunil Dhamne, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Xu Yang <xu.yang_2@nxp.com>

[ Upstream commit f6ec9bb4acc7182b25a793ad094a764e1cb819a7 ]

The port in debug accessory mode can be either a source or sink. The
previous tcpm_port_is_debug() function only checked for source port.

Commit 8db73e6a42b6 ("usb: typec: tcpm: allow sink (ufp) to toggle into
accessory mode debug") changed the detection logic to support both roles,
but left some logic in _tcpm_cc_change() unchanged, This causes the state
machine to transition to an incorrect state when operating as a sink in
debug accessory mode. Log as below:

[  978.637541] CC1: 0 -> 5, CC2: 0 -> 5 [state TOGGLING, polarity 0, connected]
[  978.637567] state change TOGGLING -> SRC_ATTACH_WAIT [rev1 NONE_AMS]
[  978.637596] pending state change SRC_ATTACH_WAIT -> DEBUG_ACC_ATTACHED @ 180 ms [rev1 NONE_AMS]
[  978.647098] CC1: 5 -> 0, CC2: 5 -> 5 [state SRC_ATTACH_WAIT, polarity 0, connected]
[  978.647115] state change SRC_ATTACH_WAIT -> SRC_ATTACH_WAIT [rev1 NONE_AMS]

It should go to SNK_ATTACH_WAIT instead of SRC_ATTACH_WAIT state.

To fix this, add tcpm_port_is_debug_source() and tcpm_port_is_debug_sink()
helper to explicitly identify the power mode in debug accessory mode.
Update the state transition logic in _tcpm_cc_change() to ensure the state
machine transitions comply with Type-C specification. Also update the logic
in run_state_machine() to keep consistency.

Fixes: 8db73e6a42b6 ("usb: typec: tcpm: allow sink (ufp) to toggle into accessory mode debug")
Cc: stable <stable@kernel.org>
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Reviewed-by: Amit Sunil Dhamne <amitsd@google.com>
Link: https://patch.msgid.link/20260424074009.2979266-1-xu.yang_2@nxp.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

[Backport to 6.12: This tree lacks 8db73e6a42b6 and the associated
sink debug-accessory state-machine support. Retain only the source-debug
macro extraction and source-side call-site updates. Keep
tcpm_port_is_debug() source-only and omit the sink-debug macro and all
sink/audio attachment transitions introduced by the upstream dependency.
This preserves existing detection and state transitions while providing
tcpm_port_is_debug_source() for cd3b9cea675b ("usb: typec: tcpm: constrain
TCPM_SOURCING_VBUS event handling"). No functions are added.]

Stable-dep-of: cd3b9cea675b ("usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/typec/tcpm/tcpm.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -602,9 +602,12 @@ static const char * const pd_rev[] = {
 	 (tcpm_cc_is_source((port)->cc2) && \
 	  !tcpm_cc_is_source((port)->cc1)))
 
-#define tcpm_port_is_debug(port) \
+#define tcpm_port_is_debug_source(port) \
 	(tcpm_cc_is_source((port)->cc1) && tcpm_cc_is_source((port)->cc2))
 
+#define tcpm_port_is_debug(port) \
+	tcpm_port_is_debug_source(port)
+
 #define tcpm_port_is_audio(port) \
 	(tcpm_cc_is_audio((port)->cc1) && tcpm_cc_is_audio((port)->cc2))
 
@@ -4742,7 +4745,7 @@ static void run_state_machine(struct tcp
 			tcpm_set_state(port, SNK_UNATTACHED, PD_T_DRP_SNK);
 		break;
 	case SRC_ATTACH_WAIT:
-		if (tcpm_port_is_debug(port))
+		if (tcpm_port_is_debug_source(port))
 			tcpm_set_state(port, DEBUG_ACC_ATTACHED,
 				       PD_T_CC_DEBOUNCE);
 		else if (tcpm_port_is_audio(port))
@@ -5868,7 +5871,7 @@ static void _tcpm_cc_change(struct tcpm_
 
 	switch (port->state) {
 	case TOGGLING:
-		if (tcpm_port_is_debug(port) || tcpm_port_is_audio(port) ||
+		if (tcpm_port_is_debug_source(port) || tcpm_port_is_audio(port) ||
 		    tcpm_port_is_source(port))
 			tcpm_set_state(port, SRC_ATTACH_WAIT, 0);
 		else if (tcpm_port_is_sink(port))
@@ -5879,7 +5882,7 @@ static void _tcpm_cc_change(struct tcpm_
 		break;
 	case SRC_UNATTACHED:
 	case ACC_UNATTACHED:
-		if (tcpm_port_is_debug(port) || tcpm_port_is_audio(port) ||
+		if (tcpm_port_is_debug_source(port) || tcpm_port_is_audio(port) ||
 		    tcpm_port_is_source(port))
 			tcpm_set_state(port, SRC_ATTACH_WAIT, 0);
 		break;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 616/877] usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (614 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 615/877] usb: typec: tcpm: fix debug accessory mode detection for sink ports Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 617/877] wifi: mt76: mt7996: bound the device EEPROM address before the EFUSE copy Greg Kroah-Hartman
                   ` (268 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, stable, Amit Sunil Dhamne,
	Badhri Jagan Sridharan, Heikki Krogerus, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Amit Sunil Dhamne <amitsd@google.com>

[ Upstream commit cd3b9cea675bbfebc223f007dc2f4e79524fa54c ]

When a sink detach occurs while waiting for TX send status, the old
TCPM_SOURCING_VBUS event along with TCPM_VBUS_EVENT and TCPM_CC_EVENT
can be queued in port->pd_events. Because TCPM_SOURCING_VBUS is
evaluated after TCPM_VBUS_EVENT and TCPM_CC_EVENT in
tcpm_pd_event_handler(), a stale TCPM_SOURCING_VBUS event can override
the detach handling and incorrectly set port->vbus_source and
port->vbus_present to true.

Add a state guard to check that the port is either operating as a
Source (tcpm_port_is_source(port)) or in a Fast Role Swap (FRS) state
up to FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED before processing
TCPM_SOURCING_VBUS. Otherwise, discard and log the event.

Log snippet for error condition before fix:
[72792.204955] state change SRC_ATTACHED -> SRC_STARTUP [rev3 NONE_AMS]
[72792.204960] sourcing vbus
[72792.204962] VBUS on
[72792.204970] AMS POWER_NEGOTIATION start
[72792.204974] cc:=4
[72792.205319] state change SRC_STARTUP -> AMS_START [rev3 POWER_NEGOTIATION]
[72792.205325] state change AMS_START -> SRC_SEND_CAPABILITIES [rev3 POWER_NEGOTIATION]
[72792.205332] PD TX, header: 0x11a1
[72792.216911] PD TX complete, status: 2
[72792.216957] pending state change SRC_SEND_CAPABILITIES -> SRC_SEND_CAPABILITIES @ 150 ms [rev3 POWER_NEGOTIATION]
[72792.218005] VBUS off
[72792.218013] pending state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED @ 650 ms [rev3 POWER_NEGOTIATION]
[72792.218020] VBUS VSAFE0V
[72792.218024] state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED [rev3 POWER_NEGOTIATION]
[72792.218458] CC1: 2 -> 0, CC2: 0 -> 0 [state SNK_UNATTACHED, polarity 0, disconnected]
[72792.218467] VBUS on --> VBUS left on
[72792.218980] disable vbus discharge ret:0
[72792.235193] Start toggling

After fix:
[ 1195.291691] state change SRC_ATTACHED -> SRC_STARTUP [rev3 NONE_AMS]
[ 1195.291698] sourcing vbus
[ 1195.291700] VBUS on
[ 1195.291707] AMS POWER_NEGOTIATION start
[ 1195.291710] cc:=4
[ 1195.291758] state change SRC_STARTUP -> AMS_START [rev3 POWER_NEGOTIATION]
[ 1195.291794] state change AMS_START -> SRC_SEND_CAPABILITIES [rev3 POWER_NEGOTIATION]
[ 1195.291798] PD TX, header: 0x11a1
[ 1195.297056] PD TX complete, status: 2
[ 1195.297092] pending state change SRC_SEND_CAPABILITIES -> SRC_SEND_CAPABILITIES @ 150 ms [rev3 POWER_NEGOTIATION]
[ 1195.297177] VBUS off
[ 1195.297184] pending state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED @ 650 ms [rev3 POWER_NEGOTIATION]
[ 1195.297227] CC1: 2 -> 0, CC2: 0 -> 0 [state SRC_SEND_CAPABILITIES, polarity 0, disconnected]
[ 1195.307469] cc:=2
[ 1195.307544] pending state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED @ 650 ms [rev3 POWER_NEGOTIATION]
[ 1195.307555] Discarding sourcing vbus! Invalid state SRC_SEND_CAPABILITIES
[ 1195.957636] state change SRC_SEND_CAPABILITIES -> SNK_UNATTACHED [delayed 650 ms]
[ 1195.957732] disable vbus discharge ret:0
[ 1195.970196] Start toggling
[ 1195.970468] VBUS off
[ 1196.051637] VBUS off
[ 1196.051642] VBUS VSAFE0V

Fixes: 8dc4bd073663 ("usb: typec: tcpm: Add support for Sink Fast Role SWAP(FRS)")
Cc: stable <stable@kernel.org>
Assisted-by: Gemini:gemini-3.1-pro
Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
Reviewed-by: Badhri Jagan Sridharan <badhri@google.com>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20260827-sourcing-vbus-v1-1-9be1aca991a0@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/typec/tcpm/tcpm.c |   28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -6385,16 +6385,32 @@ static void tcpm_pd_event_handler(struct
 			}
 		}
 		if (events & TCPM_SOURCING_VBUS) {
-			tcpm_log(port, "sourcing vbus");
 			/*
 			 * In fast role swap case TCPC autonomously sources vbus. Set vbus_source
-			 * true as TCPM wouldn't have called tcpm_set_vbus.
+			 * true conditionally as TCPM wouldn't have called tcpm_set_vbus.
+			 * If TCPM calls tcpm_set_vbus to source vbus, vbus_source would already
+			 * be true.
 			 *
-			 * When vbus is sourced on the command on TCPM i.e. TCPM called
-			 * tcpm_set_vbus to source vbus, vbus_source would already be true.
+			 * When TCPM_FRS_EVENT and TCPM_SOURCING_VBUS arrive simultaneously,
+			 * handling TCPM_FRS_EVENT above transitions the state to AMS_START
+			 * with upcoming_state FR_SWAP_SEND.
 			 */
-			port->vbus_source = true;
-			_tcpm_pd_vbus_on(port);
+
+			if (tcpm_port_is_source(port) ||
+			    tcpm_port_is_debug_source(port) ||
+			    (port->state == AMS_START && port->upcoming_state == FR_SWAP_SEND) ||
+			    port->state == FR_SWAP_SEND ||
+			    port->state == FR_SWAP_SEND_TIMEOUT ||
+			    port->state == FR_SWAP_SNK_SRC_TRANSITION_TO_OFF ||
+			    port->state == FR_SWAP_SNK_SRC_NEW_SINK_READY ||
+			    port->state == FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED) {
+				tcpm_log(port, "sourcing vbus");
+				port->vbus_source = true;
+				_tcpm_pd_vbus_on(port);
+			} else {
+				tcpm_log(port, "Discarding sourcing vbus! Invalid state %s",
+					 tcpm_states[port->state]);
+			}
 		}
 		if (events & TCPM_PORT_CLEAN) {
 			tcpm_log(port, "port clean");



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 617/877] wifi: mt76: mt7996: bound the device EEPROM address before the EFUSE copy
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (615 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 616/877] usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 618/877] xhci: Cleanup Candence controller PCI device and vendor ID usage Greg Kroah-Hartman
                   ` (267 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bryam Vargas, Felix Fietkau,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bryam Vargas <hexlabsecurity@proton.me>

[ Upstream commit 13b3c29a782033ce4a230be9e5618032813dbcd4 ]

mt7996_mcu_get_eeprom() derives the destination of the EFUSE/EXT block
copy from the address reported by the MCU response (event->addr, a
device-controlled __le32) and clamps only the copy length, never the
destination offset into dev->mt76.eeprom.data. A malicious or
malfunctioning device can report an arbitrary address and drive an
out-of-bounds write of up to MT7996_EXT_EEPROM_BLOCK_SIZE bytes past
eeprom.data.

Reject a response whose address would place the copy outside eeprom.data
before deriving the destination pointer. Devices that echo the requested
in-bounds offset are unaffected.

Fixes: 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Link: https://patch.msgid.link/20260625-b4-disp-16f99062-v1-2-aee52ecf61b9@proton.me
Signed-off-by: Felix Fietkau <nbd@nbd.name>
[ adapted mt7996_mcu_get_eeprom() changes to the older fixed 16-byte EFUSE implementation. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
@@ -3586,7 +3586,13 @@ int mt7996_mcu_get_eeprom(struct mt7996_
 	valid = le32_to_cpu(*(__le32 *)(skb->data + 16));
 	if (valid) {
 		u32 addr = le32_to_cpu(*(__le32 *)(skb->data + 12));
-		u8 *buf = (u8 *)dev->mt76.eeprom.data + addr;
+		u8 *buf;
+
+		if (addr > dev->mt76.eeprom.size - MT7996_EEPROM_BLOCK_SIZE) {
+			dev_kfree_skb(skb);
+			return -EINVAL;
+		}
+		buf = (u8 *)dev->mt76.eeprom.data + addr;
 
 		skb_pull(skb, 48);
 		memcpy(buf, skb->data, MT7996_EEPROM_BLOCK_SIZE);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 618/877] xhci: Cleanup Candence controller PCI device and vendor ID usage
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (616 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 617/877] wifi: mt76: mt7996: bound the device EEPROM address before the EFUSE copy Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 619/877] usb: cdns3: rename hibernated argument of role->resume() to lost_power Greg Kroah-Hartman
                   ` (266 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Andy Shevchenko, Mathias Nyman,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mathias Nyman <mathias.nyman@linux.intel.com>

[ Upstream commit f28a7d7db247af8b9f1090bd6b1ca1fa48a3f0e4 ]

Use predefined PCI vendor ID constant for Cadence controller in pci_ids.h
Rename the Candence device ID to match the pattern other PCI vendor and
device IDs use

Reported-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Closes: https://lore.kernel.org/linux-usb/ZuMOfHp9j_6_3-WC@surfacebook.localdomain
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://lore.kernel.org/r/20241106101459.775897-5-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: eae6460f6173 ("usb: cdnsp: fix wakeup from S3 after controller context loss")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/host/xhci-pci.c |    8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -94,8 +94,7 @@
 #define PCI_DEVICE_ID_ASMEDIA_3042_XHCI			0x3042
 #define PCI_DEVICE_ID_ASMEDIA_3242_XHCI			0x3242
 
-#define PCI_DEVICE_ID_CADENCE				0x17CD
-#define PCI_DEVICE_ID_CADENCE_SSP			0x0200
+#define PCI_DEVICE_ID_CDNS_SSP				0x0200
 
 static const char hcd_name[] = "xhci_hcd";
 
@@ -508,9 +507,8 @@ static void xhci_pci_quirks(struct devic
 		if (pdev->device == 0x9203)
 			xhci->quirks |= XHCI_TRB_OVERFETCH;
 	}
-
-	if (pdev->vendor == PCI_DEVICE_ID_CADENCE &&
-	    pdev->device == PCI_DEVICE_ID_CADENCE_SSP)
+	if (pdev->vendor == PCI_VENDOR_ID_CDNS &&
+	    pdev->device == PCI_DEVICE_ID_CDNS_SSP)
 		xhci->quirks |= XHCI_CDNS_SCTX_QUIRK;
 
 	/* xHC spec requires PCI devices to support D3hot and D3cold */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 619/877] usb: cdns3: rename hibernated argument of role->resume() to lost_power
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (617 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 618/877] xhci: Cleanup Candence controller PCI device and vendor ID usage Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 620/877] usb: cdnsp: fix wakeup from S3 after controller context loss Greg Kroah-Hartman
                   ` (265 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Théo Lebrun, Peter Chen,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Théo Lebrun <theo.lebrun@bootlin.com>

[ Upstream commit 0bde749c58c72405c54a1eabf6266a0273377226 ]

The cdns_role_driver->resume() callback takes a second boolean argument
named `hibernated` in its implementations. This is mistaken; the only
potential caller is:

int cdns_resume(struct cdns *cdns)
{
	/* ... */

	if (cdns->roles[cdns->role]->resume)
		cdns->roles[cdns->role]->resume(cdns, cdns_power_is_lost(cdns));

	return 0;
}

The argument can be true in cases outside of return from hibernation.
Reflect the true meaning by renaming both arguments to `lost_power`.

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
Acked-by: Peter Chen <peter.chen@kernel.org>
Link: https://lore.kernel.org/r/20250205-s2r-cdns-v7-3-13658a271c3c@bootlin.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: eae6460f6173 ("usb: cdnsp: fix wakeup from S3 after controller context loss")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/cdns3/cdns3-gadget.c |    4 ++--
 drivers/usb/cdns3/cdnsp-gadget.c |    2 +-
 drivers/usb/cdns3/core.h         |    2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

--- a/drivers/usb/cdns3/cdns3-gadget.c
+++ b/drivers/usb/cdns3/cdns3-gadget.c
@@ -3484,7 +3484,7 @@ __must_hold(&cdns->lock)
 	return 0;
 }
 
-static int cdns3_gadget_resume(struct cdns *cdns, bool hibernated)
+static int cdns3_gadget_resume(struct cdns *cdns, bool lost_power)
 {
 	struct cdns3_device *priv_dev = cdns->gadget_dev;
 
@@ -3492,7 +3492,7 @@ static int cdns3_gadget_resume(struct cd
 		return 0;
 
 	cdns3_gadget_config(priv_dev);
-	if (hibernated)
+	if (lost_power)
 		writel(USB_CONF_DEVEN, &priv_dev->regs->usb_conf);
 
 	return 0;
--- a/drivers/usb/cdns3/cdnsp-gadget.c
+++ b/drivers/usb/cdns3/cdnsp-gadget.c
@@ -2025,7 +2025,7 @@ static int cdnsp_gadget_suspend(struct c
 	return 0;
 }
 
-static int cdnsp_gadget_resume(struct cdns *cdns, bool hibernated)
+static int cdnsp_gadget_resume(struct cdns *cdns, bool lost_power)
 {
 	struct cdnsp_device *pdev = cdns->gadget_dev;
 	enum usb_device_speed max_speed;
--- a/drivers/usb/cdns3/core.h
+++ b/drivers/usb/cdns3/core.h
@@ -30,7 +30,7 @@ struct cdns_role_driver {
 	int (*start)(struct cdns *cdns);
 	void (*stop)(struct cdns *cdns);
 	int (*suspend)(struct cdns *cdns, bool do_wakeup);
-	int (*resume)(struct cdns *cdns, bool hibernated);
+	int (*resume)(struct cdns *cdns, bool lost_power);
 	const char *name;
 #define CDNS_ROLE_STATE_INACTIVE	0
 #define CDNS_ROLE_STATE_ACTIVE		1



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 620/877] usb: cdnsp: fix wakeup from S3 after controller context loss
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (618 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 619/877] usb: cdns3: rename hibernated argument of role->resume() to lost_power Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 621/877] usb: storage: realtek_cr: fix use-after-free on disconnect Greg Kroah-Hartman
                   ` (264 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, stable, Pawel Laszczak, Peter Chen,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pawel Laszczak <pawell@cadence.com>

[ Upstream commit eae6460f617382044c5afe5ef202f4d8b2c099b5 ]

CDNSP controller may lose its runtime register programming across S3
suspend/resume, depending on SoC power domain configuration. After
resume the operational and interrupter registers may contain reset
values, which prevents the gadget side from recovering correctly and
breaks wakeup from S3.

Fix this by detecting whether the controller lost its register context
after resume and handling both cases:
- If context was lost (CFG_3XPORT_U1_PIPE_CLK_GATE_EN set or power
  lost): reset the controller and reprogram the state required for
  normal operation, including the command ring, DCBAA pointer, doorbell
  base, event ring, ERST base/size and event ring dequeue pointer.
- If context was retained: restart the controller directly without
  reprogramming registers. Issue a wakeup if the link was in U3 before
  suspend.

Move the basic controller register programming out of the one-time memory
initialization path and make it reusable from the resume path. Also
separate ring allocation from ring initialization so that rings can be
reinitialized without reallocating DMA memory.

Always perform the full suspend sequence regardless of the current link
state. Previously, if the device was already in U3, the suspend callback
returned early without stopping the controller, which could lead to
commands being issued on a disabled slot during resume.

Fixes: 3d82904559f4 ("usb: cdnsp: cdns3 Add main part of Cadence USBSSP DRD Driver")
Cc: stable <stable@kernel.org>
Signed-off-by: Pawel Laszczak <pawell@cadence.com>
Acked-by: Peter Chen <peter.chen@kernel.org>
Link: https://patch.msgid.link/20260820-suspend_resume_fix-v3-1-5a713098b977@cadence.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/cdns3/cdnsp-gadget.c |  110 +++++++++++++++++++++++++++++++++++++--
 drivers/usb/cdns3/cdnsp-gadget.h |    1 
 drivers/usb/cdns3/cdnsp-mem.c    |   98 ++++++++++++----------------------
 3 files changed, 142 insertions(+), 67 deletions(-)

--- a/drivers/usb/cdns3/cdnsp-gadget.c
+++ b/drivers/usb/cdns3/cdnsp-gadget.c
@@ -1819,6 +1819,82 @@ static void cdnsp_get_rev_cap(struct cdn
 		 readl(&pdev->rev_cap->tx_buff_size));
 }
 
+static void cdnsp_set_event_deq(struct cdnsp_device *pdev)
+{
+	dma_addr_t deq;
+	u64 temp;
+
+	deq = cdnsp_trb_virt_to_dma(pdev->event_ring->deq_seg,
+				    pdev->event_ring->dequeue);
+
+	/* Update controller event ring dequeue pointer */
+	temp = cdnsp_read_64(&pdev->ir_set->erst_dequeue);
+	temp &= ERST_PTR_MASK;
+
+	/*
+	 * Don't clear the EHB bit (which is RW1C) because
+	 * there might be more events to service.
+	 */
+	temp &= ~ERST_EHB;
+
+	cdnsp_write_64(((u64)deq & (u64)~ERST_PTR_MASK) | temp,
+		       &pdev->ir_set->erst_dequeue);
+}
+
+static void cdnsp_add_interrupter(struct cdnsp_device *pdev)
+{
+	u64 erst_base;
+	u32 erst_size;
+
+	/* Set ERST count with the number of entries in the segment table. */
+	erst_size = readl(&pdev->ir_set->erst_size);
+	erst_size &= ERST_SIZE_MASK;
+	erst_size |= ERST_NUM_SEGS;
+	writel(erst_size, &pdev->ir_set->erst_size);
+
+	/* Set the segment table base address. */
+	erst_base = cdnsp_read_64(&pdev->ir_set->erst_base);
+	erst_base &= ERST_PTR_MASK;
+	erst_base |= (pdev->erst.erst_dma_addr & (u64)~ERST_PTR_MASK);
+	cdnsp_write_64(erst_base, &pdev->ir_set->erst_base);
+
+	/* Set the event ring dequeue address. */
+	cdnsp_set_event_deq(pdev);
+}
+
+/* Set up basic CDNSP registers */
+static void cdnsp_init(struct cdnsp_device *pdev)
+{
+	unsigned int val;
+	u64 val_64;
+
+	val = readl(&pdev->op_regs->config_reg);
+	val |= ((val & ~MAX_DEVS) | CDNSP_DEV_MAX_SLOTS) | CONFIG_U3E;
+	writel(val, &pdev->op_regs->config_reg);
+
+	/* Initialize the Command ring */
+	cdnsp_ring_init(pdev, pdev->cmd_ring);
+
+	/* Set the address in the Command Ring Control register */
+	val_64 = cdnsp_read_64(&pdev->op_regs->cmd_ring);
+	val_64 = (val_64 & (u64)CMD_RING_RSVD_BITS) |
+		 (pdev->cmd_ring->first_seg->dma & (u64)~CMD_RING_RSVD_BITS) |
+		 pdev->cmd_ring->cycle_state;
+	cdnsp_write_64(val_64, &pdev->op_regs->cmd_ring);
+
+	/* Set Device Context Base Address Array pointer */
+	cdnsp_write_64(pdev->dcbaa->dma, &pdev->op_regs->dcbaa_ptr);
+
+	/* Set Doorbell array pointer */
+	val = readl(&pdev->cap_regs->db_off);
+	val &= DBOFF_MASK;
+	pdev->dba = (void __iomem *)pdev->cap_regs + val;
+
+	/* Initialize the Primary interrupter */
+	cdnsp_ring_init(pdev, pdev->event_ring);
+	cdnsp_add_interrupter(pdev);
+}
+
 static int cdnsp_gen_setup(struct cdnsp_device *pdev)
 {
 	int ret;
@@ -1884,6 +1960,8 @@ static int cdnsp_gen_setup(struct cdnsp_
 	if (ret)
 		return ret;
 
+	cdnsp_init(pdev);
+
 	/*
 	 * Software workaround for U1: after transition
 	 * to U1 the controller starts gating clock, and in some cases,
@@ -2014,9 +2092,6 @@ static int cdnsp_gadget_suspend(struct c
 	struct cdnsp_device *pdev = cdns->gadget_dev;
 	unsigned long flags;
 
-	if (pdev->link_state == XDEV_U3)
-		return 0;
-
 	spin_lock_irqsave(&pdev->lock, flags);
 	cdnsp_disconnect_gadget(pdev);
 	cdnsp_stop(pdev);
@@ -2030,12 +2105,38 @@ static int cdnsp_gadget_resume(struct cd
 	struct cdnsp_device *pdev = cdns->gadget_dev;
 	enum usb_device_speed max_speed;
 	unsigned long flags;
+	bool context_lost;
+	u32 val;
 	int ret;
 
 	if (!pdev->gadget_driver)
 		return 0;
 
 	spin_lock_irqsave(&pdev->lock, flags);
+	val = readl(&pdev->port3x_regs->mode_2);
+	context_lost = !!(val & CFG_3XPORT_U1_PIPE_CLK_GATE_EN) || lost_power;
+
+	if (context_lost) {
+		cdnsp_halt(pdev);
+		cdnsp_set_apb_timeout_value(pdev);
+
+		/* Reset the internal controller memory state and registers. */
+		ret = cdnsp_reset(pdev);
+		if (ret)
+			goto unlock;
+
+		val = readl(&pdev->port3x_regs->mode_2);
+		val &= ~CFG_3XPORT_U1_PIPE_CLK_GATE_EN;
+		writel(val, &pdev->port3x_regs->mode_2);
+
+		cdnsp_clear_cmd_ring(pdev);
+
+		memset(pdev->event_ring->first_seg->trbs, 0,
+		       sizeof(union cdnsp_trb) * (TRBS_PER_SEGMENT));
+
+		cdnsp_init(pdev);
+	}
+
 	max_speed = pdev->gadget_driver->max_speed;
 
 	/* Limit speed if necessary. */
@@ -2043,9 +2144,10 @@ static int cdnsp_gadget_resume(struct cd
 
 	ret = cdnsp_run(pdev, max_speed);
 
-	if (pdev->link_state == XDEV_U3)
+	if (!context_lost && pdev->link_state == XDEV_U3)
 		__cdnsp_gadget_wakeup(pdev);
 
+unlock:
 	spin_unlock_irqrestore(&pdev->lock, flags);
 
 	return ret;
--- a/drivers/usb/cdns3/cdnsp-gadget.h
+++ b/drivers/usb/cdns3/cdnsp-gadget.h
@@ -1509,6 +1509,7 @@ int cdnsp_endpoint_init(struct cdnsp_dev
 int cdnsp_ring_expansion(struct cdnsp_device *pdev,
 			 struct cdnsp_ring *ring,
 			 unsigned int num_trbs, gfp_t flags);
+void cdnsp_ring_init(struct cdnsp_device *pdev, struct cdnsp_ring *ring);
 struct cdnsp_ring *cdnsp_dma_to_transfer_ring(struct cdnsp_ep *ep, u64 address);
 int cdnsp_alloc_stream_info(struct cdnsp_device *pdev,
 			    struct cdnsp_ep *pep,
--- a/drivers/usb/cdns3/cdnsp-mem.c
+++ b/drivers/usb/cdns3/cdnsp-mem.c
@@ -394,13 +394,6 @@ static struct cdnsp_ring *cdnsp_ring_all
 	if (ret)
 		goto fail;
 
-	/* Only event ring does not use link TRB. */
-	if (type != TYPE_EVENT)
-		ring->last_seg->trbs[TRBS_PER_SEGMENT - 1].link.control |=
-			cpu_to_le32(LINK_TOGGLE);
-
-	cdnsp_initialize_ring_info(ring);
-	trace_cdnsp_ring_alloc(ring);
 	return ring;
 fail:
 	kfree(ring);
@@ -604,6 +597,7 @@ int cdnsp_alloc_stream_info(struct cdnsp
 		if (!cur_ring)
 			goto cleanup_rings;
 
+		cdnsp_ring_init(pdev, cur_ring);
 		cur_ring->stream_id = cur_stream;
 		cur_ring->trb_address_map = &stream_info->trb_address_map;
 
@@ -699,6 +693,8 @@ static int cdnsp_alloc_priv_device(struc
 	if (!pdev->eps[0].ring)
 		goto fail;
 
+	cdnsp_ring_init(pdev, pdev->eps[0].ring);
+
 	/* Point to output device context in dcbaa. */
 	pdev->dcbaa->dev_context_ptrs[1] = cpu_to_le64(pdev->out_ctx.dma);
 	pdev->cmd.in_ctx = &pdev->in_ctx;
@@ -992,6 +988,8 @@ int cdnsp_endpoint_init(struct cdnsp_dev
 	if (!pep->ring)
 		return -ENOMEM;
 
+	cdnsp_ring_init(pdev, pep->ring);
+
 	pep->skip = false;
 
 	/* Fill the endpoint context */
@@ -1099,28 +1097,6 @@ void cdnsp_mem_cleanup(struct cdnsp_devi
 	pdev->active_port = NULL;
 }
 
-static void cdnsp_set_event_deq(struct cdnsp_device *pdev)
-{
-	dma_addr_t deq;
-	u64 temp;
-
-	deq = cdnsp_trb_virt_to_dma(pdev->event_ring->deq_seg,
-				    pdev->event_ring->dequeue);
-
-	/* Update controller event ring dequeue pointer */
-	temp = cdnsp_read_64(&pdev->ir_set->erst_dequeue);
-	temp &= ERST_PTR_MASK;
-
-	/*
-	 * Don't clear the EHB bit (which is RW1C) because
-	 * there might be more events to service.
-	 */
-	temp &= ~ERST_EHB;
-
-	cdnsp_write_64(((u64)deq & (u64)~ERST_PTR_MASK) | temp,
-		       &pdev->ir_set->erst_dequeue);
-}
-
 static void cdnsp_add_in_port(struct cdnsp_device *pdev,
 			      struct cdnsp_port *port,
 			      __le32 __iomem *addr)
@@ -1200,6 +1176,36 @@ static int cdnsp_setup_port_arrays(struc
 	return 0;
 }
 
+static void cdnsp_initialize_ring_segments(struct cdnsp_device *pdev, struct cdnsp_ring *ring)
+{
+	struct cdnsp_segment *seg;
+
+	/* Only event ring does not use link TRB. */
+	if (ring->type == TYPE_EVENT)
+		return;
+
+	seg = ring->first_seg;
+
+	while (seg) {
+		struct cdnsp_segment *next = seg->next;
+
+		cdnsp_link_segments(pdev, seg, next, ring->type);
+		if (next == ring->first_seg)
+			break;
+
+		seg = next;
+	}
+
+	ring->last_seg->trbs[TRBS_PER_SEGMENT - 1].link.control |= cpu_to_le32(LINK_TOGGLE);
+}
+
+void cdnsp_ring_init(struct cdnsp_device *pdev, struct cdnsp_ring *ring)
+{
+	cdnsp_initialize_ring_segments(pdev, ring);
+	cdnsp_initialize_ring_info(ring);
+	trace_cdnsp_ring_alloc(ring);
+}
+
 /*
  * Initialize memory for CDNSP (one-time init).
  *
@@ -1211,10 +1217,8 @@ int cdnsp_mem_init(struct cdnsp_device *
 {
 	struct device *dev = pdev->dev;
 	int ret = -ENOMEM;
-	unsigned int val;
 	dma_addr_t dma;
 	u32 page_size;
-	u64 val_64;
 
 	/*
 	 * Use 4K pages, since that's common and the minimum the
@@ -1222,10 +1226,6 @@ int cdnsp_mem_init(struct cdnsp_device *
 	 */
 	page_size = 1 << 12;
 
-	val = readl(&pdev->op_regs->config_reg);
-	val |= ((val & ~MAX_DEVS) | CDNSP_DEV_MAX_SLOTS) | CONFIG_U3E;
-	writel(val, &pdev->op_regs->config_reg);
-
 	/*
 	 * Doorbell array must be physically contiguous
 	 * and 64-byte (cache line) aligned.
@@ -1237,8 +1237,6 @@ int cdnsp_mem_init(struct cdnsp_device *
 
 	pdev->dcbaa->dma = dma;
 
-	cdnsp_write_64(dma, &pdev->op_regs->dcbaa_ptr);
-
 	/*
 	 * Initialize the ring segment pool.  The ring must be a contiguous
 	 * structure comprised of TRBs. The TRBs must be 16 byte aligned,
@@ -1264,17 +1262,6 @@ int cdnsp_mem_init(struct cdnsp_device *
 	if (!pdev->cmd_ring)
 		goto destroy_device_pool;
 
-	/* Set the address in the Command Ring Control register */
-	val_64 = cdnsp_read_64(&pdev->op_regs->cmd_ring);
-	val_64 = (val_64 & (u64)CMD_RING_RSVD_BITS) |
-		 (pdev->cmd_ring->first_seg->dma & (u64)~CMD_RING_RSVD_BITS) |
-		 pdev->cmd_ring->cycle_state;
-	cdnsp_write_64(val_64, &pdev->op_regs->cmd_ring);
-
-	val = readl(&pdev->cap_regs->db_off);
-	val &= DBOFF_MASK;
-	pdev->dba = (void __iomem *)pdev->cap_regs + val;
-
 	/* Set ir_set to interrupt register set 0 */
 	pdev->ir_set = &pdev->run_regs->ir_set[0];
 
@@ -1291,21 +1278,6 @@ int cdnsp_mem_init(struct cdnsp_device *
 	if (ret)
 		goto free_event_ring;
 
-	/* Set ERST count with the number of entries in the segment table. */
-	val = readl(&pdev->ir_set->erst_size);
-	val &= ERST_SIZE_MASK;
-	val |= ERST_NUM_SEGS;
-	writel(val, &pdev->ir_set->erst_size);
-
-	/* Set the segment table base address. */
-	val_64 = cdnsp_read_64(&pdev->ir_set->erst_base);
-	val_64 &= ERST_PTR_MASK;
-	val_64 |= (pdev->erst.erst_dma_addr & (u64)~ERST_PTR_MASK);
-	cdnsp_write_64(val_64, &pdev->ir_set->erst_base);
-
-	/* Set the event ring dequeue address. */
-	cdnsp_set_event_deq(pdev);
-
 	ret = cdnsp_setup_port_arrays(pdev);
 	if (ret)
 		goto free_erst;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 621/877] usb: storage: realtek_cr: fix use-after-free on disconnect
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (619 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 620/877] usb: cdnsp: fix wakeup from S3 after controller context loss Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 622/877] usb: gadget: f_mass_storage: fix null pointer dereference in fsg_common_set_num_buffers() Greg Kroah-Hartman
                   ` (263 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, stable, Ijae Kim, Myeonghun Pak,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Myeonghun Pak <mhun512@gmail.com>

[ Upstream commit 4ffee1aebb0c0ffcda9faffd17834ea9b00d42cc ]

realtek_cr_destructor() calls timer_delete() before the chip containing
the timer is freed. The timer callback may still be running and can
rearm itself, resulting in a use-after-free.

Use timer_shutdown_sync() to wait for the callback and prevent further
rearming. Do this unconditionally because ss_en may be changed after
the timer is armed.

Move timer_setup() into init_realtek_cr() so the timer is initialized
before any failure path can invoke the destructor.

Found by static analysis.

Fixes: e931830bb877 ("Realtek cr: Add autosuspend function.")
Cc: stable <stable@kernel.org>
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Link: https://patch.msgid.link/20260727123414.44700-1-mhun512@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ adapted the timer_delete() removal to the branch’s del_timer() spelling. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/storage/realtek_cr.c |    9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

--- a/drivers/usb/storage/realtek_cr.c
+++ b/drivers/usb/storage/realtek_cr.c
@@ -915,7 +915,6 @@ static int realtek_cr_autosuspend_setup(
 	us->proto_handler = rts51x_invoke_transport;
 
 	chip->timer_expires = 0;
-	timer_setup(&chip->rts51x_suspend_timer, rts51x_suspend_timer_fn, 0);
 	fw5895_init(us);
 
 	/* enable autosuspend function of the usb device */
@@ -933,10 +932,7 @@ static void realtek_cr_destructor(void *
 		return;
 
 #ifdef CONFIG_REALTEK_AUTOPM
-	if (ss_en) {
-		del_timer(&chip->rts51x_suspend_timer);
-		chip->timer_expires = 0;
-	}
+	timer_shutdown_sync(&chip->rts51x_suspend_timer);
 #endif
 	kfree(chip->status);
 }
@@ -981,6 +977,9 @@ static int init_realtek_cr(struct us_dat
 
 	us->extra = chip;
 	us->extra_destructor = realtek_cr_destructor;
+#ifdef CONFIG_REALTEK_AUTOPM
+	timer_setup(&chip->rts51x_suspend_timer, rts51x_suspend_timer_fn, 0);
+#endif
 	us->max_lun = chip->max_lun = rts51x_get_max_lun(us);
 	chip->us = us;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 622/877] usb: gadget: f_mass_storage: fix null pointer dereference in fsg_common_set_num_buffers()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (620 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 621/877] usb: storage: realtek_cr: fix use-after-free on disconnect Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 623/877] staging: rtl8723bs: fix spacing around operators Greg Kroah-Hartman
                   ` (262 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+791be35f1fbcc85d06d7, stable,
	Jeffin Philip, Alan Stern, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jeffin Philip <jeffinphilip14@gmail.com>

[ Upstream commit 2c0f5ca48674a5b5f9fa4a9c3325aa48053af0bc ]

Previously fsg_num_buffers_validate() was removed as it was not
necessary due to Kconfig setting the limits for n from 2 to 256 with
default as 2. However, setting the page content in such a way that
kstrtou8() reflects n value as either 0 or 1 bypasses these
restrictions leading to a null pointer dereference if n is 0. Fix
this by adding a check for n < 2 and returning -EINVAL if n is
either 0 or 1 consistent with Kconfig logic.

Reported-by: syzbot+791be35f1fbcc85d06d7@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=791be35f1fbcc85d06d7
Fixes: fe5a6c48fd95 ("usb: gadget: storage: get rid of fsg_num_buffers_validate()")
Cc: stable <stable@kernel.org>
Signed-off-by: Jeffin Philip <jeffinphilip14@gmail.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://patch.msgid.link/20260818035904.10324-1-jeffinphilip14@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ adjusted context to retain the branch’s existing kcalloc() call instead of kzalloc_objs(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/gadget/function/f_mass_storage.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -2748,6 +2748,9 @@ int fsg_common_set_num_buffers(struct fs
 	struct fsg_buffhd *bh, *buffhds;
 	int i;
 
+	if (n < 2)
+		return -EINVAL;
+
 	buffhds = kcalloc(n, sizeof(*buffhds), GFP_KERNEL);
 	if (!buffhds)
 		return -ENOMEM;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 623/877] staging: rtl8723bs: fix spacing around operators
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (621 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 622/877] usb: gadget: f_mass_storage: fix null pointer dereference in fsg_common_set_num_buffers() Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 624/877] staging: rtl8723bs: fix OOB read in rtw_restruct_wmm_ie() Greg Kroah-Hartman
                   ` (261 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Vivek BalachandharTN, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Vivek BalachandharTN <vivek.balachandhar@gmail.com>

[ Upstream commit 2038fe84b8bdf894b634f777096685e78e8f3774 ]

Fix several instances where operators lacked spaces around them.
This improves readability and brings the driver closer to kernel
coding-style guidelines. No functional change.

Signed-off-by: Vivek BalachandharTN <vivek.balachandhar@gmail.com>
Link: https://patch.msgid.link/20251205021417.2705864-3-vivek.balachandhar@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

For this stable dependency, retain only the spacing change to the IE
advance in rtw_restruct_wmm_ie(). This supplies the exact context needed
by target commit 28a289beaf226 ("staging: rtl8723bs: fix OOB read in
rtw_restruct_wmm_ie()"). Drop the unrelated operator-spacing hunks.

Keep the existing bounds-first WMM match condition from stable commit
4dd2d9cf563c5 (upstream a75281626fc8f); applying the older condition
would undo its out-of-bounds-read fix. No functional change.

Stable-dep-of: 28a289beaf22 ("staging: rtl8723bs: fix OOB read in rtw_restruct_wmm_ie()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/staging/rtl8723bs/core/rtw_mlme.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/staging/rtl8723bs/core/rtw_mlme.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c
@@ -1950,7 +1950,7 @@ int rtw_restruct_wmm_ie(struct adapter *
 			break;
 		}
 
-		i += (in_ie[i+1]+2); /*  to the next IE element */
+		i += (in_ie[i + 1] + 2); /*  to the next IE element */
 	}
 
 	return ielength;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 624/877] staging: rtl8723bs: fix OOB read in rtw_restruct_wmm_ie()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (622 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 623/877] staging: rtl8723bs: fix spacing around operators Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 625/877] staging: sm750fb: fix mono image source stride mismatch in lynxfb_ops_imageblit() Greg Kroah-Hartman
                   ` (260 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Muhammad Bilal, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Muhammad Bilal <meatuni001@gmail.com>

[ Upstream commit 28a289beaf226b30b1e6e7d7b1a2946fe2d6e852 ]

rtw_restruct_wmm_ie() scans in_ie for a WMM IE with:

	while (i < in_len) {
		...
		if (i + 5 < in_len && in_ie[i] == 0xDD && ...) {
			...
			break;
		}
		i += (in_ie[i + 1] + 2); /* to the next IE element */
	}

When the "i + 5 < in_len" match check fails simply because i is
within 5 bytes of the end of the buffer (i.e. no WMM IE was found
near the tail of in_ie), execution falls through to
"i += (in_ie[i + 1] + 2)", which reads in_ie[i + 1]. If i == in_len
- 1 at that point, this is a 1-byte out-of-bounds read of an
attacker-influenced IE buffer built from association/scan data.

Commit a75281626fc8f ("staging: rtl8723bs: fix potential
out-of-bounds read in rtw_restruct_wmm_ie") added the "i + 5 <
in_len" guard to the match condition itself, but did not add an
equivalent guard before the fallthrough advance, so the same class
of OOB read remained reachable through the non-matching path.

Add an explicit bounds check before advancing to the next IE.

Fixes: 554c0a3abf216 ("staging: Add rtl8723bs sdio wifi driver")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://patch.msgid.link/20260728125456.32359-4-meatuni001@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/staging/rtl8723bs/core/rtw_mlme.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/staging/rtl8723bs/core/rtw_mlme.c
+++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c
@@ -1950,6 +1950,9 @@ int rtw_restruct_wmm_ie(struct adapter *
 			break;
 		}
 
+		if (i + 1 >= in_len)
+			break;
+
 		i += (in_ie[i + 1] + 2); /*  to the next IE element */
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 625/877] staging: sm750fb: fix mono image source stride mismatch in lynxfb_ops_imageblit()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (623 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 624/877] staging: rtl8723bs: fix OOB read in rtw_restruct_wmm_ie() Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 626/877] tracing/probes: Fix anon_stack check for unnamed bitfields in btf_find_struct_member Greg Kroah-Hartman
                   ` (259 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Dan Carpenter, Muhammad Bilal,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Muhammad Bilal <meatuni001@gmail.com>

[ Upstream commit cc7cd2a9228175c975f62ad56ed7c767701cb4fa ]

sm750_hw_imageblit() advances its monochrome source pointer by
src_delta per scanline, and computes the correct rounded-up stride
internally as:

        bytes_per_scan = (width + start_bit + 7) / 8;

Its only caller, lynxfb_ops_imageblit(), instead passed src_delta as
image->width >> 3. For widths not a multiple of 8 this under-counted
the stride, so the source pointer fell further behind the real
per-scanline layout on every line, corrupting the rendered image.

Rather than just fixing the caller's calculation, remove src_delta
as a parameter entirely and have sm750_hw_imageblit() advance by the
bytes_per_scan it already computes for itself. There has only ever
been one caller, and that caller was passing an out-of-sync
derivative of the same width/start_bit values sm750_hw_imageblit()
already has, so keeping stride as a separate parameter served no
purpose beyond letting the two calculations drift apart, which is
exactly what happened here.

Rounding up, rather than down, is the direction consistent with the
rest of the fbdev core: struct fb_image mono bitmap data (the same
image->data this driver receives) is walked elsewhere with byte
strides derived from a ceiling division of width by 8. The generic
mono bit iterator in drivers/video/fbdev/core/fb_imageblit.h advances
scanlines with "iter->data += BITS_TO_BYTES(iter->width)", and
BITS_TO_BYTES() (include/linux/bitops.h) is a ceiling division.
sm750_hw_imageblit()'s own "(width + start_bit + 7) / 8" is that same
ceiling division with an added start_bit offset, so the caller's
">> 3" (floor) was the one calculation out of step with how this data
layout is handled everywhere else.

Found by code review of sm750_hw_imageblit()'s internal stride
calculation against what its only caller was passing in, and
confirmed with a clean -Werror build. I do not have this hardware,
so this has not been exercised at runtime on real sm750 silicon.

Fixes: 81dee67e215b2 ("staging: sm750fb: add sm750 to staging")
Cc: stable@vger.kernel.org
Reviewed-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://patch.msgid.link/20260901113031.161610-1-meatuni001@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/staging/sm750fb/sm750.c       |    2 +-
 drivers/staging/sm750fb/sm750.h       |    2 +-
 drivers/staging/sm750fb/sm750_accel.c |    6 ++----
 drivers/staging/sm750fb/sm750_accel.h |    4 +---
 4 files changed, 5 insertions(+), 9 deletions(-)

--- a/drivers/staging/sm750fb/sm750.c
+++ b/drivers/staging/sm750fb/sm750.c
@@ -275,7 +275,7 @@ static void lynxfb_ops_imageblit(struct
 	spin_lock(&sm750_dev->slock);
 
 	sm750_dev->accel.de_imageblit(&sm750_dev->accel,
-				      image->data, image->width >> 3, 0,
+				      image->data, 0,
 				      base, pitch, Bpp,
 				      image->dx, image->dy,
 				      image->width, image->height,
--- a/drivers/staging/sm750fb/sm750.h
+++ b/drivers/staging/sm750fb/sm750.h
@@ -73,7 +73,7 @@ struct lynx_accel {
 			   u32 rop2);
 
 	int (*de_imageblit)(struct lynx_accel *accel, const char *p_srcbuf,
-			    u32 src_delta, u32 start_bit, u32 d_base, u32 d_pitch,
+			    u32 start_bit, u32 d_base, u32 d_pitch,
 			    u32 byte_per_pixel, u32 dx, u32 dy, u32 width,
 			    u32 height, u32 f_color, u32 b_color, u32 rop2);
 
--- a/drivers/staging/sm750fb/sm750_accel.c
+++ b/drivers/staging/sm750fb/sm750_accel.c
@@ -300,8 +300,6 @@ static unsigned int deGetTransparency(st
  * sm750_hw_imageblit
  * @accel: Acceleration device data
  * @pSrcbuf: pointer to start of source buffer in system memory
- * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top down
- *	      and -ive mean button up
  * @startBit: Mono data can start at any bit in a byte, this value should be
  *	      0 to 7
  * @dBase: Address of destination: offset in frame buffer
@@ -316,7 +314,7 @@ static unsigned int deGetTransparency(st
  * @rop2: ROP value
  */
 int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf,
-		       u32 srcDelta, u32 startBit, u32 dBase, u32 dPitch,
+		       u32 startBit, u32 dBase, u32 dPitch,
 		       u32 bytePerPixel, u32 dx, u32 dy, u32 width,
 		       u32 height, u32 fColor, u32 bColor, u32 rop2)
 {
@@ -405,7 +403,7 @@ int sm750_hw_imageblit(struct lynx_accel
 			write_dpPort(accel, *(unsigned int *)ajRemain);
 		}
 
-		pSrcbuf += srcDelta;
+		pSrcbuf += ulBytesPerScan;
 	}
 
 	return 0;
--- a/drivers/staging/sm750fb/sm750_accel.h
+++ b/drivers/staging/sm750fb/sm750_accel.h
@@ -220,8 +220,6 @@ int sm750_hw_copyarea(struct lynx_accel
 /**
  * sm750_hw_imageblit
  * @pSrcbuf: pointer to start of source buffer in system memory
- * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top down
- *>-----      and -ive mean button up
  * @startBit: Mono data can start at any bit in a byte, this value should be
  *>-----      0 to 7
  * @dBase: Address of destination: offset in frame buffer
@@ -236,7 +234,7 @@ int sm750_hw_copyarea(struct lynx_accel
  * @rop2: ROP value
  */
 int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf,
-		       u32 srcDelta, u32 startBit, u32 dBase, u32 dPitch,
+		       u32 startBit, u32 dBase, u32 dPitch,
 		       u32 bytePerPixel, u32 dx, u32 dy, u32 width,
 		       u32 height, u32 fColor, u32 bColor, u32 rop2);
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 626/877] tracing/probes: Fix anon_stack check for unnamed bitfields in btf_find_struct_member
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (624 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 625/877] staging: sm750fb: fix mono image source stride mismatch in lynxfb_ops_imageblit() Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 627/877] Documentation: tracing: Add documentation about eprobes Greg Kroah-Hartman
                   ` (258 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Masami Hiramatsu (Google),
	Steven Rostedt, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>

[ Upstream commit f36d94a20ca185bcadef3a10b980cd2cfd72d53a ]

btf_find_struct_member() traverses into nested anonymous structures
and unions by pushing members with !member->name_off onto anon_stack.
However, it does not consider the unnamed bitfields (e.g. `int : 5`
or `unsigned int : 0`) which also have member->name_off == 0.

If such an unnamed bitfield is pushed to anon_stack, the
btf_find_struct_member() return an error even if there are other
valid entries in anon_stack.

To fix this, only push unnamed struct/union members to anon_stack.
Also move the btf_type_is_struct() check to the entry of this function
because now it is sure only struct/union are pushed to anon_stack.

Link: https://lore.kernel.org/all/178827249775.123716.7813217688423513612.stgit@devnote2/

Fixes: 302db0f5b3d8 ("tracing/probes: Add a function to search a member of a struct/union")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260830143859.D56991F00A3D@smtp.kernel.org/
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
[ retained the existing kcalloc() allocation instead of upstream’s kzalloc_objs() call. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/trace_btf.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

--- a/kernel/trace/trace_btf.c
+++ b/kernel/trace/trace_btf.c
@@ -74,24 +74,24 @@ const struct btf_member *btf_find_struct
 {
 	struct btf_anon_stack *anon_stack;
 	const struct btf_member *member;
+	const struct btf_type *mtype;
 	u32 tid, cur_offset = 0;
 	const char *name;
 	int i, top = 0;
 
+	if (!btf_type_is_struct(type))
+		return ERR_PTR(-EINVAL);
+
 	anon_stack = kcalloc(BTF_ANON_STACK_MAX, sizeof(*anon_stack), GFP_KERNEL);
 	if (!anon_stack)
 		return ERR_PTR(-ENOMEM);
 
 retry:
-	if (!btf_type_is_struct(type)) {
-		member = ERR_PTR(-EINVAL);
-		goto out;
-	}
-
 	for_each_member(i, type, member) {
 		if (!member->name_off) {
 			/* Anonymous union/struct: push it for later use */
-			if (btf_type_skip_modifiers(btf, member->type, &tid) &&
+			mtype = btf_type_skip_modifiers(btf, member->type, &tid);
+			if (mtype && btf_type_is_struct(mtype) &&
 			    top < BTF_ANON_STACK_MAX) {
 				anon_stack[top].tid = tid;
 				anon_stack[top++].offset =



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 627/877] Documentation: tracing: Add documentation about eprobes
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (625 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 626/877] tracing/probes: Fix anon_stack check for unnamed bitfields in btf_find_struct_member Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 628/877] tracing/probes: Fix BTF kflag check for anonymous struct member access Greg Kroah-Hartman
                   ` (257 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mark Rutland, Mathieu Desnoyers,
	Andrew Morton, Namhyung Kim, Jonathan Corbet, Randy Dunlap,
	Masami Hiramatsu (Google), Steven Rostedt (Google), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Steven Rostedt <rostedt@goodmis.org>

[ Upstream commit 623526ba8984cafdffa0eba7ee424f2e40c8a219 ]

Eprobes was added back in 5.15, but was never documented. It became a
"secret" interface even though it has been a topic of several
presentations. For some reason, when eprobes was added, documenting it
never became a priority, until now.

Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Link: https://lore.kernel.org/20250730140945.528135548@kernel.org
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Stable-dep-of: 47e93045a2db ("tracing/probes: Fix BTF kflag check for anonymous struct member access")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/trace/eprobetrace.rst |  269 ++++++++++++++++++++++++++++++++++++
 Documentation/trace/index.rst       |    1 
 2 files changed, 270 insertions(+)
 create mode 100644 Documentation/trace/eprobetrace.rst

--- /dev/null
+++ b/Documentation/trace/eprobetrace.rst
@@ -0,0 +1,269 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+==================================
+Eprobe - Event-based Probe Tracing
+==================================
+
+:Author: Steven Rostedt <rostedt@goodmis.org>
+
+- Written for v6.17
+
+Overview
+========
+
+Eprobes are dynamic events that are placed on existing events to either
+dereference a field that is a pointer, or simply to limit what fields are
+recorded in the trace event.
+
+Eprobes depend on kprobe events so to enable this feature, build your kernel
+with CONFIG_EPROBE_EVENTS=y.
+
+Eprobes are created via the /sys/kernel/tracing/dynamic_events file.
+
+Synopsis of eprobe_events
+-------------------------
+::
+
+  e[:[EGRP/][EEVENT]] GRP.EVENT [FETCHARGS]	: Set a probe
+  -:[EGRP/][EEVENT]				: Clear a probe
+
+ EGRP		: Group name of the new event. If omitted, use "eprobes" for it.
+ EEVENT		: Event name. If omitted, the event name is generated and will
+		  be the same event name as the event it attached to.
+ GRP		: Group name of the event to attach to.
+ EVENT		: Event name of the event to attach to.
+
+ FETCHARGS	: Arguments. Each probe can have up to 128 args.
+  $FIELD	: Fetch the value of the event field called FIELD.
+  @ADDR		: Fetch memory at ADDR (ADDR should be in kernel)
+  @SYM[+|-offs]	: Fetch memory at SYM +|- offs (SYM should be a data symbol)
+  $comm		: Fetch current task comm.
+  +|-[u]OFFS(FETCHARG) : Fetch memory at FETCHARG +|- OFFS address.(\*3)(\*4)
+  \IMM		: Store an immediate value to the argument.
+  NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
+  FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
+		  (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
+		  (x8/x16/x32/x64), VFS layer common type(%pd/%pD), "char",
+                  "string", "ustring", "symbol", "symstr" and "bitfield" are
+                  supported.
+
+Types
+-----
+The FETCHARGS above is very similar to the kprobe events as described in
+Documentation/trace/kprobetrace.rst.
+
+The difference between eprobes and kprobes FETCHARGS is that eprobes has a
+$FIELD command that returns the content of the event field of the event
+that is attached. Eprobes do not have access to registers, stacks and function
+arguments that kprobes has.
+
+If a field argument is a pointer, it may be dereferenced just like a memory
+address using the FETCHARGS syntax.
+
+
+Attaching to dynamic events
+---------------------------
+
+Eprobes may attach to dynamic events as well as to normal events. It may
+attach to a kprobe event, a synthetic event or a fprobe event. This is useful
+if the type of a field needs to be changed. See Example 2 below.
+
+Usage examples
+==============
+
+Example 1
+---------
+
+The basic usage of eprobes is to limit the data that is being recorded into
+the tracing buffer. For example, a common event to trace is the sched_switch
+trace event. That has a format of::
+
+	field:unsigned short common_type;	offset:0;	size:2;	signed:0;
+	field:unsigned char common_flags;	offset:2;	size:1;	signed:0;
+	field:unsigned char common_preempt_count;	offset:3;	size:1;	signed:0;
+	field:int common_pid;	offset:4;	size:4;	signed:1;
+
+	field:char prev_comm[16];	offset:8;	size:16;	signed:0;
+	field:pid_t prev_pid;	offset:24;	size:4;	signed:1;
+	field:int prev_prio;	offset:28;	size:4;	signed:1;
+	field:long prev_state;	offset:32;	size:8;	signed:1;
+	field:char next_comm[16];	offset:40;	size:16;	signed:0;
+	field:pid_t next_pid;	offset:56;	size:4;	signed:1;
+	field:int next_prio;	offset:60;	size:4;	signed:1;
+
+The first four fields are common to all events and can not be limited. But the
+rest of the event has 60 bytes of information. It records the names of the
+previous and next tasks being scheduled out and in, as well as their pids and
+priorities. It also records the state of the previous task. If only the pids
+of the tasks are of interest, why waste the ring buffer with all the other
+fields?
+
+An eprobe can limit what gets recorded. Note, it does not help in performance,
+as all the fields are recorded in a temporary buffer to process the eprobe.
+::
+
+ # echo 'e:sched/switch sched.sched_switch prev=$prev_pid:u32 next=$next_pid:u32' >> /sys/kernel/tracing/dynamic_events
+ # echo 1 > /sys/kernel/tracing/events/sched/switch/enable
+ # cat /sys/kernel/tracing/trace
+
+ # tracer: nop
+ #
+ # entries-in-buffer/entries-written: 2721/2721   #P:8
+ #
+ #                                _-----=> irqs-off/BH-disabled
+ #                               / _----=> need-resched
+ #                              | / _---=> hardirq/softirq
+ #                              || / _--=> preempt-depth
+ #                              ||| / _-=> migrate-disable
+ #                              |||| /     delay
+ #           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
+ #              | |         |   |||||     |         |
+     sshd-session-1082    [004] d..4.  5041.239906: switch: (sched.sched_switch) prev=1082 next=0
+             bash-1085    [001] d..4.  5041.240198: switch: (sched.sched_switch) prev=1085 next=141
+    kworker/u34:5-141     [001] d..4.  5041.240259: switch: (sched.sched_switch) prev=141 next=1085
+           <idle>-0       [004] d..4.  5041.240354: switch: (sched.sched_switch) prev=0 next=1082
+             bash-1085    [001] d..4.  5041.240385: switch: (sched.sched_switch) prev=1085 next=141
+    kworker/u34:5-141     [001] d..4.  5041.240410: switch: (sched.sched_switch) prev=141 next=1085
+             bash-1085    [001] d..4.  5041.240478: switch: (sched.sched_switch) prev=1085 next=0
+     sshd-session-1082    [004] d..4.  5041.240526: switch: (sched.sched_switch) prev=1082 next=0
+           <idle>-0       [001] d..4.  5041.247524: switch: (sched.sched_switch) prev=0 next=90
+           <idle>-0       [002] d..4.  5041.247545: switch: (sched.sched_switch) prev=0 next=16
+      kworker/1:1-90      [001] d..4.  5041.247580: switch: (sched.sched_switch) prev=90 next=0
+        rcu_sched-16      [002] d..4.  5041.247591: switch: (sched.sched_switch) prev=16 next=0
+           <idle>-0       [002] d..4.  5041.257536: switch: (sched.sched_switch) prev=0 next=16
+        rcu_sched-16      [002] d..4.  5041.257573: switch: (sched.sched_switch) prev=16 next=0
+
+Note, without adding the "u32" after the prev_pid and next_pid, the values
+would default showing in hexadecimal.
+
+Example 2
+---------
+
+If a specific system call is to be recorded but the syscalls events are not
+enabled, the raw_syscalls can still be used (syscalls are system call
+events are not normal events, but are created from the raw_syscalls events
+within the kernel). In order to trace the openat system call, one can create
+an event probe on top of the raw_syscalls event:
+::
+
+ # cd /sys/kernel/tracing
+ # cat events/raw_syscalls/sys_enter/format
+ name: sys_enter
+ ID: 395
+ format:
+	field:unsigned short common_type;	offset:0;	size:2;	signed:0;
+	field:unsigned char common_flags;	offset:2;	size:1;	signed:0;
+	field:unsigned char common_preempt_count;	offset:3;	size:1;	signed:0;
+	field:int common_pid;	offset:4;	size:4;	signed:1;
+
+	field:long id;	offset:8;	size:8;	signed:1;
+	field:unsigned long args[6];	offset:16;	size:48;	signed:0;
+
+ print fmt: "NR %ld (%lx, %lx, %lx, %lx, %lx, %lx)", REC->id, REC->args[0], REC->args[1], REC->args[2], REC->args[3], REC->args[4], REC->args[5]
+
+From the source code, the sys_openat() has:
+::
+
+ int sys_openat(int dirfd, const char *path, int flags, mode_t mode)
+ {
+	return my_syscall4(__NR_openat, dirfd, path, flags, mode);
+ }
+
+The path is the second parameter, and that is what is wanted.
+::
+
+ # echo 'e:openat raw_syscalls.sys_enter nr=$id filename=+8($args):ustring' >> dynamic_events
+
+This is being run on x86_64 where the word size is 8 bytes and the openat
+system call __NR_openat is set at 257.
+::
+
+ # echo 'nr == 257' > events/eprobes/openat/filter
+
+Now enable the event and look at the trace.
+::
+
+ # echo 1 > events/eprobes/openat/enable
+ # cat trace
+
+ # tracer: nop
+ #
+ # entries-in-buffer/entries-written: 4/4   #P:8
+ #
+ #                                _-----=> irqs-off/BH-disabled
+ #                               / _----=> need-resched
+ #                              | / _---=> hardirq/softirq
+ #                              || / _--=> preempt-depth
+ #                              ||| / _-=> migrate-disable
+ #                              |||| /     delay
+ #           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
+ #              | |         |   |||||     |         |
+              cat-1298    [003] ...2.  2060.875970: openat: (raw_syscalls.sys_enter) nr=0x101 filename=(fault)
+              cat-1298    [003] ...2.  2060.876197: openat: (raw_syscalls.sys_enter) nr=0x101 filename=(fault)
+              cat-1298    [003] ...2.  2060.879126: openat: (raw_syscalls.sys_enter) nr=0x101 filename=(fault)
+              cat-1298    [003] ...2.  2060.879639: openat: (raw_syscalls.sys_enter) nr=0x101 filename=(fault)
+
+The filename shows "(fault)". This is likely because the filename has not been
+pulled into memory yet and currently trace events cannot fault in memory that
+is not present. When an eprobe tries to read memory that has not been faulted
+in yet, it will show the "(fault)" text.
+
+To get around this, as the kernel will likely pull in this filename and make
+it present, attaching it to a synthetic event that can pass the address of the
+filename from the entry of the event to the end of the event, this can be used
+to show the filename when the system call returns.
+
+Remove the old eprobe::
+
+ # echo 1 > events/eprobes/openat/enable
+ # echo '-:openat' >> dynamic_events
+
+This time make an eprobe where the address of the filename is saved::
+
+ # echo 'e:openat_start raw_syscalls.sys_enter nr=$id filename=+8($args):x64' >> dynamic_events
+
+Create a synthetic event that passes the address of the filename to the
+end of the event::
+
+ # echo 's:filename u64 file' >> dynamic_events
+ # echo 'hist:keys=common_pid:f=filename if nr == 257' > events/eprobes/openat_start/trigger
+ # echo 'hist:keys=common_pid:file=$f:onmatch(eprobes.openat_start).trace(filename,$file) if id == 257' > events/raw_syscalls/sys_exit/trigger
+
+Now that the address of the filename has been passed to the end of the
+system call, create another eprobe to attach to the exit event to show the
+string::
+
+ # echo 'e:openat synthetic.filename filename=+0($file):ustring' >> dynamic_events
+ # echo 1 > events/eprobes/openat/enable
+ # cat trace
+
+ # tracer: nop
+ #
+ # entries-in-buffer/entries-written: 4/4   #P:8
+ #
+ #                                _-----=> irqs-off/BH-disabled
+ #                               / _----=> need-resched
+ #                              | / _---=> hardirq/softirq
+ #                              || / _--=> preempt-depth
+ #                              ||| / _-=> migrate-disable
+ #                              |||| /     delay
+ #           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
+ #              | |         |   |||||     |         |
+              cat-1331    [001] ...5.  2944.787977: openat: (synthetic.filename) filename="/etc/ld.so.cache"
+              cat-1331    [001] ...5.  2944.788480: openat: (synthetic.filename) filename="/lib/x86_64-linux-gnu/libc.so.6"
+              cat-1331    [001] ...5.  2944.793426: openat: (synthetic.filename) filename="/usr/lib/locale/locale-archive"
+              cat-1331    [001] ...5.  2944.831362: openat: (synthetic.filename) filename="trace"
+
+Example 3
+---------
+
+If syscall trace events are available, the above would not need the first
+eprobe, but it would still need the last one::
+
+ # echo 's:filename u64 file' >> dynamic_events
+ # echo 'hist:keys=common_pid:f=filename' > events/syscalls/sys_enter_openat/trigger
+ # echo 'hist:keys=common_pid:file=$f:onmatch(syscalls.sys_enter_openat).trace(filename,$file)' > events/syscalls/sys_exit_openat/trigger
+ # echo 'e:openat synthetic.filename filename=+0($file):ustring' >> dynamic_events
+ # echo 1 > events/eprobes/openat/enable
+
+And this would produce the same result as Example 2.
--- a/Documentation/trace/index.rst
+++ b/Documentation/trace/index.rst
@@ -36,6 +36,7 @@ the Linux kernel.
    kprobes
    kprobetrace
    fprobetrace
+   eprobetrace
    fprobe
    ring-buffer-design
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 628/877] tracing/probes: Fix BTF kflag check for anonymous struct member access
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (626 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 627/877] Documentation: tracing: Add documentation about eprobes Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 629/877] mm/secretmem: properly account locked pages Greg Kroah-Hartman
                   ` (256 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Masami Hiramatsu (Google),
	Steven Rostedt, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>

[ Upstream commit 47e93045a2db80d24f5fef65adecc6b2b32efa23 ]

btf_find_struct_member() traverses into nested anonymous structures and
unions to find a struct member. However, get_bitoffset_of_field() in
trace_probe.c checked btf_type_kflag(type) using the outer parent type
instead of the actual anonymous structure/union that directly contains
the found member.

If the parent structure and anonymous structure have mismatched kflags
(e.g., the parent has kflag=0 while the anonymous structure has kflag=1
because it contains bitfields), the bitfield size encoded in the upper
8 bits of member->offset is erroneously treated as part of the byte/bit
offset, corrupting the resolved offset and failing to set last_bitsize.
Similarly, btf_find_struct_member() pushed anonymous member offsets
onto anon_stack without masking BTF_MEMBER_BIT_OFFSET() when kflag is set.

To fix this problem, update btf_find_struct_member() to return actual
containing structure/union type via member_type, use appropriate
__btf_member_bit_offset() to get bit offset, and use member_type for
btf_type_kflag() in get_bitoffset_of_field().

Link: https://lore.kernel.org/all/178827250904.123716.17452648791331881284.stgit@devnote2/

Fixes: c440adfbe302 ("tracing/probes: Support BTF based data structure field access")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260822095110.0772E1F000E9@smtp.kernel.org/
Assisted-by: Antigravity:gemini-3.7-flash
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
[ Applied get_bitoffset_of_field() changes to the equivalent logic in parse_btf_field(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/trace_btf.c   |   19 +++++++++++--------
 kernel/trace/trace_btf.h   |    3 ++-
 kernel/trace/trace_probe.c |    5 +++--
 3 files changed, 16 insertions(+), 11 deletions(-)

--- a/kernel/trace/trace_btf.c
+++ b/kernel/trace/trace_btf.c
@@ -61,16 +61,17 @@ struct btf_anon_stack {
 
 /*
  * Find a member of data structure/union by name and return it.
- * Return NULL if not found, or -EINVAL if parameter is invalid.
- * If the member is an member of anonymous union/structure, the offset
- * of that anonymous union/structure is stored into @anon_offset. Caller
- * can calculate the correct offset from the root data structure by
- * adding anon_offset to the member's offset.
+ * Return NULL if not found, or ERR_PTR(-EINVAL) if parameter is invalid.
+ * If the member is a member of an anonymous union/structure, the bit offset
+ * of that anonymous union/structure is stored into @anon_offset.
+ * If @member_type is non-NULL, the actual containing structure/union type
+ * of the found member is stored into @member_type.
  */
 const struct btf_member *btf_find_struct_member(struct btf *btf,
 						const struct btf_type *type,
 						const char *member_name,
-						u32 *anon_offset)
+						u32 *anon_offset,
+						const struct btf_type **member_type)
 {
 	struct btf_anon_stack *anon_stack;
 	const struct btf_member *member;
@@ -94,14 +95,16 @@ retry:
 			if (mtype && btf_type_is_struct(mtype) &&
 			    top < BTF_ANON_STACK_MAX) {
 				anon_stack[top].tid = tid;
-				anon_stack[top++].offset =
-					cur_offset + member->offset;
+				anon_stack[top++].offset = cur_offset +
+					__btf_member_bit_offset(type, member);
 			}
 		} else {
 			name = btf_name_by_offset(btf, member->name_off);
 			if (name && !strcmp(member_name, name)) {
 				if (anon_offset)
 					*anon_offset = cur_offset;
+				if (member_type)
+					*member_type = type;
 				goto out;
 			}
 		}
--- a/kernel/trace/trace_btf.h
+++ b/kernel/trace/trace_btf.h
@@ -8,4 +8,5 @@ const struct btf_param *btf_get_func_par
 const struct btf_member *btf_find_struct_member(struct btf *btf,
 						const struct btf_type *type,
 						const char *member_name,
-						u32 *anon_offset);
+						u32 *anon_offset,
+						const struct btf_type **member_type);
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -534,6 +534,7 @@ static int parse_btf_field(char *fieldna
 {
 	struct fetch_insn *code = *pcode;
 	const struct btf_member *field;
+	const struct btf_type *mtype;
 	u32 bitoffs, anon_offs;
 	char *next;
 	int is_ptr;
@@ -562,7 +563,7 @@ static int parse_btf_field(char *fieldna
 
 			anon_offs = 0;
 			field = btf_find_struct_member(ctx->btf, type, fieldname,
-						       &anon_offs);
+						       &anon_offs, &mtype);
 			if (IS_ERR(field)) {
 				trace_probe_log_err(ctx->offset, BAD_BTF_TID);
 				return PTR_ERR(field);
@@ -575,7 +576,7 @@ static int parse_btf_field(char *fieldna
 			bitoffs += anon_offs;
 
 			/* Accumulate the bit-offsets of the dot-connected fields */
-			if (btf_type_kflag(type)) {
+			if (btf_type_kflag(mtype)) {
 				bitoffs += BTF_MEMBER_BIT_OFFSET(field->offset);
 				ctx->last_bitsize = BTF_MEMBER_BITFIELD_SIZE(field->offset);
 			} else {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 629/877] mm/secretmem: properly account locked pages
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (627 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 628/877] tracing/probes: Fix BTF kflag check for anonymous struct member access Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 630/877] tracing: Clean up use of trace_create_maxlat_file() Greg Kroah-Hartman
                   ` (255 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM), Daehyeon Ko,
	Mike Rapoport (Microsoft), David Hildenbrand (Arm),
	Alexei Starovoitov, David S. Miller, Hagen Paul Pfeifer,
	Jakub Kacinski, James Bottomley, Jesper Dangaard Brouer,
	John Fastabend, Liam R. Howlett, Michal Hocko, Stanislav Fomichev,
	Suren Baghdasaryan, Vlastimil Babka, Andrew Morton, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>

[ Upstream commit 97d34aa65c29cca85e3e9050f4c936389b38a054 ]

secretmem accounts folios by treating memory as if it were mlock()'d and
thus limited by the RLIMIT_MEMLOCK limit.

However the folios are unevictable and remain so until the inode is
evicted, eliminating usual mlock() semantics - mapping folios then
unmapping them does not clear their unevictable state, since it depends on
AS_UNEVICTABLE, not PG_mlocked.

A user can therefore easily work around the RLIMIT_MEMLOCK limit - simply
map then unmap and VmLck no longer counts the secretmem range.  Worse,
folios are not accounted in the process's RSS, meaning the OOM killer
won't know to kill the process.

Repeatedly mapping/unmapping (or forking) can then result in the
consumption of all available system memory with unevictable folios and
cause system instability.

A secretmem fd can be passed between processes and over fork so a
per-process limit simply does not make sense, so follow the precedent set
by io_uring, perf, skbuff, iommufd and xdp by tracking the number of
locked pages in user_struct->locked_vm.

Since the scope tracked is actually inode lifetime, the RLIMIT_MEMLOCK
applies per-user not per-process, so it doesn't make sense to bypass for
users with CAP_IPC_LOCK, therefore remove this bypass.

There is simply no reason to carry on marking the mapping as mlock()'d
since it's misleading and the lifecycle is now correctly handled, so
remove this too.

Note that secretmem does not support any form of truncation (including
hole punching) and the folios are unreclaimable, so the folios need only
be accounted on fault and unaccounted on inode destruction.

__secretmem_account_pages() is more or less a duplicate of the code that
io_uring etc.  use, but since this is a bug fix that needs backporting,
defer any de-duplication efforts to a follow-up.

test_mlock_limit() asserts mlock_future_ok() on mmap(), however this has
been removed, so remove the test altogether for the fix.  A new test will
be sent separately for upstream.

Link: https://lore.kernel.org/20260826-secretmem-accounting-v3-1-94cb04399510@kernel.org
Fixes: 1507f51255c9 ("mm: introduce memfd_secret system call to create "secret" memory areas")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reported-by: Daehyeon Ko <4ncienth@gmail.com>
Closes: https://lore.kernel.org/linux-mm/20260813225328.2010303-1-4ncienth@gmail.com/
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Tested-by: Daehyeon Ko <4ncienth@gmail.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Hagen Paul Pfeifer <hagen@jauu.net>
Cc: Jakub Kacinski <kuba@kernel.org>
Cc: James Bottomley <james.bottomley@HansenPartnership.com>
Cc: Jesper Dangaard Brouer <hawk@kernel.org>
Cc: John Fastabend <john.fastabend@gmail.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Stanislav Fomichev <sdf@fomichev.me>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[ adapted secretmem changes to Linux 6.12’s page-based fault handling and legacy mmap interface. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/linux/sched/user.h                |    3 
 mm/secretmem.c                            |  117 +++++++++++++++++++++++++++---
 tools/testing/selftests/mm/memfd_secret.c |   30 -------
 3 files changed, 110 insertions(+), 40 deletions(-)

--- a/include/linux/sched/user.h
+++ b/include/linux/sched/user.h
@@ -25,7 +25,8 @@ struct user_struct {
 
 #if defined(CONFIG_PERF_EVENTS) || defined(CONFIG_BPF_SYSCALL) || \
 	defined(CONFIG_NET) || defined(CONFIG_IO_URING) || \
-	defined(CONFIG_VFIO_PCI_ZDEV_KVM) || IS_ENABLED(CONFIG_IOMMUFD)
+	defined(CONFIG_VFIO_PCI_ZDEV_KVM) || IS_ENABLED(CONFIG_IOMMUFD) || \
+	defined(CONFIG_SECRETMEM)
 	atomic_long_t locked_vm;
 #endif
 #ifdef CONFIG_WATCH_QUEUE
--- a/mm/secretmem.c
+++ b/mm/secretmem.c
@@ -18,6 +18,8 @@
 #include <linux/secretmem.h>
 #include <linux/set_memory.h>
 #include <linux/sched/signal.h>
+#include <linux/sched/user.h>
+#include <linux/cred.h>
 
 #include <uapi/linux/magic.h>
 
@@ -47,10 +49,69 @@ bool secretmem_active(void)
 	return !!atomic_read(&secretmem_users);
 }
 
+struct secretmem_inode_state {
+	struct user_struct	*user;
+	atomic_long_t		nr_pages_accounted;
+};
+
+static bool __secretmem_account_pages(struct user_struct *user,
+		unsigned long nr_pages)
+{
+	unsigned long page_limit, cur_pages, new_pages;
+
+	if (!nr_pages)
+		return true;
+
+	page_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+
+	cur_pages = atomic_long_read(&user->locked_vm);
+	do {
+		new_pages = cur_pages + nr_pages;
+		if (new_pages > page_limit)
+			return false;
+	} while (!atomic_long_try_cmpxchg(&user->locked_vm,
+					  &cur_pages, new_pages));
+	return true;
+}
+
+static bool secretmem_account_folio(struct secretmem_inode_state *state,
+		const struct folio *folio)
+{
+	const unsigned long nr_pages = folio_nr_pages(folio);
+
+	if (!__secretmem_account_pages(state->user, nr_pages))
+		return false;
+
+	atomic_long_add(nr_pages, &state->nr_pages_accounted);
+	return true;
+}
+
+static void __secretmem_unaccount_pages(struct secretmem_inode_state *state,
+		unsigned long nr_pages)
+{
+	atomic_long_sub(nr_pages, &state->user->locked_vm);
+	atomic_long_sub(nr_pages, &state->nr_pages_accounted);
+}
+
+static void secretmem_unaccount_folio(struct secretmem_inode_state *state,
+		struct folio *folio)
+{
+	__secretmem_unaccount_pages(state, folio_nr_pages(folio));
+}
+
+static void secretmem_unaccount_all_folios(struct secretmem_inode_state *state)
+{
+	const unsigned long nr_pages_accounted =
+		atomic_long_read(&state->nr_pages_accounted);
+
+	__secretmem_unaccount_pages(state, nr_pages_accounted);
+}
+
 static vm_fault_t secretmem_fault(struct vm_fault *vmf)
 {
 	struct address_space *mapping = vmf->vma->vm_file->f_mapping;
 	struct inode *inode = file_inode(vmf->vma->vm_file);
+	struct secretmem_inode_state *state = inode->i_private;
 	pgoff_t offset = vmf->pgoff;
 	gfp_t gfp = vmf->gfp_mask;
 	unsigned long addr;
@@ -73,9 +134,16 @@ retry:
 			goto out;
 		}
 
+		if (!secretmem_account_folio(state, folio)) {
+			folio_put(folio);
+			ret = VM_FAULT_SIGBUS;
+			goto out;
+		}
+
 		page = &folio->page;
 		err = set_direct_map_invalid_noflush(page);
 		if (err) {
+			secretmem_unaccount_folio(state, folio);
 			folio_put(folio);
 			ret = vmf_error(err);
 			goto out;
@@ -84,6 +152,7 @@ retry:
 		__folio_mark_uptodate(folio);
 		err = filemap_add_folio(mapping, folio, offset, gfp);
 		if (unlikely(err)) {
+			secretmem_unaccount_folio(state, folio);
 			/*
 			 * If a split of large page was required, it
 			 * already happened when we marked the page invalid
@@ -114,23 +183,30 @@ static const struct vm_operations_struct
 	.fault = secretmem_fault,
 };
 
+static void secretmem_destroy_inode_priv(struct inode *inode)
+{
+	struct secretmem_inode_state *state = inode->i_private;
+
+	secretmem_unaccount_all_folios(state);
+	free_uid(state->user);
+	kfree(state);
+	inode->i_private = NULL;
+}
+
 static int secretmem_release(struct inode *inode, struct file *file)
 {
 	atomic_dec(&secretmem_users);
+	secretmem_destroy_inode_priv(inode);
+
 	return 0;
 }
 
 static int secretmem_mmap(struct file *file, struct vm_area_struct *vma)
 {
-	unsigned long len = vma->vm_end - vma->vm_start;
-
 	if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
 		return -EINVAL;
 
-	if (!mlock_future_ok(vma->vm_mm, vma->vm_flags | VM_LOCKED, len))
-		return -EAGAIN;
-
-	vm_flags_set(vma, VM_LOCKED | VM_DONTDUMP);
+	vm_flags_set(vma, VM_DONTDUMP);
 	vma->vm_ops = &secretmem_vm_ops;
 
 	return 0;
@@ -190,20 +266,40 @@ static const struct inode_operations sec
 
 static struct vfsmount *secretmem_mnt;
 
+static int secretmem_init_inode_priv(struct inode *inode)
+{
+	struct secretmem_inode_state *state;
+
+	state = kzalloc_obj(*state);
+	if (!state)
+		return -ENOMEM;
+
+	state->user = get_uid(current_user());
+	inode->i_private = state;
+	return 0;
+}
+
 static struct file *secretmem_file_create(unsigned long flags)
 {
 	struct file *file;
 	struct inode *inode;
 	const char *anon_name = "[secretmem]";
+	int err;
 
 	inode = anon_inode_make_secure_inode(secretmem_mnt->mnt_sb, anon_name, NULL);
 	if (IS_ERR(inode))
 		return ERR_CAST(inode);
 
+	err = secretmem_init_inode_priv(inode);
+	if (err)
+		goto err_free_inode;
+
 	file = alloc_file_pseudo(inode, secretmem_mnt, "secretmem",
 				 O_RDWR, &secretmem_fops);
-	if (IS_ERR(file))
-		goto err_free_inode;
+	if (IS_ERR(file)) {
+		err = PTR_ERR(file);
+		goto err_free_priv;
+	}
 
 	mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
 	mapping_set_unevictable(inode->i_mapping);
@@ -216,10 +312,11 @@ static struct file *secretmem_file_creat
 	inode->i_size = 0;
 
 	return file;
-
+err_free_priv:
+	secretmem_destroy_inode_priv(inode);
 err_free_inode:
 	iput(inode);
-	return file;
+	return ERR_PTR(err);
 }
 
 SYSCALL_DEFINE1(memfd_secret, unsigned int, flags)
--- a/tools/testing/selftests/mm/memfd_secret.c
+++ b/tools/testing/selftests/mm/memfd_secret.c
@@ -57,33 +57,6 @@ static void test_file_apis(int fd)
 		pass("file IO is blocked as expected\n");
 }
 
-static void test_mlock_limit(int fd)
-{
-	size_t len;
-	char *mem;
-
-	len = mlock_limit_cur;
-	if (len % page_size != 0)
-		len = (len/page_size) * page_size;
-
-	mem = mmap(NULL, len, prot, mode, fd, 0);
-	if (mem == MAP_FAILED) {
-		fail("unable to mmap secret memory\n");
-		return;
-	}
-	munmap(mem, len);
-
-	len = mlock_limit_max * 2;
-	mem = mmap(NULL, len, prot, mode, fd, 0);
-	if (mem != MAP_FAILED) {
-		fail("unexpected mlock limit violation\n");
-		munmap(mem, len);
-		return;
-	}
-
-	pass("mlock limit is respected\n");
-}
-
 static void test_vmsplice(int fd, const char *desc)
 {
 	ssize_t transferred;
@@ -297,7 +270,7 @@ static void prepare(void)
 				   strerror(errno));
 }
 
-#define NUM_TESTS 6
+#define NUM_TESTS 5
 
 int main(int argc, char *argv[])
 {
@@ -319,7 +292,6 @@ int main(int argc, char *argv[])
 	if (ftruncate(fd, page_size))
 		ksft_exit_fail_msg("ftruncate failed: %s\n", strerror(errno));
 
-	test_mlock_limit(fd);
 	test_file_apis(fd);
 	/*
 	 * We have to run the first vmsplice test before any secretmem page was



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 630/877] tracing: Clean up use of trace_create_maxlat_file()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (628 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 629/877] mm/secretmem: properly account locked pages Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 631/877] tracing: Take trace_array reference when opening options file Greg Kroah-Hartman
                   ` (254 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mathieu Desnoyers,
	Masami Hiramatsu (Google), Steven Rostedt (Google), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Steven Rostedt <rostedt@goodmis.org>

[ Upstream commit ba73713da50e5c24499ca8941171593466ea34f7 ]

In trace.c, the function trace_create_maxlat_file() is defined behind the
 #ifdef CONFIG_TRACER_MAX_TRACE block. The #else part defines it as:

 #define trace_create_maxlat_file(tr, d_tracer)				\
	trace_create_file("tracing_max_latency", TRACE_MODE_WRITE,	\
			  d_tracer, tr, &tracing_max_lat_fops)

But the one place that it it used has:

 #ifdef CONFIG_TRACER_MAX_TRACE
	trace_create_maxlat_file(tr, d_tracer);
 #endif

Which is pointless and also wrong!

It only gets created when both CONFIG_TRACE_MAX_TRACE and CONFIG_FS_NOTIFY
is defined, but the file itself should not be dependent on
CONFIG_FS_NOTIFY. Always create that file when TRACE_MAX_TRACE is defined
regardless if FS_NOTIFY is or is not.

Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Link: https://patch.msgid.link/20260207191101.0e014abd@robin
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Stable-dep-of: f2951ebd15c3 ("tracing: Take trace_array reference when opening options file")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/trace.c |   38 ++++++++++++++++----------------------
 1 file changed, 16 insertions(+), 22 deletions(-)

--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -1830,10 +1830,7 @@ static ssize_t trace_seq_to_buffer(struc
 unsigned long __read_mostly	tracing_thresh;
 
 #ifdef CONFIG_TRACER_MAX_TRACE
-static const struct file_operations tracing_max_lat_fops;
-
 #ifdef LATENCY_FS_NOTIFY
-
 static struct workqueue_struct *fsnotify_wq;
 
 static void latency_fsnotify_workfn(struct work_struct *work)
@@ -1850,17 +1847,6 @@ static void latency_fsnotify_workfn_irq(
 	queue_work(fsnotify_wq, &tr->fsnotify_work);
 }
 
-static void trace_create_maxlat_file(struct trace_array *tr,
-				     struct dentry *d_tracer)
-{
-	INIT_WORK(&tr->fsnotify_work, latency_fsnotify_workfn);
-	init_irq_work(&tr->fsnotify_irqwork, latency_fsnotify_workfn_irq);
-	tr->d_max_latency = trace_create_file("tracing_max_latency",
-					      TRACE_MODE_WRITE,
-					      d_tracer, tr,
-					      &tracing_max_lat_fops);
-}
-
 __init static int latency_fsnotify_init(void)
 {
 	fsnotify_wq = alloc_workqueue("tr_max_lat_wq",
@@ -1885,14 +1871,22 @@ void latency_fsnotify(struct trace_array
 	 */
 	irq_work_queue(&tr->fsnotify_irqwork);
 }
+#endif /* !LATENCY_FS_NOTIFY */
 
-#else /* !LATENCY_FS_NOTIFY */
-
-#define trace_create_maxlat_file(tr, d_tracer)				\
-	trace_create_file("tracing_max_latency", TRACE_MODE_WRITE,	\
-			  d_tracer, tr, &tracing_max_lat_fops)
+static const struct file_operations tracing_max_lat_fops;
 
+static void trace_create_maxlat_file(struct trace_array *tr,
+				     struct dentry *d_tracer)
+{
+#ifdef LATENCY_FS_NOTIFY
+	INIT_WORK(&tr->fsnotify_work, latency_fsnotify_workfn);
+	init_irq_work(&tr->fsnotify_irqwork, latency_fsnotify_workfn_irq);
 #endif
+	tr->d_max_latency = trace_create_file("tracing_max_latency",
+					      TRACE_MODE_WRITE,
+					      d_tracer, tr,
+					      &tracing_max_lat_fops);
+}
 
 /*
  * Copy the new maximum trace into the separate maximum-trace
@@ -2027,7 +2021,9 @@ update_max_tr_single(struct trace_array
 	__update_max_tr(tr, tsk, cpu);
 	arch_spin_unlock(&tr->max_lock);
 }
-
+#else /* !CONFIG_TRACER_MAX_TRACE */
+static inline void trace_create_maxlat_file(struct trace_array *tr,
+					    struct dentry *d_tracer) { }
 #endif /* CONFIG_TRACER_MAX_TRACE */
 
 struct pipe_wait {
@@ -9720,9 +9716,7 @@ init_tracer_tracefs(struct trace_array *
 
 	create_trace_options_dir(tr);
 
-#ifdef CONFIG_TRACER_MAX_TRACE
 	trace_create_maxlat_file(tr, d_tracer);
-#endif
 
 	if (ftrace_create_function_files(tr, d_tracer))
 		MEM_FAIL(1, "Could not allocate function filter files");



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 631/877] tracing: Take trace_array reference when opening options file
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (629 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 630/877] tracing: Clean up use of trace_create_maxlat_file() Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 632/877] ftrace: Take trace_array reference before accessing its ftrace_ops Greg Kroah-Hartman
                   ` (253 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, sashiko-bot, Steven Rostedt,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Steven Rostedt <rostedt@goodmis.org>

[ Upstream commit f2951ebd15c36a1ea4820a7f0cbb0b5f1c028b73 ]

The options files do not take the trace_array reference for the options
they represent. This could cause a use-after-free kernel crash if one of
these files is opened by one task and another task removes the instance
that the option is for. Because it doesn't take a reference upon opening,
it will not stop the removal which will free the options descriptor that
is being used.

As the options are somewhat dynamic in their creation at boot up, each
file represents a flag in the trace_array. The trace_array has an array of
indexes to represent each of these flags that is stored in the
trace_flags_index array. The address of the index array element is used to
pass to the inode->i_private pointer. Then that element is read which
holds the index (which represents the flag) and then the index is used to
calculate the trace_array descriptor from its trace_flags_index array.

One issue is that the index element can not be referenced until the
trace_array's reference is taken. To handle this, create a new helper
function called: trace_array_options_get() that will iterate all the
existing trace_arrays in the ftrace_trace_arrays list (under the
trace_types_lock), and compare the passed in address of the index element
with the entire array of the trace_array's trace_flags_index array.
If it matches, then up the corresponding trace_array's reference and
return.

Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260902121918.5a9e9d1b@gandalf.local.home
Fixes: 577b785f55168 ("tracing: add tracer dependent options to options directory")
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/linux-trace-kernel/20260828135858.2AC501F000E9@smtp.kernel.org/
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
[ replaced unavailable __trace_array_get(tr) with tr->ref++ and return 0. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/trace.c |   69 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 65 insertions(+), 4 deletions(-)

--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -8851,11 +8851,72 @@ trace_options_core_write(struct file *fi
 	return cnt;
 }
 
+/*
+ * The tr_index is the address of a trace_array->trace_flags_index[]
+ * element that holds the index of the trace flag. But since the
+ * trace_array reference has not been taken yet, it cannot be referenced
+ * as it could have been freed by a rmdir of the instance the trace_array
+ * represents.
+ *
+ * Search the list of trace_arrays and compare the tr_index to the
+ * address of the entire trace_array trace_flags_index array for each
+ * trace_array in the list. If one is matched, then take the reference
+ * and return it. If not, the trace_array no longer exits.
+ */
+static int trace_array_options_get(void *tr_index)
+{
+	struct trace_array *tr;
+	int ret;
+
+	ret = security_locked_down(LOCKDOWN_TRACEFS);
+	if (ret)
+		return ret;
+
+	if (tracing_disabled)
+		return -ENODEV;
+
+	guard(mutex)(&trace_types_lock);
+	list_for_each_entry(tr, &ftrace_trace_arrays, list) {
+		if (tr_index >= (void *)&tr->trace_flags_index[0] &&
+		    tr_index < (void *)&tr->trace_flags_index[TRACE_FLAGS_MAX_SIZE]) {
+			tr->ref++;
+			return 0;
+		}
+	}
+	return -ENODEV;
+}
+
+static int trace_options_open(struct inode *inode, struct file *filp)
+{
+	void *tr_index = inode->i_private;
+
+	if (trace_array_options_get(tr_index) < 0)
+		return -ENODEV;
+
+	filp->private_data = tr_index;
+
+	return 0;
+}
+
+static int trace_options_release(struct inode *inode, struct file *filp)
+{
+	void *tr_index = filp->private_data;
+	struct trace_array *tr;
+	unsigned int index;
+
+	get_tr_index(tr_index, &tr, &index);
+
+	trace_array_put(tr);
+
+	return 0;
+}
+
 static const struct file_operations trace_options_core_fops = {
-	.open = tracing_open_generic,
-	.read = trace_options_core_read,
-	.write = trace_options_core_write,
-	.llseek = generic_file_llseek,
+	.open		= trace_options_open,
+	.read		= trace_options_core_read,
+	.write		= trace_options_core_write,
+	.llseek		= generic_file_llseek,
+	.release	= trace_options_release,
 };
 
 struct dentry *trace_create_file(const char *name,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 632/877] ftrace: Take trace_array reference before accessing its ftrace_ops
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (630 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 631/877] tracing: Take trace_array reference when opening options file Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 633/877] dma-buf: dma-heap: dont publish fd before copy_to_user() succeeds Greg Kroah-Hartman
                   ` (252 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Breno Leitao, Steven Rostedt,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Steven Rostedt <rostedt@goodmis.org>

[ Upstream commit 9100191e5acb2e5ea2313f436667bb5fce129f47 ]

The trace instance files set_ftrace_filter and set_ftrace_notrace was
updated to work with specific trace instances (trace_arrays). The issue is
that when these files are opened, there is a small race window where it
will use the ftrace_ops from the inode->private pointer to get a reference
to the trace_array and then take its reference. The problem is that the
ftrace_ops itself could be freed. If the rmdir on the instance happens at
the same time the set_ftrace_filter file is opened, the rmdir could have
also freed the ftrace_ops and referencing it will cause a use-after-free
bug and crash the kernel.

Instead, pass in the trace_array as the file private data (NULL for the
top level instance), and then pass both the trace_array and the ftrace_ops
to the ftrace_regex_open() function. If the trace_array is NULL, then it
just uses the ftrace_ops without the need to take its reference (like
normal). If the ftrace_ops is NULL, that is only the case for the top
level instance and the global_ops can be used.

This allows the trace_array to have its reference incremented before
touching the ftrace_ops that could also be freed when the instance is.

Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260828223901.29e26edb@robin
Fixes: 591dffdade9f0 ("ftrace: Allow for function tracing instance to filter functions")
Reported-by: Breno Leitao <leitao@debian.org>
Tested-by: Breno Leitao <leitao@debian.org>
Closes: https://lore.kernel.org/all/apGORjltZgAiAYHT@gmail.com/
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
[ retained kzalloc(sizeof(*iter), GFP_KERNEL) instead of kzalloc_obj(*iter). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/linux/ftrace.h         |    5 ++-
 kernel/trace/ftrace.c          |   57 ++++++++++++++++++++++++++---------------
 kernel/trace/trace.h           |    4 +-
 kernel/trace/trace_functions.c |    2 -
 kernel/trace/trace_stack.c     |    2 -
 5 files changed, 44 insertions(+), 26 deletions(-)

--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -759,8 +759,9 @@ unsigned long ftrace_get_addr_new(struct
 unsigned long ftrace_get_addr_curr(struct dyn_ftrace *rec);
 
 extern ftrace_func_t ftrace_trace_function;
+struct trace_array;
 
-int ftrace_regex_open(struct ftrace_ops *ops, int flag,
+int ftrace_regex_open(struct trace_array *tr, struct ftrace_ops *ops, int flag,
 		  struct inode *inode, struct file *file);
 ssize_t ftrace_filter_write(struct file *file, const char __user *ubuf,
 			    size_t cnt, loff_t *ppos);
@@ -970,7 +971,7 @@ static inline unsigned long ftrace_locat
  * have them defined when ftrace is not enabled, but these
  * functions may still be called. Use a macro instead of inline.
  */
-#define ftrace_regex_open(ops, flag, inod, file) ({ -ENODEV; })
+#define ftrace_regex_open(tr, ops, flag, inode, file) ({ -ENODEV; })
 #define ftrace_set_early_filter(ops, buf, enable) do { } while (0)
 #define ftrace_set_filter_ip(ops, ip, remove, reset) ({ -ENODEV; })
 #define ftrace_set_filter_ips(ops, ips, cnt, remove, reset) ({ -ENODEV; })
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -4535,7 +4535,8 @@ ftrace_avail_addrs_open(struct inode *in
 
 /**
  * ftrace_regex_open - initialize function tracer filter files
- * @ops: The ftrace_ops that hold the hash filters
+ * @tr: The trace_array that holds the ftrace_ops [optional]
+ * @ops: The ftrace_ops that hold the hash filters [optional]
  * @flag: The type of filter to process
  * @inode: The inode, usually passed in to your open routine
  * @file: The file, usually passed in to your open routine
@@ -4549,26 +4550,45 @@ ftrace_avail_addrs_open(struct inode *in
  * tracing_lseek() should be used as the lseek routine, and
  * release must call ftrace_regex_release().
  *
+ * Note, If @tr is not NULL, its reference has to be taken before
+ *       @ops may be referenced.
+ *       If @ops is NULL and @tr is not, then @tr->ops is used.
+ *       If @tr is NULL and @ops is not then @ops->private is uesd for @tr.
+ *       If both @tr and @ops are NULL, then the &global_ops is
+ *         to be used, and @tr will be the global_ops.private pointer.
+ *
  * Returns: 0 on success or a negative errno value on failure
  */
 int
-ftrace_regex_open(struct ftrace_ops *ops, int flag,
+ftrace_regex_open(struct trace_array *tr, struct ftrace_ops *ops, int flag,
 		  struct inode *inode, struct file *file)
 {
-	struct ftrace_iterator *iter;
+	struct ftrace_iterator *iter = NULL;
 	struct ftrace_hash *hash;
 	struct list_head *mod_head;
-	struct trace_array *tr = ops->private;
-	int ret = -ENOMEM;
-
-	ftrace_ops_init(ops);
+	int ret = -ENODEV;
 
 	if (unlikely(ftrace_disabled))
 		return -ENODEV;
 
+	if (!tr) {
+		if (!ops)
+			ops = &global_ops;
+		tr = ops->private;
+	}
+
 	if (tracing_check_open_get_tr(tr))
 		return -ENODEV;
 
+	if (!ops)
+		ops = tr->ops;
+
+	if (WARN_ON_ONCE(!ops))
+		goto out;
+
+	ftrace_ops_init(ops);
+
+	ret = -ENOMEM;
 	iter = kzalloc(sizeof(*iter), GFP_KERNEL);
 	if (!iter)
 		goto out;
@@ -4646,21 +4666,19 @@ ftrace_regex_open(struct ftrace_ops *ops
 static int
 ftrace_filter_open(struct inode *inode, struct file *file)
 {
-	struct ftrace_ops *ops = inode->i_private;
+	struct trace_array *tr = inode->i_private;
 
-	/* Checks for tracefs lockdown */
-	return ftrace_regex_open(ops,
-			FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
-			inode, file);
+	return ftrace_regex_open(tr, NULL,
+				 FTRACE_ITER_FILTER | FTRACE_ITER_DO_PROBES,
+				 inode, file);
 }
 
 static int
 ftrace_notrace_open(struct inode *inode, struct file *file)
 {
-	struct ftrace_ops *ops = inode->i_private;
+	struct trace_array *tr = inode->i_private;
 
-	/* Checks for tracefs lockdown */
-	return ftrace_regex_open(ops, FTRACE_ITER_NOTRACE,
+	return ftrace_regex_open(tr, NULL, FTRACE_ITER_NOTRACE,
 				 inode, file);
 }
 
@@ -6969,15 +6987,15 @@ static const struct file_operations ftra
 };
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
 
-void ftrace_create_filter_files(struct ftrace_ops *ops,
+void ftrace_create_filter_files(struct trace_array *tr,
 				struct dentry *parent)
 {
 
 	trace_create_file("set_ftrace_filter", TRACE_MODE_WRITE, parent,
-			  ops, &ftrace_filter_fops);
+			  tr, &ftrace_filter_fops);
 
 	trace_create_file("set_ftrace_notrace", TRACE_MODE_WRITE, parent,
-			  ops, &ftrace_notrace_fops);
+			  tr, &ftrace_notrace_fops);
 }
 
 /*
@@ -7002,7 +7020,6 @@ void ftrace_destroy_filter_files(struct
 
 static __init int ftrace_init_dyn_tracefs(struct dentry *d_tracer)
 {
-
 	trace_create_file("available_filter_functions", TRACE_MODE_READ,
 			d_tracer, NULL, &ftrace_avail_fops);
 
@@ -7015,7 +7032,7 @@ static __init int ftrace_init_dyn_tracef
 	trace_create_file("touched_functions", TRACE_MODE_READ,
 			d_tracer, NULL, &ftrace_touched_fops);
 
-	ftrace_create_filter_files(&global_ops, d_tracer);
+	ftrace_create_filter_files(NULL, d_tracer);
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 	trace_create_file("set_graph_function", TRACE_MODE_WRITE, d_tracer,
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1191,7 +1191,7 @@ extern void clear_ftrace_function_probes
 int register_ftrace_command(struct ftrace_func_command *cmd);
 int unregister_ftrace_command(struct ftrace_func_command *cmd);
 
-void ftrace_create_filter_files(struct ftrace_ops *ops,
+void ftrace_create_filter_files(struct trace_array *tr,
 				struct dentry *parent);
 void ftrace_destroy_filter_files(struct ftrace_ops *ops);
 
@@ -1214,11 +1214,11 @@ static inline void clear_ftrace_function
 {
 }
 
+#define ftrace_create_filter_files(tr, parent) do { } while (0)
 /*
  * The ops parameter passed in is usually undefined.
  * This must be a macro.
  */
-#define ftrace_create_filter_files(ops, parent) do { } while (0)
 #define ftrace_destroy_filter_files(ops) do { } while (0)
 #endif /* CONFIG_FUNCTION_TRACER && CONFIG_DYNAMIC_FTRACE */
 
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -97,7 +97,7 @@ int ftrace_create_function_files(struct
 		return ret;
 	}
 
-	ftrace_create_filter_files(tr->ops, parent);
+	ftrace_create_filter_files(tr, parent);
 
 	return 0;
 }
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -499,7 +499,7 @@ stack_trace_filter_open(struct inode *in
 	struct ftrace_ops *ops = inode->i_private;
 
 	/* Checks for tracefs lockdown */
-	return ftrace_regex_open(ops, FTRACE_ITER_FILTER,
+	return ftrace_regex_open(NULL, ops, FTRACE_ITER_FILTER,
 				 inode, file);
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 633/877] dma-buf: dma-heap: dont publish fd before copy_to_user() succeeds
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (631 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 632/877] ftrace: Take trace_array reference before accessing its ftrace_ops Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 634/877] compiler_types: Move lock checking attributes to compiler-context-analysis.h Greg Kroah-Hartman
                   ` (251 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, T.J. Mercier, Christian König,
	Sumit Semwal, Baineng Shou, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Baineng Shou <shoubaineng@gmail.com>

[ Upstream commit 30d0aff2c65a277135cfd8ea28fa1ee75e0ea4e0 ]

DMA_HEAP_IOCTL_ALLOC allocates a dma-buf and installs an fd into the
caller's fd table via dma_buf_fd() -> fd_install() before
dma_heap_ioctl() copies the result back to userspace.  If the trailing
copy_to_user() fails, userspace never learns the fd number, but the
fd (and the underlying dma-buf reference) are already visible to
other threads in the same process and are leaked for the lifetime of
the process.

The obvious "close it on the failure path" fix is unsafe: once
fd_install() has run, another thread can already dup() the fd, send
it via SCM_RIGHTS, or close() it and let its number be reused, so a
subsequent close_fd() from the ioctl path can operate on an unrelated
file.  This was pointed out by Christian König on v1 [1].

Restructure the allocation path so that fd_install() is the last,
unfailable step of a successful ioctl:

  1. heap->ops->allocate()      creates the dma_buf.
  2. get_unused_fd_flags()      reserves an fd number in the caller's
                                fd table without publishing it, so
                                no other thread can observe it.
  3. copy_to_user()             delivers the fd number to userspace;
                                on failure the fd is returned with
                                put_unused_fd() and the dma_buf
                                reference is dropped with
                                dma_buf_put(), leaving no user-
                                visible state behind.
  4. dma_buf_fd_install()       publishes the fd and emits the
                                trace_dma_buf_fd tracepoint -- from
                                here on the ioctl cannot fail.

A new dma_buf_fd_install() helper is introduced in dma-buf.c to wrap
fd_install() together with the DMA_BUF_TRACE() call, preserving the
export tracing that dma_buf_fd() provides.  dma_heap_ioctl_allocate()
is refactored to return the struct dma_buf * directly (returning
ERR_PTR on failure) so the caller holds the dmabuf reference across
steps 3 and 4.

The failure at step 3 is easily reachable from userspace: pass a
struct dma_heap_allocation_data that lives in a page whose protection
is flipped to PROT_READ between copy_from_user() and copy_to_user()
(e.g. via mprotect()).  Before this change each such ioctl leaks one
dmabuf fd; after it, the fd table is unchanged on failure and only
/dev/dma_heap/<name> remains open.

No UAPI or heap-driver interface change.

[1] https://lore.kernel.org/dri-devel/175e98de-f414-47d7-81c1-c0fe0a8f7f62@amd.com/

Fixes: c02a81fba74f ("dma-buf: Add dma-buf heaps framework")
Cc: stable@vger.kernel.org
Reviewed-by: T.J. Mercier <tjmercier@google.com>
Acked-by: Christian König <christian.koenig@amd.com>
Acked-by: Sumit Semwal <sumit.semwal@linaro.org>
Signed-off-by: Baineng Shou <shoubaineng@gmail.com>
Link: https://lore.kernel.org/r/20260817050457.1005285-2-shoubaineng@gmail.com
Signed-off-by: Christian König <christian.koenig@amd.com>
[ Replaced dma_buf_fd_install(dmabuf, fd) with fd_install(fd, dmabuf->file) due to missing tracing infrastructure. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/dma-buf/dma-heap.c |   80 ++++++++++++++++++++++-----------------------
 1 file changed, 40 insertions(+), 40 deletions(-)

--- a/drivers/dma-buf/dma-heap.c
+++ b/drivers/dma-buf/dma-heap.c
@@ -48,33 +48,6 @@ static dev_t dma_heap_devt;
 static struct class *dma_heap_class;
 static DEFINE_XARRAY_ALLOC(dma_heap_minors);
 
-static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
-				 u32 fd_flags,
-				 u64 heap_flags)
-{
-	struct dma_buf *dmabuf;
-	int fd;
-
-	/*
-	 * Allocations from all heaps have to begin
-	 * and end on page boundaries.
-	 */
-	len = PAGE_ALIGN(len);
-	if (!len)
-		return -EINVAL;
-
-	dmabuf = heap->ops->allocate(heap, len, fd_flags, heap_flags);
-	if (IS_ERR(dmabuf))
-		return PTR_ERR(dmabuf);
-
-	fd = dma_buf_fd(dmabuf, fd_flags);
-	if (fd < 0) {
-		dma_buf_put(dmabuf);
-		/* just return, as put will call release and that will free */
-	}
-	return fd;
-}
-
 static int dma_heap_open(struct inode *inode, struct file *file)
 {
 	struct dma_heap *heap;
@@ -92,30 +65,42 @@ static int dma_heap_open(struct inode *i
 	return 0;
 }
 
-static long dma_heap_ioctl_allocate(struct file *file, void *data)
+static struct dma_buf *dma_heap_ioctl_allocate(struct file *file, void *data)
 {
 	struct dma_heap_allocation_data *heap_allocation = data;
 	struct dma_heap *heap = file->private_data;
+	struct dma_buf *dmabuf;
 	int fd;
+	size_t len;
 
 	if (heap_allocation->fd)
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 
 	if (heap_allocation->fd_flags & ~DMA_HEAP_VALID_FD_FLAGS)
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 
 	if (heap_allocation->heap_flags & ~DMA_HEAP_VALID_HEAP_FLAGS)
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
+
+	len = PAGE_ALIGN(heap_allocation->len);
+	if (!len)
+		return ERR_PTR(-EINVAL);
 
-	fd = dma_heap_buffer_alloc(heap, heap_allocation->len,
-				   heap_allocation->fd_flags,
-				   heap_allocation->heap_flags);
-	if (fd < 0)
-		return fd;
+	dmabuf = heap->ops->allocate(heap, len, heap_allocation->fd_flags,
+				     heap_allocation->heap_flags);
+
+	if (IS_ERR(dmabuf))
+		return dmabuf;
+
+	fd = get_unused_fd_flags(heap_allocation->fd_flags);
+	if (fd < 0) {
+		dma_buf_put(dmabuf);
+		return ERR_PTR(fd);
+	}
 
 	heap_allocation->fd = fd;
 
-	return 0;
+	return dmabuf;
 }
 
 static unsigned int dma_heap_ioctl_cmds[] = {
@@ -131,6 +116,8 @@ static long dma_heap_ioctl(struct file *
 	unsigned int in_size, out_size, drv_size, ksize;
 	int nr = _IOC_NR(ucmd);
 	int ret = 0;
+	int fd;
+	struct dma_buf *dmabuf;
 
 	if (nr >= ARRAY_SIZE(dma_heap_ioctl_cmds))
 		return -EINVAL;
@@ -167,15 +154,28 @@ static long dma_heap_ioctl(struct file *
 
 	switch (kcmd) {
 	case DMA_HEAP_IOCTL_ALLOC:
-		ret = dma_heap_ioctl_allocate(file, kdata);
+		dmabuf = dma_heap_ioctl_allocate(file, kdata);
+
+		if (IS_ERR(dmabuf)) {
+			ret = PTR_ERR(dmabuf);
+			break;
+		}
+
+		fd = ((struct dma_heap_allocation_data *)kdata)->fd;
+		if (copy_to_user((void __user *)arg, kdata, out_size) != 0) {
+			put_unused_fd(fd);
+			dma_buf_put(dmabuf);
+			ret = -EFAULT;
+		} else {
+			fd_install(fd, dmabuf->file);
+		}
+
 		break;
 	default:
 		ret = -ENOTTY;
 		goto err;
 	}
 
-	if (copy_to_user((void __user *)arg, kdata, out_size) != 0)
-		ret = -EFAULT;
 err:
 	if (kdata != stack_kdata)
 		kfree(kdata);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 634/877] compiler_types: Move lock checking attributes to compiler-context-analysis.h
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (632 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 633/877] dma-buf: dma-heap: dont publish fd before copy_to_user() succeeds Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 635/877] futex: Provide rt_mutex_.*_schedule() equivalents for futex scheduling Greg Kroah-Hartman
                   ` (250 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Marco Elver, Peter Zijlstra (Intel),
	Bart Van Assche, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Marco Elver <elver@google.com>

[ Upstream commit de15fecae44df8254fa597bad7eb3680a8b1c10c ]

The conditional definition of lock checking macros and attributes is
about to become more complex. Factor them out into their own header for
better readability, and to make it obvious which features are supported
by which mode (currently only Sparse). This is the first step towards
generalizing towards "context analysis".

No functional change intended.

Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20251219154418.3592607-2-elver@google.com
Stable-dep-of: 912edebe8501 ("futex: Provide rt_mutex_.*_schedule() equivalents for futex scheduling")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/linux/compiler-context-analysis.h |   32 ++++++++++++++++++++++++++++++
 include/linux/compiler_types.h            |   18 +---------------
 2 files changed, 34 insertions(+), 16 deletions(-)
 create mode 100644 include/linux/compiler-context-analysis.h

--- /dev/null
+++ b/include/linux/compiler-context-analysis.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Macros and attributes for compiler-based static context analysis.
+ */
+
+#ifndef _LINUX_COMPILER_CONTEXT_ANALYSIS_H
+#define _LINUX_COMPILER_CONTEXT_ANALYSIS_H
+
+#ifdef __CHECKER__
+
+/* Sparse context/lock checking support. */
+# define __must_hold(x)		__attribute__((context(x,1,1)))
+# define __acquires(x)		__attribute__((context(x,0,1)))
+# define __cond_acquires(x)	__attribute__((context(x,0,-1)))
+# define __releases(x)		__attribute__((context(x,1,0)))
+# define __acquire(x)		__context__(x,1)
+# define __release(x)		__context__(x,-1)
+# define __cond_lock(x, c)	((c) ? ({ __acquire(x); 1; }) : 0)
+
+#else /* !__CHECKER__ */
+
+# define __must_hold(x)
+# define __acquires(x)
+# define __cond_acquires(x)
+# define __releases(x)
+# define __acquire(x)		(void)0
+# define __release(x)		(void)0
+# define __cond_lock(x, c)	(c)
+
+#endif /* __CHECKER__ */
+
+#endif /* _LINUX_COMPILER_CONTEXT_ANALYSIS_H */
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -37,6 +37,8 @@
 # define BTF_TYPE_TAG(value) /* nothing */
 #endif
 
+#include <linux/compiler-context-analysis.h>
+
 /* sparse defines __CHECKER__; see Documentation/dev-tools/sparse.rst */
 #ifdef __CHECKER__
 /* address spaces */
@@ -47,14 +49,6 @@
 # define __rcu		__attribute__((noderef, address_space(__rcu)))
 static inline void __chk_user_ptr(const volatile void __user *ptr) { }
 static inline void __chk_io_ptr(const volatile void __iomem *ptr) { }
-/* context/locking */
-# define __must_hold(x)	__attribute__((context(x,1,1)))
-# define __acquires(x)	__attribute__((context(x,0,1)))
-# define __cond_acquires(x) __attribute__((context(x,0,-1)))
-# define __releases(x)	__attribute__((context(x,1,0)))
-# define __acquire(x)	__context__(x,1)
-# define __release(x)	__context__(x,-1)
-# define __cond_lock(x,c)	((c) ? ({ __acquire(x); 1; }) : 0)
 /* other */
 # define __force	__attribute__((force))
 # define __nocast	__attribute__((nocast))
@@ -75,14 +69,6 @@ static inline void __chk_io_ptr(const vo
 
 # define __chk_user_ptr(x)	(void)0
 # define __chk_io_ptr(x)	(void)0
-/* context/locking */
-# define __must_hold(x)
-# define __acquires(x)
-# define __cond_acquires(x)
-# define __releases(x)
-# define __acquire(x)	(void)0
-# define __release(x)	(void)0
-# define __cond_lock(x,c) (c)
 /* other */
 # define __force
 # define __nocast



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 635/877] futex: Provide rt_mutex_.*_schedule() equivalents for futex scheduling
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (633 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 634/877] compiler_types: Move lock checking attributes to compiler-context-analysis.h Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 636/877] rtc: rzn1: Handle unset alarm weekday in rzn1_rtc_read_alarm Greg Kroah-Hartman
                   ` (249 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yao Kai, Sebastian Andrzej Siewior,
	Thomas Gleixner, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

[ Upstream commit 912edebe8501a36c6bedcef03bd238ab90a7e060 ]

There is rt_mutex_{pre|post}_schedule() around
rt_mutex_wait_proxy_lock() to ensure that sched_submit_work()/
sched_update_worker() is invoked before we schedule out and block on
rt_mutex while waiting for it become available.

The reason is that blocking on rt_mutex assigns a pi_waiter for the PI
chain and sched_submit_work() will also assign a pi_waiter if it blocks
on lock but a this point we already have a waiter assigned.
We can't skip sched_submit_work() entirely because I/O relies on the
fact that I/O queue is flushed while it blocks on a sleeping lock.
Therefore sched_submit_work() is moved before we block on the lock.

Sleeping lock in this context means mutex or rw_semaphore not spinlock_t
on PREEMPT_RT. Because the mutex abstraction on PREEMPT_RT uses the same
abstraction as the futex proxy lock, the futex code ended up using
rt_mutex_{pre|post}_schedule(), too.
Using it is/ was just to keep the task_struct::sched_rt_mutex assertion
happy. Futex proxy lock is used only in the syscall context of a task.
At this point it never got any I/O that needs to be flushed and it can't
be a workqueue that needs to notify that it will be scheduled out.
Therefore sched_submit_work() does nothing here.

By mistake futex_wait_requeue_pi() -> rt_mutex_wait_proxy_lock() did not
get the rt_mutex_{pre|post}_schedule() annotation. This was not noticed
because in this callchain the lock is (usually) not contended and so
rt_mutex_slowlock_block() does not schedule, triggering the assert.

Adding rt_mutex_pre_schedule() here looks wrong (as noted by PeterZ)
because at this point there is a pi_waiter recorded and invoking
sched_submit_work() with a possible lock contention would be wrong.

Add rt_mutex_futex_{pre|post}_schedule() which toggles the
sched_rt_mutex assert and does not involve sched_submit_work(). Add
asserts here to ensure that sched_submit_work() would do nothing. Use it
only in futex proxy lock case which is rt_mutex_wait_proxy_lock().
Remove it from futex_lock_pi().

Fixes: d14f9e930b90 ("locking/rtmutex: Use rt_mutex specific scheduler helpers")
Reported-by: Yao Kai <yaokai34@huawei.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260901135453.3121948-2-bigeasy@linutronix.de
Closes: https://lore.kernel.org/all/20260717084922.4153317-2-yaokai34@huawei.com
[ adjusted futex context for older locking code lacking private-hash handling and futex_q_lockptr_lock(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/linux/sched/rt.h     |    2 ++
 kernel/futex/pi.c            |   10 ----------
 kernel/locking/rtmutex_api.c |    2 ++
 kernel/sched/core.c          |   16 ++++++++++++++++
 4 files changed, 20 insertions(+), 10 deletions(-)

--- a/include/linux/sched/rt.h
+++ b/include/linux/sched/rt.h
@@ -52,8 +52,10 @@ static inline bool rt_or_dl_task_policy(
 
 #ifdef CONFIG_RT_MUTEXES
 extern void rt_mutex_pre_schedule(void);
+extern void rt_mutex_futex_pre_schedule(void);
 extern void rt_mutex_schedule(void);
 extern void rt_mutex_post_schedule(void);
+extern void rt_mutex_futex_post_schedule(void);
 
 /*
  * Must hold either p->pi_lock or task_rq(p)->lock.
--- a/kernel/futex/pi.c
+++ b/kernel/futex/pi.c
@@ -992,12 +992,6 @@ retry_private:
 		goto no_block;
 	}
 
-	/*
-	 * Must be done before we enqueue the waiter, here is unfortunately
-	 * under the hb lock, but that *should* work because it does nothing.
-	 */
-	rt_mutex_pre_schedule();
-
 	rt_mutex_init_waiter(&rt_waiter);
 
 	/*
@@ -1065,10 +1059,6 @@ cleanup:
 	 * the
 	 */
 	spin_lock(q.lock_ptr);
-	/*
-	 * Waiter is unqueued.
-	 */
-	rt_mutex_post_schedule();
 no_block:
 	/*
 	 * Fixup the pi_state owner and possibly acquire the lock if we
--- a/kernel/locking/rtmutex_api.c
+++ b/kernel/locking/rtmutex_api.c
@@ -380,6 +380,7 @@ int __sched rt_mutex_wait_proxy_lock(str
 {
 	int ret;
 
+	rt_mutex_futex_pre_schedule();
 	raw_spin_lock_irq(&lock->wait_lock);
 	/* sleep on the mutex */
 	set_current_state(TASK_INTERRUPTIBLE);
@@ -390,6 +391,7 @@ int __sched rt_mutex_wait_proxy_lock(str
 	 */
 	fixup_rt_mutex_waiters(lock, true);
 	raw_spin_unlock_irq(&lock->wait_lock);
+	rt_mutex_futex_post_schedule();
 
 	return ret;
 }
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7117,6 +7117,17 @@ void rt_mutex_pre_schedule(void)
 	sched_submit_work(current);
 }
 
+/*
+ * Used within the futex syscall context, skips sched_submit_work() because none
+ * its work will be done. Asserts ensure that it is indeed the case.
+ */
+void rt_mutex_futex_pre_schedule(void)
+{
+	lockdep_assert(!(current->flags & (PF_WQ_WORKER | PF_IO_WORKER)));
+	lockdep_assert(!current->plug);
+	lockdep_assert(!fetch_and_set(current->sched_rt_mutex, 1));
+}
+
 void rt_mutex_schedule(void)
 {
 	lockdep_assert(current->sched_rt_mutex);
@@ -7129,6 +7140,11 @@ void rt_mutex_post_schedule(void)
 	lockdep_assert(fetch_and_set(current->sched_rt_mutex, 0));
 }
 
+void rt_mutex_futex_post_schedule(void)
+{
+	lockdep_assert(fetch_and_set(current->sched_rt_mutex, 0));
+}
+
 /*
  * rt_mutex_setprio - set the current priority of a task
  * @p: task to boost



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 636/877] rtc: rzn1: Handle unset alarm weekday in rzn1_rtc_read_alarm
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (634 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 635/877] futex: Provide rt_mutex_.*_schedule() equivalents for futex scheduling Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 637/877] perf/aux: Allocate non-contiguous AUX pages by default Greg Kroah-Hartman
                   ` (248 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Lad Prabhakar, Wolfram Sang,
	Alexandre Belloni, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>

[ Upstream commit 457b5dbce31209e65e1184716ed3af59cb1c0372 ]

RZN1_RTC_ALW is a weekday bitmask where bit N represents weekday N.
When no alarm has been configured, the register has its power-on-reset
value of zero.

rzn1_rtc_read_alarm() uses fls() to convert the weekday bitmask into a
weekday number. When RZN1_RTC_ALW is zero, fls(0) returns zero and
fls(wday) - 1 evaluates to -1. This invalid weekday is then used to
calculate the alarm date and can either leave tm_wday set to -1 or
produce a fabricated alarm date.

Treat a zero RZN1_RTC_ALW value as an unset alarm weekday and return
without calculating the alarm date. Move reading RZN1_RTC_CTL1 before
this check so that alrm->enabled is updated for both configured and
unconfigured alarms.

Fixes: b5ad1bf00d2c4 ("rtc: rzn1: Add alarm support")
Cc: stable@vger.kernel.org
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Link: https://patch.msgid.link/20260821211032.13554-5-prabhakar.mahadev-lad.rj@bp.renesas.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
[ retained the ALME-only enable check because RZN1_RTC_CTL1_1SE is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/rtc/rtc-rzn1.c |   16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

--- a/drivers/rtc/rtc-rzn1.c
+++ b/drivers/rtc/rtc-rzn1.c
@@ -193,13 +193,24 @@ static int rzn1_rtc_read_alarm(struct de
 	if (ret)
 		return ret;
 
+	ctl1 = readl(rtc->base + RZN1_RTC_CTL1);
+	alrm->enabled = !!(ctl1 & RZN1_RTC_CTL1_ALME);
+
 	min = readl(rtc->base + RZN1_RTC_ALM);
 	hour = readl(rtc->base + RZN1_RTC_ALH);
-	wday = readl(rtc->base + RZN1_RTC_ALW);
 
 	tm->tm_sec = 0;
 	tm->tm_min = bcd2bin(min);
 	tm->tm_hour = bcd2bin(hour);
+
+	/*
+	 * If wday is zero, no bit is set in RZN1_RTC_ALW. This is the
+	 * register's power-on reset value.
+	 */
+	wday = readl(rtc->base + RZN1_RTC_ALW);
+	if (!wday)
+		return 0;
+
 	delta_days = ((fls(wday) - 1) - tm->tm_wday + 7) % 7;
 	tm->tm_wday = fls(wday) - 1;
 
@@ -208,9 +219,6 @@ static int rzn1_rtc_read_alarm(struct de
 		rtc_time64_to_tm(alarm, tm);
 	}
 
-	ctl1 = readl(rtc->base + RZN1_RTC_CTL1);
-	alrm->enabled = !!(ctl1 & RZN1_RTC_CTL1_ALME);
-
 	return 0;
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 637/877] perf/aux: Allocate non-contiguous AUX pages by default
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (635 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 636/877] rtc: rzn1: Handle unset alarm weekday in rzn1_rtc_read_alarm Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 638/877] perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities Greg Kroah-Hartman
                   ` (247 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yabin Cui, Ingo Molnar, James Clark,
	Anshuman Khandual, Peter Zijlstra, Arnaldo Carvalho de Melo,
	Jiri Olsa, Alexander Shishkin, Mark Rutland, Namhyung Kim,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Yabin Cui <yabinc@google.com>

[ Upstream commit 18049c8cff9cc89daadc4df6975f7d9069638926 ]

perf always allocates contiguous AUX pages based on aux_watermark.
However, this contiguous allocation doesn't benefit all PMUs. For
instance, ARM SPE and TRBE operate with virtual pages, and Coresight
ETR allocates a separate buffer. For these PMUs, allocating contiguous
AUX pages unnecessarily exacerbates memory fragmentation. This
fragmentation can prevent their use on long-running devices.

This patch modifies the perf driver to be memory-friendly by default,
by allocating non-contiguous AUX pages. For PMUs requiring contiguous
pages (Intel BTS and some Intel PT), the existing
PERF_PMU_CAP_AUX_NO_SG capability can be used. For PMUs that don't
require but can benefit from contiguous pages (some Intel PT), a new
capability, PERF_PMU_CAP_AUX_PREFER_LARGE, is added to maintain their
existing behavior.

Signed-off-by: Yabin Cui <yabinc@google.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: James Clark <james.clark@linaro.org>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/r/20250508232642.148767-1-yabinc@google.com
Stable-dep-of: 8767b4d73018 ("perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/events/intel/pt.c  |    2 ++
 include/linux/perf_event.h  |    1 +
 kernel/events/ring_buffer.c |   29 ++++++++++++++++++++---------
 3 files changed, 23 insertions(+), 9 deletions(-)

--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -1896,6 +1896,8 @@ static __init int pt_init(void)
 
 	if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries))
 		pt_pmu.pmu.capabilities = PERF_PMU_CAP_AUX_NO_SG;
+	else
+		pt_pmu.pmu.capabilities = PERF_PMU_CAP_AUX_PREFER_LARGE;
 
 	pt_pmu.pmu.capabilities		|= PERF_PMU_CAP_EXCLUSIVE |
 					   PERF_PMU_CAP_ITRACE |
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -301,6 +301,7 @@ struct perf_event_pmu_context;
 #define PERF_PMU_CAP_AUX_OUTPUT			0x0080
 #define PERF_PMU_CAP_EXTENDED_HW_TYPE		0x0100
 #define PERF_PMU_CAP_AUX_PAUSE			0x0200
+#define PERF_PMU_CAP_AUX_PREFER_LARGE		0x0400
 
 /**
  * pmu::scope
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -685,7 +685,15 @@ int rb_alloc_aux(struct perf_buffer *rb,
 {
 	bool overwrite = !(flags & RING_BUFFER_WRITABLE);
 	int node = (event->cpu == -1) ? -1 : cpu_to_node(event->cpu);
-	int ret = -ENOMEM, max_order;
+	bool use_contiguous_pages = event->pmu->capabilities & (
+		PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_AUX_PREFER_LARGE);
+	/*
+	 * Initialize max_order to 0 for page allocation. This allocates single
+	 * pages to minimize memory fragmentation. This is overridden if the
+	 * PMU needs or prefers contiguous pages (use_contiguous_pages = true).
+	 */
+	int max_order = 0;
+	int ret = -ENOMEM;
 
 	if (!has_aux(event))
 		return -EOPNOTSUPP;
@@ -695,8 +703,8 @@ int rb_alloc_aux(struct perf_buffer *rb,
 
 	if (!overwrite) {
 		/*
-		 * Watermark defaults to half the buffer, and so does the
-		 * max_order, to aid PMU drivers in double buffering.
+		 * Watermark defaults to half the buffer, to aid PMU drivers
+		 * in double buffering.
 		 */
 		if (!watermark)
 			watermark = min_t(unsigned long,
@@ -704,16 +712,19 @@ int rb_alloc_aux(struct perf_buffer *rb,
 					  (unsigned long)nr_pages << (PAGE_SHIFT - 1));
 
 		/*
-		 * Use aux_watermark as the basis for chunking to
-		 * help PMU drivers honor the watermark.
+		 * If using contiguous pages, use aux_watermark as the basis
+		 * for chunking to help PMU drivers honor the watermark.
 		 */
-		max_order = get_order(watermark);
+		if (use_contiguous_pages)
+			max_order = get_order(watermark);
 	} else {
 		/*
-		 * We need to start with the max_order that fits in nr_pages,
-		 * not the other way around, hence ilog2() and not get_order.
+		 * If using contiguous pages, we need to start with the
+		 * max_order that fits in nr_pages, not the other way around,
+		 * hence ilog2() and not get_order.
 		 */
-		max_order = ilog2(nr_pages);
+		if (use_contiguous_pages)
+			max_order = ilog2(nr_pages);
 		watermark = 0;
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 638/877] perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (636 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 637/877] perf/aux: Allocate non-contiguous AUX pages by default Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 639/877] ring-buffer: Show persistent buffer dropped events in trace_pipe file Greg Kroah-Hartman
                   ` (246 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Namhyung Kim, Dapeng Mi,
	Peter Zijlstra (Intel), Zide Chen, Thomas Falcon, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dapeng Mi <dapeng1.mi@linux.intel.com>

[ Upstream commit 8767b4d73018bd3143f4c55b672064fad292f11b ]

AnyThread mode deprecation is enumerated by CPUID.0AH:EDX[15] instead of
PERF_CAPABILITIES MSR. It's not a good practice to define a bit to
represent "anythread deprecation" in perf_capabilities. It leads to the
anythread_deprecated bit could be overwritten by the real value of
PERF_CAPABILITIES MSR, just like the below code in update_pmu_cap() does.

if (!intel_pmu_broken_perf_cap()) {
	/* Perf Metric (Bit 15) and PEBS via PT (Bit 16) are hybrid enumeration */
	rdmsrq(MSR_IA32_PERF_CAPABILITIES, hybrid(pmu, intel_cap).capabilities);
}

It leads to the anythread_deprecated bit is cleared to 0 and the "any"
attribute is incorrectly shown in the /sys/devices/cpu/format/ folder on
these support Perfmon v6 platforms, like Clearwater Forest.

$ grep . /sys/devices/cpu/format/*
/sys/devices/cpu/format/acr_mask:config2:0-63
/sys/devices/cpu/format/any:config:21
/sys/devices/cpu/format/cmask:config:24-31

So remove the anythread_deprecated bit from perf_capabilities structure
and directly depends on CPUID.0AH:EDX[15] to judge if anythread is
deprecated.

Fixes: cadbaa039b99 ("perf/x86/intel: Make anythread filter support conditional")
Reported-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Zide Chen <zide.chen@intel.com>
Reviewed-by: Thomas Falcon <thomas.falcon@intel.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260616044654.3468742-2-dapeng1.mi@linux.intel.com
[ Adjusted patch context to match the older PMU initialization and capability layout. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/events/intel/core.c |   10 +++-------
 arch/x86/events/perf_event.h |    2 +-
 2 files changed, 4 insertions(+), 8 deletions(-)

--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -6568,12 +6568,6 @@ __init int intel_pmu_init(void)
 
 	x86_add_quirk(intel_arch_events_quirk); /* Install first, so it runs last */
 
-	if (version >= 5) {
-		x86_pmu.intel_cap.anythread_deprecated = edx.split.anythread_deprecated;
-		if (x86_pmu.intel_cap.anythread_deprecated)
-			pr_cont(" AnyThread deprecated, ");
-	}
-
 	/*
 	 * Install the hw-cache-events table:
 	 */
@@ -7301,8 +7295,10 @@ __init int intel_pmu_init(void)
 				      &x86_pmu.intel_ctrl);
 
 	/* AnyThread may be deprecated on arch perfmon v5 or later */
-	if (x86_pmu.intel_cap.anythread_deprecated)
+	if (version >= 5 && edx.split.anythread_deprecated) {
 		x86_pmu.format_attrs = intel_arch_formats_attr;
+		pr_cont("AnyThread deprecated, ");
+	}
 
 	intel_pmu_check_event_constraints(x86_pmu.event_constraints,
 					  x86_pmu.cntr_mask64,
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -630,7 +630,7 @@ union perf_capabilities {
 		u64	perf_metrics:1;
 		u64	pebs_output_pt_available:1;
 		u64	pebs_timing_info:1;
-		u64	anythread_deprecated:1;
+		u64	__reserved:1;
 	};
 	u64	capabilities;
 };



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 639/877] ring-buffer: Show persistent buffer dropped events in trace_pipe file
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (637 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 638/877] perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 640/877] ring-buffer: Allow splice reads on static buffers Greg Kroah-Hartman
                   ` (245 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Masami Hiramatsu (Google),
	Steven Rostedt, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Steven Rostedt <rostedt@goodmis.org>

[ Upstream commit 8928e4a3be34bf053f9ef1cad67263604bf4f05e ]

When the persistent ring buffer is validated on boot up, if a subbuffer is
deemed invalid, it resets the buffer and continues. Have the code preserve
the RB_MISSED_EVENTS flag in the commit portion of the subbuffer header
and pass that back so that the trace_pipe file can show the missed events
like the trace file does.

For example:

   <...>-1242    [005] d....  4429.120116: page_fault_user: address=0x7ffaebb6e728 ip=0x7ffaeb9d4960 error_code=0x7
   <...>-1242    [005] .....  4429.120124: mm_page_alloc: page=00000000055254f3 pfn=0x1373bd order=0 migratetype=1 gfp_flags=GFP_HIGHUSER_MOVABLE|__GFP_COMP
   <...>-1242    [005] d..2.  4429.120132: tlb_flush: pages:1 reason:local MM shootdown (3)
CPU:5 [LOST EVENTS]
   <...>-1242    [005] d....  4429.120661: page_fault_user: address=0x55ba7c2d0944 ip=0x55ba7c20cd02 error_code=0x7
   <...>-1242    [005] .....  4429.120669: mm_page_alloc: page=0000000005a02500 pfn=0x12b6e4 order=0 migratetype=1 gfp_flags=GFP_HIGHUSER_MOVABLE|__GFP_COMP
   <...>-1242    [005] d..2.  4429.120680: tlb_flush: pages:1 reason:local MM shootdown (3)

Link: https://patch.msgid.link/20260522171052.156419479@kernel.org
Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>

Backport notes for 6.18:

Keep the ring_buffer_read_page() changes needed as context for
6365c44a824f ("ring-buffer: Allow splice reads on static buffers").
Separate the raw commit flags from the page byte count and preserve the
lost-events flag when copying page contents. Keep the existing bpage name,
rb_page_capacity(reader) bounds and unsigned lost-event count. Read and
mask bpage->commit directly instead of adding the newer data-page helpers.

Drop the reader-page unknown-loss propagation: this tree lacks the
persistent invalid-subbuffer recovery and signed-loss reporting changes
that make that path meaningful.

Keep the copy loop bounded by the page size, not event_size, avoiding the
one-event-per-read regression subsequently fixed by af05b4e06279. Preserve
the loss flag when trimming a swapped page to real_end, and combine output
flags with bitwise OR so an already-set flag is not added a second time.

Stable-dep-of: 6365c44a824f ("ring-buffer: Allow splice reads on static buffers")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/ring_buffer.c |   56 +++++++++++++++++++++++++--------------------
 1 file changed, 32 insertions(+), 24 deletions(-)

--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -6534,6 +6534,7 @@ int ring_buffer_read_page(struct trace_b
 	struct buffer_page *reader;
 	unsigned long missed_events;
 	unsigned int commit;
+	unsigned int size;
 	unsigned int read;
 	u64 save_timestamp;
 
@@ -6568,7 +6569,8 @@ int ring_buffer_read_page(struct trace_b
 	event = rb_reader_event(cpu_buffer);
 
 	read = reader->read;
-	commit = rb_page_size(reader);
+	commit = rb_page_commit(reader);
+	size = rb_page_size(reader);
 
 	/* Check if any events were dropped */
 	missed_events = cpu_buffer->lost_events;
@@ -6580,13 +6582,14 @@ int ring_buffer_read_page(struct trace_b
 	 * we must copy the data from the page to the buffer.
 	 * Otherwise, we can simply swap the page with the one passed in.
 	 */
-	if (read || (len < (commit - read)) ||
+	if (read || (len < (size - read)) ||
 	    cpu_buffer->reader_page == cpu_buffer->commit_page ||
 	    cpu_buffer->mapped) {
 		struct buffer_data_page *rpage = cpu_buffer->reader_page->page;
 		unsigned int rpos = read;
 		unsigned int pos = 0;
-		unsigned int size;
+		unsigned int event_size;
+		unsigned int flags = 0;
 
 		/*
 		 * If a full page is expected, this can still be returned
@@ -6595,19 +6598,22 @@ int ring_buffer_read_page(struct trace_b
 		 * the reader page.
 		 */
 		if (full &&
-		    (!read || (len < (commit - read)) ||
+		    (!read || (len < (size - read)) ||
 		     cpu_buffer->reader_page == cpu_buffer->commit_page))
 			return -1;
 
-		if (len > (commit - read))
-			len = (commit - read);
+		if (len > (size - read))
+			len = (size - read);
 
 		/* Always keep the time extend and data together */
-		size = rb_event_ts_length(event);
+		event_size = rb_event_ts_length(event);
 
-		if (len < size)
+		if (len < event_size)
 			return -1;
 
+		if (commit & RB_MISSED_EVENTS)
+			flags = RB_MISSED_EVENTS;
+
 		/* save the current timestamp, since the user will need it */
 		save_timestamp = cpu_buffer->read_stamp;
 
@@ -6619,25 +6625,25 @@ int ring_buffer_read_page(struct trace_b
 			 * one or two events.
 			 * We have already ensured there's enough space if this
 			 * is a time extend. */
-			size = rb_event_length(event);
-			memcpy(bpage->data + pos, rpage->data + rpos, size);
+			event_size = rb_event_length(event);
+			memcpy(bpage->data + pos, rpage->data + rpos, event_size);
 
-			len -= size;
+			len -= event_size;
 
 			rb_advance_reader(cpu_buffer);
 			rpos = reader->read;
-			pos += size;
+			pos += event_size;
 
-			if (rpos >= commit)
+			if (rpos >= size)
 				break;
 
 			event = rb_reader_event(cpu_buffer);
 			/* Always keep the time extend and data together */
-			size = rb_event_ts_length(event);
-		} while (len >= size);
+			event_size = rb_event_ts_length(event);
+		} while (len >= event_size);
 
 		/* update bpage */
-		local_set(&bpage->commit, pos);
+		local_set(&bpage->commit, pos | flags);
 		bpage->time_stamp = save_timestamp;
 
 		/* we copied everything to the beginning */
@@ -6662,12 +6668,14 @@ int ring_buffer_read_page(struct trace_b
 		 * on the page.
 		 */
 		if (reader->real_end)
-			local_set(&bpage->commit, reader->real_end);
+			local_set(&bpage->commit, reader->real_end |
+				  (commit & RB_MISSED_EVENTS));
 	}
 
 	cpu_buffer->lost_events = 0;
 
 	commit = local_read(&bpage->commit);
+	size = commit & ~RB_MISSED_MASK;
 	/*
 	 * Set a flag in the commit field if we lost events
 	 */
@@ -6675,20 +6683,20 @@ int ring_buffer_read_page(struct trace_b
 		/* If there is room at the end of the page to save the
 		 * missed events, then record it there.
 		 */
-		if (rb_page_capacity(reader) - commit >= sizeof(missed_events)) {
-			memcpy(&bpage->data[commit], &missed_events,
+		if (rb_page_capacity(reader) - size >= sizeof(missed_events)) {
+			memcpy(&bpage->data[size], &missed_events,
 			       sizeof(missed_events));
-			local_add(RB_MISSED_STORED, &bpage->commit);
-			commit += sizeof(missed_events);
+			commit |= RB_MISSED_STORED;
+			size += sizeof(missed_events);
 		}
-		local_add(RB_MISSED_EVENTS, &bpage->commit);
+		local_set(&bpage->commit, commit | RB_MISSED_EVENTS);
 	}
 
 	/*
 	 * This page may be off to user land. Zero it out here.
 	 */
-	if (commit < rb_page_capacity(reader))
-		memset(&bpage->data[commit], 0, rb_page_capacity(reader) - commit);
+	if (size < rb_page_capacity(reader))
+		memset(&bpage->data[size], 0, rb_page_capacity(reader) - size);
 
 	return read;
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 640/877] ring-buffer: Allow splice reads on static buffers
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (638 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 639/877] ring-buffer: Show persistent buffer dropped events in trace_pipe file Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 641/877] nvme: add missing SRCU grace period in error path Greg Kroah-Hartman
                   ` (244 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vincent Donnefort, Steven Rostedt,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Vincent Donnefort <vdonnefort@google.com>

[ Upstream commit 6365c44a824ff138e7926413932bb5c2e28a4c8c ]

ring_buffer_read_page() rejects splice (full=1) reads on static buffers
(that is user-mapped, persistent or remote) because !read check assumes
unread pages must be swapped. However for those buffers we have no other
choice than memcpy the data.

For the memcpy case, only return an error when the writer is still on
the reader page for the splice interface to wait.

Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260901155445.1475405-2-vdonnefort@google.com
Fixes: 117c39200d9d ("ring-buffer: Introducing ring-buffer mapping functions")
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/ring_buffer.c |   11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -6591,15 +6591,8 @@ int ring_buffer_read_page(struct trace_b
 		unsigned int event_size;
 		unsigned int flags = 0;
 
-		/*
-		 * If a full page is expected, this can still be returned
-		 * if there's been a previous partial read and the
-		 * rest of the page can be read and the commit page is off
-		 * the reader page.
-		 */
-		if (full &&
-		    (!read || (len < (size - read)) ||
-		     cpu_buffer->reader_page == cpu_buffer->commit_page))
+		/* If a full page is requested, it cannot be the commit page */
+		if (full && cpu_buffer->reader_page == cpu_buffer->commit_page)
 			return -1;
 
 		if (len > (size - read))



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 641/877] nvme: add missing SRCU grace period in error path
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (639 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 640/877] ring-buffer: Allow splice reads on static buffers Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 642/877] nvme: all namespaces in a subsystem must adhere to a common atomic write size Greg Kroah-Hartman
                   ` (243 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Tristan Madani, Sagi Grimberg,
	John Garry, Christoph Hellwig, Keith Busch, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Tristan Madani <tristan@talencesecurity.com>

[ Upstream commit ef248d5de4469fb6bbaf8dbe0c4c47800080d648 ]

nvme_alloc_ns() error path at out_unlink_ns removes ns from the
namespace head siblings list with list_del_rcu(&ns->siblings) but
does not wait for SRCU readers before freeing the namespace struct.
Multipath code iterates the head->list under srcu_read_lock() in
nvme_find_path() and nvme_mpath_revalidate_paths(), so a concurrent
reader can still hold a reference to ns when kfree(ns) runs.

The normal removal path in nvme_ns_remove() correctly calls
synchronize_srcu(&ns->head->srcu) after list_del_rcu() to wait for
in-progress readers. Add the same grace period in the error path.

Fixes: ed754e5deeb1 ("nvme: track shared namespaces")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
[ Adjusted patch context to account for missing last_path reference-counting code. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/nvme/host/core.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -3974,6 +3974,9 @@ static void nvme_alloc_ns(struct nvme_ct
 	if (list_empty(&ns->head->list))
 		list_del_init(&ns->head->entry);
 	mutex_unlock(&ctrl->subsys->lock);
+
+	/* guarantee not available in head->list */
+	synchronize_srcu(&ns->head->srcu);
 	nvme_put_ns_head(ns->head);
  out_cleanup_disk:
 	put_disk(disk);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 642/877] nvme: all namespaces in a subsystem must adhere to a common atomic write size
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (640 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 641/877] nvme: add missing SRCU grace period in error path Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 643/877] nvme: refactor the atomic write unit detection Greg Kroah-Hartman
                   ` (242 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Alan Adamson, Christoph Hellwig,
	John Garry, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Alan Adamson <alan.adamson@oracle.com>

[ Upstream commit 8695f060a02953b33ac6240895dcb9c7ce16c91c ]

The first namespace configured in a subsystem sets the subsystem's
atomic write size based on its AWUPF or NAWUPF. Subsequent namespaces
must have an atomic write size (per their AWUPF or NAWUPF) less than or
equal to the subsystem's atomic write size, or their probing will be
rejected.

Signed-off-by: Alan Adamson <alan.adamson@oracle.com>
[hch: fold in review comments from John Garry]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Stable-dep-of: 3838e80fcfb3 ("nvme: skip the zoned limits update if the zone info query failed")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/nvme/host/core.c |   30 +++++++++++++++++++++++++++---
 drivers/nvme/host/nvme.h |    3 ++-
 2 files changed, 29 insertions(+), 4 deletions(-)

--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2054,7 +2054,21 @@ static bool nvme_update_disk_info(struct
 		if (id->nsfeat & NVME_NS_FEAT_ATOMICS && id->nawupf)
 			atomic_bs = (1 + le16_to_cpu(id->nawupf)) * bs;
 		else
-			atomic_bs = (1 + ns->ctrl->subsys->awupf) * bs;
+			atomic_bs = (1 + ns->ctrl->awupf) * bs;
+
+		/*
+		 * Set subsystem atomic bs.
+		 */
+		if (ns->ctrl->subsys->atomic_bs) {
+			if (atomic_bs != ns->ctrl->subsys->atomic_bs) {
+				dev_err_ratelimited(ns->ctrl->device,
+					"%s: Inconsistent Atomic Write Size, Namespace will not be added: Subsystem=%d bytes, Controller/Namespace=%d bytes\n",
+					ns->disk ? ns->disk->disk_name : "?",
+					ns->ctrl->subsys->atomic_bs,
+					atomic_bs);
+			}
+		} else
+			ns->ctrl->subsys->atomic_bs = atomic_bs;
 
 		nvme_update_atomic_write_disk_info(ns, id, lim, bs, atomic_bs);
 	}
@@ -2193,6 +2207,17 @@ static int nvme_update_ns_info_block(str
 	nvme_set_chunk_sectors(ns, id, &lim);
 	if (!nvme_update_disk_info(ns, id, &lim))
 		capacity = 0;
+
+	/*
+	 * Validate the max atomic write size fits within the subsystem's
+	 * atomic write capabilities.
+	 */
+	if (lim.atomic_write_hw_max > ns->ctrl->subsys->atomic_bs) {
+		blk_mq_unfreeze_queue(ns->disk->queue, memflags);
+		ret = -ENXIO;
+		goto out;
+	}
+
 	nvme_config_discard(ns, &lim);
 	if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
 	    ns->head->ids.csi == NVME_CSI_ZNS)
@@ -3029,7 +3054,6 @@ static int nvme_init_subsystem(struct nv
 		kfree(subsys);
 		return -EINVAL;
 	}
-	subsys->awupf = le16_to_cpu(id->awupf);
 	nvme_mpath_default_iopolicy(subsys);
 
 	subsys->dev.class = &nvme_subsys_class;
@@ -3439,7 +3463,7 @@ static int nvme_init_identify(struct nvm
 		dev_pm_qos_expose_latency_tolerance(ctrl->device);
 	else if (!ctrl->apst_enabled && prev_apst_enabled)
 		dev_pm_qos_hide_latency_tolerance(ctrl->device);
-
+	ctrl->awupf = le16_to_cpu(id->awupf);
 out_free:
 	kfree(id);
 	return ret;
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -410,6 +410,7 @@ struct nvme_ctrl {
 
 	enum nvme_ctrl_type cntrltype;
 	enum nvme_dctype dctype;
+	u16 awupf; /* 0's based value. */
 };
 
 static inline enum nvme_ctrl_state nvme_ctrl_state(struct nvme_ctrl *ctrl)
@@ -442,11 +443,11 @@ struct nvme_subsystem {
 	u8			cmic;
 	enum nvme_subsys_type	subtype;
 	u16			vendor_id;
-	u16			awupf;	/* 0's based awupf value. */
 	struct ida		ns_ida;
 #ifdef CONFIG_NVME_MULTIPATH
 	enum nvme_iopolicy	iopolicy;
 #endif
+	u32			atomic_bs;
 };
 
 /*



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 643/877] nvme: refactor the atomic write unit detection
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (641 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 642/877] nvme: all namespaces in a subsystem must adhere to a common atomic write size Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 644/877] nvme: fix atomic write size validation Greg Kroah-Hartman
                   ` (241 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Luis Chamberlain,
	John Garry, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Christoph Hellwig <hch@lst.de>

[ Upstream commit b2e607fecac15e07f50269c080e2e71b5049dfa2 ]

Move all the code out of nvme_update_disk_info into the helper, and
rename the helper to have a somewhat less clumsy name.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
Reviewed-by: John Garry <john.g.garry@oracle.com>

Stable adaptation for 6.12:
- Keep the existing atomic write helper refactor, but omit
  BLK_FEAT_ATOMIC_WRITES: this tree enables atomic writes through the
  hardware limits and does not define that feature flag.
- Call the existing discard setup helper from nvme_update_disk_info()
  after setting logical_block_size. Save the disk-info validity result
  and defer clearing capacity until after atomic-size validation. This
  preserves the result while leaving the zoned update insertion point
  clear for 3838e80fcfb32e62baffb63c6dc0a60153665a4d.
- Adapt the preceding dependency's atomic-size error path to the
  single-argument blk_mq_unfreeze_queue() API and cancel the pending
  limits update before unfreezing, releasing limits_lock on rejection.

No additional functions are introduced.

Stable-dep-of: 3838e80fcfb3 ("nvme: skip the zoned limits update if the zone info query failed")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/nvme/host/core.c |   84 +++++++++++++++++++++++++----------------------
 1 file changed, 46 insertions(+), 38 deletions(-)

--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1993,20 +1993,50 @@ static void nvme_configure_metadata(stru
 }
 
 
-static void nvme_update_atomic_write_disk_info(struct nvme_ns *ns,
-			struct nvme_id_ns *id, struct queue_limits *lim,
-			u32 bs, u32 atomic_bs)
+static u32 nvme_configure_atomic_write(struct nvme_ns *ns,
+		struct nvme_id_ns *id, struct queue_limits *lim, u32 bs)
 {
-	unsigned int boundary = 0;
+	u32 atomic_bs, boundary = 0;
 
-	if (id->nsfeat & NVME_NS_FEAT_ATOMICS && id->nawupf) {
-		if (le16_to_cpu(id->nabspf))
+	/*
+	 * We do not support an offset for the atomic boundaries.
+	 */
+	if (id->nabo)
+		return bs;
+
+	if ((id->nsfeat & NVME_NS_FEAT_ATOMICS) && id->nawupf) {
+		/*
+		 * Use the per-namespace atomic write unit when available.
+		 */
+		atomic_bs = (1 + le16_to_cpu(id->nawupf)) * bs;
+		if (id->nabspf)
 			boundary = (le16_to_cpu(id->nabspf) + 1) * bs;
+	} else {
+		/*
+		 * Use the controller wide atomic write unit.  This sucks
+		 * because the limit is defined in terms of logical blocks while
+		 * namespaces can have different formats, and because there is
+		 * no clear language in the specification prohibiting different
+		 * values for different controllers in the subsystem.
+		 */
+		atomic_bs = (1 + ns->ctrl->awupf) * bs;
 	}
+
+	if (!ns->ctrl->subsys->atomic_bs) {
+		ns->ctrl->subsys->atomic_bs = atomic_bs;
+	} else if (ns->ctrl->subsys->atomic_bs != atomic_bs) {
+		dev_err_ratelimited(ns->ctrl->device,
+			"%s: Inconsistent Atomic Write Size, Namespace will not be added: Subsystem=%d bytes, Controller/Namespace=%d bytes\n",
+			ns->disk ? ns->disk->disk_name : "?",
+			ns->ctrl->subsys->atomic_bs,
+			atomic_bs);
+	}
+
 	lim->atomic_write_hw_max = atomic_bs;
 	lim->atomic_write_hw_boundary = boundary;
 	lim->atomic_write_hw_unit_min = bs;
 	lim->atomic_write_hw_unit_max = rounddown_pow_of_two(atomic_bs);
+	return atomic_bs;
 }
 
 static u32 nvme_max_drv_segments(struct nvme_ctrl *ctrl)
@@ -2044,34 +2074,8 @@ static bool nvme_update_disk_info(struct
 		valid = false;
 	}
 
-	atomic_bs = phys_bs = bs;
-	if (id->nabo == 0) {
-		/*
-		 * Bit 1 indicates whether NAWUPF is defined for this namespace
-		 * and whether it should be used instead of AWUPF. If NAWUPF ==
-		 * 0 then AWUPF must be used instead.
-		 */
-		if (id->nsfeat & NVME_NS_FEAT_ATOMICS && id->nawupf)
-			atomic_bs = (1 + le16_to_cpu(id->nawupf)) * bs;
-		else
-			atomic_bs = (1 + ns->ctrl->awupf) * bs;
-
-		/*
-		 * Set subsystem atomic bs.
-		 */
-		if (ns->ctrl->subsys->atomic_bs) {
-			if (atomic_bs != ns->ctrl->subsys->atomic_bs) {
-				dev_err_ratelimited(ns->ctrl->device,
-					"%s: Inconsistent Atomic Write Size, Namespace will not be added: Subsystem=%d bytes, Controller/Namespace=%d bytes\n",
-					ns->disk ? ns->disk->disk_name : "?",
-					ns->ctrl->subsys->atomic_bs,
-					atomic_bs);
-			}
-		} else
-			ns->ctrl->subsys->atomic_bs = atomic_bs;
-
-		nvme_update_atomic_write_disk_info(ns, id, lim, bs, atomic_bs);
-	}
+	phys_bs = bs;
+	atomic_bs = nvme_configure_atomic_write(ns, id, lim, bs);
 
 	if (id->nsfeat & NVME_NS_FEAT_IO_OPT) {
 		/* NPWG = Namespace Preferred Write Granularity */
@@ -2095,6 +2099,7 @@ static bool nvme_update_disk_info(struct
 		lim->max_write_zeroes_sectors = UINT_MAX;
 	else
 		lim->max_write_zeroes_sectors = ns->ctrl->max_zeroes_sectors;
+	nvme_config_discard(ns, lim);
 	return valid;
 }
 
@@ -2169,6 +2174,7 @@ static int nvme_update_ns_info_block(str
 	struct nvme_id_ns *id;
 	sector_t capacity;
 	unsigned lbaf;
+	bool valid;
 	int ret;
 
 	ret = nvme_identify_ns(ns->ctrl, info->nsid, &id);
@@ -2205,20 +2211,22 @@ static int nvme_update_ns_info_block(str
 	nvme_set_ctrl_limits(ns->ctrl, &lim);
 	nvme_configure_metadata(ns->ctrl, ns->head, id, nvm, info);
 	nvme_set_chunk_sectors(ns, id, &lim);
-	if (!nvme_update_disk_info(ns, id, &lim))
-		capacity = 0;
+	valid = nvme_update_disk_info(ns, id, &lim);
 
 	/*
 	 * Validate the max atomic write size fits within the subsystem's
 	 * atomic write capabilities.
 	 */
 	if (lim.atomic_write_hw_max > ns->ctrl->subsys->atomic_bs) {
-		blk_mq_unfreeze_queue(ns->disk->queue, memflags);
+		queue_limits_cancel_update(ns->disk->queue);
+		blk_mq_unfreeze_queue(ns->disk->queue);
 		ret = -ENXIO;
 		goto out;
 	}
 
-	nvme_config_discard(ns, &lim);
+	if (!valid)
+		capacity = 0;
+
 	if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
 	    ns->head->ids.csi == NVME_CSI_ZNS)
 		nvme_update_zone_info(ns, &lim, &zi);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 644/877] nvme: fix atomic write size validation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (642 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 643/877] nvme: refactor the atomic write unit detection Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 645/877] nvme: skip the zoned limits update if the zone info query failed Greg Kroah-Hartman
                   ` (240 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yi Zhang, Christoph Hellwig,
	Luis Chamberlain, John Garry, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Christoph Hellwig <hch@lst.de>

[ Upstream commit f46d273449ba65afd53f3dd8fe0182c9df877e08 ]

Don't mix the namespace and controller values, and validate the
per-controller limit when probing the controller.  This avoid spurious
failures for controllers with namespaces that have different namespaces
with different logical block sizes, or report the per-namespace values
only for some namespaces.

It also fixes a missing queue_limits_cancel_update in an error path by
removing that error path.

Fixes: 8695f060a029 ("nvme: all namespaces in a subsystem must adhere to a common atomic write size")
Reported-by: Yi Zhang <yi.zhang@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Luis Chamberlain <mcgrof@kernel.org>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Tested-by: Yi Zhang <yi.zhang@redhat.com>

Stable adaptation for 6.12:
- Remove the atomic-size rejection together with its locally adapted
  queue_limits_cancel_update() and one-argument queue unfreeze calls.
  Validation now happens during controller identification, as upstream.
- Keep nvme_config_discard() in nvme_update_disk_info(), where the
  preceding dependency moved it. Do not restore a duplicate call here.
- Preserve the saved disk-info validity result and capacity handling,
  leaving the zoned update insertion point available for target
  3838e80fcfb32e62baffb63c6dc0a60153665a4d.

No additional functions are introduced.

Stable-dep-of: 3838e80fcfb3 ("nvme: skip the zoned limits update if the zone info query failed")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/nvme/host/core.c |   34 +++++++++++-----------------------
 drivers/nvme/host/nvme.h |    3 +--
 2 files changed, 12 insertions(+), 25 deletions(-)

--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2019,17 +2019,7 @@ static u32 nvme_configure_atomic_write(s
 		 * no clear language in the specification prohibiting different
 		 * values for different controllers in the subsystem.
 		 */
-		atomic_bs = (1 + ns->ctrl->awupf) * bs;
-	}
-
-	if (!ns->ctrl->subsys->atomic_bs) {
-		ns->ctrl->subsys->atomic_bs = atomic_bs;
-	} else if (ns->ctrl->subsys->atomic_bs != atomic_bs) {
-		dev_err_ratelimited(ns->ctrl->device,
-			"%s: Inconsistent Atomic Write Size, Namespace will not be added: Subsystem=%d bytes, Controller/Namespace=%d bytes\n",
-			ns->disk ? ns->disk->disk_name : "?",
-			ns->ctrl->subsys->atomic_bs,
-			atomic_bs);
+		atomic_bs = (1 + ns->ctrl->subsys->awupf) * bs;
 	}
 
 	lim->atomic_write_hw_max = atomic_bs;
@@ -2213,17 +2203,6 @@ static int nvme_update_ns_info_block(str
 	nvme_set_chunk_sectors(ns, id, &lim);
 	valid = nvme_update_disk_info(ns, id, &lim);
 
-	/*
-	 * Validate the max atomic write size fits within the subsystem's
-	 * atomic write capabilities.
-	 */
-	if (lim.atomic_write_hw_max > ns->ctrl->subsys->atomic_bs) {
-		queue_limits_cancel_update(ns->disk->queue);
-		blk_mq_unfreeze_queue(ns->disk->queue);
-		ret = -ENXIO;
-		goto out;
-	}
-
 	if (!valid)
 		capacity = 0;
 
@@ -3047,6 +3026,7 @@ static int nvme_init_subsystem(struct nv
 	memcpy(subsys->model, id->mn, sizeof(subsys->model));
 	subsys->vendor_id = le16_to_cpu(id->vid);
 	subsys->cmic = id->cmic;
+	subsys->awupf = le16_to_cpu(id->awupf);
 
 	/* Versions prior to 1.4 don't necessarily report a valid type */
 	if (id->cntrltype == NVME_CTRL_DISC ||
@@ -3376,6 +3356,15 @@ static int nvme_init_identify(struct nvm
 		if (ret)
 			goto out_free;
 	}
+
+	if (le16_to_cpu(id->awupf) != ctrl->subsys->awupf) {
+		dev_err_ratelimited(ctrl->device,
+			"inconsistent AWUPF, controller not added (%u/%u).\n",
+			le16_to_cpu(id->awupf), ctrl->subsys->awupf);
+		ret = -EINVAL;
+		goto out_free;
+	}
+
 	memcpy(ctrl->subsys->firmware_rev, id->fr,
 	       sizeof(ctrl->subsys->firmware_rev));
 
@@ -3471,7 +3460,6 @@ static int nvme_init_identify(struct nvm
 		dev_pm_qos_expose_latency_tolerance(ctrl->device);
 	else if (!ctrl->apst_enabled && prev_apst_enabled)
 		dev_pm_qos_hide_latency_tolerance(ctrl->device);
-	ctrl->awupf = le16_to_cpu(id->awupf);
 out_free:
 	kfree(id);
 	return ret;
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -410,7 +410,6 @@ struct nvme_ctrl {
 
 	enum nvme_ctrl_type cntrltype;
 	enum nvme_dctype dctype;
-	u16 awupf; /* 0's based value. */
 };
 
 static inline enum nvme_ctrl_state nvme_ctrl_state(struct nvme_ctrl *ctrl)
@@ -443,11 +442,11 @@ struct nvme_subsystem {
 	u8			cmic;
 	enum nvme_subsys_type	subtype;
 	u16			vendor_id;
+	u16			awupf; /* 0's based value. */
 	struct ida		ns_ida;
 #ifdef CONFIG_NVME_MULTIPATH
 	enum nvme_iopolicy	iopolicy;
 #endif
-	u32			atomic_bs;
 };
 
 /*



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 645/877] nvme: skip the zoned limits update if the zone info query failed
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (643 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 644/877] nvme: fix atomic write size validation Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 646/877] s390/vfio-ap: Fix missing lock required to access list of ap_matrix_mdev objects Greg Kroah-Hartman
                   ` (239 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Weidong Zhu, Keith Busch,
	Christoph Hellwig, Chao Shi, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Chao Shi <coshi036@gmail.com>

[ Upstream commit 3838e80fcfb32e62baffb63c6dc0a60153665a4d ]

nvme_query_zone_info() returns either a negative errno or a positive
NVMe status code, but nvme_update_ns_info_block() only tests for the
negative case:

	ret = nvme_query_zone_info(ns, lbaf, &zi);
	if (ret < 0)
		goto out;

If the device fails the Identify Namespace (I/O Command Set specific)
command, or the Identify Controller command issued by
nvme_set_max_append(), the positive status falls through and setup
continues with the zero-initialized zone info.  nvme_update_zone_info()
then marks the queue zoned with chunk_sectors and ns->head->zsze set to
zero.

blk_validate_zoned_limits() does not check chunk_sectors, so the limits
commit succeeds.  blk_revalidate_disk_zones() does reject the zero zone
size, but by then the limits are live and nothing rolls them back, so
I/O keeps being submitted to a zoned queue with a zero zone size and
disk_zone_no() shifts by ilog2(0):

  nvme0n1: Invalid non power of two zone size (0)
  UBSAN: shift-out-of-bounds in include/linux/blkdev.h:747:16
  shift exponent -1 is negative
   disk_zone_no include/linux/blkdev.h:747 [inline]
   bio_straddles_zones include/linux/blkdev.h:1058 [inline]
   blk_zone_wplug_handle_write block/blk-zoned.c:1423 [inline]
   blk_zone_plug_bio.cold+0x25/0x1c8 block/blk-zoned.c:1605
   blk_mq_submit_bio+0x18fb/0x2870 block/blk-mq.c:3196
   submit_bh_wbc+0x575/0x740 fs/buffer.c:2824
   __block_write_full_folio+0x728/0xdd0 fs/buffer.c:1933

Any device, firmware or NVMe-oF target that fails this one command
reaches this.

Skip the zoned limits update in that case, and log which of the two
things happened: during a revalidation the queue keeps the zone
geometry it was last validated with, and on a first scan the namespace
is registered without zoned limits, so that it is still available as a
handle for admin commands.  Neither of the paths in
nvme_query_zone_info() that return a positive status logs anything, so
the failure would otherwise be silent.

zi.zone_size is an exact indicator: every path that returns a positive
status returns before it is assigned, and after that the only failure
left is -ENODEV, which the caller already handles.

Found by FuzzNvme.
Fixes: c85c9ab926a5 ("nvme: split nvme_update_zone_info")
Cc: stable@vger.kernel.org
Cc: Weidong Zhu <weizhu@fiu.edu>
Suggested-by: Keith Busch <kbusch@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Chao Shi <coshi036@gmail.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/nvme/host/core.c |   21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2206,9 +2206,26 @@ static int nvme_update_ns_info_block(str
 	if (!valid)
 		capacity = 0;
 
+	/*
+	 * A failed zone info query leaves zi zero-initialized, so skip the
+	 * zoned limits update instead of configuring the queue from it.
+	 * During a revalidation that keeps the zone geometry the queue was
+	 * last validated with; on a first scan the namespace is registered
+	 * without zoned limits, so that it is still available as a handle
+	 * for admin commands.
+	 */
 	if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
-	    ns->head->ids.csi == NVME_CSI_ZNS)
-		nvme_update_zone_info(ns, &lim, &zi);
+	    ns->head->ids.csi == NVME_CSI_ZNS) {
+		if (zi.zone_size)
+			nvme_update_zone_info(ns, &lim, &zi);
+		else
+			dev_warn(ns->ctrl->device,
+				 "zone info query failed for nsid %u, %s\n",
+				 ns->head->ns_id,
+				 blk_queue_is_zoned(ns->disk->queue) ?
+				 "keeping the previous zone limits" :
+				 "not enabling zoned mode");
+	}
 
 	if (ns->ctrl->vwc & NVME_CTRL_VWC_PRESENT)
 		lim.features |= BLK_FEAT_WRITE_CACHE | BLK_FEAT_FUA;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 646/877] s390/vfio-ap: Fix missing lock required to access list of ap_matrix_mdev objects
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (644 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 645/877] nvme: skip the zoned limits update if the zone info query failed Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 647/877] mm: fix incorrect vm_flags usage when checking allowable orders for tmpfs Greg Kroah-Hartman
                   ` (238 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Anthony Krowiak, Matthew Rosato,
	Christian Borntraeger, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Anthony Krowiak <akrowiak@linux.ibm.com>

[ Upstream commit 7fa61c29850d05e40ca9ed41bfdf57673023f581 ]

In order to traverse or add/remove ap_matrix_mdev objects in the
matrix_dev->mdev_list, the matrix_dev->guests_lock mutex must be held.
There are two functions that access the list without holding the mutex:

vfio_ap_mdev_probe function
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The vfio_ap_mdev_probe function uses the matrix_dev->mdevs_lock
mutex to guard the add of a newly created ap_matrix_mdev object to the
matrix_dev->mdev_list. This mutex does not protect list access; its purpose
is to guard against concurrent access to fields contained in an
ap_matrix_mdev object. This could lead to kernel memory corruption or
use-after-free if another mdev is created or removed concurrently.

The adding of an ap_matrix_mdev object to matrix_dev->mdev_list
is now guarded by the matrix_dev->guests_lock which is the correct
way to protect against concurrent mdev_list access.

Also removed the following two lines of code because the matrix_mdev is
allocated via vfio_alloc_device macro which uses kzalloc, so req_trigger
and cfg_chg_trigger are already zero-initialised when the struct is
allocated before the call to vfio_register_emulated_iommu_dev. This
prevents a window whereby these triggers are set to NULL after
the device is exposed to userspace.

matrix_mdev->req_trigger = NULL;
matrix_mdev->cfg_chg_trigger = NULL;

vfio_ap_mdev_for_queue function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The status_show function that supports display of the status attribute of
the devices in /sys/bus/ap/devices calls the vfio_ap_mdev_for_queue
function which iterates the matrix_dev->mdev_list to find the object
representing the queue device whose status is to be displayed. In order to
traverse this list, the matrix_dev->guests_lock mutex must be held.

To fix this, the guests_lock mutex is taken prior to taking the
matrix_dev->mdevs_lock mutex in the status_show function. It is taken
there rather than the vfio_ap_mdev_for_queue function - where it is
needed - because it must be taken prior to the mdevs_lock mutex in order to
adhere to the proper locking order and prevent a lockdep splat; also
because the mdevs_lock is needed there to access fields within
the matrix_mdev object in that function.

See the vfio-ap-locking.rst in the linux kernel tree.

Fixes: 2c1ee8983aa3 ("s390/vfio-ap: prepare for dynamic update of guest's APCB on queue probe/remove")
Cc: stable@vger.kernel.org
Signed-off-by: Anthony Krowiak <akrowiak@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
[ Omitted deletion of cfg_chg_trigger initialization because the field is absent in Linux 6.12. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/s390/crypto/vfio_ap_ops.c |   26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -786,11 +786,17 @@ static int vfio_ap_mdev_probe(struct mde
 	ret = vfio_register_emulated_iommu_dev(&matrix_mdev->vdev);
 	if (ret)
 		goto err_put_vdev;
-	matrix_mdev->req_trigger = NULL;
+
+	/*
+	 * Take the matrix_dev->guests_lock mutex before adding the matrix_mdev
+	 * to the mdev_list. All functions that traverse the list must also hold
+	 * this lock to guard against additions to or removals from the list
+	 * while it is being traversed.
+	 */
+	mutex_lock(&matrix_dev->guests_lock);
 	dev_set_drvdata(&mdev->dev, matrix_mdev);
-	mutex_lock(&matrix_dev->mdevs_lock);
 	list_add(&matrix_mdev->node, &matrix_dev->mdev_list);
-	mutex_unlock(&matrix_dev->mdevs_lock);
+	mutex_unlock(&matrix_dev->guests_lock);
 	return 0;
 
 err_put_vdev:
@@ -2247,6 +2253,8 @@ static struct ap_matrix_mdev *vfio_ap_md
 	unsigned long apid = AP_QID_CARD(q->apqn);
 	unsigned long apqi = AP_QID_QUEUE(q->apqn);
 
+	lockdep_assert_held(&matrix_dev->guests_lock);
+
 	list_for_each_entry(matrix_mdev, &matrix_dev->mdev_list, node) {
 		if (test_bit_inv(apid, matrix_mdev->matrix.apm) &&
 		    test_bit_inv(apqi, matrix_mdev->matrix.aqm))
@@ -2266,6 +2274,7 @@ static ssize_t status_show(struct device
 	struct ap_matrix_mdev *matrix_mdev;
 	struct ap_device *apdev = to_ap_dev(dev);
 
+	mutex_lock(&matrix_dev->guests_lock);
 	mutex_lock(&matrix_dev->mdevs_lock);
 	q = dev_get_drvdata(&apdev->device);
 
@@ -2314,6 +2323,7 @@ static ssize_t status_show(struct device
 
 done:
 	mutex_unlock(&matrix_dev->mdevs_lock);
+	mutex_unlock(&matrix_dev->guests_lock);
 
 	return nchars;
 }
@@ -2746,6 +2756,12 @@ static void vfio_ap_mdev_cfg_add(unsigne
 
 	vfio_ap_filter_apid_by_qtype(apm_add, aqm_add);
 
+	/*
+	 * It is safe to traverse this list here because the
+	 * required guard - matrix_dev->guests_lock - is taken in the
+	 * vfio_ap_on_cfg_changed function prior to this function getting
+	 * called.
+	 */
 	list_for_each_entry(matrix_mdev, &matrix_dev->mdev_list, node) {
 		/*
 		 * The mdevs_lock must be held in order to access fields
@@ -2813,6 +2829,10 @@ void vfio_ap_on_cfg_changed(struct ap_co
 	if (!cur_cfg_info || !prev_cfg_info)
 		return;
 
+	/*
+	 * Take the guests_lock mutex here to guard access to the
+	 * matrix_dev->mdev_list in the two functions called below.
+	 */
 	mutex_lock(&matrix_dev->guests_lock);
 
 	vfio_ap_mdev_on_cfg_remove(cur_cfg_info, prev_cfg_info);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 647/877] mm: fix incorrect vm_flags usage when checking allowable orders for tmpfs
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (645 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 646/877] s390/vfio-ap: Fix missing lock required to access list of ap_matrix_mdev objects Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:25 ` [PATCH 6.12 648/877] nvdimm: preserve flush callback -ENOMEM Greg Kroah-Hartman
                   ` (237 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Baolin Wang, Lance Yang,
	Lorenzo Stoakes (ARM), Zi Yan, Barry Song, David Hildenbrand,
	Dev Jain, Hugh Dickins, Liam R. Howlett, Ryan Roberts,
	Vlastimil Babka, Andrew Morton, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Baolin Wang <baolin.wang@linux.alibaba.com>

[ Upstream commit 2fd4e7693674b17807a6d082feb01a3fbf86f5f8 ]

Lance reported that when nothing else causes the mm to be considered for
khugepaged collapse, an MADV_HUGEPAGE-advised tmpfs VMA alone does not
trigger scanning.

After commit 6beeab870e70 ("mm: shmem: move shmem_huge_global_enabled()
into shmem_allowable_huge_orders()"), the shmem/tmpfs allowable order
check reads vma->flags directly.  However, when MADV_HUGEPAGE is handled,
khugepaged_enter_vma() is called before the VMA's flags have been updated,
so the check uses stale flags and incorrectly rejects the VMA for
collapse.  As a result, khugepaged does not collapse the tmpfs file into
PMD order in time.

Fix this by calling khugepaged_enter_vma() with the new VMA flags in
madvise_update_vma().  Meanwhile we can remove the khugepaged_enter_vma()
in hugepage_madvise().

Link: https://lore.kernel.org/7d5b5eb27be798f89d563b06254c947ff53db0b2.1787020910.git.baolin.wang@linux.alibaba.com
Fixes: 6beeab870e70 ("mm: shmem: move shmem_huge_global_enabled() into shmem_allowable_huge_orders()")
Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Reported-by: Lance Yang <lance.yang@linux.dev>
Closes: https://lore.kernel.org/all/20260815181632.21453-1-lance.yang@linux.dev/
Suggested-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Cc: Barry Song <baohua@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[ adapted newer VMA flag helpers to the branch’s legacy new_flags bitmask API. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 mm/khugepaged.c |    6 ------
 mm/madvise.c    |    8 ++++++++
 2 files changed, 8 insertions(+), 6 deletions(-)

--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -369,12 +369,6 @@ int hugepage_madvise(struct vm_area_stru
 #endif
 		*vm_flags &= ~VM_NOHUGEPAGE;
 		*vm_flags |= VM_HUGEPAGE;
-		/*
-		 * If the vma become good for khugepaged to scan,
-		 * register it here without waiting a page fault that
-		 * may not happen any time soon.
-		 */
-		khugepaged_enter_vma(vma, *vm_flags);
 		break;
 	case MADV_NOHUGEPAGE:
 		*vm_flags &= ~VM_HUGEPAGE;
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -158,6 +158,14 @@ static int madvise_update_vma(struct vm_
 	/* vm_flags is protected by the mmap_lock held in write mode. */
 	vma_start_write(vma);
 	vm_flags_reset(vma, new_flags);
+	/*
+	 * If the vma become good for khugepaged to scan,
+	 * register it here without waiting a page fault that
+	 * may not happen any time soon.
+	 */
+	if (new_flags & VM_HUGEPAGE)
+		khugepaged_enter_vma(vma, new_flags);
+
 	if (!vma->vm_file || vma_is_anon_shmem(vma)) {
 		error = replace_anon_vma_name(vma, anon_name);
 		if (error)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 648/877] nvdimm: preserve flush callback -ENOMEM
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (646 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 647/877] mm: fix incorrect vm_flags usage when checking allowable orders for tmpfs Greg Kroah-Hartman
@ 2026-09-30 15:25 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 649/877] nvdimm: pmem: keep PREFLUSH before data writes Greg Kroah-Hartman
                   ` (236 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:25 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Pankaj Gupta, Li Chen,
	Michael S. Tsirkin, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Li Chen <me@linux.beauty>

[ Upstream commit 6b7108712a4b1c37cac69815aede1dde202b3187 ]

nvdimm_flush() maps provider flush failures to -EIO. Keep that default
because provider callbacks can report host-side or backend failures that
should remain generic I/O errors to the guest.

Guest-side allocation failures should not be reported as I/O errors. In the
virtio-pmem path, the flush request allocation can fail with -ENOMEM before
any request is submitted to the host. Mapping that to -EIO makes resource
pressure look like media failure.

Preserve -ENOMEM from provider callbacks and continue to map other non-zero
provider failures to -EIO. The generic flush path still returns 0, and
pmem_submit_bio() already converts errno values to block status for bio
completion.

Suggested-by: Pankaj Gupta <pankaj.gupta.linux@gmail.com>
Signed-off-by: Li Chen <me@linux.beauty>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260630092338.2094628-2-me@linux.beauty>
Stable-dep-of: e57140944b5a ("nvdimm: virtio_pmem: refcount requests for token lifetime")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/nvdimm/region_devs.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -1112,7 +1112,8 @@ int nvdimm_flush(struct nd_region *nd_re
 	if (!nd_region->flush)
 		rc = generic_nvdimm_flush(nd_region);
 	else {
-		if (nd_region->flush(nd_region, bio))
+		rc = nd_region->flush(nd_region, bio);
+		if (rc && rc != -ENOMEM)
 			rc = -EIO;
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 649/877] nvdimm: pmem: keep PREFLUSH before data writes
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (647 preceding siblings ...)
  2026-09-30 15:25 ` [PATCH 6.12 648/877] nvdimm: preserve flush callback -ENOMEM Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 650/877] nvdimm: virtio_pmem: stop allocating child flush bio Greg Kroah-Hartman
                   ` (235 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Li Chen, Michael S. Tsirkin,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Li Chen <me@linux.beauty>

[ Upstream commit c644a2f8fef5618fcf453c591177700fd07dd024 ]

pmem_submit_bio() records a REQ_PREFLUSH error, but continues to copy the
bio data and can later overwrite the error with a successful REQ_FUA flush.
That lets data writes run after a failed preflush and can complete the bio
successfully despite the failed ordering barrier.

Run the REQ_PREFLUSH flush synchronously before touching the bio data and
complete the bio with the flush error if it fails. Keep asynchronous flush
chaining for REQ_FUA. At that point, data copy has completed and the parent
bio can wait for the chained flush bio.

Signed-off-by: Li Chen <me@linux.beauty>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260630092338.2094628-3-me@linux.beauty>
Stable-dep-of: e57140944b5a ("nvdimm: virtio_pmem: refcount requests for token lifetime")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/nvdimm/pmem.c |   12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -209,8 +209,14 @@ static void pmem_submit_bio(struct bio *
 	struct pmem_device *pmem = bio->bi_bdev->bd_disk->private_data;
 	struct nd_region *nd_region = to_region(pmem);
 
-	if (bio->bi_opf & REQ_PREFLUSH)
-		ret = nvdimm_flush(nd_region, bio);
+	if (bio->bi_opf & REQ_PREFLUSH) {
+		ret = nvdimm_flush(nd_region, NULL);
+		if (ret) {
+			bio->bi_status = errno_to_blk_status(ret);
+			bio_endio(bio);
+			return;
+		}
+	}
 
 	do_acct = blk_queue_io_stat(bio->bi_bdev->bd_disk->queue);
 	if (do_acct)
@@ -230,7 +236,7 @@ static void pmem_submit_bio(struct bio *
 	if (do_acct)
 		bio_end_io_acct(bio, start);
 
-	if (bio->bi_opf & REQ_FUA)
+	if ((bio->bi_opf & REQ_FUA) && !bio->bi_status)
 		ret = nvdimm_flush(nd_region, bio);
 
 	if (ret)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 650/877] nvdimm: virtio_pmem: stop allocating child flush bio
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (648 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 649/877] nvdimm: pmem: keep PREFLUSH before data writes Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 651/877] nvdimm: virtio_pmem: always wake -ENOSPC waiters Greg Kroah-Hartman
                   ` (234 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Li Chen, Michael S. Tsirkin,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Li Chen <me@linux.beauty>

[ Upstream commit 40f356e610df95728074b1fc2e2ccb54ca1b5659 ]

pmem_submit_bio() passes the parent bio to nvdimm_flush() for
REQ_FUA. For virtio-pmem this makes async_pmem_flush() allocate
and submit a child PREFLUSH bio chained to the parent.

That child allocation is in the block submit path. Making it
blocking with GFP_NOIO can consume the same global bio mempool that
submit_bio() uses, while making it GFP_ATOMIC can fail under
pressure. A forced failure of the child allocation produced:

virtio_pmem: forcing child bio allocation failure for test
Buffer I/O error on dev pmem0, logical block 0, lost sync page write
EXT4-fs (pmem0): I/O error while writing superblock
EXT4-fs (pmem0): mount failed

Avoid the child bio without turning REQ_FUA into a synchronous
submit-path wait. Let provider flush callbacks return
NVDIMM_FLUSH_ASYNC after taking ownership of parent bio completion.
pmem_submit_bio() returns in that case, and virtio-pmem queues an
ordered WQ_MEM_RECLAIM work item that runs the existing host flush
path and completes the parent bio.

This keeps the asynchronous completion model of the child-bio path
while removing the child bio allocation from the submit path.

Signed-off-by: Li Chen <me@linux.beauty>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260630092338.2094628-5-me@linux.beauty>

Backport notes for 6.12:
Drop the freeze callback hunk: this tree does not have the upstream
virtio-pmem freeze/restore callbacks. Keep the workqueue allocation,
probe error cleanup, and removal drain without adding those callbacks.

Use the available kmalloc_obj() helper for the existing request allocation,
matching upstream without changing its GFP_KERNEL behavior. This keeps the
following GFP_NOIO dependency applicable. Correct the existing "repsonse"
comment typo to match the context of the wait-flag dependency. The remaining
request-wakeup and wait-flag dependencies are still needed before the
refcount target.

Stable-dep-of: e57140944b5a ("nvdimm: virtio_pmem: refcount requests for token lifetime")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/nvdimm/nd_virtio.c   |   58 +++++++++++++++++++++++++++++--------------
 drivers/nvdimm/pmem.c        |    5 ++-
 drivers/nvdimm/region_devs.c |    2 +
 drivers/nvdimm/virtio_pmem.c |   14 +++++++++-
 drivers/nvdimm/virtio_pmem.h |    4 ++
 include/linux/libnvdimm.h    |    9 ++++++
 6 files changed, 72 insertions(+), 20 deletions(-)

--- a/drivers/nvdimm/nd_virtio.c
+++ b/drivers/nvdimm/nd_virtio.c
@@ -9,6 +9,12 @@
 #include "virtio_pmem.h"
 #include "nd.h"
 
+struct virtio_pmem_flush_work {
+	struct work_struct work;
+	struct nd_region *nd_region;
+	struct bio *bio;
+};
+
  /* The interrupt handler */
 void virtio_pmem_host_ack(struct virtqueue *vq)
 {
@@ -55,7 +61,7 @@ static int virtio_pmem_flush(struct nd_r
 		return -EIO;
 	}
 
-	req_data = kmalloc(sizeof(*req_data), GFP_KERNEL);
+	req_data = kmalloc_obj(*req_data);
 	if (!req_data)
 		return -ENOMEM;
 
@@ -98,7 +104,7 @@ static int virtio_pmem_flush(struct nd_r
 		dev_info(&vdev->dev, "failed to send command to virtio pmem device\n");
 		err = -EIO;
 	} else {
-		/* A host repsonse results in "host_ack" getting called */
+		/* A host response results in "host_ack" getting called */
 		wait_event(req_data->host_acked, req_data->done);
 		err = le32_to_cpu(req_data->resp.ret);
 	}
@@ -107,30 +113,46 @@ static int virtio_pmem_flush(struct nd_r
 	return err;
 };
 
+static void virtio_pmem_flush_work(struct work_struct *work)
+{
+	struct virtio_pmem_flush_work *flush;
+	int err;
+
+	flush = container_of(work, struct virtio_pmem_flush_work, work);
+	err = virtio_pmem_flush(flush->nd_region);
+	if (err > 0)
+		err = -EIO;
+	if (err)
+		flush->bio->bi_status = errno_to_blk_status(err);
+	bio_endio(flush->bio);
+	kfree(flush);
+}
+
 /* The asynchronous flush callback function */
 int async_pmem_flush(struct nd_region *nd_region, struct bio *bio)
 {
-	/*
-	 * Create child bio for asynchronous flush and chain with
-	 * parent bio. Otherwise directly call nd_region flush.
-	 */
-	if (bio && bio->bi_iter.bi_sector != -1) {
-		struct bio *child = bio_alloc(bio->bi_bdev, 0,
-					      REQ_OP_WRITE | REQ_PREFLUSH,
-					      GFP_ATOMIC);
+	struct virtio_device *vdev = nd_region->provider_data;
+	struct virtio_pmem *vpmem = vdev->priv;
+	struct virtio_pmem_flush_work *flush;
+	int err;
 
-		if (!child)
+	if (bio && bio->bi_iter.bi_sector != -1) {
+		flush = kmalloc_obj(*flush, GFP_NOIO);
+		if (!flush)
 			return -ENOMEM;
-		bio_clone_blkg_association(child, bio);
-		child->bi_iter.bi_sector = -1;
-		bio_chain(child, bio);
-		submit_bio(child);
-		return 0;
+
+		INIT_WORK(&flush->work, virtio_pmem_flush_work);
+		flush->nd_region = nd_region;
+		flush->bio = bio;
+		queue_work(vpmem->flush_wq, &flush->work);
+		return NVDIMM_FLUSH_ASYNC;
 	}
-	if (virtio_pmem_flush(nd_region))
+
+	err = virtio_pmem_flush(nd_region);
+	if (err > 0)
 		return -EIO;
 
-	return 0;
+	return err;
 };
 EXPORT_SYMBOL_GPL(async_pmem_flush);
 MODULE_DESCRIPTION("Virtio Persistent Memory Driver");
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -236,8 +236,11 @@ static void pmem_submit_bio(struct bio *
 	if (do_acct)
 		bio_end_io_acct(bio, start);
 
-	if ((bio->bi_opf & REQ_FUA) && !bio->bi_status)
+	if ((bio->bi_opf & REQ_FUA) && !bio->bi_status) {
 		ret = nvdimm_flush(nd_region, bio);
+		if (ret == NVDIMM_FLUSH_ASYNC)
+			return;
+	}
 
 	if (ret)
 		bio->bi_status = errno_to_blk_status(ret);
--- a/drivers/nvdimm/region_devs.c
+++ b/drivers/nvdimm/region_devs.c
@@ -1113,6 +1113,8 @@ int nvdimm_flush(struct nd_region *nd_re
 		rc = generic_nvdimm_flush(nd_region);
 	else {
 		rc = nd_region->flush(nd_region, bio);
+		if (rc > 0)
+			return rc;
 		if (rc && rc != -ENOMEM)
 			rc = -EIO;
 	}
--- a/drivers/nvdimm/virtio_pmem.c
+++ b/drivers/nvdimm/virtio_pmem.c
@@ -67,10 +67,17 @@ static int virtio_pmem_probe(struct virt
 	mutex_init(&vpmem->flush_lock);
 	vpmem->vdev = vdev;
 	vdev->priv = vpmem;
+	vpmem->flush_wq = alloc_ordered_workqueue("virtio-pmem-flush",
+						  WQ_MEM_RECLAIM);
+	if (!vpmem->flush_wq) {
+		err = -ENOMEM;
+		goto out_err;
+	}
+
 	err = init_vq(vpmem);
 	if (err) {
 		dev_err(&vdev->dev, "failed to initialize virtio pmem vq's\n");
-		goto out_err;
+		goto out_wq;
 	}
 
 	if (virtio_has_feature(vdev, VIRTIO_PMEM_F_SHMEM_REGION)) {
@@ -131,6 +138,8 @@ out_nd:
 	nvdimm_bus_unregister(vpmem->nvdimm_bus);
 out_vq:
 	vdev->config->del_vqs(vdev);
+out_wq:
+	destroy_workqueue(vpmem->flush_wq);
 out_err:
 	return err;
 }
@@ -138,10 +147,13 @@ out_err:
 static void virtio_pmem_remove(struct virtio_device *vdev)
 {
 	struct nvdimm_bus *nvdimm_bus = dev_get_drvdata(&vdev->dev);
+	struct virtio_pmem *vpmem = vdev->priv;
 
 	nvdimm_bus_unregister(nvdimm_bus);
+	drain_workqueue(vpmem->flush_wq);
 	vdev->config->del_vqs(vdev);
 	virtio_reset_device(vdev);
+	destroy_workqueue(vpmem->flush_wq);
 }
 
 static unsigned int features[] = {
--- a/drivers/nvdimm/virtio_pmem.h
+++ b/drivers/nvdimm/virtio_pmem.h
@@ -15,6 +15,7 @@
 #include <linux/libnvdimm.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
+#include <linux/workqueue.h>
 
 struct virtio_pmem_request {
 	struct virtio_pmem_req req;
@@ -39,6 +40,9 @@ struct virtio_pmem {
 	/* Serialize flush requests to the device. */
 	struct mutex flush_lock;
 
+	/* Complete asynchronous FUA flushes outside the submit path. */
+	struct workqueue_struct *flush_wq;
+
 	/* nvdimm bus registers virtio pmem device */
 	struct nvdimm_bus *nvdimm_bus;
 	struct nvdimm_bus_descriptor nd_desc;
--- a/include/linux/libnvdimm.h
+++ b/include/linux/libnvdimm.h
@@ -122,6 +122,15 @@ struct nd_mapping_desc {
 };
 
 struct nd_region;
+
+/*
+ * Provider flush callback return values:
+ *   0: flush completed synchronously
+ *  <0: flush failed
+ *  >0: flush completion was queued and @bio will be completed later
+ */
+#define NVDIMM_FLUSH_ASYNC 1
+
 struct nd_region_desc {
 	struct resource *res;
 	struct nd_mapping_desc *mapping;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 651/877] nvdimm: virtio_pmem: always wake -ENOSPC waiters
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (649 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 650/877] nvdimm: virtio_pmem: stop allocating child flush bio Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 652/877] nvdimm: virtio_pmem: use READ_ONCE()/WRITE_ONCE() for wait flags Greg Kroah-Hartman
                   ` (233 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Li Chen, Michael S. Tsirkin,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Li Chen <me@linux.beauty>

[ Upstream commit 811808761e19fdea1c25b7c76734b8945f758f27 ]

virtio_pmem_host_ack() reclaims virtqueue descriptors with
virtqueue_get_buf(). The -ENOSPC waiter wakeup is tied to completing the
returned token. If token completion is skipped for any reason, reclaimed
descriptors may not wake a waiter and the submitter may sleep forever
waiting for a free slot. Always wake one -ENOSPC waiter for each virtqueue
completion before touching the returned token.

Signed-off-by: Li Chen <me@linux.beauty>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260630092338.2094628-7-me@linux.beauty>
Stable-dep-of: e57140944b5a ("nvdimm: virtio_pmem: refcount requests for token lifetime")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/nvdimm/nd_virtio.c |   25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

--- a/drivers/nvdimm/nd_virtio.c
+++ b/drivers/nvdimm/nd_virtio.c
@@ -15,26 +15,33 @@ struct virtio_pmem_flush_work {
 	struct bio *bio;
 };
 
+static void virtio_pmem_wake_one_waiter(struct virtio_pmem *vpmem)
+{
+	struct virtio_pmem_request *req_buf;
+
+	if (list_empty(&vpmem->req_list))
+		return;
+
+	req_buf = list_first_entry(&vpmem->req_list,
+				   struct virtio_pmem_request, list);
+	req_buf->wq_buf_avail = true;
+	wake_up(&req_buf->wq_buf);
+	list_del(&req_buf->list);
+}
+
  /* The interrupt handler */
 void virtio_pmem_host_ack(struct virtqueue *vq)
 {
 	struct virtio_pmem *vpmem = vq->vdev->priv;
-	struct virtio_pmem_request *req_data, *req_buf;
+	struct virtio_pmem_request *req_data;
 	unsigned long flags;
 	unsigned int len;
 
 	spin_lock_irqsave(&vpmem->pmem_lock, flags);
 	while ((req_data = virtqueue_get_buf(vq, &len)) != NULL) {
+		virtio_pmem_wake_one_waiter(vpmem);
 		req_data->done = true;
 		wake_up(&req_data->host_acked);
-
-		if (!list_empty(&vpmem->req_list)) {
-			req_buf = list_first_entry(&vpmem->req_list,
-					struct virtio_pmem_request, list);
-			req_buf->wq_buf_avail = true;
-			wake_up(&req_buf->wq_buf);
-			list_del(&req_buf->list);
-		}
 	}
 	spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 652/877] nvdimm: virtio_pmem: use READ_ONCE()/WRITE_ONCE() for wait flags
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (650 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 651/877] nvdimm: virtio_pmem: always wake -ENOSPC waiters Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 653/877] nvdimm: virtio_pmem: refcount requests for token lifetime Greg Kroah-Hartman
                   ` (232 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Pankaj Gupta, Li Chen,
	Michael S. Tsirkin, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Li Chen <me@linux.beauty>

[ Upstream commit 08e72a5ba1ab9dc0adf993ff0f4d606a1e3445a8 ]

Use READ_ONCE()/WRITE_ONCE() for the wait_event() flags (done and
wq_buf_avail). They are observed by waiters without pmem_lock, so make
the accesses explicit single loads/stores and avoid compiler
reordering/caching across the wait/wake paths.

Acked-by: Pankaj Gupta <pankaj.gupta.linux@gmail.com>
Signed-off-by: Li Chen <me@linux.beauty>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260630092338.2094628-8-me@linux.beauty>
Stable-dep-of: e57140944b5a ("nvdimm: virtio_pmem: refcount requests for token lifetime")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/nvdimm/nd_virtio.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

--- a/drivers/nvdimm/nd_virtio.c
+++ b/drivers/nvdimm/nd_virtio.c
@@ -24,9 +24,9 @@ static void virtio_pmem_wake_one_waiter(
 
 	req_buf = list_first_entry(&vpmem->req_list,
 				   struct virtio_pmem_request, list);
-	req_buf->wq_buf_avail = true;
+	list_del_init(&req_buf->list);
+	WRITE_ONCE(req_buf->wq_buf_avail, true);
 	wake_up(&req_buf->wq_buf);
-	list_del(&req_buf->list);
 }
 
  /* The interrupt handler */
@@ -40,7 +40,7 @@ void virtio_pmem_host_ack(struct virtque
 	spin_lock_irqsave(&vpmem->pmem_lock, flags);
 	while ((req_data = virtqueue_get_buf(vq, &len)) != NULL) {
 		virtio_pmem_wake_one_waiter(vpmem);
-		req_data->done = true;
+		WRITE_ONCE(req_data->done, true);
 		wake_up(&req_data->host_acked);
 	}
 	spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
@@ -72,7 +72,7 @@ static int virtio_pmem_flush(struct nd_r
 	if (!req_data)
 		return -ENOMEM;
 
-	req_data->done = false;
+	WRITE_ONCE(req_data->done, false);
 	init_waitqueue_head(&req_data->host_acked);
 	init_waitqueue_head(&req_data->wq_buf);
 	INIT_LIST_HEAD(&req_data->list);
@@ -93,12 +93,12 @@ static int virtio_pmem_flush(struct nd_r
 					GFP_ATOMIC)) == -ENOSPC) {
 
 		dev_info(&vdev->dev, "failed to send command to virtio pmem device, no free slots in the virtqueue\n");
-		req_data->wq_buf_avail = false;
+		WRITE_ONCE(req_data->wq_buf_avail, false);
 		list_add_tail(&req_data->list, &vpmem->req_list);
 		spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
 
 		/* A host response results in "host_ack" getting called */
-		wait_event(req_data->wq_buf, req_data->wq_buf_avail);
+		wait_event(req_data->wq_buf, READ_ONCE(req_data->wq_buf_avail));
 		spin_lock_irqsave(&vpmem->pmem_lock, flags);
 	}
 	err1 = virtqueue_kick(vpmem->req_vq);
@@ -112,7 +112,7 @@ static int virtio_pmem_flush(struct nd_r
 		err = -EIO;
 	} else {
 		/* A host response results in "host_ack" getting called */
-		wait_event(req_data->host_acked, req_data->done);
+		wait_event(req_data->host_acked, READ_ONCE(req_data->done));
 		err = le32_to_cpu(req_data->resp.ret);
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 653/877] nvdimm: virtio_pmem: refcount requests for token lifetime
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (651 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 652/877] nvdimm: virtio_pmem: use READ_ONCE()/WRITE_ONCE() for wait flags Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 654/877] mtd: rawnand: pl353: Add message about ECC mode Greg Kroah-Hartman
                   ` (231 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Li Chen, Michael S. Tsirkin,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Li Chen <me@linux.beauty>

[ Upstream commit e57140944b5a47a7fd5a142faab29a02af040bc8 ]

KASAN reports slab-use-after-free in __wake_up_common():
BUG: KASAN: slab-use-after-free in __wake_up_common+0x114/0x160
Read of size 8 at addr ffff88810fdcb710 by task swapper/0/0

CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted
6.19.0-next-20260220-00006-g1eae5f204ec3 #4 PREEMPT(full)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Arch Linux
1.17.0-2-2 04/01/2014
Call Trace:
 <IRQ>
 dump_stack_lvl+0x6d/0xb0
 print_report+0x170/0x4e2
 ? __pfx__raw_spin_lock_irqsave+0x10/0x10
 ? __virt_addr_valid+0x1dc/0x380
 kasan_report+0xbc/0xf0
 ? __wake_up_common+0x114/0x160
 ? __wake_up_common+0x114/0x160
 __wake_up_common+0x114/0x160
 ? __pfx__raw_spin_lock_irqsave+0x10/0x10
 __wake_up+0x36/0x60
 virtio_pmem_host_ack+0x11d/0x3b0
 ? sched_balance_domains+0x29f/0xb00
 ? __pfx_virtio_pmem_host_ack+0x10/0x10
 ? _raw_spin_lock_irqsave+0x98/0x100
 ? __pfx__raw_spin_lock_irqsave+0x10/0x10
 vring_interrupt+0x1c9/0x5e0
 ? __pfx_vp_interrupt+0x10/0x10
 vp_vring_interrupt+0x87/0x100
 ? __pfx_vp_interrupt+0x10/0x10
 __handle_irq_event_percpu+0x17f/0x550
 ? __pfx__raw_spin_lock+0x10/0x10
 handle_irq_event+0xab/0x1c0
 handle_fasteoi_irq+0x276/0xae0
 __common_interrupt+0x65/0x130
 common_interrupt+0x78/0xa0
 </IRQ>

virtio_pmem_host_ack() wakes a request that has already been freed by the
submitter.

This happens when the request token is still reachable via the virtqueue,
but virtio_pmem_flush() returns and frees it.

Fix the token lifetime by refcounting struct virtio_pmem_request.
virtio_pmem_flush() holds a submitter reference, and the virtqueue holds an
extra reference once the request is queued. The completion path drops the
virtqueue reference, and the submitter drops its reference before
returning.

Fixes: 6e84200c0a29 ("virtio-pmem: Add virtio pmem driver")
Cc: stable@vger.kernel.org
Signed-off-by: Li Chen <me@linux.beauty>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260630092338.2094628-9-me@linux.beauty>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/nvdimm/nd_virtio.c   |   32 ++++++++++++++++++++++++++++----
 drivers/nvdimm/virtio_pmem.h |    2 ++
 2 files changed, 30 insertions(+), 4 deletions(-)

--- a/drivers/nvdimm/nd_virtio.c
+++ b/drivers/nvdimm/nd_virtio.c
@@ -15,6 +15,14 @@ struct virtio_pmem_flush_work {
 	struct bio *bio;
 };
 
+static void virtio_pmem_req_release(struct kref *kref)
+{
+	struct virtio_pmem_request *req;
+
+	req = container_of(kref, struct virtio_pmem_request, kref);
+	kfree(req);
+}
+
 static void virtio_pmem_wake_one_waiter(struct virtio_pmem *vpmem)
 {
 	struct virtio_pmem_request *req_buf;
@@ -42,6 +50,7 @@ void virtio_pmem_host_ack(struct virtque
 		virtio_pmem_wake_one_waiter(vpmem);
 		WRITE_ONCE(req_data->done, true);
 		wake_up(&req_data->host_acked);
+		kref_put(&req_data->kref, virtio_pmem_req_release);
 	}
 	spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
 }
@@ -72,6 +81,7 @@ static int virtio_pmem_flush(struct nd_r
 	if (!req_data)
 		return -ENOMEM;
 
+	kref_init(&req_data->kref);
 	WRITE_ONCE(req_data->done, false);
 	init_waitqueue_head(&req_data->host_acked);
 	init_waitqueue_head(&req_data->wq_buf);
@@ -89,10 +99,23 @@ static int virtio_pmem_flush(struct nd_r
 	  * to req_list and wait for host_ack to wake us up when free
 	  * slots are available.
 	  */
-	while ((err = virtqueue_add_sgs(vpmem->req_vq, sgs, 1, 1, req_data,
-					GFP_ATOMIC)) == -ENOSPC) {
+	for (;;) {
+		err = virtqueue_add_sgs(vpmem->req_vq, sgs, 1, 1, req_data,
+					GFP_ATOMIC);
+		if (!err) {
+			/*
+			 * Take the virtqueue reference while @pmem_lock is
+			 * held so completion cannot run concurrently.
+			 */
+			kref_get(&req_data->kref);
+			break;
+		}
+
+		if (err != -ENOSPC)
+			break;
 
-		dev_info(&vdev->dev, "failed to send command to virtio pmem device, no free slots in the virtqueue\n");
+		dev_info_ratelimited(&vdev->dev,
+				     "failed to send command to virtio pmem device, no free slots in the virtqueue\n");
 		WRITE_ONCE(req_data->wq_buf_avail, false);
 		list_add_tail(&req_data->list, &vpmem->req_list);
 		spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
@@ -101,6 +124,7 @@ static int virtio_pmem_flush(struct nd_r
 		wait_event(req_data->wq_buf, READ_ONCE(req_data->wq_buf_avail));
 		spin_lock_irqsave(&vpmem->pmem_lock, flags);
 	}
+
 	err1 = virtqueue_kick(vpmem->req_vq);
 	spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
 	/*
@@ -116,7 +140,7 @@ static int virtio_pmem_flush(struct nd_r
 		err = le32_to_cpu(req_data->resp.ret);
 	}
 
-	kfree(req_data);
+	kref_put(&req_data->kref, virtio_pmem_req_release);
 	return err;
 };
 
--- a/drivers/nvdimm/virtio_pmem.h
+++ b/drivers/nvdimm/virtio_pmem.h
@@ -12,12 +12,14 @@
 
 #include <linux/module.h>
 #include <uapi/linux/virtio_pmem.h>
+#include <linux/kref.h>
 #include <linux/libnvdimm.h>
 #include <linux/mutex.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
 
 struct virtio_pmem_request {
+	struct kref kref;
 	struct virtio_pmem_req req;
 	struct virtio_pmem_resp resp;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 654/877] mtd: rawnand: pl353: Add message about ECC mode
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (652 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 653/877] nvdimm: virtio_pmem: refcount requests for token lifetime Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 655/877] mtd: rawnand: pl353: Make sure we use the monolithic helpers for raw accesses Greg Kroah-Hartman
                   ` (230 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Andrea Scian, Miquel Raynal,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Andrea Scian <andrea.scian@dave.eu>

[ Upstream commit 1e06dbfdfb851170b243d6498e442b449324c664 ]

This just add some information on kernel log about the selected ECC

Signed-off-by: Andrea Scian <andrea.scian@dave.eu>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Stable-dep-of: 80ecacd054ff ("mtd: rawnand: pl353: Make sure we use the monolithic helpers for raw accesses")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mtd/nand/raw/pl35x-nand-controller.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/mtd/nand/raw/pl35x-nand-controller.c
+++ b/drivers/mtd/nand/raw/pl35x-nand-controller.c
@@ -973,15 +973,18 @@ static int pl35x_nand_attach_chip(struct
 
 	switch (chip->ecc.engine_type) {
 	case NAND_ECC_ENGINE_TYPE_ON_DIE:
+		dev_dbg(nfc->dev, "Using on-die ECC\n");
 		/* Keep these legacy BBT descriptors for ON_DIE situations */
 		chip->bbt_td = &bbt_main_descr;
 		chip->bbt_md = &bbt_mirror_descr;
 		fallthrough;
 	case NAND_ECC_ENGINE_TYPE_NONE:
 	case NAND_ECC_ENGINE_TYPE_SOFT:
+		dev_dbg(nfc->dev, "Using software ECC (Hamming 1-bit/512B)\n");
 		chip->ecc.write_page_raw = nand_monolithic_write_page_raw;
 		break;
 	case NAND_ECC_ENGINE_TYPE_ON_HOST:
+		dev_dbg(nfc->dev, "Using hardware ECC\n");
 		ret = pl35x_nand_init_hw_ecc_controller(nfc, chip);
 		if (ret)
 			return ret;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 655/877] mtd: rawnand: pl353: Make sure we use the monolithic helpers for raw accesses
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (653 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 654/877] mtd: rawnand: pl353: Add message about ECC mode Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 656/877] clk: qcom: Fix test_ctl_hi field for DEFAULT_EVO PLLs Greg Kroah-Hartman
                   ` (229 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Andrea Scian, Miquel Raynal (DAVE),
	Michal Simek, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Miquel Raynal (DAVE)" <miquel.raynal@bootlin.com>

[ Upstream commit 80ecacd054ffeb60cd28e46ed5cd6bd0d2de318b ]

Any access not using the hardware ECC engine should be monolithic
because the controller has its very own way of handling the end of a
transaction during operation configuration, so we cannot easily make
repeated reads.

This has the side effect of fixing support for software ECC engines.

Suggested-by: Andrea Scian <andrea.scian@dave.eu>
Cc: stable@vger.kernel.org
Fixes: 08d8c62164a3 ("mtd: rawnand: pl353: Add support for the ARM PL353 SMC NAND controller")
Signed-off-by: Miquel Raynal (DAVE) <miquel.raynal@bootlin.com>
Acked-by: Michal Simek <michal.simek@amd.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mtd/nand/raw/pl35x-nand-controller.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/mtd/nand/raw/pl35x-nand-controller.c
+++ b/drivers/mtd/nand/raw/pl35x-nand-controller.c
@@ -914,7 +914,6 @@ static int pl35x_nand_init_hw_ecc_contro
 	chip->ecc.steps = mtd->writesize / chip->ecc.size;
 	chip->ecc.read_page = pl35x_nand_read_page_hwecc;
 	chip->ecc.write_page = pl35x_nand_write_page_hwecc;
-	chip->ecc.write_page_raw = nand_monolithic_write_page_raw;
 	pl35x_smc_set_ecc_pg_size(nfc, chip, mtd->writesize);
 
 	nfc->ecc_buf = devm_kmalloc(nfc->dev, chip->ecc.bytes * chip->ecc.steps,
@@ -981,7 +980,6 @@ static int pl35x_nand_attach_chip(struct
 	case NAND_ECC_ENGINE_TYPE_NONE:
 	case NAND_ECC_ENGINE_TYPE_SOFT:
 		dev_dbg(nfc->dev, "Using software ECC (Hamming 1-bit/512B)\n");
-		chip->ecc.write_page_raw = nand_monolithic_write_page_raw;
 		break;
 	case NAND_ECC_ENGINE_TYPE_ON_HOST:
 		dev_dbg(nfc->dev, "Using hardware ECC\n");
@@ -995,6 +993,9 @@ static int pl35x_nand_attach_chip(struct
 		return -EINVAL;
 	}
 
+	chip->ecc.read_page_raw = nand_monolithic_read_page_raw;
+	chip->ecc.write_page_raw = nand_monolithic_write_page_raw;
+
 	return 0;
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 656/877] clk: qcom: Fix test_ctl_hi field for DEFAULT_EVO PLLs
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (654 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 655/877] mtd: rawnand: pl353: Make sure we use the monolithic helpers for raw accesses Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 657/877] ASoC: tegra210_mixer: sort the register default table Greg Kroah-Hartman
                   ` (228 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Imran Shaik, Konrad Dybcio,
	Bjorn Andersson, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Imran Shaik <imran.shaik@oss.qualcomm.com>

[ Upstream commit 830ead322c39c99bf972425b3c35323ec56c29de ]

CLK_ALPHA_PLL_TYPE_DEFAULT_EVO type PLLs do not have the PLL_TEST_CTL_U1
register, so clk_alpha_pll_configure() does not program test_ctl_hi1_val
for this PLL type.

The GCC PLL configurations for QCM2290, Shikra and SM6115 wrongly use
test_ctl_hi1_val instead of test_ctl_hi_val, deviating from the hardware
recommended settings. Fix them to use test_ctl_hi_val.

Fixes: 496d1a13d405 ("clk: qcom: Add Global Clock Controller driver for QCM2290")
Fixes: 01cf3e27824d ("clk: qcom: Add Global clock controller support on Qualcomm Shikra SoC")
Fixes: e88c533d8a2a ("clk: qcom: gcc-sm6115: Add missing PLL config properties")
Cc: stable@vger.kernel.org
Signed-off-by: Imran Shaik <imran.shaik@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260729-pll-test-ctrl-fixup-v1-1-246d79589380@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
[ Omitted gcc-shikra.c changes because the driver is absent from the target branch. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/clk/qcom/gcc-qcm2290.c |    6 +++---
 drivers/clk/qcom/gcc-sm6115.c  |    6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

--- a/drivers/clk/qcom/gcc-qcm2290.c
+++ b/drivers/clk/qcom/gcc-qcm2290.c
@@ -116,7 +116,7 @@ static const struct alpha_pll_config gpl
 	.vco_mask = GENMASK(21, 20),
 	.main_output_mask = BIT(0),
 	.config_ctl_val = 0x4001055B,
-	.test_ctl_hi1_val = 0x1,
+	.test_ctl_hi_val = 0x1,
 };
 
 static struct clk_alpha_pll gpll10 = {
@@ -148,7 +148,7 @@ static const struct alpha_pll_config gpl
 	.vco_mask = GENMASK(21, 20),
 	.main_output_mask = BIT(0),
 	.config_ctl_val = 0x4001055B,
-	.test_ctl_hi1_val = 0x1,
+	.test_ctl_hi_val = 0x1,
 };
 
 static struct clk_alpha_pll gpll11 = {
@@ -309,7 +309,7 @@ static const struct alpha_pll_config gpl
 	.post_div_val = 0x1 << 8,
 	.post_div_mask = GENMASK(11, 8),
 	.config_ctl_val = 0x4001055B,
-	.test_ctl_hi1_val = 0x1,
+	.test_ctl_hi_val = 0x1,
 };
 
 static struct clk_alpha_pll gpll8 = {
--- a/drivers/clk/qcom/gcc-sm6115.c
+++ b/drivers/clk/qcom/gcc-sm6115.c
@@ -120,7 +120,7 @@ static const struct alpha_pll_config gpl
 	.vco_mask = GENMASK(21, 20),
 	.main_output_mask = BIT(0),
 	.config_ctl_val = 0x4001055b,
-	.test_ctl_hi1_val = 0x1,
+	.test_ctl_hi_val = 0x1,
 	.test_ctl_hi_mask = 0x1,
 };
 
@@ -173,7 +173,7 @@ static const struct alpha_pll_config gpl
 	.vco_val = 0x2 << 20,
 	.vco_mask = GENMASK(21, 20),
 	.config_ctl_val = 0x4001055b,
-	.test_ctl_hi1_val = 0x1,
+	.test_ctl_hi_val = 0x1,
 	.test_ctl_hi_mask = 0x1,
 };
 
@@ -367,7 +367,7 @@ static const struct alpha_pll_config gpl
 	.post_div_val = 0x1 << 8,
 	.post_div_mask = GENMASK(11, 8),
 	.config_ctl_val = 0x4001055b,
-	.test_ctl_hi1_val = 0x1,
+	.test_ctl_hi_val = 0x1,
 	.test_ctl_hi_mask = 0x1,
 };
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 657/877] ASoC: tegra210_mixer: sort the register default table
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (655 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 656/877] clk: qcom: Fix test_ctl_hi field for DEFAULT_EVO PLLs Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 658/877] ASoC: tegra: Fix the MIXER enable default value Greg Kroah-Hartman
                   ` (227 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Peter Ujfalusi, Mark Brown,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>

[ Upstream commit f70bc276fc7f712ff5c8e995d5050558a3198df2 ]

reg_defaults must be sorted by ascending register address, as
regcache_lookup_reg() locates entries in it with bsearch().  See commit
fd80df352ba1 ("regcache: Add support for sorting defaults arrays").

TEGRA210_MIXER_ENABLE (0x400) is the last entry of the table, after
TEGRA210_MIXER_PEAKM_RAM_CTRL (0x434), which makes it unreachable.
regcache_reg_needs_sync() then cannot compare it against its default and
reports that a sync is needed, so it is written to the device on every
regcache_sync() even when it was never touched.

Sort the table by register address.

Fixes: 05bb3d5ec64a ("ASoC: tegra: Add Tegra210 based Mixer driver")
Cc: stable@vger.kernel.org
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://patch.msgid.link/20260805122748.13090-4-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 5442b8093a2f ("ASoC: tegra: Fix the MIXER enable default value")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 sound/soc/tegra/tegra210_mixer.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/sound/soc/tegra/tegra210_mixer.c
+++ b/sound/soc/tegra/tegra210_mixer.c
@@ -57,10 +57,10 @@ static const struct reg_default tegra210
 	MIXER_TX_REG_DEFAULTS(3),
 	MIXER_TX_REG_DEFAULTS(4),
 
+	{ TEGRA210_MIXER_ENABLE, 0x1 },
 	{ TEGRA210_MIXER_CG, 0x00000001},
 	{ TEGRA210_MIXER_GAIN_CFG_RAM_CTRL, 0x00004000},
 	{ TEGRA210_MIXER_PEAKM_RAM_CTRL, 0x00004000},
-	{ TEGRA210_MIXER_ENABLE, 0x1 },
 };
 
 /* Default gain parameters */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 658/877] ASoC: tegra: Fix the MIXER enable default value
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (656 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 657/877] ASoC: tegra210_mixer: sort the register default table Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 659/877] mm/mremap: reset unfaulted VMA page offset for MREMAP_DONTUNMAP Greg Kroah-Hartman
                   ` (226 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Jon Hunter, Mark Brown, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jon Hunter <jonathanh@nvidia.com>

[ Upstream commit 5442b8093a2f94ecd4696b3875194be09e2676c5 ]

Commit 4b05ccb17f92 ("regcache: Sort the local copy of an unsorted
reg_defaults array") exposed an issue in the Tegra MIXER driver where
the register default for the TEGRA210_MIXER_ENABLE is specified as 1,
but the hardware default is actually 0. After this commit was added the
MIXER driver is no longer working and so fix this by correcting the
default value for this register and explicitly configuring the
MIXER_ENABLE register when runtime resuming the MIXER device.

Fixes: 05bb3d5ec64a ("ASoC: tegra: Add Tegra210 based Mixer driver")
Cc: stable@vger.kernel.org
Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
Link: https://patch.msgid.link/20260821153734.158426-3-jonathanh@nvidia.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 sound/soc/tegra/tegra210_mixer.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

--- a/sound/soc/tegra/tegra210_mixer.c
+++ b/sound/soc/tegra/tegra210_mixer.c
@@ -57,7 +57,7 @@ static const struct reg_default tegra210
 	MIXER_TX_REG_DEFAULTS(3),
 	MIXER_TX_REG_DEFAULTS(4),
 
-	{ TEGRA210_MIXER_ENABLE, 0x1 },
+	{ TEGRA210_MIXER_ENABLE, 0x0 },
 	{ TEGRA210_MIXER_CG, 0x00000001},
 	{ TEGRA210_MIXER_GAIN_CFG_RAM_CTRL, 0x00004000},
 	{ TEGRA210_MIXER_PEAKM_RAM_CTRL, 0x00004000},
@@ -86,11 +86,15 @@ static int __maybe_unused tegra210_mixer
 static int __maybe_unused tegra210_mixer_runtime_resume(struct device *dev)
 {
 	struct tegra210_mixer *mixer = dev_get_drvdata(dev);
+	int err;
 
 	regcache_cache_only(mixer->regmap, false);
-	regcache_sync(mixer->regmap);
+	err = regcache_sync(mixer->regmap);
+	if (err)
+		return err;
 
-	return 0;
+	return regmap_write(mixer->regmap, TEGRA210_MIXER_ENABLE,
+			    TEGRA210_MIXER_EN);
 }
 
 static int tegra210_mixer_write_ram(struct tegra210_mixer *mixer,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 659/877] mm/mremap: reset unfaulted VMA page offset for MREMAP_DONTUNMAP
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (657 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 658/877] ASoC: tegra: Fix the MIXER enable default value Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 660/877] KVM: x86/mmu: Dynamically allocate shadow MMUs hashed page list Greg Kroah-Hartman
                   ` (225 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM),
	syzbot+f12658786a4153df5113, Vlastimil Babka (SUSE), Kunwu Chan,
	Pedro Falcato, Jann Horn, Liam R. Howlett, Li Xinhai,
	Andrew Morton, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>

[ Upstream commit 35b0fb391b0df57383bc15985bb769f4555c97ba ]

Uniquely an mremap() invocation using the MREMAP_DONTUNMAP flag can reset
a faulted VMA into an unfaulted one.

It does so after the page tables have been moved to the copied VMA with
MREMAP_DONTUNMAP leaving the old VMA in place which is naturally unfaulted
as the page tables it had are no longer present.

However, in doing so, it violates the invariant that the anonymous page
offset of an unfaulted VMA is vma->vm_start >> PAGE_SHIFT.

This is because a VMA may have been faulted in, mremap()'d (causing a
delta between its page offset and vma->vm_start >> PAGE_SHIFT), and then
mremap()'d again with MREMAP_DONTUNMAP resulting in the unfaulting.

This condition is a violation of a fundamental assumption in mm, but now
also triggers an assert in assert_sane_pgoff() which explicitly checks for
this condition.

Correct it by resetting the VMA's page offset at the point of completing
the MREMAP_DONTUNMAP operation.

Link: https://lore.kernel.org/20260825-fix-mremap-dontunmap-pgoff-v1-1-39a40b2c98b3@kernel.org
Fixes: 1583aa278f5f ("mm: mremap: unlink anon_vmas when mremap with MREMAP_DONTUNMAP success")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reported-by: syzbot+f12658786a4153df5113@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/6a87853b.ae6ddae5.3da009.0023.GAE@google.com/
Tested-by: syzbot+f12658786a4153df5113@syzkaller.appspotmail.com
Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Reviewed-by: Kunwu Chan <kunwu.chan@gmail.com>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Cc: Jann Horn <jannh@google.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Li Xinhai <lixinhai.lxh@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[ adapted dontunmap_complete() changes to move_vma() using direct vm_pgoff assignment instead of unavailable helpers. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 mm/mremap.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -811,8 +811,18 @@ static unsigned long move_vma(struct vm_
 		 * table has been moved.
 		 */
 		if (new_vma != vma && vma->vm_start == old_addr &&
-			vma->vm_end == (old_addr + old_len))
+			vma->vm_end == (old_addr + old_len)) {
+			const pgoff_t pgoff_unfaulted = vma->vm_start >> PAGE_SHIFT;
+
 			unlink_anon_vmas(vma);
+			/*
+			 * The VMA is now unfaulted and it is an invariant that
+			 * unfaulted anonymous VMAs have page offset equal to
+			 * vma->vm_start >> PAGE_SHIFT.
+			 */
+			if (vma_is_anonymous(vma) && !vma->vm_file)
+				vma->vm_pgoff = pgoff_unfaulted;
+		}
 
 		/* Because we won't unmap we don't need to touch locked_vm */
 		return new_addr;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 660/877] KVM: x86/mmu: Dynamically allocate shadow MMUs hashed page list
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (658 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 659/877] mm/mremap: reset unfaulted VMA page offset for MREMAP_DONTUNMAP Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 661/877] KVM: x86/mmu: Split kvm_mmu_zap_all_fast() into "front" and "back" halves Greg Kroah-Hartman
                   ` (224 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vipin Sharma, Xiaoyao Li,
	Sean Christopherson, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sean Christopherson <seanjc@google.com>

[ Upstream commit 039ef33e2f9346258fe2bd344f212c645942575e ]

Dynamically allocate the (massive) array of hashed lists used to track
shadow pages, as the array itself is 32KiB, i.e. is an order-3 allocation
all on its own, and is *exactly* an order-3 allocation.  Dynamically
allocating the array will allow allocating "struct kvm" using kvmalloc(),
and will also allow deferring allocation of the array until it's actually
needed, i.e. until the first shadow root is allocated.

Opportunistically use kvmalloc() for the hashed lists, as an order-3
allocation is (stating the obvious) less likely to fail than an order-4
allocation, and the overhead of vmalloc() is undesirable given that the
size of the allocation is fixed.

Cc: Vipin Sharma <vipinsh@google.com>
Reviewed-by: Xiaoyao Li <xiaoyao.li@intel.com>
Link: https://lore.kernel.org/r/20250523001138.3182794-3-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Stable-dep-of: b27622c4eeb1 ("KVM: x86/mmu: Split kvm_mmu_zap_all_fast() into "front" and "back" halves")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/include/asm/kvm_host.h |    4 ++--
 arch/x86/kvm/mmu/mmu.c          |   23 ++++++++++++++++++++++-
 arch/x86/kvm/x86.c              |    5 ++++-
 3 files changed, 28 insertions(+), 4 deletions(-)

--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1307,7 +1307,7 @@ struct kvm_arch {
 	bool has_private_mem;
 	bool has_protected_state;
 	bool pre_fault_allowed;
-	struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];
+	struct hlist_head *mmu_page_hash;
 	struct list_head active_mmu_pages;
 	struct list_head zapped_obsolete_pages;
 	/*
@@ -1954,7 +1954,7 @@ void kvm_mmu_vendor_module_exit(void);
 
 void kvm_mmu_destroy(struct kvm_vcpu *vcpu);
 int kvm_mmu_create(struct kvm_vcpu *vcpu);
-void kvm_mmu_init_vm(struct kvm *kvm);
+int kvm_mmu_init_vm(struct kvm *kvm);
 void kvm_mmu_uninit_vm(struct kvm *kvm);
 
 void kvm_mmu_init_memslot_memory_attributes(struct kvm *kvm,
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -3772,6 +3772,18 @@ out_unlock:
 	return r;
 }
 
+static int kvm_mmu_alloc_page_hash(struct kvm *kvm)
+{
+	struct hlist_head *h;
+
+	h = kvcalloc(KVM_NUM_MMU_PAGES, sizeof(*h), GFP_KERNEL_ACCOUNT);
+	if (!h)
+		return -ENOMEM;
+
+	kvm->arch.mmu_page_hash = h;
+	return 0;
+}
+
 static int mmu_first_shadow_root_alloc(struct kvm *kvm)
 {
 	struct kvm_memslots *slots;
@@ -6542,14 +6554,20 @@ static bool kvm_has_zapped_obsolete_page
 	return unlikely(!list_empty_careful(&kvm->arch.zapped_obsolete_pages));
 }
 
-void kvm_mmu_init_vm(struct kvm *kvm)
+int kvm_mmu_init_vm(struct kvm *kvm)
 {
+	int r;
+
 	kvm->arch.shadow_mmio_value = shadow_mmio_value;
 	INIT_LIST_HEAD(&kvm->arch.active_mmu_pages);
 	INIT_LIST_HEAD(&kvm->arch.zapped_obsolete_pages);
 	INIT_LIST_HEAD(&kvm->arch.possible_nx_huge_pages);
 	spin_lock_init(&kvm->arch.mmu_unsync_pages_lock);
 
+	r = kvm_mmu_alloc_page_hash(kvm);
+	if (r)
+		return r;
+
 	if (tdp_mmu_enabled)
 		kvm_mmu_init_tdp_mmu(kvm);
 
@@ -6560,6 +6578,7 @@ void kvm_mmu_init_vm(struct kvm *kvm)
 
 	kvm->arch.split_desc_cache.kmem_cache = pte_list_desc_cache;
 	kvm->arch.split_desc_cache.gfp_zero = __GFP_ZERO;
+	return 0;
 }
 
 static void mmu_free_vm_memory_caches(struct kvm *kvm)
@@ -6571,6 +6590,8 @@ static void mmu_free_vm_memory_caches(st
 
 void kvm_mmu_uninit_vm(struct kvm *kvm)
 {
+	kvfree(kvm->arch.mmu_page_hash);
+
 	if (tdp_mmu_enabled)
 		kvm_mmu_uninit_tdp_mmu(kvm);
 
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -12827,7 +12827,9 @@ int kvm_arch_init_vm(struct kvm *kvm, un
 	if (ret)
 		goto out;
 
-	kvm_mmu_init_vm(kvm);
+	ret = kvm_mmu_init_vm(kvm);
+	if (ret)
+		goto out_cleanup_page_track;
 
 	ret = kvm_x86_call(vm_init)(kvm);
 	if (ret)
@@ -12872,6 +12874,7 @@ int kvm_arch_init_vm(struct kvm *kvm, un
 
 out_uninit_mmu:
 	kvm_mmu_uninit_vm(kvm);
+out_cleanup_page_track:
 	kvm_page_track_cleanup(kvm);
 out:
 	return ret;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 661/877] KVM: x86/mmu: Split kvm_mmu_zap_all_fast() into "front" and "back" halves
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (659 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 660/877] KVM: x86/mmu: Dynamically allocate shadow MMUs hashed page list Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 662/877] KVM: x86: Extract REGS and SREGS runtime sync code to helpers Greg Kroah-Hartman
                   ` (223 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Michael Roth, Sean Christopherson,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sean Christopherson <seanjc@google.com>

[ Upstream commit b27622c4eeb125814081baaefe9175191be5b94d ]

Split kvm_mmu_zap_all_fast() into a "front half" and a "back half", where
the front half is everything that runs with mmu_lock held for write, and
the back half is the code that runs outside of mmu_lock.  This will allow
putting more code inside kvm_arch_flush_shadow_memslot()'s critical section
without having to take mmu_lock twice in quick succession.

No functional change intended.

Cc: stable@vger.kernel.org # 6.12.x
Reviewed-by: Michael Roth <michael.roth@amd.com>
Link: https://patch.msgid.link/20260709204948.1988414-9-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/kvm/mmu/mmu.c |   37 +++++++++++++++++++++++++------------
 1 file changed, 25 insertions(+), 12 deletions(-)

--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -6489,20 +6489,11 @@ restart:
 	kvm_mmu_commit_zap_page(kvm, &kvm->arch.zapped_obsolete_pages);
 }
 
-/*
- * Fast invalidate all shadow pages and use lock-break technique
- * to zap obsolete pages.
- *
- * It's required when memslot is being deleted or VM is being
- * destroyed, in these cases, we should ensure that KVM MMU does
- * not use any resource of the being-deleted slot or all slots
- * after calling the function.
- */
-static void kvm_mmu_zap_all_fast(struct kvm *kvm)
+static void __kvm_mmu_zap_all_fast_front_half(struct kvm *kvm)
 {
 	lockdep_assert_held(&kvm->slots_lock);
+	lockdep_assert_held_write(&kvm->mmu_lock);
 
-	write_lock(&kvm->mmu_lock);
 	trace_kvm_mmu_zap_all_fast(kvm);
 
 	/*
@@ -6534,8 +6525,12 @@ static void kvm_mmu_zap_all_fast(struct
 	kvm_make_all_cpus_request(kvm, KVM_REQ_MMU_FREE_OBSOLETE_ROOTS);
 
 	kvm_zap_obsolete_pages(kvm);
+}
 
-	write_unlock(&kvm->mmu_lock);
+static void __kvm_mmu_zap_all_fast_back_half(struct kvm *kvm)
+{
+	lockdep_assert_held(&kvm->slots_lock);
+	lockdep_assert_not_held(&kvm->mmu_lock);
 
 	/*
 	 * Zap the invalidated TDP MMU roots, all SPTEs must be dropped before
@@ -6554,6 +6549,24 @@ static bool kvm_has_zapped_obsolete_page
 	return unlikely(!list_empty_careful(&kvm->arch.zapped_obsolete_pages));
 }
 
+/*
+ * Fast invalidate all shadow pages and use lock-break technique
+ * to zap obsolete pages.
+ *
+ * It's required when memslot is being deleted or VM is being
+ * destroyed, in these cases, we should ensure that KVM MMU does
+ * not use any resource of the being-deleted slot or all slots
+ * after calling the function.
+ */
+static void kvm_mmu_zap_all_fast(struct kvm *kvm)
+{
+	write_lock(&kvm->mmu_lock);
+	__kvm_mmu_zap_all_fast_front_half(kvm);
+	write_unlock(&kvm->mmu_lock);
+
+	__kvm_mmu_zap_all_fast_back_half(kvm);
+}
+
 int kvm_mmu_init_vm(struct kvm *kvm)
 {
 	int r;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 662/877] KVM: x86: Extract REGS and SREGS runtime sync code to helpers
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (660 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 661/877] KVM: x86/mmu: Split kvm_mmu_zap_all_fast() into "front" and "back" halves Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 663/877] KVM: x86: Rename __{g,s}et_sregs2() => kvm_vcpu_ioctl_x86_{g,s}et_sregs2() Greg Kroah-Hartman
                   ` (222 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yosry Ahmed, Sean Christopherson,
	Kai Huang, Binbin Wu, Paolo Bonzini, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sean Christopherson <seanjc@google.com>

[ Upstream commit 6a8a98aa9c147eb63f5a360f157f207bf46c05ee ]

Extract the REGS and SREGS portions of {store,sync}_regs() into separate
helpers in anticipation of moving the register specific code out of x86.c
and into regs.c.

No functional change intended.

Cc: Yosry Ahmed <yosry@kernel.org>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Reviewed-by: Kai Huang <kai.huang@intel.com>
Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>
Message-ID: <20260613000329.732085-2-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Stable-dep-of: 184bd464bdb6 ("KVM: x86: Check EFER validity on KVM_SET_SREGS*")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/kvm/x86.c |   17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -12310,7 +12310,7 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct k
 	return 0;
 }
 
-static void store_regs(struct kvm_vcpu *vcpu)
+static void kvm_run_sync_regs_to_user(struct kvm_vcpu *vcpu)
 {
 	BUILD_BUG_ON(sizeof(struct kvm_sync_regs) > SYNC_REGS_SIZE_BYTES);
 
@@ -12319,13 +12319,18 @@ static void store_regs(struct kvm_vcpu *
 
 	if (vcpu->run->kvm_valid_regs & KVM_SYNC_X86_SREGS)
 		__get_sregs(vcpu, &vcpu->run->s.regs.sregs);
+}
+
+static void store_regs(struct kvm_vcpu *vcpu)
+{
+	kvm_run_sync_regs_to_user(vcpu);
 
 	if (vcpu->run->kvm_valid_regs & KVM_SYNC_X86_EVENTS)
 		kvm_vcpu_ioctl_x86_get_vcpu_events(
 				vcpu, &vcpu->run->s.regs.events);
 }
 
-static int sync_regs(struct kvm_vcpu *vcpu)
+static int kvm_run_sync_regs_from_user(struct kvm_vcpu *vcpu)
 {
 	if (vcpu->run->kvm_dirty_regs & KVM_SYNC_X86_REGS) {
 		__set_regs(vcpu, &vcpu->run->s.regs.regs);
@@ -12341,6 +12346,14 @@ static int sync_regs(struct kvm_vcpu *vc
 		vcpu->run->kvm_dirty_regs &= ~KVM_SYNC_X86_SREGS;
 	}
 
+	return 0;
+}
+
+static int sync_regs(struct kvm_vcpu *vcpu)
+{
+	if (kvm_run_sync_regs_from_user(vcpu))
+		return -EINVAL;
+
 	if (vcpu->run->kvm_dirty_regs & KVM_SYNC_X86_EVENTS) {
 		struct kvm_vcpu_events events = vcpu->run->s.regs.events;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 663/877] KVM: x86: Rename __{g,s}et_sregs2() => kvm_vcpu_ioctl_x86_{g,s}et_sregs2()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (661 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 662/877] KVM: x86: Extract REGS and SREGS runtime sync code to helpers Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 664/877] KVM: x86: Move the bulk of register specific code from x86.c to regs.c Greg Kroah-Hartman
                   ` (221 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yosry Ahmed, Sean Christopherson,
	Kai Huang, Paolo Bonzini, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sean Christopherson <seanjc@google.com>

[ Upstream commit bd130c8d72a1c7dde5523b3f3fae9867eafaa1dc ]

Rename the KVM_{G,S}ET_SREGS2 helpers in anticipation of moving them out of
x86.c (while leaving the ioctl dispatch behind).  Having globally visible
APIs named __{g,s}et_sregs2() would be "fine", but ugly, given that
__{g,s}et_sregs() will NOT be globally visible.  As a bonus, this makes it
a bit more obvious that the helpers implement newer versions of
kvm_arch_vcpu_ioctl_set_sregs().

No functional change intended.

Cc: Yosry Ahmed <yosry@kernel.org>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Reviewed-by: Kai Huang <kai.huang@intel.com>
Message-ID: <20260613000329.732085-4-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Stable-dep-of: 184bd464bdb6 ("KVM: x86: Check EFER validity on KVM_SET_SREGS*")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/kvm/x86.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -135,8 +135,10 @@ static void store_regs(struct kvm_vcpu *
 static int sync_regs(struct kvm_vcpu *vcpu);
 static int kvm_vcpu_do_singlestep(struct kvm_vcpu *vcpu);
 
-static int __set_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2);
-static void __get_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2);
+static int kvm_vcpu_ioctl_x86_set_sregs2(struct kvm_vcpu *vcpu,
+					 struct kvm_sregs2 *sregs2);
+static void kvm_vcpu_ioctl_x86_get_sregs2(struct kvm_vcpu *vcpu,
+					  struct kvm_sregs2 *sregs2);
 
 static DEFINE_MUTEX(vendor_module_lock);
 struct kvm_x86_ops kvm_x86_ops __read_mostly;
@@ -6304,7 +6306,7 @@ long kvm_arch_vcpu_ioctl(struct file *fi
 		r = -ENOMEM;
 		if (!u.sregs2)
 			goto out;
-		__get_sregs2(vcpu, u.sregs2);
+		kvm_vcpu_ioctl_x86_get_sregs2(vcpu, u.sregs2);
 		r = -EFAULT;
 		if (copy_to_user(argp, u.sregs2, sizeof(struct kvm_sregs2)))
 			goto out;
@@ -6323,7 +6325,7 @@ long kvm_arch_vcpu_ioctl(struct file *fi
 			u.sregs2 = NULL;
 			goto out;
 		}
-		r = __set_sregs2(vcpu, u.sregs2);
+		r = kvm_vcpu_ioctl_x86_set_sregs2(vcpu, u.sregs2);
 		break;
 	}
 	case KVM_HAS_DEVICE_ATTR:
@@ -11845,7 +11847,8 @@ static void __get_sregs(struct kvm_vcpu
 			(unsigned long *)sregs->interrupt_bitmap);
 }
 
-static void __get_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2)
+static void kvm_vcpu_ioctl_x86_get_sregs2(struct kvm_vcpu *vcpu,
+					  struct kvm_sregs2 *sregs2)
 {
 	int i;
 
@@ -12108,7 +12111,8 @@ static int __set_sregs(struct kvm_vcpu *
 	return 0;
 }
 
-static int __set_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2)
+static int kvm_vcpu_ioctl_x86_set_sregs2(struct kvm_vcpu *vcpu,
+					 struct kvm_sregs2 *sregs2)
 {
 	int mmu_reset_needed = 0;
 	bool valid_pdptrs = sregs2->flags & KVM_SREGS2_FLAGS_PDPTRS_VALID;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 664/877] KVM: x86: Move the bulk of register specific code from x86.c to regs.c
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (662 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 663/877] KVM: x86: Rename __{g,s}et_sregs2() => kvm_vcpu_ioctl_x86_{g,s}et_sregs2() Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 665/877] KVM: x86: Check EFER validity on KVM_SET_SREGS* Greg Kroah-Hartman
                   ` (220 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Kai Huang, Sean Christopherson,
	Binbin Wu, Paolo Bonzini, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sean Christopherson <seanjc@google.com>

[ Upstream commit 2f5bb3fe583510cf20f9d64aa73089577be3dc36 ]

Introduce regs.c, and move the vast majority of register specific code out
of x86.c and into regs.c.  Deliberately leave behind MSR code, as KVM's MSR
support is complex enough to warrant its own compilation unit, and doesn't
have much in common with the other register code.

Note, "struct kvm_sregs" has fields for EFER and MSR_IA32_APICBASE, and so
the {G,S}ET_REGS flows technically contain a tiny amount of MSR code.
MSR_IA32_APICBASE is already managed by lapic.c, and so doesn't require a
"placement decision".  As for EFER, leave all other EFER handling in x86.c
(later to be moved to msrs.c).  The primary interface to EFER, set_efer(),
is very much MSR specific, even though EFER is arguably more of a Control
Register than an MSR.

No functional change intended.

Reviewed-by: Kai Huang <kai.huang@intel.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>
Message-ID: <20260613000329.732085-5-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Backport to 6.12: move the existing stable register implementations instead
of importing upstream versions that depend on newer MMU, APIC, register
cache and symbol-export interfaces. Keep the stable Makefile objects and
add regs.o. Use kvm_cache_regs.h and x86.h instead of introducing regs.h.

Move the existing kvm_pv_async_pf_enabled() and get_segment_base() helpers
to x86.h for use by both compilation units, and expose the existing
update_cr8_intercept() alongside the upstream cross-file declarations.
Preserve all function bodies and exported symbols; no new functions are
introduced. The resulting regs.c accepts the EFER validation fix in
184bd464bdb66daa9173670904f24c29c7b7f7d4 without changes.

[ sashal: Reduced backport -- upstream 2f5bb3fe58351 touches 5 file(s), this
  backport carries 4. Not backported here:
  arch/x86/kvm/regs.h
  This note is generated from the file lists only; see the resolution record
  for the reasoning. ]

Stable-dep-of: 184bd464bdb6 ("KVM: x86: Check EFER validity on KVM_SET_SREGS*")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/kvm/Makefile |    2 
 arch/x86/kvm/regs.c   |  871 ++++++++++++++++++++++++++++++++++++++++++++++++
 arch/x86/kvm/x86.c    |  889 --------------------------------------------------
 arch/x86/kvm/x86.h    |   28 +
 4 files changed, 903 insertions(+), 887 deletions(-)
 create mode 100644 arch/x86/kvm/regs.c

--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -6,7 +6,7 @@ ccflags-$(CONFIG_KVM_WERROR) += -Werror
 include $(srctree)/virt/kvm/Makefile.kvm
 
 kvm-y			+= x86.o emulate.o i8259.o irq.o lapic.o \
-			   i8254.o ioapic.o irq_comm.o cpuid.o pmu.o mtrr.o \
+			   i8254.o ioapic.o irq_comm.o cpuid.o pmu.o regs.o mtrr.o \
 			   debugfs.o mmu/mmu.o mmu/page_track.o \
 			   mmu/spte.o
 
--- /dev/null
+++ b/arch/x86/kvm/regs.c
@@ -0,0 +1,871 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/kvm_host.h>
+
+#include "lapic.h"
+#include "mmu.h"
+#include "kvm_cache_regs.h"
+#include "x86.h"
+
+unsigned long kvm_get_linear_rip(struct kvm_vcpu *vcpu)
+{
+	/* Can't read the RIP when guest state is protected, just return 0 */
+	if (vcpu->arch.guest_state_protected)
+		return 0;
+
+	if (is_64_bit_mode(vcpu))
+		return kvm_rip_read(vcpu);
+	return (u32)(get_segment_base(vcpu, VCPU_SREG_CS) +
+		     kvm_rip_read(vcpu));
+}
+EXPORT_SYMBOL_GPL(kvm_get_linear_rip);
+
+bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip)
+{
+	return kvm_get_linear_rip(vcpu) == linear_rip;
+}
+EXPORT_SYMBOL_GPL(kvm_is_linear_rip);
+
+unsigned long kvm_get_rflags(struct kvm_vcpu *vcpu)
+{
+	unsigned long rflags;
+
+	rflags = kvm_x86_call(get_rflags)(vcpu);
+	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
+		rflags &= ~X86_EFLAGS_TF;
+	return rflags;
+}
+EXPORT_SYMBOL_GPL(kvm_get_rflags);
+
+void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
+{
+	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP &&
+	    kvm_is_linear_rip(vcpu, vcpu->arch.singlestep_rip))
+		rflags |= X86_EFLAGS_TF;
+	kvm_x86_call(set_rflags)(vcpu, rflags);
+}
+
+void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
+{
+	__kvm_set_rflags(vcpu, rflags);
+	kvm_make_request(KVM_REQ_EVENT, vcpu);
+}
+EXPORT_SYMBOL_GPL(kvm_set_rflags);
+
+static void __get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
+{
+	if (vcpu->arch.emulate_regs_need_sync_to_vcpu) {
+		/*
+		 * We are here if userspace calls get_regs() in the middle of
+		 * instruction emulation. Registers state needs to be copied
+		 * back from emulation context to vcpu. Userspace shouldn't do
+		 * that usually, but some bad designed PV devices (vmware
+		 * backdoor interface) need this to work
+		 */
+		emulator_writeback_register_cache(vcpu->arch.emulate_ctxt);
+		vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
+	}
+	regs->rax = kvm_rax_read(vcpu);
+	regs->rbx = kvm_rbx_read(vcpu);
+	regs->rcx = kvm_rcx_read(vcpu);
+	regs->rdx = kvm_rdx_read(vcpu);
+	regs->rsi = kvm_rsi_read(vcpu);
+	regs->rdi = kvm_rdi_read(vcpu);
+	regs->rsp = kvm_rsp_read(vcpu);
+	regs->rbp = kvm_rbp_read(vcpu);
+#ifdef CONFIG_X86_64
+	regs->r8 = kvm_r8_read(vcpu);
+	regs->r9 = kvm_r9_read(vcpu);
+	regs->r10 = kvm_r10_read(vcpu);
+	regs->r11 = kvm_r11_read(vcpu);
+	regs->r12 = kvm_r12_read(vcpu);
+	regs->r13 = kvm_r13_read(vcpu);
+	regs->r14 = kvm_r14_read(vcpu);
+	regs->r15 = kvm_r15_read(vcpu);
+#endif
+
+	regs->rip = kvm_rip_read(vcpu);
+	regs->rflags = kvm_get_rflags(vcpu);
+}
+
+int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
+{
+	if (vcpu->kvm->arch.has_protected_state &&
+	    vcpu->arch.guest_state_protected)
+		return -EINVAL;
+
+	vcpu_load(vcpu);
+	__get_regs(vcpu, regs);
+	vcpu_put(vcpu);
+	return 0;
+}
+
+static void __set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
+{
+	vcpu->arch.emulate_regs_need_sync_from_vcpu = true;
+	vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
+
+	kvm_rax_write(vcpu, regs->rax);
+	kvm_rbx_write(vcpu, regs->rbx);
+	kvm_rcx_write(vcpu, regs->rcx);
+	kvm_rdx_write(vcpu, regs->rdx);
+	kvm_rsi_write(vcpu, regs->rsi);
+	kvm_rdi_write(vcpu, regs->rdi);
+	kvm_rsp_write(vcpu, regs->rsp);
+	kvm_rbp_write(vcpu, regs->rbp);
+#ifdef CONFIG_X86_64
+	kvm_r8_write(vcpu, regs->r8);
+	kvm_r9_write(vcpu, regs->r9);
+	kvm_r10_write(vcpu, regs->r10);
+	kvm_r11_write(vcpu, regs->r11);
+	kvm_r12_write(vcpu, regs->r12);
+	kvm_r13_write(vcpu, regs->r13);
+	kvm_r14_write(vcpu, regs->r14);
+	kvm_r15_write(vcpu, regs->r15);
+#endif
+
+	kvm_rip_write(vcpu, regs->rip);
+	kvm_set_rflags(vcpu, regs->rflags | X86_EFLAGS_FIXED);
+
+	vcpu->arch.exception.pending = false;
+	vcpu->arch.exception_vmexit.pending = false;
+
+	kvm_make_request(KVM_REQ_EVENT, vcpu);
+}
+
+int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
+{
+	if (vcpu->kvm->arch.has_protected_state &&
+	    vcpu->arch.guest_state_protected)
+		return -EINVAL;
+
+	vcpu_load(vcpu);
+	__set_regs(vcpu, regs);
+	vcpu_put(vcpu);
+	return 0;
+}
+
+static inline u64 pdptr_rsvd_bits(struct kvm_vcpu *vcpu)
+{
+	return vcpu->arch.reserved_gpa_bits | rsvd_bits(5, 8) | rsvd_bits(1, 2);
+}
+
+/*
+ * Load the pae pdptrs.  Return 1 if they are all valid, 0 otherwise.
+ */
+int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
+{
+	struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
+	gfn_t pdpt_gfn = cr3 >> PAGE_SHIFT;
+	gpa_t real_gpa;
+	int i;
+	int ret;
+	u64 pdpte[ARRAY_SIZE(mmu->pdptrs)];
+
+	/*
+	 * If the MMU is nested, CR3 holds an L2 GPA and needs to be translated
+	 * to an L1 GPA.
+	 */
+	real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(pdpt_gfn),
+				     PFERR_USER_MASK | PFERR_WRITE_MASK, NULL);
+	if (real_gpa == INVALID_GPA)
+		return 0;
+
+	/* Note the offset, PDPTRs are 32 byte aligned when using PAE paging. */
+	ret = kvm_vcpu_read_guest_page(vcpu, gpa_to_gfn(real_gpa), pdpte,
+				       cr3 & GENMASK(11, 5), sizeof(pdpte));
+	if (ret < 0)
+		return 0;
+
+	for (i = 0; i < ARRAY_SIZE(pdpte); ++i) {
+		if ((pdpte[i] & PT_PRESENT_MASK) &&
+		    (pdpte[i] & pdptr_rsvd_bits(vcpu))) {
+			return 0;
+		}
+	}
+
+	/*
+	 * Marking VCPU_EXREG_PDPTR dirty doesn't work for !tdp_enabled.
+	 * Shadow page roots need to be reconstructed instead.
+	 */
+	if (!tdp_enabled && memcmp(mmu->pdptrs, pdpte, sizeof(mmu->pdptrs)))
+		kvm_mmu_free_roots(vcpu->kvm, mmu, KVM_MMU_ROOT_CURRENT);
+
+	memcpy(mmu->pdptrs, pdpte, sizeof(mmu->pdptrs));
+	kvm_register_mark_dirty(vcpu, VCPU_EXREG_PDPTR);
+	kvm_make_request(KVM_REQ_LOAD_MMU_PGD, vcpu);
+	vcpu->arch.pdptrs_from_userspace = false;
+
+	return 1;
+}
+EXPORT_SYMBOL_GPL(load_pdptrs);
+
+static bool kvm_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
+{
+#ifdef CONFIG_X86_64
+	if (cr0 & 0xffffffff00000000UL)
+		return false;
+#endif
+
+	if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD))
+		return false;
+
+	if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE))
+		return false;
+
+	return kvm_x86_call(is_valid_cr0)(vcpu, cr0);
+}
+
+void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned long cr0)
+{
+	/*
+	 * CR0.WP is incorporated into the MMU role, but only for non-nested,
+	 * indirect shadow MMUs.  If paging is disabled, no updates are needed
+	 * as there are no permission bits to emulate.  If TDP is enabled, the
+	 * MMU's metadata needs to be updated, e.g. so that emulating guest
+	 * translations does the right thing, but there's no need to unload the
+	 * root as CR0.WP doesn't affect SPTEs.
+	 */
+	if ((cr0 ^ old_cr0) == X86_CR0_WP) {
+		if (!(cr0 & X86_CR0_PG))
+			return;
+
+		if (tdp_enabled) {
+			kvm_init_mmu(vcpu);
+			return;
+		}
+	}
+
+	if ((cr0 ^ old_cr0) & X86_CR0_PG) {
+		/*
+		 * Clearing CR0.PG is defined to flush the TLB from the guest's
+		 * perspective.
+		 */
+		if (!(cr0 & X86_CR0_PG))
+			kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
+		/*
+		 * Check for async #PF completion events when enabling paging,
+		 * as the vCPU may have previously encountered async #PFs (it's
+		 * entirely legal for the guest to toggle paging on/off without
+		 * waiting for the async #PF queue to drain).
+		 */
+		else if (kvm_pv_async_pf_enabled(vcpu))
+			kvm_make_request(KVM_REQ_APF_READY, vcpu);
+	}
+
+	if ((cr0 ^ old_cr0) & KVM_MMU_CR0_ROLE_BITS)
+		kvm_mmu_reset_context(vcpu);
+}
+EXPORT_SYMBOL_GPL(kvm_post_set_cr0);
+
+int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
+{
+	unsigned long old_cr0 = kvm_read_cr0(vcpu);
+
+	if (!kvm_is_valid_cr0(vcpu, cr0))
+		return 1;
+
+	cr0 |= X86_CR0_ET;
+
+	/* Write to CR0 reserved bits are ignored, even on Intel. */
+	cr0 &= ~CR0_RESERVED_BITS;
+
+#ifdef CONFIG_X86_64
+	if ((vcpu->arch.efer & EFER_LME) && !is_paging(vcpu) &&
+	    (cr0 & X86_CR0_PG)) {
+		int cs_db, cs_l;
+
+		if (!is_pae(vcpu))
+			return 1;
+		kvm_x86_call(get_cs_db_l_bits)(vcpu, &cs_db, &cs_l);
+		if (cs_l)
+			return 1;
+	}
+#endif
+	if (!(vcpu->arch.efer & EFER_LME) && (cr0 & X86_CR0_PG) &&
+	    is_pae(vcpu) && ((cr0 ^ old_cr0) & X86_CR0_PDPTR_BITS) &&
+	    !load_pdptrs(vcpu, kvm_read_cr3(vcpu)))
+		return 1;
+
+	if (!(cr0 & X86_CR0_PG) &&
+	    (is_64_bit_mode(vcpu) || kvm_is_cr4_bit_set(vcpu, X86_CR4_PCIDE)))
+		return 1;
+
+	kvm_x86_call(set_cr0)(vcpu, cr0);
+
+	kvm_post_set_cr0(vcpu, old_cr0, cr0);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(kvm_set_cr0);
+
+void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw)
+{
+	(void)kvm_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~0x0eul) | (msw & 0x0f));
+}
+EXPORT_SYMBOL_GPL(kvm_lmsw);
+
+int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
+{
+	bool skip_tlb_flush = false;
+	unsigned long pcid = 0;
+#ifdef CONFIG_X86_64
+	if (kvm_is_cr4_bit_set(vcpu, X86_CR4_PCIDE)) {
+		skip_tlb_flush = cr3 & X86_CR3_PCID_NOFLUSH;
+		cr3 &= ~X86_CR3_PCID_NOFLUSH;
+		pcid = cr3 & X86_CR3_PCID_MASK;
+	}
+#endif
+
+	/* PDPTRs are always reloaded for PAE paging. */
+	if (cr3 == kvm_read_cr3(vcpu) && !is_pae_paging(vcpu))
+		goto handle_tlb_flush;
+
+	/*
+	 * Do not condition the GPA check on long mode, this helper is used to
+	 * stuff CR3, e.g. for RSM emulation, and there is no guarantee that
+	 * the current vCPU mode is accurate.
+	 */
+	if (!kvm_vcpu_is_legal_cr3(vcpu, cr3))
+		return 1;
+
+	if (is_pae_paging(vcpu) && !load_pdptrs(vcpu, cr3))
+		return 1;
+
+	if (cr3 != kvm_read_cr3(vcpu))
+		kvm_mmu_new_pgd(vcpu, cr3);
+
+	vcpu->arch.cr3 = cr3;
+	kvm_register_mark_dirty(vcpu, VCPU_EXREG_CR3);
+	/* Do not call post_set_cr3, we do not get here for confidential guests.  */
+
+handle_tlb_flush:
+	/*
+	 * A load of CR3 that flushes the TLB flushes only the current PCID,
+	 * even if PCID is disabled, in which case PCID=0 is flushed.  It's a
+	 * moot point in the end because _disabling_ PCID will flush all PCIDs,
+	 * and it's impossible to use a non-zero PCID when PCID is disabled,
+	 * i.e. only PCID=0 can be relevant.
+	 */
+	if (!skip_tlb_flush)
+		kvm_invalidate_pcid(vcpu, pcid);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(kvm_set_cr3);
+
+static bool kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
+{
+	return __kvm_is_valid_cr4(vcpu, cr4) &&
+	       kvm_x86_call(is_valid_cr4)(vcpu, cr4);
+}
+
+void kvm_post_set_cr4(struct kvm_vcpu *vcpu, unsigned long old_cr4, unsigned long cr4)
+{
+	if ((cr4 ^ old_cr4) & KVM_MMU_CR4_ROLE_BITS)
+		kvm_mmu_reset_context(vcpu);
+
+	/*
+	 * If CR4.PCIDE is changed 0 -> 1, there is no need to flush the TLB
+	 * according to the SDM; however, stale prev_roots could be reused
+	 * incorrectly in the future after a MOV to CR3 with NOFLUSH=1, so we
+	 * free them all.  This is *not* a superset of KVM_REQ_TLB_FLUSH_GUEST
+	 * or KVM_REQ_TLB_FLUSH_CURRENT, because the hardware TLB is not flushed,
+	 * so fall through.
+	 */
+	if (!tdp_enabled &&
+	    (cr4 & X86_CR4_PCIDE) && !(old_cr4 & X86_CR4_PCIDE))
+		kvm_mmu_unload(vcpu);
+
+	/*
+	 * The TLB has to be flushed for all PCIDs if any of the following
+	 * (architecturally required) changes happen:
+	 * - CR4.PCIDE is changed from 1 to 0
+	 * - CR4.PGE is toggled
+	 *
+	 * This is a superset of KVM_REQ_TLB_FLUSH_CURRENT.
+	 */
+	if (((cr4 ^ old_cr4) & X86_CR4_PGE) ||
+	    (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE)))
+		kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
+
+	/*
+	 * The TLB has to be flushed for the current PCID if any of the
+	 * following (architecturally required) changes happen:
+	 * - CR4.SMEP is changed from 0 to 1
+	 * - CR4.PAE is toggled
+	 */
+	else if (((cr4 ^ old_cr4) & X86_CR4_PAE) ||
+		 ((cr4 & X86_CR4_SMEP) && !(old_cr4 & X86_CR4_SMEP)))
+		kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu);
+
+}
+EXPORT_SYMBOL_GPL(kvm_post_set_cr4);
+
+int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
+{
+	unsigned long old_cr4 = kvm_read_cr4(vcpu);
+
+	if (!kvm_is_valid_cr4(vcpu, cr4))
+		return 1;
+
+	if (is_long_mode(vcpu)) {
+		if (!(cr4 & X86_CR4_PAE))
+			return 1;
+		if ((cr4 ^ old_cr4) & X86_CR4_LA57)
+			return 1;
+	} else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE)
+		   && ((cr4 ^ old_cr4) & X86_CR4_PDPTR_BITS)
+		   && !load_pdptrs(vcpu, kvm_read_cr3(vcpu)))
+		return 1;
+
+	if ((cr4 & X86_CR4_PCIDE) && !(old_cr4 & X86_CR4_PCIDE)) {
+		/* PCID can not be enabled when cr3[11:0]!=000H or EFER.LMA=0 */
+		if ((kvm_read_cr3(vcpu) & X86_CR3_PCID_MASK) || !is_long_mode(vcpu))
+			return 1;
+	}
+
+	kvm_x86_call(set_cr4)(vcpu, cr4);
+
+	kvm_post_set_cr4(vcpu, old_cr4, cr4);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(kvm_set_cr4);
+
+int kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
+{
+	if (cr8 & CR8_RESERVED_BITS)
+		return 1;
+	if (lapic_in_kernel(vcpu))
+		kvm_lapic_set_tpr(vcpu, cr8);
+	else
+		vcpu->arch.cr8 = cr8;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(kvm_set_cr8);
+
+unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu)
+{
+	if (lapic_in_kernel(vcpu))
+		return kvm_lapic_get_cr8(vcpu);
+	else
+		return vcpu->arch.cr8;
+}
+EXPORT_SYMBOL_GPL(kvm_get_cr8);
+
+static void __get_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
+{
+	struct desc_ptr dt;
+
+	if (vcpu->arch.guest_state_protected)
+		goto skip_protected_regs;
+
+	kvm_handle_exception_payload_quirk(vcpu);
+
+	kvm_get_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
+	kvm_get_segment(vcpu, &sregs->ds, VCPU_SREG_DS);
+	kvm_get_segment(vcpu, &sregs->es, VCPU_SREG_ES);
+	kvm_get_segment(vcpu, &sregs->fs, VCPU_SREG_FS);
+	kvm_get_segment(vcpu, &sregs->gs, VCPU_SREG_GS);
+	kvm_get_segment(vcpu, &sregs->ss, VCPU_SREG_SS);
+
+	kvm_get_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
+	kvm_get_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
+
+	kvm_x86_call(get_idt)(vcpu, &dt);
+	sregs->idt.limit = dt.size;
+	sregs->idt.base = dt.address;
+	kvm_x86_call(get_gdt)(vcpu, &dt);
+	sregs->gdt.limit = dt.size;
+	sregs->gdt.base = dt.address;
+
+	sregs->cr2 = vcpu->arch.cr2;
+	sregs->cr3 = kvm_read_cr3(vcpu);
+
+skip_protected_regs:
+	sregs->cr0 = kvm_read_cr0(vcpu);
+	sregs->cr4 = kvm_read_cr4(vcpu);
+	sregs->cr8 = kvm_get_cr8(vcpu);
+	sregs->efer = vcpu->arch.efer;
+	sregs->apic_base = vcpu->arch.apic_base;
+}
+
+static void __get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
+{
+	__get_sregs_common(vcpu, sregs);
+
+	if (vcpu->arch.guest_state_protected)
+		return;
+
+	if (vcpu->arch.interrupt.injected && !vcpu->arch.interrupt.soft)
+		set_bit(vcpu->arch.interrupt.nr,
+			(unsigned long *)sregs->interrupt_bitmap);
+}
+
+int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
+				  struct kvm_sregs *sregs)
+{
+	if (vcpu->kvm->arch.has_protected_state &&
+	    vcpu->arch.guest_state_protected)
+		return -EINVAL;
+
+	vcpu_load(vcpu);
+	__get_sregs(vcpu, sregs);
+	vcpu_put(vcpu);
+	return 0;
+}
+
+void kvm_vcpu_ioctl_x86_get_sregs2(struct kvm_vcpu *vcpu,
+				   struct kvm_sregs2 *sregs2)
+{
+	int i;
+
+	__get_sregs_common(vcpu, (struct kvm_sregs *)sregs2);
+
+	if (vcpu->arch.guest_state_protected)
+		return;
+
+	if (is_pae_paging(vcpu)) {
+		kvm_vcpu_srcu_read_lock(vcpu);
+		for (i = 0 ; i < 4 ; i++)
+			sregs2->pdptrs[i] = kvm_pdptr_read(vcpu, i);
+		sregs2->flags |= KVM_SREGS2_FLAGS_PDPTRS_VALID;
+		kvm_vcpu_srcu_read_unlock(vcpu);
+	}
+}
+
+static bool kvm_is_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
+{
+	if ((sregs->efer & EFER_LME) && (sregs->cr0 & X86_CR0_PG)) {
+		/*
+		 * When EFER.LME and CR0.PG are set, the processor is in
+		 * 64-bit mode (though maybe in a 32-bit code segment).
+		 * CR4.PAE and EFER.LMA must be set.
+		 */
+		if (!(sregs->cr4 & X86_CR4_PAE) || !(sregs->efer & EFER_LMA))
+			return false;
+		if (!kvm_vcpu_is_legal_cr3(vcpu, sregs->cr3))
+			return false;
+	} else {
+		/*
+		 * Not in 64-bit mode: EFER.LMA is clear and the code
+		 * segment cannot be 64-bit.
+		 */
+		if (sregs->efer & EFER_LMA || sregs->cs.l)
+			return false;
+	}
+
+	return kvm_is_valid_cr4(vcpu, sregs->cr4) &&
+	       kvm_is_valid_cr0(vcpu, sregs->cr0);
+}
+
+static int __set_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs,
+		int *mmu_reset_needed, bool update_pdptrs)
+{
+	struct msr_data apic_base_msr;
+	int idx;
+	struct desc_ptr dt;
+
+	if (!kvm_is_valid_sregs(vcpu, sregs))
+		return -EINVAL;
+
+	apic_base_msr.data = sregs->apic_base;
+	apic_base_msr.host_initiated = true;
+	if (kvm_set_apic_base(vcpu, &apic_base_msr))
+		return -EINVAL;
+
+	if (vcpu->arch.guest_state_protected)
+		return 0;
+
+	dt.size = sregs->idt.limit;
+	dt.address = sregs->idt.base;
+	kvm_x86_call(set_idt)(vcpu, &dt);
+	dt.size = sregs->gdt.limit;
+	dt.address = sregs->gdt.base;
+	kvm_x86_call(set_gdt)(vcpu, &dt);
+
+	vcpu->arch.cr2 = sregs->cr2;
+	*mmu_reset_needed |= kvm_read_cr3(vcpu) != sregs->cr3;
+	vcpu->arch.cr3 = sregs->cr3;
+	kvm_register_mark_dirty(vcpu, VCPU_EXREG_CR3);
+	kvm_x86_call(post_set_cr3)(vcpu, sregs->cr3);
+
+	kvm_set_cr8(vcpu, sregs->cr8);
+
+	*mmu_reset_needed |= vcpu->arch.efer != sregs->efer;
+	kvm_x86_call(set_efer)(vcpu, sregs->efer);
+
+	*mmu_reset_needed |= kvm_read_cr0(vcpu) != sregs->cr0;
+	kvm_x86_call(set_cr0)(vcpu, sregs->cr0);
+
+	*mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4;
+	kvm_x86_call(set_cr4)(vcpu, sregs->cr4);
+
+	if (update_pdptrs) {
+		idx = srcu_read_lock(&vcpu->kvm->srcu);
+		if (is_pae_paging(vcpu)) {
+			load_pdptrs(vcpu, kvm_read_cr3(vcpu));
+			*mmu_reset_needed = 1;
+		}
+		srcu_read_unlock(&vcpu->kvm->srcu, idx);
+	}
+
+	kvm_set_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
+	kvm_set_segment(vcpu, &sregs->ds, VCPU_SREG_DS);
+	kvm_set_segment(vcpu, &sregs->es, VCPU_SREG_ES);
+	kvm_set_segment(vcpu, &sregs->fs, VCPU_SREG_FS);
+	kvm_set_segment(vcpu, &sregs->gs, VCPU_SREG_GS);
+	kvm_set_segment(vcpu, &sregs->ss, VCPU_SREG_SS);
+
+	kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
+	kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
+
+	update_cr8_intercept(vcpu);
+
+	/* Older userspace won't unhalt the vcpu on reset. */
+	if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 &&
+	    sregs->cs.selector == 0xf000 && sregs->cs.base == 0xffff0000 &&
+	    !is_protmode(vcpu))
+		vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+
+	return 0;
+}
+
+static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
+{
+	int pending_vec, max_bits;
+	int mmu_reset_needed = 0;
+	int ret = __set_sregs_common(vcpu, sregs, &mmu_reset_needed, true);
+
+	if (ret)
+		return ret;
+
+	if (mmu_reset_needed) {
+		kvm_mmu_reset_context(vcpu);
+		kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
+	}
+
+	max_bits = KVM_NR_INTERRUPTS;
+	pending_vec = find_first_bit(
+		(const unsigned long *)sregs->interrupt_bitmap, max_bits);
+
+	if (pending_vec < max_bits) {
+		kvm_queue_interrupt(vcpu, pending_vec, false);
+		pr_debug("Set back pending irq %d\n", pending_vec);
+		kvm_make_request(KVM_REQ_EVENT, vcpu);
+	}
+	return 0;
+}
+
+int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
+				  struct kvm_sregs *sregs)
+{
+	int ret;
+
+	if (vcpu->kvm->arch.has_protected_state &&
+	    vcpu->arch.guest_state_protected)
+		return -EINVAL;
+
+	vcpu_load(vcpu);
+	ret = __set_sregs(vcpu, sregs);
+	vcpu_put(vcpu);
+	return ret;
+}
+
+int kvm_vcpu_ioctl_x86_set_sregs2(struct kvm_vcpu *vcpu,
+				  struct kvm_sregs2 *sregs2)
+{
+	int mmu_reset_needed = 0;
+	bool valid_pdptrs = sregs2->flags & KVM_SREGS2_FLAGS_PDPTRS_VALID;
+	bool pae = (sregs2->cr0 & X86_CR0_PG) && (sregs2->cr4 & X86_CR4_PAE) &&
+		!(sregs2->efer & EFER_LMA);
+	int i, ret;
+
+	if (sregs2->flags & ~KVM_SREGS2_FLAGS_PDPTRS_VALID)
+		return -EINVAL;
+
+	if (valid_pdptrs && (!pae || vcpu->arch.guest_state_protected))
+		return -EINVAL;
+
+	ret = __set_sregs_common(vcpu, (struct kvm_sregs *)sregs2,
+				 &mmu_reset_needed, !valid_pdptrs);
+	if (ret)
+		return ret;
+
+	if (valid_pdptrs) {
+		for (i = 0; i < 4 ; i++)
+			kvm_pdptr_write(vcpu, i, sregs2->pdptrs[i]);
+
+		kvm_register_mark_dirty(vcpu, VCPU_EXREG_PDPTR);
+		mmu_reset_needed = 1;
+		vcpu->arch.pdptrs_from_userspace = true;
+	}
+	if (mmu_reset_needed) {
+		kvm_mmu_reset_context(vcpu);
+		kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
+	}
+	return 0;
+}
+
+void kvm_run_sync_regs_to_user(struct kvm_vcpu *vcpu)
+{
+	BUILD_BUG_ON(sizeof(struct kvm_sync_regs) > SYNC_REGS_SIZE_BYTES);
+
+	if (vcpu->run->kvm_valid_regs & KVM_SYNC_X86_REGS)
+		__get_regs(vcpu, &vcpu->run->s.regs.regs);
+
+	if (vcpu->run->kvm_valid_regs & KVM_SYNC_X86_SREGS)
+		__get_sregs(vcpu, &vcpu->run->s.regs.sregs);
+}
+
+int kvm_run_sync_regs_from_user(struct kvm_vcpu *vcpu)
+{
+	if (vcpu->run->kvm_dirty_regs & KVM_SYNC_X86_REGS) {
+		__set_regs(vcpu, &vcpu->run->s.regs.regs);
+		vcpu->run->kvm_dirty_regs &= ~KVM_SYNC_X86_REGS;
+	}
+
+	if (vcpu->run->kvm_dirty_regs & KVM_SYNC_X86_SREGS) {
+		struct kvm_sregs sregs = vcpu->run->s.regs.sregs;
+
+		if (__set_sregs(vcpu, &sregs))
+			return -EINVAL;
+
+		vcpu->run->kvm_dirty_regs &= ~KVM_SYNC_X86_SREGS;
+	}
+
+	return 0;
+}
+
+void kvm_update_dr0123(struct kvm_vcpu *vcpu)
+{
+	int i;
+
+	if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) {
+		for (i = 0; i < KVM_NR_DB_REGS; i++)
+			vcpu->arch.eff_db[i] = vcpu->arch.db[i];
+	}
+}
+
+void kvm_update_dr7(struct kvm_vcpu *vcpu)
+{
+	unsigned long dr7;
+
+	if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
+		dr7 = vcpu->arch.guest_debug_dr7;
+	else
+		dr7 = vcpu->arch.dr7;
+	kvm_x86_call(set_dr7)(vcpu, dr7);
+	vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_BP_ENABLED;
+	if (dr7 & DR7_BP_EN_MASK)
+		vcpu->arch.switch_db_regs |= KVM_DEBUGREG_BP_ENABLED;
+}
+EXPORT_SYMBOL_GPL(kvm_update_dr7);
+
+static u64 kvm_dr6_fixed(struct kvm_vcpu *vcpu)
+{
+	u64 fixed = DR6_FIXED_1;
+
+	if (!guest_cpuid_has(vcpu, X86_FEATURE_RTM))
+		fixed |= DR6_RTM;
+
+	if (!guest_cpuid_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT))
+		fixed |= DR6_BUS_LOCK;
+	return fixed;
+}
+
+int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val)
+{
+	size_t size = ARRAY_SIZE(vcpu->arch.db);
+
+	switch (dr) {
+	case 0 ... 3:
+		vcpu->arch.db[array_index_nospec(dr, size)] = val;
+		if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
+			vcpu->arch.eff_db[dr] = val;
+		break;
+	case 4:
+	case 6:
+		if (!kvm_dr6_valid(val))
+			return 1; /* #GP */
+		vcpu->arch.dr6 = (val & DR6_VOLATILE) | kvm_dr6_fixed(vcpu);
+		break;
+	case 5:
+	default: /* 7 */
+		if (!kvm_dr7_valid(val))
+			return 1; /* #GP */
+		vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1;
+		kvm_update_dr7(vcpu);
+		break;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(kvm_set_dr);
+
+unsigned long kvm_get_dr(struct kvm_vcpu *vcpu, int dr)
+{
+	size_t size = ARRAY_SIZE(vcpu->arch.db);
+
+	switch (dr) {
+	case 0 ... 3:
+		return vcpu->arch.db[array_index_nospec(dr, size)];
+	case 4:
+	case 6:
+		return vcpu->arch.dr6;
+	case 5:
+	default: /* 7 */
+		return vcpu->arch.dr7;
+	}
+}
+EXPORT_SYMBOL_GPL(kvm_get_dr);
+
+int kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu,
+				     struct kvm_debugregs *dbgregs)
+{
+	unsigned int i;
+
+	if (vcpu->kvm->arch.has_protected_state &&
+	    vcpu->arch.guest_state_protected)
+		return -EINVAL;
+
+	kvm_handle_exception_payload_quirk(vcpu);
+
+	memset(dbgregs, 0, sizeof(*dbgregs));
+
+	BUILD_BUG_ON(ARRAY_SIZE(vcpu->arch.db) != ARRAY_SIZE(dbgregs->db));
+	for (i = 0; i < ARRAY_SIZE(vcpu->arch.db); i++)
+		dbgregs->db[i] = vcpu->arch.db[i];
+
+	dbgregs->dr6 = vcpu->arch.dr6;
+	dbgregs->dr7 = vcpu->arch.dr7;
+	return 0;
+}
+
+int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
+				     struct kvm_debugregs *dbgregs)
+{
+	unsigned int i;
+
+	if (vcpu->kvm->arch.has_protected_state &&
+	    vcpu->arch.guest_state_protected)
+		return -EINVAL;
+
+	if (dbgregs->flags)
+		return -EINVAL;
+
+	if (!kvm_dr6_valid(dbgregs->dr6))
+		return -EINVAL;
+	if (!kvm_dr7_valid(dbgregs->dr7))
+		return -EINVAL;
+
+	for (i = 0; i < ARRAY_SIZE(vcpu->arch.db); i++)
+		vcpu->arch.db[i] = dbgregs->db[i];
+
+	kvm_update_dr0123(vcpu);
+	vcpu->arch.dr6 = dbgregs->dr6;
+	vcpu->arch.dr7 = dbgregs->dr7;
+	kvm_update_dr7(vcpu);
+
+	return 0;
+}
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -128,18 +128,11 @@ static u64 __read_mostly cr4_reserved_bi
 #define KVM_X2APIC_API_VALID_FLAGS (KVM_X2APIC_API_USE_32BIT_IDS | \
                                     KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK)
 
-static void update_cr8_intercept(struct kvm_vcpu *vcpu);
 static void process_nmi(struct kvm_vcpu *vcpu);
-static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
 static void store_regs(struct kvm_vcpu *vcpu);
 static int sync_regs(struct kvm_vcpu *vcpu);
 static int kvm_vcpu_do_singlestep(struct kvm_vcpu *vcpu);
 
-static int kvm_vcpu_ioctl_x86_set_sregs2(struct kvm_vcpu *vcpu,
-					 struct kvm_sregs2 *sregs2);
-static void kvm_vcpu_ioctl_x86_get_sregs2(struct kvm_vcpu *vcpu,
-					  struct kvm_sregs2 *sregs2);
-
 static DEFINE_MUTEX(vendor_module_lock);
 struct kvm_x86_ops kvm_x86_ops __read_mostly;
 
@@ -1034,173 +1027,6 @@ bool kvm_require_dr(struct kvm_vcpu *vcp
 }
 EXPORT_SYMBOL_GPL(kvm_require_dr);
 
-static bool kvm_pv_async_pf_enabled(struct kvm_vcpu *vcpu)
-{
-	u64 mask = KVM_ASYNC_PF_ENABLED | KVM_ASYNC_PF_DELIVERY_AS_INT;
-
-	return (vcpu->arch.apf.msr_en_val & mask) == mask;
-}
-
-static inline u64 pdptr_rsvd_bits(struct kvm_vcpu *vcpu)
-{
-	return vcpu->arch.reserved_gpa_bits | rsvd_bits(5, 8) | rsvd_bits(1, 2);
-}
-
-/*
- * Load the pae pdptrs.  Return 1 if they are all valid, 0 otherwise.
- */
-int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
-{
-	struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
-	gfn_t pdpt_gfn = cr3 >> PAGE_SHIFT;
-	gpa_t real_gpa;
-	int i;
-	int ret;
-	u64 pdpte[ARRAY_SIZE(mmu->pdptrs)];
-
-	/*
-	 * If the MMU is nested, CR3 holds an L2 GPA and needs to be translated
-	 * to an L1 GPA.
-	 */
-	real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(pdpt_gfn),
-				     PFERR_USER_MASK | PFERR_WRITE_MASK, NULL);
-	if (real_gpa == INVALID_GPA)
-		return 0;
-
-	/* Note the offset, PDPTRs are 32 byte aligned when using PAE paging. */
-	ret = kvm_vcpu_read_guest_page(vcpu, gpa_to_gfn(real_gpa), pdpte,
-				       cr3 & GENMASK(11, 5), sizeof(pdpte));
-	if (ret < 0)
-		return 0;
-
-	for (i = 0; i < ARRAY_SIZE(pdpte); ++i) {
-		if ((pdpte[i] & PT_PRESENT_MASK) &&
-		    (pdpte[i] & pdptr_rsvd_bits(vcpu))) {
-			return 0;
-		}
-	}
-
-	/*
-	 * Marking VCPU_EXREG_PDPTR dirty doesn't work for !tdp_enabled.
-	 * Shadow page roots need to be reconstructed instead.
-	 */
-	if (!tdp_enabled && memcmp(mmu->pdptrs, pdpte, sizeof(mmu->pdptrs)))
-		kvm_mmu_free_roots(vcpu->kvm, mmu, KVM_MMU_ROOT_CURRENT);
-
-	memcpy(mmu->pdptrs, pdpte, sizeof(mmu->pdptrs));
-	kvm_register_mark_dirty(vcpu, VCPU_EXREG_PDPTR);
-	kvm_make_request(KVM_REQ_LOAD_MMU_PGD, vcpu);
-	vcpu->arch.pdptrs_from_userspace = false;
-
-	return 1;
-}
-EXPORT_SYMBOL_GPL(load_pdptrs);
-
-static bool kvm_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
-{
-#ifdef CONFIG_X86_64
-	if (cr0 & 0xffffffff00000000UL)
-		return false;
-#endif
-
-	if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD))
-		return false;
-
-	if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE))
-		return false;
-
-	return kvm_x86_call(is_valid_cr0)(vcpu, cr0);
-}
-
-void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned long cr0)
-{
-	/*
-	 * CR0.WP is incorporated into the MMU role, but only for non-nested,
-	 * indirect shadow MMUs.  If paging is disabled, no updates are needed
-	 * as there are no permission bits to emulate.  If TDP is enabled, the
-	 * MMU's metadata needs to be updated, e.g. so that emulating guest
-	 * translations does the right thing, but there's no need to unload the
-	 * root as CR0.WP doesn't affect SPTEs.
-	 */
-	if ((cr0 ^ old_cr0) == X86_CR0_WP) {
-		if (!(cr0 & X86_CR0_PG))
-			return;
-
-		if (tdp_enabled) {
-			kvm_init_mmu(vcpu);
-			return;
-		}
-	}
-
-	if ((cr0 ^ old_cr0) & X86_CR0_PG) {
-		/*
-		 * Clearing CR0.PG is defined to flush the TLB from the guest's
-		 * perspective.
-		 */
-		if (!(cr0 & X86_CR0_PG))
-			kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
-		/*
-		 * Check for async #PF completion events when enabling paging,
-		 * as the vCPU may have previously encountered async #PFs (it's
-		 * entirely legal for the guest to toggle paging on/off without
-		 * waiting for the async #PF queue to drain).
-		 */
-		else if (kvm_pv_async_pf_enabled(vcpu))
-			kvm_make_request(KVM_REQ_APF_READY, vcpu);
-	}
-
-	if ((cr0 ^ old_cr0) & KVM_MMU_CR0_ROLE_BITS)
-		kvm_mmu_reset_context(vcpu);
-}
-EXPORT_SYMBOL_GPL(kvm_post_set_cr0);
-
-int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
-{
-	unsigned long old_cr0 = kvm_read_cr0(vcpu);
-
-	if (!kvm_is_valid_cr0(vcpu, cr0))
-		return 1;
-
-	cr0 |= X86_CR0_ET;
-
-	/* Write to CR0 reserved bits are ignored, even on Intel. */
-	cr0 &= ~CR0_RESERVED_BITS;
-
-#ifdef CONFIG_X86_64
-	if ((vcpu->arch.efer & EFER_LME) && !is_paging(vcpu) &&
-	    (cr0 & X86_CR0_PG)) {
-		int cs_db, cs_l;
-
-		if (!is_pae(vcpu))
-			return 1;
-		kvm_x86_call(get_cs_db_l_bits)(vcpu, &cs_db, &cs_l);
-		if (cs_l)
-			return 1;
-	}
-#endif
-	if (!(vcpu->arch.efer & EFER_LME) && (cr0 & X86_CR0_PG) &&
-	    is_pae(vcpu) && ((cr0 ^ old_cr0) & X86_CR0_PDPTR_BITS) &&
-	    !load_pdptrs(vcpu, kvm_read_cr3(vcpu)))
-		return 1;
-
-	if (!(cr0 & X86_CR0_PG) &&
-	    (is_64_bit_mode(vcpu) || kvm_is_cr4_bit_set(vcpu, X86_CR4_PCIDE)))
-		return 1;
-
-	kvm_x86_call(set_cr0)(vcpu, cr0);
-
-	kvm_post_set_cr0(vcpu, old_cr0, cr0);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(kvm_set_cr0);
-
-void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw)
-{
-	(void)kvm_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~0x0eul) | (msw & 0x0f));
-}
-EXPORT_SYMBOL_GPL(kvm_lmsw);
-
 void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu)
 {
 	if (vcpu->arch.guest_state_protected)
@@ -1327,86 +1153,7 @@ bool __kvm_is_valid_cr4(struct kvm_vcpu
 }
 EXPORT_SYMBOL_GPL(__kvm_is_valid_cr4);
 
-static bool kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
-{
-	return __kvm_is_valid_cr4(vcpu, cr4) &&
-	       kvm_x86_call(is_valid_cr4)(vcpu, cr4);
-}
-
-void kvm_post_set_cr4(struct kvm_vcpu *vcpu, unsigned long old_cr4, unsigned long cr4)
-{
-	if ((cr4 ^ old_cr4) & KVM_MMU_CR4_ROLE_BITS)
-		kvm_mmu_reset_context(vcpu);
-
-	/*
-	 * If CR4.PCIDE is changed 0 -> 1, there is no need to flush the TLB
-	 * according to the SDM; however, stale prev_roots could be reused
-	 * incorrectly in the future after a MOV to CR3 with NOFLUSH=1, so we
-	 * free them all.  This is *not* a superset of KVM_REQ_TLB_FLUSH_GUEST
-	 * or KVM_REQ_TLB_FLUSH_CURRENT, because the hardware TLB is not flushed,
-	 * so fall through.
-	 */
-	if (!tdp_enabled &&
-	    (cr4 & X86_CR4_PCIDE) && !(old_cr4 & X86_CR4_PCIDE))
-		kvm_mmu_unload(vcpu);
-
-	/*
-	 * The TLB has to be flushed for all PCIDs if any of the following
-	 * (architecturally required) changes happen:
-	 * - CR4.PCIDE is changed from 1 to 0
-	 * - CR4.PGE is toggled
-	 *
-	 * This is a superset of KVM_REQ_TLB_FLUSH_CURRENT.
-	 */
-	if (((cr4 ^ old_cr4) & X86_CR4_PGE) ||
-	    (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE)))
-		kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
-
-	/*
-	 * The TLB has to be flushed for the current PCID if any of the
-	 * following (architecturally required) changes happen:
-	 * - CR4.SMEP is changed from 0 to 1
-	 * - CR4.PAE is toggled
-	 */
-	else if (((cr4 ^ old_cr4) & X86_CR4_PAE) ||
-		 ((cr4 & X86_CR4_SMEP) && !(old_cr4 & X86_CR4_SMEP)))
-		kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu);
-
-}
-EXPORT_SYMBOL_GPL(kvm_post_set_cr4);
-
-int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
-{
-	unsigned long old_cr4 = kvm_read_cr4(vcpu);
-
-	if (!kvm_is_valid_cr4(vcpu, cr4))
-		return 1;
-
-	if (is_long_mode(vcpu)) {
-		if (!(cr4 & X86_CR4_PAE))
-			return 1;
-		if ((cr4 ^ old_cr4) & X86_CR4_LA57)
-			return 1;
-	} else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE)
-		   && ((cr4 ^ old_cr4) & X86_CR4_PDPTR_BITS)
-		   && !load_pdptrs(vcpu, kvm_read_cr3(vcpu)))
-		return 1;
-
-	if ((cr4 & X86_CR4_PCIDE) && !(old_cr4 & X86_CR4_PCIDE)) {
-		/* PCID can not be enabled when cr3[11:0]!=000H or EFER.LMA=0 */
-		if ((kvm_read_cr3(vcpu) & X86_CR3_PCID_MASK) || !is_long_mode(vcpu))
-			return 1;
-	}
-
-	kvm_x86_call(set_cr4)(vcpu, cr4);
-
-	kvm_post_set_cr4(vcpu, old_cr4, cr4);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(kvm_set_cr4);
-
-static void kvm_invalidate_pcid(struct kvm_vcpu *vcpu, unsigned long pcid)
+void kvm_invalidate_pcid(struct kvm_vcpu *vcpu, unsigned long pcid)
 {
 	struct kvm_mmu *mmu = vcpu->arch.mmu;
 	unsigned long roots_to_free = 0;
@@ -1449,159 +1196,6 @@ static void kvm_invalidate_pcid(struct k
 	kvm_mmu_free_roots(vcpu->kvm, mmu, roots_to_free);
 }
 
-int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
-{
-	bool skip_tlb_flush = false;
-	unsigned long pcid = 0;
-#ifdef CONFIG_X86_64
-	if (kvm_is_cr4_bit_set(vcpu, X86_CR4_PCIDE)) {
-		skip_tlb_flush = cr3 & X86_CR3_PCID_NOFLUSH;
-		cr3 &= ~X86_CR3_PCID_NOFLUSH;
-		pcid = cr3 & X86_CR3_PCID_MASK;
-	}
-#endif
-
-	/* PDPTRs are always reloaded for PAE paging. */
-	if (cr3 == kvm_read_cr3(vcpu) && !is_pae_paging(vcpu))
-		goto handle_tlb_flush;
-
-	/*
-	 * Do not condition the GPA check on long mode, this helper is used to
-	 * stuff CR3, e.g. for RSM emulation, and there is no guarantee that
-	 * the current vCPU mode is accurate.
-	 */
-	if (!kvm_vcpu_is_legal_cr3(vcpu, cr3))
-		return 1;
-
-	if (is_pae_paging(vcpu) && !load_pdptrs(vcpu, cr3))
-		return 1;
-
-	if (cr3 != kvm_read_cr3(vcpu))
-		kvm_mmu_new_pgd(vcpu, cr3);
-
-	vcpu->arch.cr3 = cr3;
-	kvm_register_mark_dirty(vcpu, VCPU_EXREG_CR3);
-	/* Do not call post_set_cr3, we do not get here for confidential guests.  */
-
-handle_tlb_flush:
-	/*
-	 * A load of CR3 that flushes the TLB flushes only the current PCID,
-	 * even if PCID is disabled, in which case PCID=0 is flushed.  It's a
-	 * moot point in the end because _disabling_ PCID will flush all PCIDs,
-	 * and it's impossible to use a non-zero PCID when PCID is disabled,
-	 * i.e. only PCID=0 can be relevant.
-	 */
-	if (!skip_tlb_flush)
-		kvm_invalidate_pcid(vcpu, pcid);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(kvm_set_cr3);
-
-int kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
-{
-	if (cr8 & CR8_RESERVED_BITS)
-		return 1;
-	if (lapic_in_kernel(vcpu))
-		kvm_lapic_set_tpr(vcpu, cr8);
-	else
-		vcpu->arch.cr8 = cr8;
-	return 0;
-}
-EXPORT_SYMBOL_GPL(kvm_set_cr8);
-
-unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu)
-{
-	if (lapic_in_kernel(vcpu))
-		return kvm_lapic_get_cr8(vcpu);
-	else
-		return vcpu->arch.cr8;
-}
-EXPORT_SYMBOL_GPL(kvm_get_cr8);
-
-static void kvm_update_dr0123(struct kvm_vcpu *vcpu)
-{
-	int i;
-
-	if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) {
-		for (i = 0; i < KVM_NR_DB_REGS; i++)
-			vcpu->arch.eff_db[i] = vcpu->arch.db[i];
-	}
-}
-
-void kvm_update_dr7(struct kvm_vcpu *vcpu)
-{
-	unsigned long dr7;
-
-	if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
-		dr7 = vcpu->arch.guest_debug_dr7;
-	else
-		dr7 = vcpu->arch.dr7;
-	kvm_x86_call(set_dr7)(vcpu, dr7);
-	vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_BP_ENABLED;
-	if (dr7 & DR7_BP_EN_MASK)
-		vcpu->arch.switch_db_regs |= KVM_DEBUGREG_BP_ENABLED;
-}
-EXPORT_SYMBOL_GPL(kvm_update_dr7);
-
-static u64 kvm_dr6_fixed(struct kvm_vcpu *vcpu)
-{
-	u64 fixed = DR6_FIXED_1;
-
-	if (!guest_cpuid_has(vcpu, X86_FEATURE_RTM))
-		fixed |= DR6_RTM;
-
-	if (!guest_cpuid_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT))
-		fixed |= DR6_BUS_LOCK;
-	return fixed;
-}
-
-int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val)
-{
-	size_t size = ARRAY_SIZE(vcpu->arch.db);
-
-	switch (dr) {
-	case 0 ... 3:
-		vcpu->arch.db[array_index_nospec(dr, size)] = val;
-		if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
-			vcpu->arch.eff_db[dr] = val;
-		break;
-	case 4:
-	case 6:
-		if (!kvm_dr6_valid(val))
-			return 1; /* #GP */
-		vcpu->arch.dr6 = (val & DR6_VOLATILE) | kvm_dr6_fixed(vcpu);
-		break;
-	case 5:
-	default: /* 7 */
-		if (!kvm_dr7_valid(val))
-			return 1; /* #GP */
-		vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1;
-		kvm_update_dr7(vcpu);
-		break;
-	}
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(kvm_set_dr);
-
-unsigned long kvm_get_dr(struct kvm_vcpu *vcpu, int dr)
-{
-	size_t size = ARRAY_SIZE(vcpu->arch.db);
-
-	switch (dr) {
-	case 0 ... 3:
-		return vcpu->arch.db[array_index_nospec(dr, size)];
-	case 4:
-	case 6:
-		return vcpu->arch.dr6;
-	case 5:
-	default: /* 7 */
-		return vcpu->arch.dr7;
-	}
-}
-EXPORT_SYMBOL_GPL(kvm_get_dr);
-
 int kvm_emulate_rdpmc(struct kvm_vcpu *vcpu)
 {
 	u32 ecx = kvm_rcx_read(vcpu);
@@ -5344,7 +4938,7 @@ static struct kvm_queued_exception *kvm_
 	return &vcpu->arch.exception;
 }
 
-static void kvm_handle_exception_payload_quirk(struct kvm_vcpu *vcpu)
+void kvm_handle_exception_payload_quirk(struct kvm_vcpu *vcpu)
 {
 	struct kvm_queued_exception *ex = kvm_get_exception_to_save(vcpu);
 
@@ -5554,56 +5148,6 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_e
 	return 0;
 }
 
-static int kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu,
-					    struct kvm_debugregs *dbgregs)
-{
-	unsigned int i;
-
-	if (vcpu->kvm->arch.has_protected_state &&
-	    vcpu->arch.guest_state_protected)
-		return -EINVAL;
-
-	kvm_handle_exception_payload_quirk(vcpu);
-
-	memset(dbgregs, 0, sizeof(*dbgregs));
-
-	BUILD_BUG_ON(ARRAY_SIZE(vcpu->arch.db) != ARRAY_SIZE(dbgregs->db));
-	for (i = 0; i < ARRAY_SIZE(vcpu->arch.db); i++)
-		dbgregs->db[i] = vcpu->arch.db[i];
-
-	dbgregs->dr6 = vcpu->arch.dr6;
-	dbgregs->dr7 = vcpu->arch.dr7;
-	return 0;
-}
-
-static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
-					    struct kvm_debugregs *dbgregs)
-{
-	unsigned int i;
-
-	if (vcpu->kvm->arch.has_protected_state &&
-	    vcpu->arch.guest_state_protected)
-		return -EINVAL;
-
-	if (dbgregs->flags)
-		return -EINVAL;
-
-	if (!kvm_dr6_valid(dbgregs->dr6))
-		return -EINVAL;
-	if (!kvm_dr7_valid(dbgregs->dr7))
-		return -EINVAL;
-
-	for (i = 0; i < ARRAY_SIZE(vcpu->arch.db); i++)
-		vcpu->arch.db[i] = dbgregs->db[i];
-
-	kvm_update_dr0123(vcpu);
-	vcpu->arch.dr6 = dbgregs->dr6;
-	vcpu->arch.dr7 = dbgregs->dr7;
-	kvm_update_dr7(vcpu);
-
-	return 0;
-}
-
 
 static int kvm_vcpu_ioctl_x86_get_xsave2(struct kvm_vcpu *vcpu,
 					 u8 *state, unsigned int size)
@@ -8274,11 +7818,6 @@ static int emulator_pio_out_emulated(str
 	return emulator_pio_out(emul_to_vcpu(ctxt), size, port, val, count);
 }
 
-static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
-{
-	return kvm_x86_call(get_segment_base)(vcpu, seg);
-}
-
 static void emulator_invlpg(struct x86_emulate_ctxt *ctxt, ulong address)
 {
 	kvm_mmu_invlpg(emul_to_vcpu(ctxt), address);
@@ -10249,7 +9788,7 @@ static void post_kvm_run_save(struct kvm
 		kvm_run->flags |= KVM_RUN_X86_GUEST_MODE;
 }
 
-static void update_cr8_intercept(struct kvm_vcpu *vcpu)
+void update_cr8_intercept(struct kvm_vcpu *vcpu)
 {
 	int max_irr, tpr;
 
@@ -11705,180 +11244,6 @@ out:
 	return r;
 }
 
-static void __get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
-{
-	if (vcpu->arch.emulate_regs_need_sync_to_vcpu) {
-		/*
-		 * We are here if userspace calls get_regs() in the middle of
-		 * instruction emulation. Registers state needs to be copied
-		 * back from emulation context to vcpu. Userspace shouldn't do
-		 * that usually, but some bad designed PV devices (vmware
-		 * backdoor interface) need this to work
-		 */
-		emulator_writeback_register_cache(vcpu->arch.emulate_ctxt);
-		vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
-	}
-	regs->rax = kvm_rax_read(vcpu);
-	regs->rbx = kvm_rbx_read(vcpu);
-	regs->rcx = kvm_rcx_read(vcpu);
-	regs->rdx = kvm_rdx_read(vcpu);
-	regs->rsi = kvm_rsi_read(vcpu);
-	regs->rdi = kvm_rdi_read(vcpu);
-	regs->rsp = kvm_rsp_read(vcpu);
-	regs->rbp = kvm_rbp_read(vcpu);
-#ifdef CONFIG_X86_64
-	regs->r8 = kvm_r8_read(vcpu);
-	regs->r9 = kvm_r9_read(vcpu);
-	regs->r10 = kvm_r10_read(vcpu);
-	regs->r11 = kvm_r11_read(vcpu);
-	regs->r12 = kvm_r12_read(vcpu);
-	regs->r13 = kvm_r13_read(vcpu);
-	regs->r14 = kvm_r14_read(vcpu);
-	regs->r15 = kvm_r15_read(vcpu);
-#endif
-
-	regs->rip = kvm_rip_read(vcpu);
-	regs->rflags = kvm_get_rflags(vcpu);
-}
-
-int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
-{
-	if (vcpu->kvm->arch.has_protected_state &&
-	    vcpu->arch.guest_state_protected)
-		return -EINVAL;
-
-	vcpu_load(vcpu);
-	__get_regs(vcpu, regs);
-	vcpu_put(vcpu);
-	return 0;
-}
-
-static void __set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
-{
-	vcpu->arch.emulate_regs_need_sync_from_vcpu = true;
-	vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
-
-	kvm_rax_write(vcpu, regs->rax);
-	kvm_rbx_write(vcpu, regs->rbx);
-	kvm_rcx_write(vcpu, regs->rcx);
-	kvm_rdx_write(vcpu, regs->rdx);
-	kvm_rsi_write(vcpu, regs->rsi);
-	kvm_rdi_write(vcpu, regs->rdi);
-	kvm_rsp_write(vcpu, regs->rsp);
-	kvm_rbp_write(vcpu, regs->rbp);
-#ifdef CONFIG_X86_64
-	kvm_r8_write(vcpu, regs->r8);
-	kvm_r9_write(vcpu, regs->r9);
-	kvm_r10_write(vcpu, regs->r10);
-	kvm_r11_write(vcpu, regs->r11);
-	kvm_r12_write(vcpu, regs->r12);
-	kvm_r13_write(vcpu, regs->r13);
-	kvm_r14_write(vcpu, regs->r14);
-	kvm_r15_write(vcpu, regs->r15);
-#endif
-
-	kvm_rip_write(vcpu, regs->rip);
-	kvm_set_rflags(vcpu, regs->rflags | X86_EFLAGS_FIXED);
-
-	vcpu->arch.exception.pending = false;
-	vcpu->arch.exception_vmexit.pending = false;
-
-	kvm_make_request(KVM_REQ_EVENT, vcpu);
-}
-
-int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
-{
-	if (vcpu->kvm->arch.has_protected_state &&
-	    vcpu->arch.guest_state_protected)
-		return -EINVAL;
-
-	vcpu_load(vcpu);
-	__set_regs(vcpu, regs);
-	vcpu_put(vcpu);
-	return 0;
-}
-
-static void __get_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
-{
-	struct desc_ptr dt;
-
-	if (vcpu->arch.guest_state_protected)
-		goto skip_protected_regs;
-
-	kvm_handle_exception_payload_quirk(vcpu);
-
-	kvm_get_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
-	kvm_get_segment(vcpu, &sregs->ds, VCPU_SREG_DS);
-	kvm_get_segment(vcpu, &sregs->es, VCPU_SREG_ES);
-	kvm_get_segment(vcpu, &sregs->fs, VCPU_SREG_FS);
-	kvm_get_segment(vcpu, &sregs->gs, VCPU_SREG_GS);
-	kvm_get_segment(vcpu, &sregs->ss, VCPU_SREG_SS);
-
-	kvm_get_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
-	kvm_get_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
-
-	kvm_x86_call(get_idt)(vcpu, &dt);
-	sregs->idt.limit = dt.size;
-	sregs->idt.base = dt.address;
-	kvm_x86_call(get_gdt)(vcpu, &dt);
-	sregs->gdt.limit = dt.size;
-	sregs->gdt.base = dt.address;
-
-	sregs->cr2 = vcpu->arch.cr2;
-	sregs->cr3 = kvm_read_cr3(vcpu);
-
-skip_protected_regs:
-	sregs->cr0 = kvm_read_cr0(vcpu);
-	sregs->cr4 = kvm_read_cr4(vcpu);
-	sregs->cr8 = kvm_get_cr8(vcpu);
-	sregs->efer = vcpu->arch.efer;
-	sregs->apic_base = vcpu->arch.apic_base;
-}
-
-static void __get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
-{
-	__get_sregs_common(vcpu, sregs);
-
-	if (vcpu->arch.guest_state_protected)
-		return;
-
-	if (vcpu->arch.interrupt.injected && !vcpu->arch.interrupt.soft)
-		set_bit(vcpu->arch.interrupt.nr,
-			(unsigned long *)sregs->interrupt_bitmap);
-}
-
-static void kvm_vcpu_ioctl_x86_get_sregs2(struct kvm_vcpu *vcpu,
-					  struct kvm_sregs2 *sregs2)
-{
-	int i;
-
-	__get_sregs_common(vcpu, (struct kvm_sregs *)sregs2);
-
-	if (vcpu->arch.guest_state_protected)
-		return;
-
-	if (is_pae_paging(vcpu)) {
-		kvm_vcpu_srcu_read_lock(vcpu);
-		for (i = 0 ; i < 4 ; i++)
-			sregs2->pdptrs[i] = kvm_pdptr_read(vcpu, i);
-		sregs2->flags |= KVM_SREGS2_FLAGS_PDPTRS_VALID;
-		kvm_vcpu_srcu_read_unlock(vcpu);
-	}
-}
-
-int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
-				  struct kvm_sregs *sregs)
-{
-	if (vcpu->kvm->arch.has_protected_state &&
-	    vcpu->arch.guest_state_protected)
-		return -EINVAL;
-
-	vcpu_load(vcpu);
-	__get_sregs(vcpu, sregs);
-	vcpu_put(vcpu);
-	return 0;
-}
-
 int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
 				    struct kvm_mp_state *mp_state)
 {
@@ -11988,179 +11353,6 @@ int kvm_task_switch(struct kvm_vcpu *vcp
 }
 EXPORT_SYMBOL_GPL(kvm_task_switch);
 
-static bool kvm_is_valid_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
-{
-	if ((sregs->efer & EFER_LME) && (sregs->cr0 & X86_CR0_PG)) {
-		/*
-		 * When EFER.LME and CR0.PG are set, the processor is in
-		 * 64-bit mode (though maybe in a 32-bit code segment).
-		 * CR4.PAE and EFER.LMA must be set.
-		 */
-		if (!(sregs->cr4 & X86_CR4_PAE) || !(sregs->efer & EFER_LMA))
-			return false;
-		if (!kvm_vcpu_is_legal_cr3(vcpu, sregs->cr3))
-			return false;
-	} else {
-		/*
-		 * Not in 64-bit mode: EFER.LMA is clear and the code
-		 * segment cannot be 64-bit.
-		 */
-		if (sregs->efer & EFER_LMA || sregs->cs.l)
-			return false;
-	}
-
-	return kvm_is_valid_cr4(vcpu, sregs->cr4) &&
-	       kvm_is_valid_cr0(vcpu, sregs->cr0);
-}
-
-static int __set_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs,
-		int *mmu_reset_needed, bool update_pdptrs)
-{
-	struct msr_data apic_base_msr;
-	int idx;
-	struct desc_ptr dt;
-
-	if (!kvm_is_valid_sregs(vcpu, sregs))
-		return -EINVAL;
-
-	apic_base_msr.data = sregs->apic_base;
-	apic_base_msr.host_initiated = true;
-	if (kvm_set_apic_base(vcpu, &apic_base_msr))
-		return -EINVAL;
-
-	if (vcpu->arch.guest_state_protected)
-		return 0;
-
-	dt.size = sregs->idt.limit;
-	dt.address = sregs->idt.base;
-	kvm_x86_call(set_idt)(vcpu, &dt);
-	dt.size = sregs->gdt.limit;
-	dt.address = sregs->gdt.base;
-	kvm_x86_call(set_gdt)(vcpu, &dt);
-
-	vcpu->arch.cr2 = sregs->cr2;
-	*mmu_reset_needed |= kvm_read_cr3(vcpu) != sregs->cr3;
-	vcpu->arch.cr3 = sregs->cr3;
-	kvm_register_mark_dirty(vcpu, VCPU_EXREG_CR3);
-	kvm_x86_call(post_set_cr3)(vcpu, sregs->cr3);
-
-	kvm_set_cr8(vcpu, sregs->cr8);
-
-	*mmu_reset_needed |= vcpu->arch.efer != sregs->efer;
-	kvm_x86_call(set_efer)(vcpu, sregs->efer);
-
-	*mmu_reset_needed |= kvm_read_cr0(vcpu) != sregs->cr0;
-	kvm_x86_call(set_cr0)(vcpu, sregs->cr0);
-
-	*mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4;
-	kvm_x86_call(set_cr4)(vcpu, sregs->cr4);
-
-	if (update_pdptrs) {
-		idx = srcu_read_lock(&vcpu->kvm->srcu);
-		if (is_pae_paging(vcpu)) {
-			load_pdptrs(vcpu, kvm_read_cr3(vcpu));
-			*mmu_reset_needed = 1;
-		}
-		srcu_read_unlock(&vcpu->kvm->srcu, idx);
-	}
-
-	kvm_set_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
-	kvm_set_segment(vcpu, &sregs->ds, VCPU_SREG_DS);
-	kvm_set_segment(vcpu, &sregs->es, VCPU_SREG_ES);
-	kvm_set_segment(vcpu, &sregs->fs, VCPU_SREG_FS);
-	kvm_set_segment(vcpu, &sregs->gs, VCPU_SREG_GS);
-	kvm_set_segment(vcpu, &sregs->ss, VCPU_SREG_SS);
-
-	kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
-	kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
-
-	update_cr8_intercept(vcpu);
-
-	/* Older userspace won't unhalt the vcpu on reset. */
-	if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 &&
-	    sregs->cs.selector == 0xf000 && sregs->cs.base == 0xffff0000 &&
-	    !is_protmode(vcpu))
-		vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
-
-	return 0;
-}
-
-static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
-{
-	int pending_vec, max_bits;
-	int mmu_reset_needed = 0;
-	int ret = __set_sregs_common(vcpu, sregs, &mmu_reset_needed, true);
-
-	if (ret)
-		return ret;
-
-	if (mmu_reset_needed) {
-		kvm_mmu_reset_context(vcpu);
-		kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
-	}
-
-	max_bits = KVM_NR_INTERRUPTS;
-	pending_vec = find_first_bit(
-		(const unsigned long *)sregs->interrupt_bitmap, max_bits);
-
-	if (pending_vec < max_bits) {
-		kvm_queue_interrupt(vcpu, pending_vec, false);
-		pr_debug("Set back pending irq %d\n", pending_vec);
-		kvm_make_request(KVM_REQ_EVENT, vcpu);
-	}
-	return 0;
-}
-
-static int kvm_vcpu_ioctl_x86_set_sregs2(struct kvm_vcpu *vcpu,
-					 struct kvm_sregs2 *sregs2)
-{
-	int mmu_reset_needed = 0;
-	bool valid_pdptrs = sregs2->flags & KVM_SREGS2_FLAGS_PDPTRS_VALID;
-	bool pae = (sregs2->cr0 & X86_CR0_PG) && (sregs2->cr4 & X86_CR4_PAE) &&
-		!(sregs2->efer & EFER_LMA);
-	int i, ret;
-
-	if (sregs2->flags & ~KVM_SREGS2_FLAGS_PDPTRS_VALID)
-		return -EINVAL;
-
-	if (valid_pdptrs && (!pae || vcpu->arch.guest_state_protected))
-		return -EINVAL;
-
-	ret = __set_sregs_common(vcpu, (struct kvm_sregs *)sregs2,
-				 &mmu_reset_needed, !valid_pdptrs);
-	if (ret)
-		return ret;
-
-	if (valid_pdptrs) {
-		for (i = 0; i < 4 ; i++)
-			kvm_pdptr_write(vcpu, i, sregs2->pdptrs[i]);
-
-		kvm_register_mark_dirty(vcpu, VCPU_EXREG_PDPTR);
-		mmu_reset_needed = 1;
-		vcpu->arch.pdptrs_from_userspace = true;
-	}
-	if (mmu_reset_needed) {
-		kvm_mmu_reset_context(vcpu);
-		kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
-	}
-	return 0;
-}
-
-int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
-				  struct kvm_sregs *sregs)
-{
-	int ret;
-
-	if (vcpu->kvm->arch.has_protected_state &&
-	    vcpu->arch.guest_state_protected)
-		return -EINVAL;
-
-	vcpu_load(vcpu);
-	ret = __set_sregs(vcpu, sregs);
-	vcpu_put(vcpu);
-	return ret;
-}
-
 static void kvm_arch_vcpu_guestdbg_update_apicv_inhibit(struct kvm *kvm)
 {
 	bool set = false;
@@ -12314,17 +11506,6 @@ int kvm_arch_vcpu_ioctl_set_fpu(struct k
 	return 0;
 }
 
-static void kvm_run_sync_regs_to_user(struct kvm_vcpu *vcpu)
-{
-	BUILD_BUG_ON(sizeof(struct kvm_sync_regs) > SYNC_REGS_SIZE_BYTES);
-
-	if (vcpu->run->kvm_valid_regs & KVM_SYNC_X86_REGS)
-		__get_regs(vcpu, &vcpu->run->s.regs.regs);
-
-	if (vcpu->run->kvm_valid_regs & KVM_SYNC_X86_SREGS)
-		__get_sregs(vcpu, &vcpu->run->s.regs.sregs);
-}
-
 static void store_regs(struct kvm_vcpu *vcpu)
 {
 	kvm_run_sync_regs_to_user(vcpu);
@@ -12334,25 +11515,6 @@ static void store_regs(struct kvm_vcpu *
 				vcpu, &vcpu->run->s.regs.events);
 }
 
-static int kvm_run_sync_regs_from_user(struct kvm_vcpu *vcpu)
-{
-	if (vcpu->run->kvm_dirty_regs & KVM_SYNC_X86_REGS) {
-		__set_regs(vcpu, &vcpu->run->s.regs.regs);
-		vcpu->run->kvm_dirty_regs &= ~KVM_SYNC_X86_REGS;
-	}
-
-	if (vcpu->run->kvm_dirty_regs & KVM_SYNC_X86_SREGS) {
-		struct kvm_sregs sregs = vcpu->run->s.regs.sregs;
-
-		if (__set_sregs(vcpu, &sregs))
-			return -EINVAL;
-
-		vcpu->run->kvm_dirty_regs &= ~KVM_SYNC_X86_SREGS;
-	}
-
-	return 0;
-}
-
 static int sync_regs(struct kvm_vcpu *vcpu)
 {
 	if (kvm_run_sync_regs_from_user(vcpu))
@@ -13390,51 +12552,6 @@ int kvm_arch_interrupt_allowed(struct kv
 	return kvm_x86_call(interrupt_allowed)(vcpu, false);
 }
 
-unsigned long kvm_get_linear_rip(struct kvm_vcpu *vcpu)
-{
-	/* Can't read the RIP when guest state is protected, just return 0 */
-	if (vcpu->arch.guest_state_protected)
-		return 0;
-
-	if (is_64_bit_mode(vcpu))
-		return kvm_rip_read(vcpu);
-	return (u32)(get_segment_base(vcpu, VCPU_SREG_CS) +
-		     kvm_rip_read(vcpu));
-}
-EXPORT_SYMBOL_GPL(kvm_get_linear_rip);
-
-bool kvm_is_linear_rip(struct kvm_vcpu *vcpu, unsigned long linear_rip)
-{
-	return kvm_get_linear_rip(vcpu) == linear_rip;
-}
-EXPORT_SYMBOL_GPL(kvm_is_linear_rip);
-
-unsigned long kvm_get_rflags(struct kvm_vcpu *vcpu)
-{
-	unsigned long rflags;
-
-	rflags = kvm_x86_call(get_rflags)(vcpu);
-	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
-		rflags &= ~X86_EFLAGS_TF;
-	return rflags;
-}
-EXPORT_SYMBOL_GPL(kvm_get_rflags);
-
-static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
-{
-	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP &&
-	    kvm_is_linear_rip(vcpu, vcpu->arch.singlestep_rip))
-		rflags |= X86_EFLAGS_TF;
-	kvm_x86_call(set_rflags)(vcpu, rflags);
-}
-
-void kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
-{
-	__kvm_set_rflags(vcpu, rflags);
-	kvm_make_request(KVM_REQ_EVENT, vcpu);
-}
-EXPORT_SYMBOL_GPL(kvm_set_rflags);
-
 static inline u32 kvm_async_pf_hash_fn(gfn_t gfn)
 {
 	BUILD_BUG_ON(!is_power_of_2(ASYNC_PF_PER_VCPU));
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -615,4 +615,32 @@ int kvm_sev_es_string_io(struct kvm_vcpu
 			 unsigned int port, void *data,  unsigned int count,
 			 int in);
 
+static inline bool kvm_pv_async_pf_enabled(struct kvm_vcpu *vcpu)
+{
+	u64 mask = KVM_ASYNC_PF_ENABLED | KVM_ASYNC_PF_DELIVERY_AS_INT;
+
+	return (vcpu->arch.apf.msr_en_val & mask) == mask;
+}
+
+static inline unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
+{
+	return kvm_x86_call(get_segment_base)(vcpu, seg);
+}
+
+void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
+void kvm_vcpu_ioctl_x86_get_sregs2(struct kvm_vcpu *vcpu,
+				   struct kvm_sregs2 *sregs2);
+int kvm_vcpu_ioctl_x86_set_sregs2(struct kvm_vcpu *vcpu,
+				  struct kvm_sregs2 *sregs2);
+void kvm_run_sync_regs_to_user(struct kvm_vcpu *vcpu);
+int kvm_run_sync_regs_from_user(struct kvm_vcpu *vcpu);
+void kvm_update_dr0123(struct kvm_vcpu *vcpu);
+int kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu,
+				     struct kvm_debugregs *dbgregs);
+int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
+				     struct kvm_debugregs *dbgregs);
+void kvm_invalidate_pcid(struct kvm_vcpu *vcpu, unsigned long pcid);
+void kvm_handle_exception_payload_quirk(struct kvm_vcpu *vcpu);
+void update_cr8_intercept(struct kvm_vcpu *vcpu);
+
 #endif



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 665/877] KVM: x86: Check EFER validity on KVM_SET_SREGS*
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (663 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 664/877] KVM: x86: Move the bulk of register specific code from x86.c to regs.c Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 666/877] media: i2c: imx355: Replace client->dev usage Greg Kroah-Hartman
                   ` (219 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yosry Ahmed, Sean Christopherson,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Yosry Ahmed <yosry@kernel.org>

[ Upstream commit 184bd464bdb66daa9173670904f24c29c7b7f7d4 ]

When handling userspace SREGS writes, check the validity of EFER (i.e.
allowed bits) before writing the new value of EFER through the
per-vendor set_efer callbacks. This prevents userspace from writing
bogus values (e.g. EFER.SVME=1 with nested=0).

Note: on KVM_SET_MSRS, KVM only checks EFER validity in terms of KVM
caps, not guest caps, so it is possible to set EFER bits that are
supported by KVM but not by the guest CPUID. Potentially allowing
userspace to set msrs before CPUID.

However, for KVM_SET_SREGS*, check the validity of the set bits against
both KVM and guest caps. This is consistent with other validity checks
(e.g. for CR4) that check validity against guest caps, which already
imposes the need to set CPUID before SREGS.

Cc: stable@vger.kernel.org
Signed-off-by: Yosry Ahmed <yosry@kernel.org>
Link: https://patch.msgid.link/20260713180153.2728382-2-yosry@kernel.org
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/kvm/regs.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/arch/x86/kvm/regs.c
+++ b/arch/x86/kvm/regs.c
@@ -556,7 +556,8 @@ static bool kvm_is_valid_sregs(struct kv
 	}
 
 	return kvm_is_valid_cr4(vcpu, sregs->cr4) &&
-	       kvm_is_valid_cr0(vcpu, sregs->cr0);
+	       kvm_is_valid_cr0(vcpu, sregs->cr0) &&
+	       kvm_valid_efer(vcpu, sregs->efer);
 }
 
 static int __set_sregs_common(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 666/877] media: i2c: imx355: Replace client->dev usage
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (664 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 665/877] KVM: x86: Check EFER validity on KVM_SET_SREGS* Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 667/877] media: imx355: Avoid calling imx355_power_off twice in error path Greg Kroah-Hartman
                   ` (218 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Laurent Pinchart, Sakari Ailus,
	Mehdi Djait, Hans Verkuil, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

[ Upstream commit 49c6ac166cf77cd53eeda69e8ccdcbe4a57a4fdf ]

The driver needs to access the struct device in many places, and
retrieves it from the i2c_client itself retrieved with
v4l2_get_subdevdata(). Store it as a pointer in struct imx355 and access
it from there instead, to simplify the driver.

While at it, fix a mistake in the sort order of include statements.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Mehdi Djait <mehdi.djait@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Stable-dep-of: ee737bc3ccae ("media: imx355: Avoid calling imx355_power_off twice in error path")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/media/i2c/imx355.c |   61 ++++++++++++++++++++++-----------------------
 1 file changed, 30 insertions(+), 31 deletions(-)

--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -1,11 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0
 // Copyright (C) 2018 Intel Corporation
 
-#include <linux/unaligned.h>
 #include <linux/acpi.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
+#include <linux/unaligned.h>
+
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-event.h>
@@ -97,6 +98,8 @@ struct imx355_hwcfg {
 };
 
 struct imx355 {
+	struct device *dev;
+
 	struct v4l2_subdev sd;
 	struct media_pad pad;
 
@@ -1136,14 +1139,13 @@ static int imx355_write_reg(struct imx35
 static int imx355_write_regs(struct imx355 *imx355,
 			     const struct imx355_reg *regs, u32 len)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
 	int ret;
 	u32 i;
 
 	for (i = 0; i < len; i++) {
 		ret = imx355_write_reg(imx355, regs[i].address, 1, regs[i].val);
 		if (ret) {
-			dev_err_ratelimited(&client->dev,
+			dev_err_ratelimited(imx355->dev,
 					    "write reg 0x%4.4x return err %d",
 					    regs[i].address, ret);
 
@@ -1178,7 +1180,6 @@ static int imx355_set_ctrl(struct v4l2_c
 {
 	struct imx355 *imx355 = container_of(ctrl->handler,
 					     struct imx355, ctrl_handler);
-	struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
 	s64 max;
 	int ret;
 
@@ -1197,7 +1198,7 @@ static int imx355_set_ctrl(struct v4l2_c
 	 * Applying V4L2 control value only happens
 	 * when power is up for streaming
 	 */
-	if (!pm_runtime_get_if_in_use(&client->dev))
+	if (!pm_runtime_get_if_in_use(imx355->dev))
 		return 0;
 
 	switch (ctrl->id) {
@@ -1231,12 +1232,12 @@ static int imx355_set_ctrl(struct v4l2_c
 		break;
 	default:
 		ret = -EINVAL;
-		dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
+		dev_info(imx355->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
 			 ctrl->id, ctrl->val);
 		break;
 	}
 
-	pm_runtime_put(&client->dev);
+	pm_runtime_put(imx355->dev);
 
 	return ret;
 }
@@ -1385,7 +1386,6 @@ imx355_set_pad_format(struct v4l2_subdev
 /* Start streaming */
 static int imx355_start_streaming(struct imx355 *imx355)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
 	const struct imx355_reg_list *reg_list;
 	int ret;
 
@@ -1393,7 +1393,7 @@ static int imx355_start_streaming(struct
 	reg_list = &imx355_global_setting;
 	ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
 	if (ret) {
-		dev_err(&client->dev, "failed to set global settings");
+		dev_err(imx355->dev, "failed to set global settings");
 		return ret;
 	}
 
@@ -1401,7 +1401,7 @@ static int imx355_start_streaming(struct
 	reg_list = &imx355->cur_mode->reg_list;
 	ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
 	if (ret) {
-		dev_err(&client->dev, "failed to set mode");
+		dev_err(imx355->dev, "failed to set mode");
 		return ret;
 	}
 
@@ -1429,13 +1429,12 @@ static int imx355_stop_streaming(struct
 static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
 {
 	struct imx355 *imx355 = to_imx355(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 	int ret = 0;
 
 	mutex_lock(&imx355->mutex);
 
 	if (enable) {
-		ret = pm_runtime_resume_and_get(&client->dev);
+		ret = pm_runtime_resume_and_get(imx355->dev);
 		if (ret < 0)
 			goto err_unlock;
 
@@ -1448,7 +1447,7 @@ static int imx355_set_stream(struct v4l2
 			goto err_rpm_put;
 	} else {
 		imx355_stop_streaming(imx355);
-		pm_runtime_put(&client->dev);
+		pm_runtime_put(imx355->dev);
 	}
 
 	/* vflip and hflip cannot change during streaming */
@@ -1460,7 +1459,7 @@ static int imx355_set_stream(struct v4l2
 	return ret;
 
 err_rpm_put:
-	pm_runtime_put(&client->dev);
+	pm_runtime_put(imx355->dev);
 err_unlock:
 	mutex_unlock(&imx355->mutex);
 
@@ -1470,7 +1469,6 @@ err_unlock:
 /* Verify chip ID */
 static int imx355_identify_module(struct imx355 *imx355)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
 	int ret;
 	u32 val;
 
@@ -1479,7 +1477,7 @@ static int imx355_identify_module(struct
 		return ret;
 
 	if (val != IMX355_CHIP_ID) {
-		dev_err(&client->dev, "chip id mismatch: %x!=%x",
+		dev_err(imx355->dev, "chip id mismatch: %x!=%x",
 			IMX355_CHIP_ID, val);
 		return -EIO;
 	}
@@ -1519,7 +1517,6 @@ static const struct v4l2_subdev_internal
 /* Initialize control handlers */
 static int imx355_init_controls(struct imx355 *imx355)
 {
-	struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
 	struct v4l2_fwnode_device_properties props;
 	struct v4l2_ctrl_handler *ctrl_hdlr;
 	s64 exposure_max;
@@ -1600,11 +1597,11 @@ static int imx355_init_controls(struct i
 				     0, 0, imx355_test_pattern_menu);
 	if (ctrl_hdlr->error) {
 		ret = ctrl_hdlr->error;
-		dev_err(&client->dev, "control init failed: %d", ret);
+		dev_err(imx355->dev, "control init failed: %d", ret);
 		goto error;
 	}
 
-	ret = v4l2_fwnode_device_parse(&client->dev, &props);
+	ret = v4l2_fwnode_device_parse(imx355->dev, &props);
 	if (ret)
 		goto error;
 
@@ -1689,6 +1686,8 @@ static int imx355_probe(struct i2c_clien
 	if (!imx355)
 		return -ENOMEM;
 
+	imx355->dev = &client->dev;
+
 	mutex_init(&imx355->mutex);
 
 	/* Initialize subdev */
@@ -1697,13 +1696,13 @@ static int imx355_probe(struct i2c_clien
 	/* Check module identity */
 	ret = imx355_identify_module(imx355);
 	if (ret) {
-		dev_err(&client->dev, "failed to find sensor: %d", ret);
+		dev_err(imx355->dev, "failed to find sensor: %d", ret);
 		goto error_probe;
 	}
 
-	imx355->hwcfg = imx355_get_hwcfg(&client->dev);
+	imx355->hwcfg = imx355_get_hwcfg(imx355->dev);
 	if (!imx355->hwcfg) {
-		dev_err(&client->dev, "failed to get hwcfg");
+		dev_err(imx355->dev, "failed to get hwcfg");
 		ret = -ENODEV;
 		goto error_probe;
 	}
@@ -1713,7 +1712,7 @@ static int imx355_probe(struct i2c_clien
 
 	ret = imx355_init_controls(imx355);
 	if (ret) {
-		dev_err(&client->dev, "failed to init controls: %d", ret);
+		dev_err(imx355->dev, "failed to init controls: %d", ret);
 		goto error_probe;
 	}
 
@@ -1728,7 +1727,7 @@ static int imx355_probe(struct i2c_clien
 	imx355->pad.flags = MEDIA_PAD_FL_SOURCE;
 	ret = media_entity_pads_init(&imx355->sd.entity, 1, &imx355->pad);
 	if (ret) {
-		dev_err(&client->dev, "failed to init entity pads: %d", ret);
+		dev_err(imx355->dev, "failed to init entity pads: %d", ret);
 		goto error_handler_free;
 	}
 
@@ -1736,9 +1735,9 @@ static int imx355_probe(struct i2c_clien
 	 * Device is already turned on by i2c-core with ACPI domain PM.
 	 * Enable runtime PM and turn off the device.
 	 */
-	pm_runtime_set_active(&client->dev);
-	pm_runtime_enable(&client->dev);
-	pm_runtime_idle(&client->dev);
+	pm_runtime_set_active(imx355->dev);
+	pm_runtime_enable(imx355->dev);
+	pm_runtime_idle(imx355->dev);
 
 	ret = v4l2_async_register_subdev_sensor(&imx355->sd);
 	if (ret < 0)
@@ -1747,8 +1746,8 @@ static int imx355_probe(struct i2c_clien
 	return 0;
 
 error_media_entity_runtime_pm:
-	pm_runtime_disable(&client->dev);
-	pm_runtime_set_suspended(&client->dev);
+	pm_runtime_disable(imx355->dev);
+	pm_runtime_set_suspended(imx355->dev);
 	media_entity_cleanup(&imx355->sd.entity);
 
 error_handler_free:
@@ -1769,8 +1768,8 @@ static void imx355_remove(struct i2c_cli
 	media_entity_cleanup(&sd->entity);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
 
-	pm_runtime_disable(&client->dev);
-	pm_runtime_set_suspended(&client->dev);
+	pm_runtime_disable(imx355->dev);
+	pm_runtime_set_suspended(imx355->dev);
 
 	mutex_destroy(&imx355->mutex);
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 667/877] media: imx355: Avoid calling imx355_power_off twice in error path
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (665 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 666/877] media: i2c: imx355: Replace client->dev usage Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 668/877] media: rkvdec: Propagate platform_get_irq() errors Greg Kroah-Hartman
                   ` (217 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Dave Stevenson, Sakari Ailus,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dave Stevenson <dave.stevenson@raspberrypi.com>

[ Upstream commit ee737bc3ccae7dc713ccaa83ffa46080c6031b3e ]

If v4l2_async_register_subdev_sensor failed, then the sensor had
already been powered down by pm_runtime_idle, but the error path
then also explicitly called imx355_power_off as well. That left
an imbalance in the regulator and clock calls.

Call pm_runtime_idle only after v4l2_async_register_subdev_sensor
succeeds to avoid this.

Fixes: efa5fe19c0a9 ("media: imx355: Enable runtime PM before registering async sub-device")
Cc: stable@vger.kernel.org
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/media/i2c/imx355.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -1737,12 +1737,13 @@ static int imx355_probe(struct i2c_clien
 	 */
 	pm_runtime_set_active(imx355->dev);
 	pm_runtime_enable(imx355->dev);
-	pm_runtime_idle(imx355->dev);
 
 	ret = v4l2_async_register_subdev_sensor(&imx355->sd);
 	if (ret < 0)
 		goto error_media_entity_runtime_pm;
 
+	pm_runtime_idle(imx355->dev);
+
 	return 0;
 
 error_media_entity_runtime_pm:



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 668/877] media: rkvdec: Propagate platform_get_irq() errors
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (666 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 667/877] media: imx355: Avoid calling imx355_power_off twice in error path Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 669/877] KVM: s390: Zero initialize data structures for inject_pfault_token Greg Kroah-Hartman
                   ` (216 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Narasimharao Vadlamudi,
	Detlev Casanova, Nicolas Dufresne, Hans Verkuil, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Narasimharao Vadlamudi <ahmisaranrao@gmail.com>

[ Upstream commit c37aca64206fafe938119e801a3fd10a537a051f ]

platform_get_irq() returns a positive IRQ number on success and a
negative error code on failure. It no longer returns zero. The driver
currently returns -ENXIO for all failures, which loses useful errors
such as -EPROBE_DEFER.

Return the error from platform_get_irq() directly.

Fixes: cd33c830448b ("media: rkvdec: Add the rkvdec driver")
Cc: stable@vger.kernel.org
Signed-off-by: Narasimharao Vadlamudi <ahmisaranrao@gmail.com>
Reviewed-by: Detlev Casanova <detlev.casanova@collabora.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
[ adjusted the patch path to drivers/staging/media/rkvdec/rkvdec.c. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/staging/media/rkvdec/rkvdec.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/staging/media/rkvdec/rkvdec.c
+++ b/drivers/staging/media/rkvdec/rkvdec.c
@@ -1044,8 +1044,8 @@ static int rkvdec_probe(struct platform_
 	vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
 
 	irq = platform_get_irq(pdev, 0);
-	if (irq <= 0)
-		return -ENXIO;
+	if (irq < 0)
+		return irq;
 
 	ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
 					rkvdec_irq_handler, IRQF_ONESHOT,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 669/877] KVM: s390: Zero initialize data structures for inject_pfault_token
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (667 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 668/877] media: rkvdec: Propagate platform_get_irq() errors Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 670/877] KVM: x86: Disallow EFER.LME and EFER.LMA if long mode is not supported Greg Kroah-Hartman
                   ` (215 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Christian Borntraeger,
	Matthew Rosato, Claudio Imbrenda, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Christian Borntraeger <borntraeger@linux.ibm.com>

[ Upstream commit 4e2c7f7cbc27418f9a290399b986c1b85ff93b90 ]

__kvm_inject_pfault_token() only sets .type and .u.ext.ext_params2 of
the on-stack struct kvm_s390_irq but the full ext substructure is copied
into the cpu local variable on inject. ext_params and pad contain stale
stack values.

Interrupt delivery only uses ext_params2, so nothing leaks to the guest,
but a host user can use the migration ioctls to get to the data.

Fix by zero-initializing the irq struct.
Do the same for the inti data structure.

Fixes: 383d0b050106 ("KVM: s390: handle pending local interrupts via bitmap")
Cc: stable@vger.kernel.org
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Message-ID: <20260805110455.7200-3-borntraeger@linux.ibm.com>
[ Adjusted context for missing inti_mem and ret declarations in __kvm_inject_pfault_token(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/s390/kvm/kvm-s390.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -4601,8 +4601,8 @@ long kvm_arch_fault_in_page(struct kvm_v
 static void __kvm_inject_pfault_token(struct kvm_vcpu *vcpu, bool start_token,
 				      unsigned long token)
 {
-	struct kvm_s390_interrupt inti;
-	struct kvm_s390_irq irq;
+	struct kvm_s390_interrupt inti = {};
+	struct kvm_s390_irq irq = {};
 
 	if (start_token) {
 		irq.u.ext.ext_params2 = token;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 670/877] KVM: x86: Disallow EFER.LME and EFER.LMA if long mode is not supported
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (668 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 669/877] KVM: s390: Zero initialize data structures for inject_pfault_token Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 671/877] scsi: qla2xxx: Zero dport diagnostics buffer to avoid info leak Greg Kroah-Hartman
                   ` (214 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yosry Ahmed, Sean Christopherson,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Yosry Ahmed <yosry@kernel.org>

[ Upstream commit e62392bf39ebfdf60d1d082799397fe1cbf8dfc5 ]

Remove EFER.LME and EFER.LMA from EFER reserved bits only if long mode
is actually supported. KVM does check long-mode support before allowing
the bits for guest writes and userspace writes through KVM_SET_SREGS*
(in __kvm_valid_efer()), but userspace writes through KVM_SET_MSRS only
check reserved bits.

In practice, this doesn't really matter. The true motiviation is getting
rid of the #ifdeffery when initializing efer_reserved_bits.

Cc: stable@vger.kernel.org
Signed-off-by: Yosry Ahmed <yosry@kernel.org>
Link: https://patch.msgid.link/20260713181020.2735367-3-yosry@kernel.org
Signed-off-by: Sean Christopherson <seanjc@google.com>
[ adapted EFER changes to x86.c, placing the capability check in kvm_x86_vendor_init() because kvm_setup_efer_caps() is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/kvm/x86.c |   13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -108,16 +108,8 @@ EXPORT_SYMBOL_GPL(kvm_host);
 #define emul_to_vcpu(ctxt) \
 	((struct kvm_vcpu *)(ctxt)->vcpu)
 
-/* EFER defaults:
- * - enable syscall per default because its emulated by KVM
- * - enable LME and LMA per default on 64 bit KVM
- */
-#ifdef CONFIG_X86_64
-static
-u64 __read_mostly efer_reserved_bits = ~((u64)(EFER_SCE | EFER_LME | EFER_LMA));
-#else
+/* Enable syscall by default because its emulated by KVM */
 static u64 __read_mostly efer_reserved_bits = ~((u64)EFER_SCE);
-#endif
 
 static u64 __read_mostly cr4_reserved_bits = CR4_RESERVED_BITS;
 
@@ -9366,6 +9358,9 @@ int kvm_x86_vendor_init(struct kvm_x86_i
 	if (r != 0)
 		goto out_mmu_exit;
 
+	if (kvm_cpu_cap_has(X86_FEATURE_LM))
+		kvm_enable_efer_bits(EFER_LME | EFER_LMA);
+
 	kvm_ops_update(ops);
 
 	for_each_online_cpu(cpu) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 671/877] scsi: qla2xxx: Zero dport diagnostics buffer to avoid info leak
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (669 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 670/877] KVM: x86: Disallow EFER.LME and EFER.LMA if long mode is not supported Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 672/877] scsi: qla2xxx: Fix queue teardown NULL dma_free and bitmap locking Greg Kroah-Hartman
                   ` (213 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nilesh Javali, Hannes Reinecke,
	Martin K. Petersen (Oracle), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nilesh Javali <njavali@marvell.com>

[ Upstream commit a152edab3854f01dd2daf3eaf8f32cbabdb3834e ]

qla2x00_do_dport_diagnostics() allocates the qla_dport_diag response
buffer with kmalloc_obj() (non-zeroing) and, on success, copies the full
sizeof(*dd) back to user space via sg_copy_from_buffer(). The inbound
sg_copy_to_buffer() only fills as many bytes as the user request payload
provides, and qla26xx_dport_diagnostics() zeroes only dd->buf. The
options and unused[] fields are therefore copied out uninitialized,
leaking kernel heap contents to user space.

Allocate with kzalloc_obj(), matching qla2x00_do_dport_diagnostics_v2().

Fixes: ec89146215d1 ("qla2xxx: Add bsg interface to support D_Port Diagnostics.")
Cc: stable@vger.kernel.org
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-54-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ Adapted kzalloc_obj(*dd) to kzalloc(sizeof(*dd), GFP_KERNEL) to match the branch’s allocation syntax. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/qla2xxx/qla_bsg.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -2412,7 +2412,7 @@ qla2x00_do_dport_diagnostics(struct bsg_
 	    !IS_QLA28XX(vha->hw))
 		return -EPERM;
 
-	dd = kmalloc(sizeof(*dd), GFP_KERNEL);
+	dd = kzalloc(sizeof(*dd), GFP_KERNEL);
 	if (!dd) {
 		ql_log(ql_log_warn, vha, 0x70db,
 		    "Failed to allocate memory for dport.\n");



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 672/877] scsi: qla2xxx: Fix queue teardown NULL dma_free and bitmap locking
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (670 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 671/877] scsi: qla2xxx: Zero dport diagnostics buffer to avoid info leak Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 673/877] scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown Greg Kroah-Hartman
                   ` (212 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nilesh Javali, Hannes Reinecke,
	Martin K. Petersen (Oracle), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nilesh Javali <njavali@marvell.com>

[ Upstream commit 34a40e0dff940ac5eba494a69b553ea571e24873 ]

qla25xx_free_req_que() and qla25xx_free_rsp_que() have two pre-existing
bugs exposed on the error path of qla25xx_create_{req,rsp}_que():

 1. When dma_alloc_coherent() fails during queue creation, the error
    path calls the free function with req->ring / rsp->ring still NULL
    (from kzalloc).  The unconditional dma_free_coherent() with a NULL
    cpu_addr is undefined behavior and can panic.

 2. The free functions clear req_qid_map / rsp_qid_map under vport_lock,
    but the create functions protect the same bitmaps with mq_lock.
    This provides no mutual exclusion.  Additionally, the create error
    path clears the bit and releases mq_lock before calling the free
    function, creating a window where another thread can allocate the
    same que_id and have its ha->req_q_map entry clobbered by the
    subsequent lockless NULL assignment in the free function.

Fix by:

 - Guarding dma_free_coherent() with a NULL check on the ring pointer.

 - Using mq_lock (the lock held by all creators) in the free functions
   to atomically NULL the map entry and clear the bitmap bit.

 - Removing the now-redundant clear_bit blocks from the create error
   paths since the free functions handle it atomically.

Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-41-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>

Backport adaptation for the stable tree: the 29xx IOCB size-selection
helpers are absent, and queue creation still allocates fixed-size entries.
Initialize the local req_entry_size and rsp_entry_size values with
sizeof(request_t) and sizeof(response_t), respectively, so DMA freeing
continues to match allocation without adding helper functions or 29xx
support. Retain all NULL-ring guards, mq_lock protection, and removal of
the premature bitmap clears.

Keep the response-ring cleanup layout used by upstream so target commit
19788a55cab61d78e33e0914a5a31d27843e8a4a applies unchanged.

Stable-dep-of: 19788a55cab6 ("scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/qla2xxx/qla_mid.c |   29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -574,16 +574,19 @@ qla25xx_free_req_que(struct scsi_qla_hos
 {
 	struct qla_hw_data *ha = vha->hw;
 	uint16_t que_id = req->id;
+	size_t req_entry_size = sizeof(request_t);
 
-	dma_free_coherent(&ha->pdev->dev, (req->length + 1) *
-		sizeof(request_t), req->ring, req->dma);
+	if (req->ring)
+		dma_free_coherent(&ha->pdev->dev,
+				  (req->length + 1) * req_entry_size,
+				  req->ring, req->dma);
 	req->ring = NULL;
 	req->dma = 0;
 	if (que_id) {
+		mutex_lock(&ha->mq_lock);
 		ha->req_q_map[que_id] = NULL;
-		mutex_lock(&ha->vport_lock);
 		clear_bit(que_id, ha->req_qid_map);
-		mutex_unlock(&ha->vport_lock);
+		mutex_unlock(&ha->mq_lock);
 	}
 	kfree(req->outstanding_cmds);
 	kfree(req);
@@ -594,6 +597,7 @@ qla25xx_free_rsp_que(struct scsi_qla_hos
 {
 	struct qla_hw_data *ha = vha->hw;
 	uint16_t que_id = rsp->id;
+	size_t rsp_entry_size = sizeof(response_t);
 
 	if (rsp->msix && rsp->msix->have_irq) {
 		free_irq(rsp->msix->vector, rsp->msix->handle);
@@ -601,15 +605,18 @@ qla25xx_free_rsp_que(struct scsi_qla_hos
 		rsp->msix->in_use = 0;
 		rsp->msix->handle = NULL;
 	}
-	dma_free_coherent(&ha->pdev->dev, (rsp->length + 1) *
-		sizeof(response_t), rsp->ring, rsp->dma);
+
+	if (rsp->ring)
+		dma_free_coherent(&ha->pdev->dev,
+				  (rsp->length + 1) * rsp_entry_size,
+				  rsp->ring, rsp->dma);
 	rsp->ring = NULL;
 	rsp->dma = 0;
 	if (que_id) {
+		mutex_lock(&ha->mq_lock);
 		ha->rsp_q_map[que_id] = NULL;
-		mutex_lock(&ha->vport_lock);
 		clear_bit(que_id, ha->rsp_qid_map);
-		mutex_unlock(&ha->vport_lock);
+		mutex_unlock(&ha->mq_lock);
 	}
 	kfree(rsp);
 }
@@ -794,9 +801,6 @@ qla25xx_create_req_que(struct qla_hw_dat
 		if (ret != QLA_SUCCESS) {
 			ql_log(ql_log_fatal, base_vha, 0x00df,
 			    "%s failed.\n", __func__);
-			mutex_lock(&ha->mq_lock);
-			clear_bit(que_id, ha->req_qid_map);
-			mutex_unlock(&ha->mq_lock);
 			goto que_failed;
 		}
 		vha->flags.qpairs_req_created = 1;
@@ -908,9 +912,6 @@ qla25xx_create_rsp_que(struct qla_hw_dat
 		if (ret != QLA_SUCCESS) {
 			ql_log(ql_log_fatal, base_vha, 0x00e7,
 			    "%s failed.\n", __func__);
-			mutex_lock(&ha->mq_lock);
-			clear_bit(que_id, ha->rsp_qid_map);
-			mutex_unlock(&ha->mq_lock);
 			goto que_failed;
 		}
 		vha->flags.qpairs_rsp_created = 1;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 673/877] scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (671 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 672/877] scsi: qla2xxx: Fix queue teardown NULL dma_free and bitmap locking Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 674/877] scsi: qla2xxx: Null out freed pointers in qla2x00_mem_alloc() error path Greg Kroah-Hartman
                   ` (211 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
	Martin K. Petersen (Oracle), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nilesh Javali <njavali@marvell.com>

[ Upstream commit 19788a55cab61d78e33e0914a5a31d27843e8a4a ]

The response queue MSI-X handler qla2xxx_msix_rsp_q() schedules
qla_do_work() via queue_work(ha->wq, &qpair->q_work). qla_do_work()
dereferences the qpair (vha, rsp) and takes qpair->qp_lock.

During teardown, qla2xxx_delete_qpair() deletes the response queue, which
calls free_irq() in qla25xx_free_rsp_que(), and then frees the queue and
the qpair. free_irq() waits for running hardirq handlers but does not
cancel work already placed on ha->wq. A still-pending q_work then runs
qla_do_work() against the freed qpair and response queue, causing a
use-after-free. This is especially likely during full adapter teardown,
where destroy_workqueue(ha->wq) forces pending work to run after the queue
pairs have been freed.

Flush the work item with cancel_work_sync() in qla25xx_free_rsp_que()
after free_irq() has released the interrupt (so no new work can be
queued) and before the response queue and qpair memory are freed (so the
flushed handler still sees valid memory). Guard on rsp->qpair and ha->wq
to match the INIT_WORK() condition and avoid operating on an
uninitialized work_struct.

Fixes: 68ca949cdb04 ("[SCSI] qla2xxx: Add CPU affinity support.")
Reported-by: Sashiko <sashiko-dev@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-5-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/qla2xxx/qla_mid.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -606,6 +606,10 @@ qla25xx_free_rsp_que(struct scsi_qla_hos
 		rsp->msix->handle = NULL;
 	}
 
+	/* Flush any queued response work before freeing the queue/qpair. */
+	if (rsp->qpair && ha->wq)
+		cancel_work_sync(&rsp->qpair->q_work);
+
 	if (rsp->ring)
 		dma_free_coherent(&ha->pdev->dev,
 				  (rsp->length + 1) * rsp_entry_size,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 674/877] scsi: qla2xxx: Null out freed pointers in qla2x00_mem_alloc() error path
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (672 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 673/877] scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 675/877] scsi: qla2xxx: Bound VP index against VP_CTRL IOCB bitmap size Greg Kroah-Hartman
                   ` (210 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
	Martin K. Petersen (Oracle), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nilesh Javali <njavali@marvell.com>

[ Upstream commit 6d90f0feb929f6c0f3010f9af4747c7230b75993 ]

When qla2x00_mem_alloc() fails, qla2x00_probe_one() jumps to
probe_hw_failed and calls qla2x00_mem_free(). Several error labels in
qla2x00_mem_alloc() freed adapter members (elsrej.c, purex_dma_pool,
flt, sfp_data, loop_id_map, async_pd, sf_init_cb, ex_init_cb, npiv_info)
but left the pointers dangling. qla2x00_mem_free() then freed them a
second time. Worse, for the dma_pool members it issued
dma_pool_free(ha->s_dma_pool, ...) after s_dma_pool had already been
destroyed and set to NULL at fail_s_dma_pool, dereferencing a NULL pool.

Clear each freed pointer (and its DMA handle) in the error labels so the
subsequent qla2x00_mem_free() skips them.

Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-13-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ adjusted cleanup context for the missing fail_flt_data block. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/qla2xxx/qla_os.c |   15 +++++++++++++++
 1 file changed, 15 insertions(+)

--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -4482,25 +4482,40 @@ qla2x00_mem_alloc(struct qla_hw_data *ha
 fail_lsrjt:
 	dma_free_coherent(&ha->pdev->dev, ha->elsrej.size,
 			  ha->elsrej.c, ha->elsrej.cdma);
+	ha->elsrej.c = NULL;
+	ha->elsrej.cdma = 0;
 fail_elsrej:
 	dma_pool_destroy(ha->purex_dma_pool);
+	ha->purex_dma_pool = NULL;
 fail_flt:
 	dma_free_coherent(&ha->pdev->dev, sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE,
 	    ha->flt, ha->flt_dma);
+	ha->flt = NULL;
+	ha->flt_dma = 0;
 
 fail_flt_buffer:
 	dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE,
 	    ha->sfp_data, ha->sfp_data_dma);
+	ha->sfp_data = NULL;
+	ha->sfp_data_dma = 0;
 fail_sfp_data:
 	kfree(ha->loop_id_map);
+	ha->loop_id_map = NULL;
 fail_loop_id_map:
 	dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma);
+	ha->async_pd = NULL;
+	ha->async_pd_dma = 0;
 fail_async_pd:
 	dma_pool_free(ha->s_dma_pool, ha->sf_init_cb, ha->sf_init_cb_dma);
+	ha->sf_init_cb = NULL;
+	ha->sf_init_cb_dma = 0;
 fail_sf_init_cb:
 	dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma);
+	ha->ex_init_cb = NULL;
+	ha->ex_init_cb_dma = 0;
 fail_ex_init_cb:
 	kfree(ha->npiv_info);
+	ha->npiv_info = NULL;
 fail_npiv_info:
 	dma_free_coherent(&ha->pdev->dev, ((*rsp)->length + 1) *
 		sizeof(response_t), (*rsp)->ring, (*rsp)->dma);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 675/877] scsi: qla2xxx: Bound VP index against VP_CTRL IOCB bitmap size
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (673 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 674/877] scsi: qla2xxx: Null out freed pointers in qla2x00_mem_alloc() error path Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 676/877] media: chips-media: wave5: Add timeout while stop_streaming Greg Kroah-Hartman
                   ` (209 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nilesh Javali, Hannes Reinecke,
	Martin K. Petersen (Oracle), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nilesh Javali <njavali@marvell.com>

[ Upstream commit 878613ecb5a36db26859c4fd83daf9283a334fa2 ]

The VP control IOCB selects its target virtual port by setting one bit
in vp_idx_map, a fixed 16-byte (128-bit) array in both
vp_ctrl_entry_24xx and vp_ctrl_entry_24xx_ext. qla25xx_ctrlvp_iocb()
computes map = (vp_index - 1) / 8 and writes vce->vp_idx_map[map]
without checking that map stays within the array.

max_npiv_vports is taken from firmware and only sanitized to a
MIN_MULTI_ID_FABRIC-aligned boundary, so it can legitimately be 191 or
255, and qla24xx_control_vp() only rejects vp_index >= max_npiv_vports.
A vp_index above 128 therefore yields map >= 16 and an out-of-bounds
write of up to 16 bytes past vp_idx_map, corrupting the trailing IOCB
fields (or the adjacent request-ring slot on the 64-byte layout).

Reject a vp_index that cannot be represented in the IOCB bitmap in
qla24xx_control_vp(), and add a defensive ARRAY_SIZE() guard in
qla25xx_ctrlvp_iocb() before the write. Adapters that report the usual
63 or 127 NPIV vports are unaffected.

Fixes: 2853192e154b ("scsi: qla2xxx: Use IOCB path to submit Control VP MBX command")
Cc: stable@vger.kernel.org
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-49-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ Adjusted guard placement in qla25xx_ctrlvp_iocb() to match the older initialization order. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/qla2xxx/qla_iocb.c |    6 ++++++
 drivers/scsi/qla2xxx/qla_mid.c  |    8 ++++++++
 2 files changed, 14 insertions(+)

--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -3828,6 +3828,12 @@ qla25xx_ctrlvp_iocb(srb_t *sp, struct vp
 	 */
 	map = (sp->u.iocb_cmd.u.ctrlvp.vp_index - 1) / 8;
 	pos = (sp->u.iocb_cmd.u.ctrlvp.vp_index - 1) & 7;
+	if (map >= ARRAY_SIZE(vce->vp_idx_map)) {
+		ql_log(ql_log_warn, sp->vha, 0x307c,
+		       "ctrlvp: vp_index %u exceeds vp_idx_map capacity\n",
+		       sp->u.iocb_cmd.u.ctrlvp.vp_index);
+		return;
+	}
 	vce->vp_idx_map[map] |= 1 << pos;
 }
 
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -962,6 +962,14 @@ int qla24xx_control_vp(scsi_qla_host_t *
 	if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
 		return QLA_PARAMETER_ERROR;
 
+	/*
+	 * The VP_CTRL IOCB selects the target VP through a fixed 128-bit
+	 * (16-byte) vp_idx_map bitmap, so vp_index must fit within it even
+	 * if firmware advertises more NPIV vports.
+	 */
+	if (vp_index > sizeof_field(struct vp_ctrl_entry_24xx, vp_idx_map) * 8)
+		return QLA_PARAMETER_ERROR;
+
 	/* ref: INIT */
 	sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL);
 	if (!sp)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 676/877] media: chips-media: wave5: Add timeout while stop_streaming
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (674 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 675/877] scsi: qla2xxx: Bound VP index against VP_CTRL IOCB bitmap size Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 677/877] scsi: qla2xxx: Use ring-slot helpers in __qla2x00_alloc_iocbs Greg Kroah-Hartman
                   ` (208 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jackson Lee, Nas Chung,
	Nicolas Dufresne, Hans Verkuil, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jackson Lee <jackson.lee@chipsnmedia.com>

[ Upstream commit 2ae7faed2e60d6d07d9efdd962d20dcb15330ced ]

When stop_streaming is called, an infinite loop may occur in some cases.
Add a bounded poll of the queue status: loop until the queues drain,
sleeping briefly between polls, and bail out once VPU_DEC_STOP_TIMEOUT
elapses.

Fixes: 9707a6254a8a ("media: chips-media: wave5: Add the v4l2 layer")
Cc: stable@vger.kernel.org
Signed-off-by: Jackson Lee <jackson.lee@chipsnmedia.com>
Signed-off-by: Nas Chung <nas.chung@chipsnmedia.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
[ adapted the stop loop to use 6.12’s existing report_queue_count condition. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c   |   12 ++++++------
 drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h |    1 +
 2 files changed, 7 insertions(+), 6 deletions(-)

--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c
@@ -5,6 +5,7 @@
  * Copyright (C) 2021-2023 CHIPS&MEDIA INC
  */
 
+#include <linux/delay.h>
 #include "wave5-helper.h"
 
 #define VPU_DEC_DEV_NAME "C&M Wave5 VPU decoder"
@@ -1567,24 +1568,23 @@ static void wave5_vpu_dec_stop_streaming
 {
 	struct vpu_instance *inst = vb2_get_drv_priv(q);
 	struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
-	bool check_cmd = TRUE;
+	unsigned long timeout;
 
 	dev_dbg(inst->dev->dev, "%s: type: %u\n", __func__, q->type);
 
-	while (check_cmd) {
+	timeout = jiffies + msecs_to_jiffies(VPU_DEC_STOP_TIMEOUT);
+	while (true) {
 		struct queue_status_info q_status;
-		struct dec_output_info dec_output_info;
 
 		wave5_vpu_dec_give_command(inst, DEC_GET_QUEUE_STATUS, &q_status);
 
 		if (q_status.report_queue_count == 0)
 			break;
 
-		if (wave5_vpu_wait_interrupt(inst, VPU_DEC_TIMEOUT) < 0)
+		if (time_after(jiffies, timeout))
 			break;
 
-		if (wave5_vpu_dec_get_output_info(inst, &dec_output_info))
-			dev_dbg(inst->dev->dev, "there is no output info\n");
+		usleep_range(1000, 2000);
 	}
 
 	v4l2_m2m_update_stop_streaming_state(m2m_ctx, q);
--- a/drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h
+++ b/drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h
@@ -40,6 +40,7 @@
 //  application specific configuration
 #define VPU_ENC_TIMEOUT                 60000
 #define VPU_DEC_TIMEOUT                 60000
+#define VPU_DEC_STOP_TIMEOUT            300
 
 // for WAVE encoder
 #define USE_SRC_PRP_AXI         0



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 677/877] scsi: qla2xxx: Use ring-slot helpers in __qla2x00_alloc_iocbs
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (675 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 676/877] media: chips-media: wave5: Add timeout while stop_streaming Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 678/877] scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot Greg Kroah-Hartman
                   ` (207 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nilesh Javali, Hannes Reinecke,
	Martin K. Petersen (Oracle), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nilesh Javali <njavali@marvell.com>

[ Upstream commit 7e51b6d2d8f6b7f48d9cef1cf87471b55b12f6de ]

__qla2x00_alloc_iocbs() open-codes ring pointer selection and entry size
based on IS_QLA29XX(ha): 29xx reaches the slot via ring_ext_ptr and
zeroes REQUEST_ENTRY_SIZE_EXT bytes, while other adapters use ring_ptr
with REQUEST_ENTRY_SIZE bytes.

Replace the two branches with the qla_req_ring_slot() and
qla_req_entry_size() helpers, and initialise pkt at declaration.  The
IS_QLAFX00 register-mapped writes remain guarded because IS_QLAFX00 and
IS_QLA29XX cannot be true simultaneously.

No functional change: the bytes written to the firmware-visible IOCB are
identical.

Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-24-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>

Stable adaptation:
This tree has no QLA29xx support, extended request ring, or ring-slot
helpers. Provide file-local macro helpers mapping to req->ring_ptr and
REQUEST_ENTRY_SIZE, preserving the existing 64-byte ring behavior without
adding functions or importing the unrelated QLA29xx support series.

Retain the helper calls and declaration initialization from this change.
Use a multiline packet-preparation comment so commit 626e44f3d8a9
("scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot")
applies unchanged, including its leading context. That commit remains
responsible for changing the FX00 clearing operation to memset_io().

Stable-dep-of: 626e44f3d8a9 ("scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/qla2xxx/qla_iocb.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -11,6 +11,10 @@
 
 #include <scsi/scsi_tcq.h>
 
+/* All adapters supported by this tree use the 64-byte request ring. */
+#define qla_req_ring_slot(ha, req) ((req)->ring_ptr)
+#define qla_req_entry_size(ha) REQUEST_ENTRY_SIZE
+
 static int qla_start_scsi_type6(srb_t *sp);
 /**
  * qla2x00_get_cmd_direction() - Determine control_flag data direction.
@@ -2286,10 +2290,9 @@ __qla2x00_alloc_iocbs(struct qla_qpair *
 	struct req_que *req = qpair->req;
 	device_reg_t *reg = ISP_QUE_REG(ha, req->id);
 	uint32_t handle;
-	request_t *pkt;
 	uint16_t cnt, req_cnt;
+	request_t *pkt = NULL;
 
-	pkt = NULL;
 	req_cnt = 1;
 	handle = 0;
 
@@ -2343,10 +2346,12 @@ __qla2x00_alloc_iocbs(struct qla_qpair *
 		sp->handle = handle;
 	}
 
-	/* Prep packet */
+	/*
+	 * Prep the current request-ring slot.
+	 */
 	req->cnt -= req_cnt;
-	pkt = req->ring_ptr;
-	memset(pkt, 0, REQUEST_ENTRY_SIZE);
+	pkt = qla_req_ring_slot(ha, req);
+	memset(pkt, 0, qla_req_entry_size(ha));
 	if (IS_QLAFX00(ha)) {
 		wrt_reg_byte((u8 __force __iomem *)&pkt->entry_count, req_cnt);
 		wrt_reg_dword((__le32 __force __iomem *)&pkt->handle, handle);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 678/877] scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (676 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 677/877] scsi: qla2xxx: Use ring-slot helpers in __qla2x00_alloc_iocbs Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 679/877] scsi: qla2xxx: Fix 64G link speed reporting in get_data_rate Greg Kroah-Hartman
                   ` (206 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
	Martin K. Petersen (Oracle), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nilesh Javali <njavali@marvell.com>

[ Upstream commit 626e44f3d8a924a97a3848a9fd45833947e081e9 ]

For QLAFX00 the request ring is ioremapped device I/O memory
(ha->iobase + req_que_off), not DMA-coherent RAM, which is why the rest
of the FX00 path accesses it through memcpy_toio() and the wrt_reg_*
helpers. __qla2x00_alloc_iocbs() however zeroed the producer slot with a
plain memset(). On architectures such as ARM64 a regular memset() may
emit unaligned or block-zeroing instructions (e.g. DC ZVA) that are
invalid on Device memory, leading to a synchronous external abort.

Use memset_io() to clear the slot for QLAFX00, matching the I/O
accessors used elsewhere on this ring. Other adapters keep the plain
memset() on their DMA-coherent rings. The zero-fill is retained for FX00
because its IOCB builders (e.g. qlafx00_fxdisc_iocb()) copy only part of
the entry and rely on the unused tail being pre-zeroed.

Fixes: 8ae6d9c7eb10 ("[SCSI] qla2xxx: Enhancements to support ISPFx00.")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-12-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/qla2xxx/qla_iocb.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -2351,11 +2351,13 @@ __qla2x00_alloc_iocbs(struct qla_qpair *
 	 */
 	req->cnt -= req_cnt;
 	pkt = qla_req_ring_slot(ha, req);
-	memset(pkt, 0, qla_req_entry_size(ha));
 	if (IS_QLAFX00(ha)) {
+		memset_io((void __iomem __force *)pkt, 0,
+			  qla_req_entry_size(ha));
 		wrt_reg_byte((u8 __force __iomem *)&pkt->entry_count, req_cnt);
 		wrt_reg_dword((__le32 __force __iomem *)&pkt->handle, handle);
 	} else {
+		memset(pkt, 0, qla_req_entry_size(ha));
 		pkt->entry_count = req_cnt;
 		pkt->handle = handle;
 	}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 679/877] scsi: qla2xxx: Fix 64G link speed reporting in get_data_rate
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (677 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 678/877] scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 680/877] scsi: qla2xxx: Skip vport under deletion in report ID acquisition Greg Kroah-Hartman
                   ` (205 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Nilesh Javali, Hannes Reinecke,
	Martin K. Petersen (Oracle), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nilesh Javali <njavali@marvell.com>

[ Upstream commit 52fba32317ee631faa878725b2f7cd5c08acacd3 ]

qla2x00_get_data_rate() skips updating ha->link_data_rate when the
firmware returns mcp->mb[1] == 0x7.  That value was a legacy sentinel
from before 64G hardware existed, but PORT_SPEED_64GB is now defined as
0x07 and ha->link_data_rate is decoded with the PORT_SPEED_* encoding.
On a 64G-capable adapter a genuine 64G link is therefore dropped, and
the port speed is misreported (port_speed sysfs, fc_host speed, FDMI).

Only 28xx and 29xx support 64G, so accept 0x07 on those adapters while
keeping the legacy filter for older ones.  Also drop the duplicate copy
of the check at the end of the success branch; it repeated the first
assignment with no intervening change.

Fixes: ecc89f25e225 ("scsi: qla2xxx: Add Device ID for ISP28XX")
Cc: stable@vger.kernel.org
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-46-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ Omitted IS_QLA29XX() checks because this branch lacks 29xx adapter support. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/qla2xxx/qla_mbx.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -5658,7 +5658,7 @@ qla2x00_get_data_rate(scsi_qla_host_t *v
 		ql_dbg(ql_dbg_mbx, vha, 0x1107,
 		    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
 	} else {
-		if (mcp->mb[1] != 0x7)
+		if (mcp->mb[1] != 0x7 || IS_QLA28XX(ha))
 			ha->link_data_rate = mcp->mb[1];
 
 		if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
@@ -5669,8 +5669,6 @@ qla2x00_get_data_rate(scsi_qla_host_t *v
 
 		ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
 		    "Done %s.\n", __func__);
-		if (mcp->mb[1] != 0x7)
-			ha->link_data_rate = mcp->mb[1];
 	}
 
 	return rval;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 680/877] scsi: qla2xxx: Skip vport under deletion in report ID acquisition
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (678 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 679/877] scsi: qla2xxx: Fix 64G link speed reporting in get_data_rate Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 681/877] scsi: qla2xxx: Fix soft lockup polling continuation IOCB signature Greg Kroah-Hartman
                   ` (204 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
	Martin K. Petersen (Oracle), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nilesh Javali <njavali@marvell.com>

[ Upstream commit 23582731afa35031c94fadb71a4f3b4afd094649 ]

qla24xx_report_id_acquisition() format-1 handling walks ha->vp_list under
vport_slock, takes a vref_count on the matching vport and calls
qla_update_host_map() to register its port id.

A vport teardown via qla24xx_vport_delete() sets VPORT_DELETE, then
qla24xx_disable_vp() removes the vport from the host_map btree and zeroes
vha->d_id (RESET_AL_PA). The vport is only unlinked from vp_list later,
in qla24xx_deallocate_vp_id(), which clears vp_map[idx] (RESET_VP_IDX)
but does not touch host_map. In the window in between, report ID
acquisition can still find the vport on vp_list and call
qla_update_host_map(); with d_id already zeroed it takes the
btree_insert32() path and re-inserts the dying vport into host_map.
Nothing cleans that entry afterwards, so once scsi_host_put() frees the
vha a later host_map lookup dereferences freed memory.

Skip a vport that has VPORT_DELETE set before taking the reference, so it
is neither re-registered nor scheduled for DPC re-registration. This
mirrors the existing guard in qla2x00_alert_all_vps().

Fixes: 41dc529a4602 ("qla2xxx: Improve RSCN handling in driver")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-22-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ Adjusted context to use rptid_entry->vp_idx instead of the missing local vp_idx variable. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/qla2xxx/qla_mbx.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -4147,6 +4147,8 @@ qla24xx_report_id_acquisition(scsi_qla_h
 			spin_lock_irqsave(&ha->vport_slock, flags);
 			list_for_each_entry(vp, &ha->vp_list, list) {
 				if (rptid_entry->vp_idx == vp->vp_idx) {
+					if (test_bit(VPORT_DELETE, &vp->dpc_flags))
+						break;
 					found = 1;
 					atomic_inc(&vp->vref_count);
 					break;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 681/877] scsi: qla2xxx: Fix soft lockup polling continuation IOCB signature
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (679 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 680/877] scsi: qla2xxx: Skip vport under deletion in report ID acquisition Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 682/877] scsi: qla2xxx: Clamp max_npiv_vports to VP_CTRL bitmap capacity Greg Kroah-Hartman
                   ` (203 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
	Martin K. Petersen (Oracle), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nilesh Javali <njavali@marvell.com>

[ Upstream commit d7e3fa7d06bf7fcaac186d3c4d635caac166d36c ]

qla27xx_copy_multiple_pkt() and qla27xx_copy_fpin_pkt() poll
rsp_q->ring_ptr->signature for RESPONSE_PROCESSED (0xDEADDEAD) to decide
whether the next continuation IOCB has arrived, spinning on cpu_relax()
without advancing the ring or decrementing the entry count while it has
not. response_t::signature lives at byte offset 60, but a continuation
IOCB (sts_cont_entry_t / struct sts_cont_entry_ext) carries raw FC frame
payload at that offset (data[56..59]). A received frame whose payload
bytes happen to equal 0xDEADDEAD is therefore misread as "not yet
arrived", and the loop spins forever in interrupt/DPC context, causing a
CPU soft lockup.

The poll is also unnecessary: callers of qla27xx_copy_multiple_pkt()
(PT_LS4_UNSOL and the NVMe purls path) already gate on
qla_chk_cont_iocb_avail(), which guarantees all entry_count IOCBs are
present before copying begins. The sibling helper
__qla_copy_purex_to_buffer() already drops the signature poll and relies
on the entry_type == STATUS_CONT_TYPE guard instead.

Remove the signature busy-wait from both helpers, keeping the entry_type
guard, and gate the FPIN path with qla_chk_cont_iocb_avail() so it defers
and re-processes on the next interrupt once all continuation IOCBs have
arrived, mirroring the ELS_AUTH_ELS and PT_LS4_UNSOL arms. With this the
signature field is never read on a continuation IOCB, eliminating the
payload-aliasing lockup.

Fixes: 9f2475fe7406 ("scsi: qla2xxx: SAN congestion management implementation")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-15-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ replaced unavailable qla_rsp_ring_rewind_to() with direct ring pointer and index assignments ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/qla2xxx/qla_isr.c |   33 ++++++++++++++++-----------------
 1 file changed, 16 insertions(+), 17 deletions(-)

--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -921,14 +921,6 @@ qla27xx_copy_multiple_pkt(struct scsi_ql
 
 	do {
 		while ((total_bytes > 0) && (entry_count_remaining > 0)) {
-			if (rsp_q->ring_ptr->signature == RESPONSE_PROCESSED) {
-				ql_dbg(ql_dbg_async, vha, 0x5084,
-				       "Ran out of IOCBs, partial data 0x%x\n",
-				       buffer_copy_offset);
-				cpu_relax();
-				continue;
-			}
-
 			new_pkt = (sts_cont_entry_t *)rsp_q->ring_ptr;
 			*pkt = new_pkt;
 
@@ -1205,14 +1197,6 @@ qla27xx_copy_fpin_pkt(struct scsi_qla_ho
 
 	do {
 		while ((total_bytes > 0) && (entry_count_remaining > 0)) {
-			if (rsp_q->ring_ptr->signature == RESPONSE_PROCESSED) {
-				ql_dbg(ql_dbg_async, vha, 0x5084,
-				       "Ran out of IOCBs, partial data 0x%x\n",
-				       buffer_copy_offset);
-				cpu_relax();
-				continue;
-			}
-
 			new_pkt = (sts_cont_entry_t *)rsp_q->ring_ptr;
 			*pkt = new_pkt;
 
@@ -4142,9 +4126,24 @@ process_err:
 					       "SCM not active for this port\n");
 					break;
 				}
+				if (qla_chk_cont_iocb_avail(vha, rsp,
+				    (response_t *)pkt, rsp_in)) {
+					/*
+					 * ring_ptr and ring_index were
+					 * pre-incremented above. Reset them
+					 * back to current. Wait for next
+					 * interrupt with all IOCBs to arrive
+					 * and re-process.
+					 */
+					rsp->ring_ptr = (response_t *)pkt;
+					rsp->ring_index = cur_ring_index;
+
+					ql_dbg(ql_dbg_init, vha, 0x5095,
+					    "Defer processing FPIN...\n");
+					return;
+				}
 				pure_item = qla27xx_copy_fpin_pkt(vha,
 							  (void **)&pkt, &rsp);
-				__update_rsp_in(is_shadow_hba, rsp, rsp_in);
 				if (!pure_item)
 					break;
 				qla24xx_queue_purex_item(vha, pure_item,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 682/877] scsi: qla2xxx: Clamp max_npiv_vports to VP_CTRL bitmap capacity
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (680 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 681/877] scsi: qla2xxx: Fix soft lockup polling continuation IOCB signature Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 683/877] scsi: qla2xxx: Unlink NVMe unsol ctx before freeing on LS reject error Greg Kroah-Hartman
                   ` (202 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
	Martin K. Petersen (Oracle), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nilesh Javali <njavali@marvell.com>

[ Upstream commit 2ac6a829843cf3df522d19e091276109b94c4c7a ]

ha->max_npiv_vports is taken from firmware (mcp->mb[11]) and only
constrained so that (max_npiv_vports + 1) is a multiple of
MIN_MULTI_ID_FABRIC, which permits values of 63, 127, 191 and 255.
NPIV vports are then allocated up to that count.

VP enable uses the VP_CONFIG IOCB, which addresses a vport through a
plain vp_index byte, so a vp_index beyond 128 is enabled without issue.
VP disable, however, uses the VP_CTRL IOCB, which selects target vports
through the fixed 128-bit vp_idx_map bitmap. qla24xx_control_vp()
rejects a vp_index past that bitmap and the IOCB builder cannot set a bit
beyond 127, yet qla24xx_vport_delete() frees the local state regardless.
A vport with vp_index > 128 can therefore be created and enabled but
never disabled, leaving it permanently active in firmware: a resource
leak.

Cap ha->max_npiv_vports at init to the vp_idx_map capacity so such
vports are never created. This collapses 191/255 to 127 (still
modulo-valid) and leaves the real-world 63/127 cases unaffected.

Fixes: 4d0ea24769c8 ("[SCSI] qla2xxx: Retrieve max-NPIV support capabilities from FW.")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-20-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ adapted the qla24xx_control_vp() hunk to include the prerequisite bounds-check block missing from this branch. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/qla2xxx/qla_fw.h   |    4 ++++
 drivers/scsi/qla2xxx/qla_init.c |   13 +++++++++++++
 drivers/scsi/qla2xxx/qla_mid.c  |    8 ++++++++
 3 files changed, 25 insertions(+)

--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1442,6 +1442,10 @@ struct vp_ctrl_entry_24xx {
 	uint8_t reserved_5[24];
 };
 
+/* vp_idx_map is a 128-bit (16-byte) bitmap selecting target VPs. */
+#define VP_CTRL_IDX_MAP_BITS \
+	(sizeof_field(struct vp_ctrl_entry_24xx, vp_idx_map) * 8)
+
 /*
  * Modify Virtual Port Configuration IOCB
  */
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -4408,6 +4408,19 @@ enable_82xx_npiv:
 					    MIN_MULTI_ID_FABRIC))
 						ha->max_npiv_vports =
 						    MIN_MULTI_ID_FABRIC - 1;
+
+					/*
+					 * The VP_CTRL IOCB selects target VPs
+					 * through the fixed vp_idx_map bitmap,
+					 * so a vp_index beyond it can be enabled
+					 * via VP_CONFIG but never disabled via
+					 * VP_CTRL, leaking the VP.  Cap the count
+					 * to the bitmap capacity.
+					 */
+					if (ha->max_npiv_vports >=
+					    VP_CTRL_IDX_MAP_BITS)
+						ha->max_npiv_vports =
+						    VP_CTRL_IDX_MAP_BITS - 1;
 				}
 				qla2x00_get_resource_cnts(vha);
 				qla_init_iocb_limit(vha);
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -970,6 +970,14 @@ int qla24xx_control_vp(scsi_qla_host_t *
 	if (vp_index > sizeof_field(struct vp_ctrl_entry_24xx, vp_idx_map) * 8)
 		return QLA_PARAMETER_ERROR;
 
+	/*
+	 * The VP_CTRL IOCB selects the target VP through a fixed 128-bit
+	 * (16-byte) vp_idx_map bitmap, so vp_index must fit within it even
+	 * if firmware advertises more NPIV vports.
+	 */
+	if (vp_index > VP_CTRL_IDX_MAP_BITS)
+		return QLA_PARAMETER_ERROR;
+
 	/* ref: INIT */
 	sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL);
 	if (!sp)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 683/877] scsi: qla2xxx: Unlink NVMe unsol ctx before freeing on LS reject error
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (681 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 682/877] scsi: qla2xxx: Clamp max_npiv_vports to VP_CTRL bitmap capacity Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 684/877] scsi: qla2xxx: Serialize NVMe unsol ctx list with a per-fcport lock Greg Kroah-Hartman
                   ` (201 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
	Martin K. Petersen (Oracle), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nilesh Javali <njavali@marvell.com>

[ Upstream commit e46160a5d4fa59bf4d5f3412b6b5cb79edb967dd ]

qla_nvme_xmt_ls_rsp() obtains uctx, which was linked into
fcport->unsol_ctx_head by qla2xxx_process_purls_iocb() and is still linked
when the NVMe transport calls back to transmit the LS response. On the
error (out:) path the function frees uctx with kfree() but never removes
it from the list. This leaves a freed node in fcport->unsol_ctx_head: the
next list_add_tail() for that fcport writes through the freed node, and a
subsequent list_del() can corrupt the list or panic.

Unlink uctx with list_del() before kfree() on the error path, matching the
other free sites in qla_nvme_release_lsrsp_cmd_kref() and
qla2xxx_process_purls_pkt(). qla2x00_rel_sp() in the failure path only
returns the SRB to its pool and does not invoke sp->put_fn, so the out:
path is the sole free and uctx is always still linked there.

Fixes: 875386b98857 ("scsi: qla2xxx: Add Unsolicited LS Request and Response Support for NVMe")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-27-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Stable-dep-of: 76da0c43c63e ("scsi: qla2xxx: Serialize NVMe unsol ctx list with a per-fcport lock")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/qla2xxx/qla_nvme.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/scsi/qla2xxx/qla_nvme.c
+++ b/drivers/scsi/qla2xxx/qla_nvme.c
@@ -446,6 +446,7 @@ out:
 		qla_nvme_ls_reject_iocb(vha, ha->base_qpair, &a, true);
 		spin_unlock_irqrestore(ha->base_qpair->qp_lock_ptr, flags);
 	}
+	list_del(&uctx->elem);
 	kfree(uctx);
 	return rval;
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 684/877] scsi: qla2xxx: Serialize NVMe unsol ctx list with a per-fcport lock
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (682 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 683/877] scsi: qla2xxx: Unlink NVMe unsol ctx before freeing on LS reject error Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 685/877] scsi: qla2xxx: Validate BSG request_len before reading vendor_cmd[] Greg Kroah-Hartman
                   ` (200 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
	Martin K. Petersen (Oracle), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nilesh Javali <njavali@marvell.com>

[ Upstream commit 76da0c43c63eb0496649e372ac64466364d0fe7d ]

The fcport->unsol_ctx_head list is modified from several contexts without
a common lock. Entries are added in qla2xxx_process_purls_iocb() from the
response queue ISR (under the qpair qp_lock), while they are removed from
qla2xxx_process_purls_pkt() (DPC/purex worker), qla_nvme_xmt_ls_rsp()
(NVMe-FC transport callback) and qla_nvme_release_lsrsp_cmd_kref() (SRB
completion). The qpair qp_lock cannot serialize this per-fcport list since
multiqueue adapters add entries through different qpairs, so a concurrent
add and delete (or two concurrent deletes) can corrupt the list pointers.

Introduce a dedicated per-fcport spinlock, unsol_ctx_lock, initialized in
qla2x00_alloc_fcport(), and take it around every list_add_tail()/list_del()
on unsol_ctx_head. The add nests under the existing qp_lock; no delete path
takes qp_lock, so the lock order is consistent and deadlock free.

Fixes: 875386b98857 ("scsi: qla2xxx: Add Unsolicited LS Request and Response Support for NVMe")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-28-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/qla2xxx/qla_def.h  |    2 ++
 drivers/scsi/qla2xxx/qla_init.c |    1 +
 drivers/scsi/qla2xxx/qla_nvme.c |    9 +++++++++
 3 files changed, 12 insertions(+)

--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2570,6 +2570,8 @@ typedef struct fc_port {
 	struct list_head list;
 	struct scsi_qla_host *vha;
 	struct list_head unsol_ctx_head;
+	/* Serializes unsol_ctx_head against ISR, DPC and NVMe transport. */
+	spinlock_t unsol_ctx_lock;
 
 	unsigned int conf_compl_supported:1;
 	unsigned int deleted:2;
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -5649,6 +5649,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vh
 	INIT_LIST_HEAD(&fcport->gnl_entry);
 	INIT_LIST_HEAD(&fcport->list);
 	INIT_LIST_HEAD(&fcport->unsol_ctx_head);
+	spin_lock_init(&fcport->unsol_ctx_lock);
 
 	INIT_LIST_HEAD(&fcport->sess_cmd_list);
 	spin_lock_init(&fcport->sess_cmd_lock);
--- a/drivers/scsi/qla2xxx/qla_nvme.c
+++ b/drivers/scsi/qla2xxx/qla_nvme.c
@@ -257,7 +257,9 @@ static void qla_nvme_release_lsrsp_cmd_k
 
 	fd_rsp = uctx->fd_rsp;
 
+	spin_lock_irqsave(&uctx->fcport->unsol_ctx_lock, flags);
 	list_del(&uctx->elem);
+	spin_unlock_irqrestore(&uctx->fcport->unsol_ctx_lock, flags);
 
 	fd_rsp->done(fd_rsp);
 	kfree(uctx);
@@ -446,7 +448,9 @@ out:
 		qla_nvme_ls_reject_iocb(vha, ha->base_qpair, &a, true);
 		spin_unlock_irqrestore(ha->base_qpair->qp_lock_ptr, flags);
 	}
+	spin_lock_irqsave(&uctx->fcport->unsol_ctx_lock, flags);
 	list_del(&uctx->elem);
+	spin_unlock_irqrestore(&uctx->fcport->unsol_ctx_lock, flags);
 	kfree(uctx);
 	return rval;
 }
@@ -1216,7 +1220,9 @@ qla2xxx_process_purls_pkt(struct scsi_ql
 			spin_unlock_irqrestore(vha->hw->base_qpair->qp_lock_ptr,
 					       flags);
 		}
+		spin_lock_irqsave(&uctx->fcport->unsol_ctx_lock, flags);
 		list_del(&uctx->elem);
+		spin_unlock_irqrestore(&uctx->fcport->unsol_ctx_lock, flags);
 		kfree(uctx);
 	}
 }
@@ -1258,6 +1264,7 @@ void qla2xxx_process_purls_iocb(void **p
 	struct purex_item *item;
 	port_id_t d_id = {0};
 	port_id_t id = {0};
+	unsigned long flags;
 	u8 *opcode;
 	bool xmt_reject = false;
 
@@ -1323,7 +1330,9 @@ void qla2xxx_process_purls_iocb(void **p
 	uctx->ox_id = p->ox_id;
 	qla_rport->uctx = uctx;
 	INIT_LIST_HEAD(&uctx->elem);
+	spin_lock_irqsave(&fcport->unsol_ctx_lock, flags);
 	list_add_tail(&uctx->elem, &fcport->unsol_ctx_head);
+	spin_unlock_irqrestore(&fcport->unsol_ctx_lock, flags);
 	item->purls_context = (void *)uctx;
 
 	ql_dbg(ql_dbg_unsol, vha, 0x2121,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 685/877] scsi: qla2xxx: Validate BSG request_len before reading vendor_cmd[]
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (683 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 684/877] scsi: qla2xxx: Serialize NVMe unsol ctx list with a per-fcport lock Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 686/877] f2fs: validate MOVE_RANGE destination size Greg Kroah-Hartman
                   ` (199 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
	Martin K. Petersen (Oracle), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Nilesh Javali <njavali@marvell.com>

[ Upstream commit 4cf38dd9465736141263ebb63375868311a0ec81 ]

The FC BSG transport allocates job->request via memdup_user() using the
exact user-supplied request_len. For FC_BSG_HST_VENDOR,
fc_bsg_host_dispatch() only guarantees request_len covers msgcode and
vendor_id; it does not account for the vendor_cmd[] flexible array.

qla2xxx then reads the command selector vendor_cmd[0] and, in several
sub-handlers, vendor_cmd[1]/[2] or structures overlaid on the vendor
command area without verifying request_len. A caller holding
CAP_SYS_RAWIO can submit a short request whose vendor_id matches the
host, triggering out-of-bounds heap reads (KASAN-detectable, and able to
mis-select a command or panic).

Add a central guard in qla2x00_process_vendor_specific() so the selector
is always in bounds, restrict the early vendor_cmd[0] read in
qla24xx_bsg_request() to sufficiently long vendor messages, and add
request_len checks to the sub-handlers that read further:
qla24xx_proc_fcp_prio_cfg_cmd(), qla2x00_process_loopback(),
qla84xx_reset(), qla84xx_updatefw(), qla2x00_read_optrom(),
qla2x00_update_optrom(), qlafx00_mgmt_cmd() and
qla28xx_validate_flash_image().

Fixes: 01e0e15c8b3b ("scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-31-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ adapted hunks to the existing OPTROM helper and absence of qla28xx_validate_flash_image(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/qla2xxx/qla_bsg.c |   45 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 43 insertions(+), 2 deletions(-)

--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -158,6 +158,12 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct bsg
 		goto exit_fcp_prio_cfg;
 	}
 
+	if (bsg_job->request_len <
+	    sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t)) {
+		ret = -EINVAL;
+		goto exit_fcp_prio_cfg;
+	}
+
 	/* Get the sub command */
 	oper = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
 
@@ -756,6 +762,10 @@ qla2x00_process_loopback(struct bsg_job
 		return -EIO;
 	}
 
+	if (bsg_job->request_len <
+	    sizeof(struct fc_bsg_request) + 3 * sizeof(uint32_t))
+		return -EINVAL;
+
 	memset(&elreq, 0, sizeof(elreq));
 
 	elreq.req_sg_cnt = dma_map_sg(&ha->pdev->dev,
@@ -988,6 +998,10 @@ qla84xx_reset(struct bsg_job *bsg_job)
 		return -EINVAL;
 	}
 
+	if (bsg_job->request_len <
+	    sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t))
+		return -EINVAL;
+
 	flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
 
 	rval = qla84xx_reset_chip(vha, flag == A84_ISSUE_RESET_DIAG_FW);
@@ -1032,6 +1046,10 @@ qla84xx_updatefw(struct bsg_job *bsg_job
 		return -EINVAL;
 	}
 
+	if (bsg_job->request_len <
+	    sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t))
+		return -EINVAL;
+
 	sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
 		bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
 	if (!sg_cnt) {
@@ -1482,6 +1500,10 @@ qla2x00_read_optrom(struct bsg_job *bsg_
 	struct qla_hw_data *ha = vha->hw;
 	int rval = 0;
 
+	if (bsg_job->request_len <
+	    sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t))
+		return -EINVAL;
+
 	if (ha->flags.nic_core_reset_hdlr_active)
 		return -EBUSY;
 
@@ -1519,6 +1541,10 @@ qla2x00_update_optrom(struct bsg_job *bs
 	struct qla_hw_data *ha = vha->hw;
 	int rval = 0;
 
+	if (bsg_job->request_len <
+	    sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t))
+		return -EINVAL;
+
 	mutex_lock(&ha->optrom_mutex);
 	rval = qla2x00_optrom_setup(bsg_job, vha, 1);
 	if (rval) {
@@ -2010,6 +2036,11 @@ qlafx00_mgmt_cmd(struct bsg_job *bsg_job
 	struct fc_port *fcport;
 	char  *type = "FC_BSG_HST_FX_MGMT";
 
+	if (bsg_job->request_len <
+	    sizeof(struct fc_bsg_request) + sizeof(uint32_t) +
+	    sizeof(struct qla_mt_iocb_rqst_fx00))
+		return -EINVAL;
+
 	/* Copy the IOCB specific information */
 	piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
 	    &bsg_request->rqst_data.h_vendor.vendor_cmd[1];
@@ -2899,6 +2930,13 @@ qla2x00_process_vendor_specific(struct s
 {
 	struct fc_bsg_request *bsg_request = bsg_job->request;
 
+	if (bsg_job->request_len <
+	    sizeof(struct fc_bsg_request) + sizeof(uint32_t)) {
+		ql_log(ql_log_warn, vha, 0x7000,
+		       "BSG request too small for vendor cmd.\n");
+		return -EINVAL;
+	}
+
 	ql_dbg(ql_dbg_edif, vha, 0x911b, "%s FC_BSG_HST_VENDOR cmd[0]=0x%x\n",
 	    __func__, bsg_request->rqst_data.h_vendor.vendor_cmd[0]);
 
@@ -3024,8 +3062,11 @@ qla24xx_bsg_request(struct bsg_job *bsg_
 	}
 
 	/* Disable port will bring down the chip, allow enable command */
-	if (bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_MANAGE_HOST_PORT ||
-	    bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_GET_HOST_STATS)
+	if (bsg_request->msgcode == FC_BSG_HST_VENDOR &&
+	    bsg_job->request_len >=
+		sizeof(struct fc_bsg_request) + sizeof(uint32_t) &&
+	    (bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_MANAGE_HOST_PORT ||
+	     bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_GET_HOST_STATS))
 		goto skip_chip_chk;
 
 	if (vha->hw->flags.port_isolated) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 686/877] f2fs: validate MOVE_RANGE destination size
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (684 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 685/877] scsi: qla2xxx: Validate BSG request_len before reading vendor_cmd[] Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 687/877] f2fs: convert F2FS_I_SB to sbi in f2fs_setattr() Greg Kroah-Hartman
                   ` (198 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, stable, Wenjie Qi, Chao Yu,
	Jaegeuk Kim, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wenjie Qi <qwjhust@gmail.com>

[ Upstream commit e533889fc26aea0cd83c90327063f272061dd820 ]

F2FS_IOC_MOVE_RANGE checks the source range, but not the destination end
before updating i_size. A source hole can expose this: __clone_blkaddrs()
skips NULL_ADDR entries and returns success, so the caller can still extend
the destination inode with unchecked pos_out + len.

Reject destination overflow and use inode_newsize_ok() before extending
the destination inode.

Fixes: 4dd6f977fc77 ("f2fs: support an ioctl to move a range of data blocks")
Cc: stable@kernel.org
Assisted-by: Codex:gpt-5.5
Signed-off-by: Wenjie Qi <qiwenjie@xiaomi.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ Adjusted declaration context for the missing `struct f2fs_lock_context lc`. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/f2fs/file.c |   16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -3100,8 +3100,9 @@ static int f2fs_move_file_range(struct f
 	struct inode *src = file_inode(file_in);
 	struct inode *dst = file_inode(file_out);
 	struct f2fs_sb_info *sbi = F2FS_I_SB(src);
-	size_t olen = len, dst_max_i_size = 0;
-	size_t dst_osize;
+	size_t olen = len;
+	loff_t dst_max_i_size = 0;
+	loff_t dst_osize, dst_end;
 	int ret;
 
 	if (file_in->f_path.mnt != file_out->f_path.mnt ||
@@ -3158,8 +3159,15 @@ static int f2fs_move_file_range(struct f
 	}
 
 	dst_osize = dst->i_size;
-	if (pos_out + olen > dst->i_size)
-		dst_max_i_size = pos_out + olen;
+	if (olen > LLONG_MAX - pos_out)
+		goto out_unlock;
+	dst_end = pos_out + olen;
+	if (dst_end > dst->i_size) {
+		ret = inode_newsize_ok(dst, dst_end);
+		if (ret)
+			goto out_unlock;
+		dst_max_i_size = dst_end;
+	}
 
 	/* verify the end result is block aligned */
 	if (!IS_ALIGNED(pos_in, F2FS_BLKSIZE) ||



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 687/877] f2fs: convert F2FS_I_SB to sbi in f2fs_setattr()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (685 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 686/877] f2fs: validate MOVE_RANGE destination size Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 688/877] f2fs: dont allow unaligned truncation to smaller/equal size on pinned file Greg Kroah-Hartman
                   ` (197 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, wangzijie, Chao Yu, Jaegeuk Kim,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: wangzijie <wangzijie1@honor.com>

[ Upstream commit 90c5ce37adf074ed85b26d1cd43074f29c0743ba ]

Introduce sbi in f2fs_setattr() and convert F2FS_I_SB to it. No logic
change, just cleanup and prepare to get CAP_BLKS_PER_SEC(sbi).

Signed-off-by: wangzijie <wangzijie1@honor.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Stable-dep-of: d0a481fad5c7 ("f2fs: fix to avoid potential section-unaligned pinfile")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/f2fs/file.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -1064,9 +1064,10 @@ int f2fs_setattr(struct mnt_idmap *idmap
 {
 	struct inode *inode = d_inode(dentry);
 	struct f2fs_inode_info *fi = F2FS_I(inode);
+	struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
 	int err;
 
-	if (unlikely(f2fs_cp_error(F2FS_I_SB(inode))))
+	if (unlikely(f2fs_cp_error(sbi)))
 		return -EIO;
 
 	err = setattr_prepare(idmap, dentry, attr);
@@ -1105,12 +1106,11 @@ int f2fs_setattr(struct mnt_idmap *idmap
 	}
 	if (i_uid_needs_update(idmap, attr, inode) ||
 	    i_gid_needs_update(idmap, attr, inode)) {
-		f2fs_lock_op(F2FS_I_SB(inode));
+		f2fs_lock_op(sbi);
 		err = dquot_transfer(idmap, inode, attr);
 		if (err) {
-			set_sbi_flag(F2FS_I_SB(inode),
-					SBI_QUOTA_NEED_REPAIR);
-			f2fs_unlock_op(F2FS_I_SB(inode));
+			set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR);
+			f2fs_unlock_op(sbi);
 			return err;
 		}
 		/*
@@ -1120,7 +1120,7 @@ int f2fs_setattr(struct mnt_idmap *idmap
 		i_uid_update(idmap, attr, inode);
 		i_gid_update(idmap, attr, inode);
 		f2fs_mark_inode_dirty_sync(inode, true);
-		f2fs_unlock_op(F2FS_I_SB(inode));
+		f2fs_unlock_op(sbi);
 	}
 
 	if (attr->ia_valid & ATTR_SIZE) {
@@ -1188,7 +1188,7 @@ err_out:
 	f2fs_mark_inode_dirty_sync(inode, true);
 
 	/* inode change will produce dirty node pages flushed by checkpoint */
-	f2fs_balance_fs(F2FS_I_SB(inode), true);
+	f2fs_balance_fs(sbi, true);
 
 	return err;
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 688/877] f2fs: dont allow unaligned truncation to smaller/equal size on pinned file
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (686 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 687/877] f2fs: convert F2FS_I_SB to sbi in f2fs_setattr() Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 689/877] f2fs: fix to avoid potential section-unaligned pinfile Greg Kroah-Hartman
                   ` (196 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, wangzijie, Chao Yu, Jaegeuk Kim,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: wangzijie <wangzijie1@honor.com>

[ Upstream commit d738f708564764ed591cb6ab50d55489f87c726a ]

To prevent scattered pin block generation, don't allow non-section aligned truncation
to smaller or equal size on pinned file. But for truncation to larger size, after
commit 3fdd89b452c2("f2fs: prevent writing without fallocate() for pinned files"),
we only support overwrite IO to pinned file, so we don't need to consider
attr->ia_size > i_size case.

Signed-off-by: wangzijie <wangzijie1@honor.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Stable-dep-of: d0a481fad5c7 ("f2fs: fix to avoid potential section-unaligned pinfile")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/f2fs/file.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -1097,6 +1097,17 @@ int f2fs_setattr(struct mnt_idmap *idmap
 			!IS_ALIGNED(attr->ia_size,
 			F2FS_BLK_TO_BYTES(fi->i_cluster_size)))
 			return -EINVAL;
+		/*
+		 * To prevent scattered pin block generation, we don't allow
+		 * smaller/equal size unaligned truncation for pinned file.
+		 * We only support overwrite IO to pinned file, so don't
+		 * care about larger size truncation.
+		 */
+		if (f2fs_is_pinned_file(inode) &&
+			attr->ia_size <= i_size_read(inode) &&
+			!IS_ALIGNED(attr->ia_size,
+			F2FS_BLK_TO_BYTES(CAP_BLKS_PER_SEC(sbi))))
+			return -EINVAL;
 	}
 
 	if (is_quota_modification(idmap, inode, attr)) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 689/877] f2fs: fix to avoid potential section-unaligned pinfile
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (687 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 688/877] f2fs: dont allow unaligned truncation to smaller/equal size on pinned file Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 690/877] f2fs: dirty directory inodes on mtime/ctime update Greg Kroah-Hartman
                   ` (195 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, stable, Daeho Jeong, Chao Yu,
	Jaegeuk Kim, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Chao Yu <chao@kernel.org>

[ Upstream commit d0a481fad5c7a3a56ecf54a099651216869f4d0a ]

Blocks of pinfile may not aligned to section size due to wrong use
on pinfile, result in heavy overhead of GC, let avoid this by
adding additional check condition in f2fs_setattr().

- truncate -s 8mb pinfile
: random checkpoint may persist filesize w/ inode
- fallocate -o 0 -l 8mb pinfile
 - f2fs_fallocate
  - f2fs_expand_inode_data
   - f2fs_allocate_pinning_section
   - f2fs_map_blocks
    - f2fs_map_lock
    - __allocate_data_block
    - file_need_truncate
    : w/ FADVISE_TRUNC_BIT, we can expect unaligned mapping can be
      truncated while open() if f2fs is not umount abnormally
    - f2fs_map_unlock
    : following f2fs checkpoint and sudden power-cut

- mount
- open pinfile
 - f2fs_file_open
  - finish_preallocate_blocks
   - truncate_setsize
   : filesize is 8mb
   - f2fs_truncate
   : can only truncate block outside filesize, rather than truncating
     unaligned blocks inside filesize

Fixes: f5a53edcf01e ("f2fs: support aligned pinned file")
Cc: stable@kernel.org
Cc: Daeho Jeong <daehojeong@google.com>
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/f2fs/file.c |   28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -1097,17 +1097,23 @@ int f2fs_setattr(struct mnt_idmap *idmap
 			!IS_ALIGNED(attr->ia_size,
 			F2FS_BLK_TO_BYTES(fi->i_cluster_size)))
 			return -EINVAL;
-		/*
-		 * To prevent scattered pin block generation, we don't allow
-		 * smaller/equal size unaligned truncation for pinned file.
-		 * We only support overwrite IO to pinned file, so don't
-		 * care about larger size truncation.
-		 */
-		if (f2fs_is_pinned_file(inode) &&
-			attr->ia_size <= i_size_read(inode) &&
-			!IS_ALIGNED(attr->ia_size,
-			F2FS_BLK_TO_BYTES(CAP_BLKS_PER_SEC(sbi))))
-			return -EINVAL;
+
+		if (f2fs_is_pinned_file(inode)) {
+			/*
+			 * It may break section-aligned fallocate recovery
+			 * mechanism, so do not allow larger size truncation.
+			 */
+			if (attr->ia_size > i_size_read(inode))
+				return -EINVAL;
+			/*
+			 * To prevent scattered pin block generation, we don't
+			 * allow smaller/equal size unaligned truncation for
+			 * pinned file.
+			 */
+			else if (!IS_ALIGNED(attr->ia_size,
+				F2FS_BLK_TO_BYTES(CAP_BLKS_PER_SEC(sbi))))
+				return -EINVAL;
+		}
 	}
 
 	if (is_quota_modification(idmap, inode, attr)) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 690/877] f2fs: dirty directory inodes on mtime/ctime update
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (688 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 689/877] f2fs: fix to avoid potential section-unaligned pinfile Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 691/877] f2fs: limit recovery filename logging to stored length Greg Kroah-Hartman
                   ` (194 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Joanne Chang, Chao Yu, Jaegeuk Kim,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Joanne Chang <joannechien@google.com>

[ Upstream commit 9ec09d5f4b317a417c8655c14056f70cbe71eb6c ]

Xfstests generic/547 sometimes fail with mismatched directory metadata
before and after a power failure. This happens because when a directory
entry is added, renamed, or deleted, its mtime and ctime are updated and
the inode is marked dirty via
f2fs_mark_inode_dirty_sync(dir, sync=false). The sync=false flag means
the dirty inode is not added to the global DIRTY_META list. Therefore,
subsequent checkpoints skip flushing these updated directory blocks,
causing directory timestamps to revert to stale values after a sudden
power failure.

Address this by changing the dirtying parameter to sync=true during
directory entry mutations and renames. This forces F2FS to immediately
queue the updated directory blocks on the global DIRTY_META list,
ensuring timestamps are committed to checkpoints.

Fixes: 7c45729a4d6d ("f2fs: keep dirty inodes selectively for checkpoint")
Cc: stable@vger.kernel.org
Signed-off-by: Joanne Chang <joannechien@google.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ Adjusted f2fs_set_link() context to retain f2fs_put_page(page, 1) instead of f2fs_folio_put(folio, true). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/f2fs/dir.c    |    6 +++---
 fs/f2fs/inline.c |    2 +-
 fs/f2fs/namei.c  |    6 +++---
 3 files changed, 7 insertions(+), 7 deletions(-)

--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -437,7 +437,7 @@ void f2fs_set_link(struct inode *dir, st
 	set_page_dirty(page);
 
 	inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
-	f2fs_mark_inode_dirty_sync(dir, false);
+	f2fs_mark_inode_dirty_sync(dir, true);
 	f2fs_put_page(page, 1);
 }
 
@@ -591,7 +591,7 @@ void f2fs_update_parent_metadata(struct
 		clear_inode_flag(inode, FI_NEW_INODE);
 	}
 	inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
-	f2fs_mark_inode_dirty_sync(dir, false);
+	f2fs_mark_inode_dirty_sync(dir, true);
 
 	if (F2FS_I(dir)->i_current_depth != current_depth)
 		f2fs_i_depth_write(dir, current_depth);
@@ -903,7 +903,7 @@ void f2fs_delete_entry(struct f2fs_dir_e
 	f2fs_put_page(page, 1);
 
 	inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
-	f2fs_mark_inode_dirty_sync(dir, false);
+	f2fs_mark_inode_dirty_sync(dir, true);
 
 	if (inode)
 		f2fs_drop_nlink(dir, inode);
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -727,7 +727,7 @@ void f2fs_delete_inline_entry(struct f2f
 	f2fs_put_page(page, 1);
 
 	inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
-	f2fs_mark_inode_dirty_sync(dir, false);
+	f2fs_mark_inode_dirty_sync(dir, true);
 
 	if (inode)
 		f2fs_drop_nlink(dir, inode);
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -1038,7 +1038,7 @@ static int f2fs_rename(struct mnt_idmap
 	f2fs_up_write(&F2FS_I(old_inode)->i_sem);
 
 	inode_set_ctime_current(old_inode);
-	f2fs_mark_inode_dirty_sync(old_inode, false);
+	f2fs_mark_inode_dirty_sync(old_inode, true);
 
 	f2fs_delete_entry(old_entry, old_page, old_dir, NULL);
 	old_page = NULL;
@@ -1207,7 +1207,7 @@ static int f2fs_cross_rename(struct inod
 		f2fs_i_links_write(old_dir, old_nlink > 0);
 		f2fs_up_write(&F2FS_I(old_dir)->i_sem);
 	}
-	f2fs_mark_inode_dirty_sync(old_dir, false);
+	f2fs_mark_inode_dirty_sync(old_dir, true);
 
 	/* update directory entry info of new dir inode */
 	f2fs_set_link(new_dir, new_entry, new_page, old_inode);
@@ -1226,7 +1226,7 @@ static int f2fs_cross_rename(struct inod
 		f2fs_i_links_write(new_dir, new_nlink > 0);
 		f2fs_up_write(&F2FS_I(new_dir)->i_sem);
 	}
-	f2fs_mark_inode_dirty_sync(new_dir, false);
+	f2fs_mark_inode_dirty_sync(new_dir, true);
 
 	if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) {
 		f2fs_add_ino_entry(sbi, old_dir->i_ino, TRANS_DIR_INO);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 691/877] f2fs: limit recovery filename logging to stored length
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (689 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 690/877] f2fs: dirty directory inodes on mtime/ctime update Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 692/877] f2fs: fix dentry folio leak in find_in_level Greg Kroah-Hartman
                   ` (193 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, stable, Wenjie Qi, Chao Yu,
	Jaegeuk Kim, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wenjie Qi <qwjhust@gmail.com>

[ Upstream commit 01027b2fcb74dade59fb833b51023f6593b6a9a2 ]

F2FS stores recovery filenames as a length plus a fixed-size i_name
buffer.  The buffer is not NUL-terminated, but recover_inode() and
recover_dentry() print it with %s.

For a 255-byte filename, recovery logging can read past i_name into the
following raw inode fields.

Print the name with a precision bounded by i_namelen and F2FS_NAME_LEN.

Fixes: f356fe0cba0e ("f2fs: add debug msgs in the recovery routine")
Cc: stable@kernel.org
Assisted-by: Codex:gpt-5.5
Signed-off-by: Wenjie Qi <qiwenjie@xiaomi.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ adapted folio references to pages and retained %lx formatting for unsigned long inode numbers ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/f2fs/recovery.c |   41 +++++++++++++++++++++++++++--------------
 1 file changed, 27 insertions(+), 14 deletions(-)

--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -157,6 +157,22 @@ static int init_recovered_filename(const
 	return 0;
 }
 
+static const char *recover_printable_name(struct inode *inode,
+					  struct f2fs_inode *raw,
+					  int *name_len)
+{
+	static const char encrypted_name[] = "<encrypted>";
+
+	if (file_enc_name(inode)) {
+		*name_len = sizeof(encrypted_name) - 1;
+		return encrypted_name;
+	}
+
+	*name_len = min_t(unsigned int, le32_to_cpu(raw->i_namelen),
+			  F2FS_NAME_LEN);
+	return raw->i_name;
+}
+
 static int recover_dentry(struct inode *inode, struct page *ipage,
 						struct list_head *dir_list)
 {
@@ -169,7 +185,8 @@ static int recover_dentry(struct inode *
 	struct inode *dir, *einode;
 	struct fsync_inode_entry *entry;
 	int err = 0;
-	char *name;
+	const char *name;
+	int name_len;
 
 	entry = get_fsync_inode(dir_list, pino);
 	if (!entry) {
@@ -228,12 +245,9 @@ retry:
 out_put:
 	f2fs_put_page(page, 0);
 out:
-	if (file_enc_name(inode))
-		name = "<encrypted>";
-	else
-		name = raw_inode->i_name;
-	f2fs_notice(F2FS_I_SB(inode), "%s: ino = %x, name = %s, dir = %lx, err = %d",
-		    __func__, ino_of_node(ipage), name,
+	name = recover_printable_name(inode, raw_inode, &name_len);
+	f2fs_notice(F2FS_I_SB(inode), "%s: ino = %x, name = %.*s, dir = %lx, err = %d",
+		    __func__, ino_of_node(ipage), name_len, name,
 		    IS_ERR(dir) ? 0 : dir->i_ino, err);
 	return err;
 }
@@ -281,7 +295,8 @@ static int recover_inode(struct inode *i
 {
 	struct f2fs_inode *raw = F2FS_INODE(page);
 	struct f2fs_inode_info *fi = F2FS_I(inode);
-	char *name;
+	const char *name;
+	int name_len;
 	int err;
 
 	inode->i_mode = le16_to_cpu(raw->i_mode);
@@ -330,13 +345,11 @@ static int recover_inode(struct inode *i
 
 	f2fs_mark_inode_dirty_sync(inode, true);
 
-	if (file_enc_name(inode))
-		name = "<encrypted>";
-	else
-		name = F2FS_INODE(page)->i_name;
+	name = recover_printable_name(inode, raw, &name_len);
 
-	f2fs_notice(F2FS_I_SB(inode), "recover_inode: ino = %x, name = %s, inline = %x",
-		    ino_of_node(page), name, raw->i_inline);
+	f2fs_notice(F2FS_I_SB(inode), "%s: ino = %x, name = %.*s, inline = %x",
+		    __func__, ino_of_node(page), name_len, name,
+		    raw->i_inline);
 	return 0;
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 692/877] f2fs: fix dentry folio leak in find_in_level
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (690 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 691/877] f2fs: limit recovery filename logging to stored length Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 693/877] f2fs: embed f2fs_gc_kthread in f2fs_sb_info Greg Kroah-Hartman
                   ` (192 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Chao Yu, Guanghui Yang, Jaegeuk Kim,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Guanghui Yang <3497809730@qq.com>

[ Upstream commit cca7d3e30bf30333314e31bc70b9a739f1342167 ]

find_in_level() gets a dentry folio with f2fs_find_data_folio() before
calling find_in_block().  If find_in_block() returns an error, the
function stores the error in res_folio and breaks out of the loop without
dropping the dentry folio.

This leaks the folio reference on the find_in_block() error path.  Drop
the dentry folio before returning the error to the caller.

Fixes: 7ad08a58bf67 ("f2fs: Handle casefolding with Encryption")
Cc: stable@vger.kernel.org
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Guanghui Yang <3497809730@qq.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ Replaced f2fs_folio_put(dentry_folio, false) with f2fs_put_page(dentry_page, 0) for the page-based API. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/f2fs/dir.c |    1 +
 1 file changed, 1 insertion(+)

--- a/fs/f2fs/dir.c
+++ b/fs/f2fs/dir.c
@@ -298,6 +298,7 @@ start_find_bucket:
 
 		de = find_in_block(dir, dentry_page, fname, &max_slots, use_hash);
 		if (IS_ERR(de)) {
+			f2fs_put_page(dentry_page, 0);
 			*res_page = ERR_CAST(de);
 			de = NULL;
 			break;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 693/877] f2fs: embed f2fs_gc_kthread in f2fs_sb_info
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (691 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 692/877] f2fs: fix dentry folio leak in find_in_level Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 694/877] f2fs: Convert clear_node_page_dirty() to clear_node_folio_dirty() Greg Kroah-Hartman
                   ` (191 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, stable, Chao Yu, Jaegeuk Kim,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Chao Yu <chao@kernel.org>

[ Upstream commit 3d7bca9d583793bb7d0bac0d95a24ddd2e129eed ]

Instead of allocating f2fs_gc_kthread dynamically, embed it in
f2fs_sb_info. This simplifies lifetime management and prepares for
fixing race conditions during teardown.

- __sbi_store			- remount|shutdown
				 - f2fs_stop_gc_thread
 - access sbi->gc_thread
				  - sbi->gc_thread = NULL
 - access sbi->gc_thread->f2fs_gc_task

Fixes: 52190933c37a ("f2fs: sysfs: introduce critical_task_priority")
Fixes: 7950e9ac638e ("f2fs: stop gc/discard thread after fs shutdown")
Cc: stable@kernel.org
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ adapted the valid_thresh_ratio member-access conversion to get_gc_cost() instead of f2fs_get_victim(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/f2fs/debug.c   |    4 ----
 fs/f2fs/f2fs.h    |   29 ++++++++++++++++++++++++++++-
 fs/f2fs/gc.c      |   36 +++++++++++++++---------------------
 fs/f2fs/gc.h      |   25 -------------------------
 fs/f2fs/segment.c |    9 ++++-----
 fs/f2fs/super.c   |    4 ++--
 fs/f2fs/sysfs.c   |   18 +++++++++---------
 7 files changed, 58 insertions(+), 67 deletions(-)

--- a/fs/f2fs/debug.c
+++ b/fs/f2fs/debug.c
@@ -285,10 +285,6 @@ static void update_mem_info(struct f2fs_
 get_cache:
 	si->cache_mem = 0;
 
-	/* build gc */
-	if (sbi->gc_thread)
-		si->cache_mem += sizeof(struct f2fs_gc_kthread);
-
 	/* build merge flush thread */
 	if (SM_I(sbi)->fcc_info)
 		si->cache_mem += sizeof(struct flush_cmd_control);
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1578,6 +1578,33 @@ struct decompress_io_ctx {
 #define MAX_COMPRESS_LOG_SIZE		8
 #define MAX_COMPRESS_WINDOW_SIZE(log_size)	((PAGE_SIZE) << (log_size))
 
+struct f2fs_gc_kthread {
+	struct task_struct *f2fs_gc_task;
+	wait_queue_head_t gc_wait_queue_head;
+
+	/* for gc sleep time */
+	unsigned int urgent_sleep_time;
+	unsigned int min_sleep_time;
+	unsigned int max_sleep_time;
+	unsigned int no_gc_sleep_time;
+
+	/* for changing gc mode */
+	bool gc_wake;
+
+	/* for GC_MERGE mount option */
+	wait_queue_head_t fggc_wq;		/*
+						 * caller of f2fs_balance_fs()
+						 * will wait on this wait queue.
+						 */
+
+	/* for gc control for zoned devices */
+	unsigned int no_zoned_gc_percent;
+	unsigned int boost_zoned_gc_percent;
+	unsigned int valid_thresh_ratio;
+	unsigned int boost_gc_multiple;
+	unsigned int boost_gc_greedy;
+};
+
 struct f2fs_sb_info {
 	struct super_block *sb;			/* pointer to VFS super block */
 	struct proc_dir_entry *s_proc;		/* proc entry */
@@ -1702,7 +1729,7 @@ struct f2fs_sb_info {
 						 * semaphore for GC, avoid
 						 * race between GC and GC or CP
 						 */
-	struct f2fs_gc_kthread	*gc_thread;	/* GC thread */
+	struct f2fs_gc_kthread gc_thread;	/* GC thread */
 	struct atgc_management am;		/* atgc management */
 	unsigned int cur_victim_sec;		/* current victim section num */
 	unsigned int gc_mode;			/* current GC state */
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -31,9 +31,9 @@ static unsigned int count_bits(const uns
 static int gc_thread_func(void *data)
 {
 	struct f2fs_sb_info *sbi = data;
-	struct f2fs_gc_kthread *gc_th = sbi->gc_thread;
-	wait_queue_head_t *wq = &sbi->gc_thread->gc_wait_queue_head;
-	wait_queue_head_t *fggc_wq = &sbi->gc_thread->fggc_wq;
+	struct f2fs_gc_kthread *gc_th = &sbi->gc_thread;
+	wait_queue_head_t *wq = &sbi->gc_thread.gc_wait_queue_head;
+	wait_queue_head_t *fggc_wq = &sbi->gc_thread.fggc_wq;
 	unsigned int wait_ms;
 	struct f2fs_gc_control gc_control = {
 		.victim_segno = NULL_SEGNO,
@@ -191,13 +191,9 @@ next:
 
 int f2fs_start_gc_thread(struct f2fs_sb_info *sbi)
 {
-	struct f2fs_gc_kthread *gc_th;
+	struct f2fs_gc_kthread *gc_th = &sbi->gc_thread;
 	dev_t dev = sbi->sb->s_bdev->bd_dev;
 
-	gc_th = f2fs_kmalloc(sbi, sizeof(struct f2fs_gc_kthread), GFP_KERNEL);
-	if (!gc_th)
-		return -ENOMEM;
-
 	gc_th->urgent_sleep_time = DEF_GC_THREAD_URGENT_SLEEP_TIME;
 	gc_th->valid_thresh_ratio = DEF_GC_THREAD_VALID_THRESH_RATIO;
 	gc_th->boost_gc_multiple = BOOST_GC_MULTIPLE;
@@ -219,16 +215,14 @@ int f2fs_start_gc_thread(struct f2fs_sb_
 
 	gc_th->gc_wake = false;
 
-	sbi->gc_thread = gc_th;
-	init_waitqueue_head(&sbi->gc_thread->gc_wait_queue_head);
-	init_waitqueue_head(&sbi->gc_thread->fggc_wq);
-	sbi->gc_thread->f2fs_gc_task = kthread_run(gc_thread_func, sbi,
+	init_waitqueue_head(&gc_th->gc_wait_queue_head);
+	init_waitqueue_head(&gc_th->fggc_wq);
+	gc_th->f2fs_gc_task = kthread_run(gc_thread_func, sbi,
 			"f2fs_gc-%u:%u", MAJOR(dev), MINOR(dev));
 	if (IS_ERR(gc_th->f2fs_gc_task)) {
 		int err = PTR_ERR(gc_th->f2fs_gc_task);
 
-		kfree(gc_th);
-		sbi->gc_thread = NULL;
+		gc_th->f2fs_gc_task = NULL;
 		return err;
 	}
 
@@ -237,14 +231,14 @@ int f2fs_start_gc_thread(struct f2fs_sb_
 
 void f2fs_stop_gc_thread(struct f2fs_sb_info *sbi)
 {
-	struct f2fs_gc_kthread *gc_th = sbi->gc_thread;
+	struct f2fs_gc_kthread *gc_th = &sbi->gc_thread;
 
-	if (!gc_th)
+	if (!gc_th->f2fs_gc_task)
 		return;
+
 	kthread_stop(gc_th->f2fs_gc_task);
+	gc_th->f2fs_gc_task = NULL;
 	wake_up_all(&gc_th->fggc_wq);
-	kfree(gc_th);
-	sbi->gc_thread = NULL;
 }
 
 static int select_gc_type(struct f2fs_sb_info *sbi, int gc_type)
@@ -406,7 +400,7 @@ static inline unsigned int get_gc_cost(s
 		return get_seg_entry(sbi, segno)->ckpt_valid_blocks;
 
 	if (p->one_time_gc && (get_valid_blocks(sbi, segno, true) >=
-		CAP_BLKS_PER_SEC(sbi) * sbi->gc_thread->valid_thresh_ratio /
+		CAP_BLKS_PER_SEC(sbi) * sbi->gc_thread.valid_thresh_ratio /
 		100))
 		return UINT_MAX;
 
@@ -1795,9 +1789,9 @@ static int do_garbage_collect(struct f2f
 
 			if (f2fs_sb_has_blkzoned(sbi) &&
 					!has_enough_free_blocks(sbi,
-					sbi->gc_thread->boost_zoned_gc_percent))
+					sbi->gc_thread.boost_zoned_gc_percent))
 				window_granularity *=
-					sbi->gc_thread->boost_gc_multiple;
+					sbi->gc_thread.boost_gc_multiple;
 
 			end_segno = start_segno + window_granularity;
 		}
--- a/fs/f2fs/gc.h
+++ b/fs/f2fs/gc.h
@@ -45,32 +45,7 @@
 
 #define NR_GC_CHECKPOINT_SECS (3)	/* data/node/dentry sections */
 
-struct f2fs_gc_kthread {
-	struct task_struct *f2fs_gc_task;
-	wait_queue_head_t gc_wait_queue_head;
 
-	/* for gc sleep time */
-	unsigned int urgent_sleep_time;
-	unsigned int min_sleep_time;
-	unsigned int max_sleep_time;
-	unsigned int no_gc_sleep_time;
-
-	/* for changing gc mode */
-	bool gc_wake;
-
-	/* for GC_MERGE mount option */
-	wait_queue_head_t fggc_wq;		/*
-						 * caller of f2fs_balance_fs()
-						 * will wait on this wait queue.
-						 */
-
-	/* for gc control for zoned devices */
-	unsigned int no_zoned_gc_percent;
-	unsigned int boost_zoned_gc_percent;
-	unsigned int valid_thresh_ratio;
-	unsigned int boost_gc_multiple;
-	unsigned int boost_gc_greedy;
-};
 
 struct gc_inode_list {
 	struct list_head ilist;
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -441,15 +441,14 @@ void f2fs_balance_fs(struct f2fs_sb_info
 	f2fs_submit_merged_write(sbi, DATA);
 	f2fs_submit_all_merged_ipu_writes(sbi);
 
-	if (test_opt(sbi, GC_MERGE) && sbi->gc_thread &&
-				sbi->gc_thread->f2fs_gc_task) {
+	if (test_opt(sbi, GC_MERGE) && sbi->gc_thread.f2fs_gc_task) {
 		DEFINE_WAIT(wait);
 
-		prepare_to_wait(&sbi->gc_thread->fggc_wq, &wait,
+		prepare_to_wait(&sbi->gc_thread.fggc_wq, &wait,
 					TASK_UNINTERRUPTIBLE);
-		wake_up(&sbi->gc_thread->gc_wait_queue_head);
+		wake_up(&sbi->gc_thread.gc_wait_queue_head);
 		io_schedule();
-		finish_wait(&sbi->gc_thread->fggc_wq, &wait);
+		finish_wait(&sbi->gc_thread.fggc_wq, &wait);
 	} else {
 		struct f2fs_gc_control gc_control = {
 			.victim_segno = NULL_SEGNO,
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2492,11 +2492,11 @@ static int f2fs_remount(struct super_blo
 	if ((*flags & SB_RDONLY) ||
 			(F2FS_OPTION(sbi).bggc_mode == BGGC_MODE_OFF &&
 			!test_opt(sbi, GC_MERGE))) {
-		if (sbi->gc_thread) {
+		if (sbi->gc_thread.f2fs_gc_task) {
 			f2fs_stop_gc_thread(sbi);
 			need_restart_gc = true;
 		}
-	} else if (!sbi->gc_thread) {
+	} else if (!sbi->gc_thread.f2fs_gc_task) {
 		err = f2fs_start_gc_thread(sbi);
 		if (err)
 			goto restore_opts;
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -74,7 +74,7 @@ static ssize_t f2fs_sbi_show(struct f2fs
 static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type)
 {
 	if (struct_type == GC_THREAD)
-		return (unsigned char *)sbi->gc_thread;
+		return (unsigned char *)&sbi->gc_thread;
 	else if (struct_type == SM_INFO)
 		return (unsigned char *)SM_I(sbi);
 	else if (struct_type == DCC_INFO)
@@ -631,20 +631,20 @@ out:
 			sbi->gc_mode = GC_NORMAL;
 		} else if (t == 1) {
 			sbi->gc_mode = GC_URGENT_HIGH;
-			if (sbi->gc_thread) {
-				sbi->gc_thread->gc_wake = true;
+			if (sbi->gc_thread.f2fs_gc_task) {
+				sbi->gc_thread.gc_wake = true;
 				wake_up_interruptible_all(
-					&sbi->gc_thread->gc_wait_queue_head);
+					&sbi->gc_thread.gc_wait_queue_head);
 				wake_up_discard_thread(sbi, true);
 			}
 		} else if (t == 2) {
 			sbi->gc_mode = GC_URGENT_LOW;
 		} else if (t == 3) {
 			sbi->gc_mode = GC_URGENT_MID;
-			if (sbi->gc_thread) {
-				sbi->gc_thread->gc_wake = true;
+			if (sbi->gc_thread.f2fs_gc_task) {
+				sbi->gc_thread.gc_wake = true;
 				wake_up_interruptible_all(
-					&sbi->gc_thread->gc_wait_queue_head);
+					&sbi->gc_thread.gc_wait_queue_head);
 			}
 		} else {
 			return -EINVAL;
@@ -901,14 +901,14 @@ out:
 	if (!strcmp(a->attr.name, "gc_boost_gc_multiple")) {
 		if (t < 1 || t > SEGS_PER_SEC(sbi))
 			return -EINVAL;
-		sbi->gc_thread->boost_gc_multiple = (unsigned int)t;
+		sbi->gc_thread.boost_gc_multiple = (unsigned int)t;
 		return count;
 	}
 
 	if (!strcmp(a->attr.name, "gc_boost_gc_greedy")) {
 		if (t > GC_GREEDY)
 			return -EINVAL;
-		sbi->gc_thread->boost_gc_greedy = (unsigned int)t;
+		sbi->gc_thread.boost_gc_greedy = (unsigned int)t;
 		return count;
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 694/877] f2fs: Convert clear_node_page_dirty() to clear_node_folio_dirty()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (692 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 693/877] f2fs: embed f2fs_gc_kthread in f2fs_sb_info Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 695/877] f2fs: fix to clear dirty flag on folio in error path Greg Kroah-Hartman
                   ` (190 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Matthew Wilcox (Oracle), Chao Yu,
	Jaegeuk Kim, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Matthew Wilcox (Oracle)" <willy@infradead.org>

[ Upstream commit f16ebe0de73274fd1cf885b30cc4fe42d2a1821a ]

Both callers have a folio so pass it in, removing five calls to
compound_head().

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

Backport to 6.12: retain the page-based node interfaces and pass
page_folio() at the two existing cleanup call sites. Use
F2FS_M_SB(folio->mapping), since this tree has no F2FS_F_SB() helper.

Keep a folio reference in __get_node_page() and convert its existing
uptodate clearing and error reporting to use that folio. This preserves
behavior while allowing the one-line error-path change in upstream
commit 5b86eab84ac8e9289b5afc52ef88ab18ba5bacab to cherry-pick cleanly.
No new functions or wider node-interface conversions are needed.

Stable-dep-of: 5b86eab84ac8 ("f2fs: fix to clear dirty flag on folio in error path")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/f2fs/node.c |   22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -125,14 +125,14 @@ bool f2fs_available_free_memory(struct f
 	return res;
 }
 
-static void clear_node_page_dirty(struct page *page)
+static void clear_node_folio_dirty(struct folio *folio)
 {
-	if (PageDirty(page)) {
-		f2fs_clear_page_cache_dirty_tag(page_folio(page));
-		clear_page_dirty_for_io(page);
-		dec_page_count(F2FS_P_SB(page), F2FS_DIRTY_NODES);
+	if (folio_test_dirty(folio)) {
+		f2fs_clear_page_cache_dirty_tag(folio);
+		folio_clear_dirty_for_io(folio);
+		dec_page_count(F2FS_M_SB(folio->mapping), F2FS_DIRTY_NODES);
 	}
-	ClearPageUptodate(page);
+	folio_clear_uptodate(folio);
 }
 
 static struct page *get_current_nat_page(struct f2fs_sb_info *sbi, nid_t nid)
@@ -941,7 +941,7 @@ static int truncate_node(struct dnode_of
 		f2fs_inode_synced(dn->inode);
 	}
 
-	clear_node_page_dirty(dn->node_page);
+	clear_node_folio_dirty(page_folio(dn->node_page));
 	set_sbi_flag(sbi, SBI_IS_DIRTY);
 
 	index = page_folio(dn->node_page)->index;
@@ -1394,7 +1394,7 @@ struct page *f2fs_new_node_page(struct d
 		inc_valid_inode_count(sbi);
 	return page;
 fail:
-	clear_node_page_dirty(page);
+	clear_node_folio_dirty(page_folio(page));
 	f2fs_put_page(page, 1);
 	return ERR_PTR(err);
 }
@@ -1476,6 +1476,7 @@ static struct page *__get_node_page(stru
 					struct page *parent, int start)
 {
 	struct page *page;
+	struct folio *folio;
 	int err;
 
 	if (!nid)
@@ -1487,6 +1488,7 @@ repeat:
 	if (!page)
 		return ERR_PTR(-ENOMEM);
 
+	folio = page_folio(page);
 	err = read_node_page(page, 0);
 	if (err < 0) {
 		goto out_put_err;
@@ -1526,11 +1528,11 @@ page_hit:
 	f2fs_handle_error(sbi, ERROR_INCONSISTENT_FOOTER);
 	err = -EFSCORRUPTED;
 out_err:
-	ClearPageUptodate(page);
+	folio_clear_uptodate(folio);
 out_put_err:
 	/* ENOENT comes from read_node_page which is not an error. */
 	if (err != -ENOENT)
-		f2fs_handle_page_eio(sbi, page_folio(page), NODE);
+		f2fs_handle_page_eio(sbi, folio, NODE);
 	f2fs_put_page(page, 1);
 	return ERR_PTR(err);
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 695/877] f2fs: fix to clear dirty flag on folio in error path
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (693 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 694/877] f2fs: Convert clear_node_page_dirty() to clear_node_folio_dirty() Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 696/877] f2fs: accurately adjust free_sections during free_segment_range Greg Kroah-Hartman
                   ` (189 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, stable, Chao Yu, Jaegeuk Kim,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Chao Yu <chao@kernel.org>

[ Upstream commit 5b86eab84ac8e9289b5afc52ef88ab18ba5bacab ]

If node block is corrupted due to chksum mismatch or inconsistent
footer info, it needs to drop clear flag of node folio, in order
to persist inconsistent node data to storage.

Cc: stable@kernel.org
Fixes: b42b179bda9f ("f2fs: fix to do checksum even if inode page is uptodate")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/f2fs/node.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1528,7 +1528,7 @@ page_hit:
 	f2fs_handle_error(sbi, ERROR_INCONSISTENT_FOOTER);
 	err = -EFSCORRUPTED;
 out_err:
-	folio_clear_uptodate(folio);
+	clear_node_folio_dirty(folio);
 out_put_err:
 	/* ENOENT comes from read_node_page which is not an error. */
 	if (err != -ENOENT)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 696/877] f2fs: accurately adjust free_sections during free_segment_range
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (694 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 695/877] f2fs: fix to clear dirty flag on folio in error path Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 697/877] drm/amdgpu: Fix missing unwind in amdgpu_ib_schedule() error path Greg Kroah-Hartman
                   ` (188 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Daeho Jeong, Sunmin Jeong, Chao Yu,
	Jaegeuk Kim, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Daeho Jeong <daehojeong@google.com>

[ Upstream commit 8c963d1738fdca400082ff5f9d99e083de4f4e70 ]

In free_segment_range(), MAIN_SECS(sbi) is temporarily reduced by `secs`
to restrict block allocation to the safe remaining main area while valid
blocks in the truncated range are evacuated by GC.

However, FREE_I(sbi)->free_sections tracks the total number of free
sections across the whole filesystem. If any sections within the
truncated range were already free upon entering free_segment_range(),
failing to deduct them from free_sections causes the filesystem to
overestimate available free sections in the active, reduced main area.
This leads to inconsistent free section accounting during GC data
migration and can trigger unexpected allocation failures or assertion
errors when space is tight.

Fix this by calculating the number of already-free sections in the
truncated range, deducting them from free_sections upon entering
free_segment_range(), and restoring them on exit.

Fixes: b4b10061ef98 ("f2fs: refactor resize_fs to avoid meta updates in progress")
Cc: stable@vger.kernel.org
Signed-off-by: Daeho Jeong <daehojeong@google.com>
Signed-off-by: Sunmin Jeong <s_min.jeong@samsung.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ retained gc_mode and gc_type declarations needed by the older inline GC reset logic. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/f2fs/gc.c |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -2144,8 +2144,9 @@ int f2fs_gc_range(struct f2fs_sb_info *s
 static int free_segment_range(struct f2fs_sb_info *sbi,
 				unsigned int secs, bool dry_run)
 {
-	unsigned int next_inuse, start, end;
+	unsigned int secno, next_inuse, start, end, end_secno;
 	struct cp_control cpc = { CP_RESIZE, 0, 0, 0 };
+	unsigned int freed_secs = 0;
 	int gc_mode, gc_type;
 	int err = 0;
 	int type;
@@ -2154,6 +2155,7 @@ static int free_segment_range(struct f2f
 	MAIN_SECS(sbi) -= secs;
 	start = MAIN_SECS(sbi) * SEGS_PER_SEC(sbi);
 	end = MAIN_SEGS(sbi) - 1;
+	end_secno = GET_SEC_FROM_SEG(sbi, end);
 
 	mutex_lock(&DIRTY_I(sbi)->seglist_lock);
 	for (gc_mode = 0; gc_mode < MAX_GC_POLICY; gc_mode++)
@@ -2165,6 +2167,14 @@ static int free_segment_range(struct f2f
 			sbi->next_victim_seg[gc_type] = NULL_SEGNO;
 	mutex_unlock(&DIRTY_I(sbi)->seglist_lock);
 
+	spin_lock(&FREE_I(sbi)->segmap_lock);
+	for (secno = MAIN_SECS(sbi); secno <= end_secno; secno++) {
+		if (!test_bit(secno, FREE_I(sbi)->free_secmap))
+			freed_secs++;
+	}
+	FREE_I(sbi)->free_sections -= freed_secs;
+	spin_unlock(&FREE_I(sbi)->segmap_lock);
+
 	/* Move out cursegs from the target range */
 	for (type = CURSEG_HOT_DATA; type < NR_CURSEG_TYPE; type++) {
 		err = f2fs_allocate_segment_for_resize(sbi, type, start, end);
@@ -2189,6 +2199,9 @@ static int free_segment_range(struct f2f
 		f2fs_bug_on(sbi, 1);
 	}
 out:
+	spin_lock(&FREE_I(sbi)->segmap_lock);
+	FREE_I(sbi)->free_sections += freed_secs;
+	spin_unlock(&FREE_I(sbi)->segmap_lock);
 	MAIN_SECS(sbi) += secs;
 	return err;
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 697/877] drm/amdgpu: Fix missing unwind in amdgpu_ib_schedule() error path
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (695 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 696/877] f2fs: accurately adjust free_sections during free_segment_range Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 698/877] drm/amdgpu: add a helper to calculate ring distance Greg Kroah-Hartman
                   ` (187 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Dan Carpenter, Alex Deucher,
	Christian König, Srinivasan Shanmugam, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>

[ Upstream commit ba038065655c45728be346d0b174a6da08d8a5c5 ]

amdgpu_ib_schedule() returns early after calling amdgpu_ring_undo().
This skips the common free_fence cleanup path.  Other error paths were
already changed to use goto free_fence, but this one was missed.

Change the early return to goto free_fence so all error paths clean up
the same way.

Fixes the below:
drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c:232 amdgpu_ib_schedule()
warn: missing unwind goto?

drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
    124 int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs,
    125                        struct amdgpu_ib *ibs, struct amdgpu_job *job,
    126                        struct dma_fence **f)
    127 {

    ...

    224
    225         if (ring->funcs->insert_start)
    226                 ring->funcs->insert_start(ring);
    227
    228         if (job) {
    229                 r = amdgpu_vm_flush(ring, job, need_pipe_sync);
    230                 if (r) {
    231                         amdgpu_ring_undo(ring);
--> 232                         return r;

	The patch changed the other error paths to goto free_fence but
	this one was accidentally skipped.

    233                 }
    234         }
    235
    236         amdgpu_ring_ib_begin(ring);

    ...

    338
    339 free_fence:
    340         if (!job)
    341                 kfree(af);
    342         return r;
    343 }

Fixes: f903b85ed0f1 ("drm/amdgpu: fix possible fence leaks from job structure")
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Christian König <christian.koenig@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Stable-dep-of: 6760f5cb12d2 ("drm/amdgpu: avoid force-completing uninitialized UVD rings")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -217,7 +217,7 @@ int amdgpu_ib_schedule(struct amdgpu_rin
 		r = amdgpu_vm_flush(ring, job, need_pipe_sync);
 		if (r) {
 			amdgpu_ring_undo(ring);
-			return r;
+			goto free_fence;
 		}
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 698/877] drm/amdgpu: add a helper to calculate ring distance
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (696 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 697/877] drm/amdgpu: Fix missing unwind in amdgpu_ib_schedule() error path Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 699/877] drm/amdgpu: plumb timedout fence through to force completion Greg Kroah-Hartman
                   ` (186 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Pierre-Eric Pelloux-Prayer,
	Alex Deucher, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Alex Deucher <alexander.deucher@amd.com>

[ Upstream commit 08e7d6c3cee880bd3ec3eb14c478f9fa805b0bdc ]

Add a helper to calculate the distance in DWs between
two wptrs.

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Stable-dep-of: 6760f5cb12d2 ("drm/amdgpu: avoid force-completing uninitialized UVD rings")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h |   18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -431,6 +431,17 @@ static inline void amdgpu_ring_write_mul
 	ring->count_dw -= count_dw;
 }
 
+static inline unsigned int amdgpu_ring_get_dw_distance(struct amdgpu_ring *ring,
+						       u64 start_wptr, u64 end_wptr)
+{
+	unsigned int start = start_wptr & ring->buf_mask;
+	unsigned int end = end_wptr & ring->buf_mask;
+
+	if (end < start)
+		end += ring->ring_size >> 2;
+	return end - start;
+}
+
 /**
  * amdgpu_ring_patch_cond_exec - patch dw count of conditional execute
  * @ring: amdgpu_ring structure
@@ -441,18 +452,13 @@ static inline void amdgpu_ring_write_mul
 static inline void amdgpu_ring_patch_cond_exec(struct amdgpu_ring *ring,
 					       unsigned int offset)
 {
-	unsigned cur;
-
 	if (!ring->funcs->init_cond_exec)
 		return;
 
 	WARN_ON(offset > ring->buf_mask);
 	WARN_ON(ring->ring[offset] != 0);
 
-	cur = (ring->wptr - 1) & ring->buf_mask;
-	if (cur < offset)
-		cur += ring->ring_size >> 2;
-	ring->ring[offset] = cur - offset;
+	ring->ring[offset] = amdgpu_ring_get_dw_distance(ring, offset, ring->wptr - 1);
 }
 
 #define amdgpu_mes_ctx_get_offs_gpu_addr(ring, offset)			\



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 699/877] drm/amdgpu: plumb timedout fence through to force completion
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (697 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 698/877] drm/amdgpu: add a helper to calculate ring distance Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 700/877] drm/amdgpu: avoid force-completing uninitialized UVD rings Greg Kroah-Hartman
                   ` (185 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Christian König, Alex Deucher,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Alex Deucher <alexander.deucher@amd.com>

[ Upstream commit c184df870db1e328691ea0fbb7d0e59efd9d3f9f ]

When we do a full adapter reset, if we know the timedout fence
mark the fence with -ETIME rather than -ECANCELED so it
gets properly handled by userspace.

v2: rebase

Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

Adapt this dependency to 6.12 without importing newer queue-reset
infrastructure. Drop the SDMA/VCN/JPEG reset hunks and the adjacent
ring-reset helper context because those functions do not exist here.
Keep the two-argument force-completion API and its fence error handling.

Use &job->hw_fence.base for this branch's embedded job fence, and update
the additional per-ring timeout caller in amdgpu_job.c to pass that fence.
Preserve the existing full-reset job-fence clearing and resubmission flow.
The UVD resume caller now matches the context required by the target fix.
No functions are added.

The prerequisite ba038065655c also introduced a goto to the absent
free_fence label in amdgpu_ib_schedule(). Restore the original return r:
6.12 embeds job fences and allocates non-job fences later, in
amdgpu_fence_emit(), so this VM-flush failure path has no new fence to
free. This removes the pre-existing build failure without importing the
newer fence allocation and cleanup infrastructure.

[ sashal: Reduced backport -- upstream c184df870db1e touches 9 file(s), this
  backport carries 7. Not backported here:
  drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c
  drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c
  drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c
  drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
  This note is generated from the file lists only; see the resolution record
  for the reasoning. ]

Stable-dep-of: 6760f5cb12d2 ("drm/amdgpu: avoid force-completing uninitialized UVD rings")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c |    2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c  |    6 +++++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c   |   25 ++++++++++++++++++++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c      |    2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c     |    2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h    |    3 ++-
 drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c     |    2 +-
 7 files changed, 33 insertions(+), 9 deletions(-)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -1962,7 +1962,7 @@ static int amdgpu_debugfs_ib_preempt(voi
 		/* swap out the old fences */
 		amdgpu_ib_preempt_fences_swap(ring, fences);
 
-		amdgpu_fence_driver_force_completion(ring);
+		amdgpu_fence_driver_force_completion(ring, NULL);
 
 		/* resubmit unfinished jobs */
 		amdgpu_ib_preempt_job_recovery(&ring->sched);
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -5470,6 +5470,7 @@ int amdgpu_device_pre_asic_reset(struct
 {
 	int i, r = 0;
 	struct amdgpu_job *job = NULL;
+	struct dma_fence *fence = NULL;
 	struct amdgpu_device *tmp_adev = reset_context->reset_req_dev;
 	bool need_full_reset =
 		test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
@@ -5482,6 +5483,9 @@ int amdgpu_device_pre_asic_reset(struct
 
 	amdgpu_fence_driver_isr_toggle(adev, true);
 
+	if (job)
+		fence = &job->hw_fence.base;
+
 	/* block all schedulers and reset given job's ring */
 	for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
 		struct amdgpu_ring *ring = adev->rings[i];
@@ -5495,7 +5499,7 @@ int amdgpu_device_pre_asic_reset(struct
 		amdgpu_fence_driver_clear_job_fences(ring);
 
 		/* after all hw jobs are reset, hw fence is meaningless, so force_completion */
-		amdgpu_fence_driver_force_completion(ring);
+		amdgpu_fence_driver_force_completion(ring, fence);
 	}
 
 	amdgpu_fence_driver_isr_toggle(adev, false);
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
@@ -594,7 +594,7 @@ void amdgpu_fence_driver_hw_fini(struct
 			r = -ENODEV;
 		/* no need to trigger GPU reset as we are unloading */
 		if (r)
-			amdgpu_fence_driver_force_completion(ring);
+			amdgpu_fence_driver_force_completion(ring, NULL);
 
 		if (!drm_dev_is_unplugged(adev_to_drm(adev)) &&
 		    ring->fence_drv.irq_src &&
@@ -739,11 +739,30 @@ void amdgpu_fence_driver_set_error(struc
  * amdgpu_fence_driver_force_completion - force signal latest fence of ring
  *
  * @ring: fence of the ring to signal
+ * @timedout_fence: fence of the timedout job
  *
  */
-void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring)
+void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring,
+					  struct dma_fence *timedout_fence)
 {
-	amdgpu_fence_driver_set_error(ring, -ECANCELED);
+	struct amdgpu_fence_driver *drv = &ring->fence_drv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&drv->lock, flags);
+	for (unsigned int i = 0; i <= drv->num_fences_mask; ++i) {
+		struct dma_fence *fence;
+
+		fence = rcu_dereference_protected(drv->fences[i],
+						  lockdep_is_held(&drv->lock));
+		if (fence && !dma_fence_is_signaled_locked(fence)) {
+			if (fence == timedout_fence)
+				dma_fence_set_error(fence, -ETIME);
+			else
+				dma_fence_set_error(fence, -ECANCELED);
+		}
+	}
+	spin_unlock_irqrestore(&drv->lock, flags);
+
 	amdgpu_fence_write(ring, ring->fence_drv.sync_seq);
 	amdgpu_fence_process(ring);
 }
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -217,7 +217,7 @@ int amdgpu_ib_schedule(struct amdgpu_rin
 		r = amdgpu_vm_flush(ring, job, need_pipe_sync);
 		if (r) {
 			amdgpu_ring_undo(ring);
-			goto free_fence;
+			return r;
 		}
 	}
 
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -148,7 +148,7 @@ static enum drm_gpu_sched_stat amdgpu_jo
 			if (amdgpu_ring_sched_ready(ring))
 				drm_sched_stop(&ring->sched, s_job);
 			atomic_inc(&ring->adev->gpu_reset_counter);
-			amdgpu_fence_driver_force_completion(ring);
+			amdgpu_fence_driver_force_completion(ring, &job->hw_fence.base);
 			if (amdgpu_ring_sched_ready(ring))
 				drm_sched_start(&ring->sched);
 			goto exit;
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -146,7 +146,8 @@ extern const struct drm_sched_backend_op
 
 void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring);
 void amdgpu_fence_driver_set_error(struct amdgpu_ring *ring, int error);
-void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring);
+void amdgpu_fence_driver_force_completion(struct amdgpu_ring *ring,
+					  struct dma_fence *timedout_fence);
 
 int amdgpu_fence_driver_init_ring(struct amdgpu_ring *ring);
 int amdgpu_fence_driver_start_ring(struct amdgpu_ring *ring,
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -516,7 +516,7 @@ int amdgpu_uvd_resume(struct amdgpu_devi
 			}
 			memset_io(ptr, 0, size);
 			/* to restore uvd fence seq */
-			amdgpu_fence_driver_force_completion(&adev->uvd.inst[i].ring);
+			amdgpu_fence_driver_force_completion(&adev->uvd.inst[i].ring, NULL);
 		}
 	}
 	return 0;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 700/877] drm/amdgpu: avoid force-completing uninitialized UVD rings
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (698 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 699/877] drm/amdgpu: plumb timedout fence through to force completion Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 701/877] drm/nouveau/disp/r535: Add scanline position support + head state support Greg Kroah-Hartman
                   ` (184 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bob Zhou, Leo Liu, Frank Min,
	Alex Deucher, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bob Zhou <bobzhou2@amd.com>

[ Upstream commit 6760f5cb12d2366ddd58a2d8637f7583d73f596b ]

uvd_v7_0_sw_init() does not initialize the UVD decode ring for an
SR-IOV VF. However, amdgpu_uvd_resume() unconditionally force-completes
the decode ring when restoring its fence sequence.

Skip fence completion when the fence driver is not initialized.

Fixes: 0a33b11d26c6 ("drm/amdgpu: mark force completed fences with -ECANCELED")
Cc: stable@vger.kernel.org
Signed-off-by: Bob Zhou <bobzhou2@amd.com>
Acked-by: Leo Liu <leo.liu@amd.com>
Acked-by: Frank Min <Frank.Min@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c
@@ -516,7 +516,8 @@ int amdgpu_uvd_resume(struct amdgpu_devi
 			}
 			memset_io(ptr, 0, size);
 			/* to restore uvd fence seq */
-			amdgpu_fence_driver_force_completion(&adev->uvd.inst[i].ring, NULL);
+			if (adev->uvd.inst[i].ring.fence_drv.initialized)
+				amdgpu_fence_driver_force_completion(&adev->uvd.inst[i].ring, NULL);
 		}
 	}
 	return 0;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 701/877] drm/nouveau/disp/r535: Add scanline position support + head state support
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (699 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 700/877] drm/amdgpu: avoid force-completing uninitialized UVD rings Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 702/877] drm/amd/display: Set gpuvm min page size to 4K on dcn35/36 Greg Kroah-Hartman
                   ` (183 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ben Skeggs, Dave Airlie, Timur Tabi,
	Ben Skeggs, James Jones, Faith Ekstrand, Suraj Kandpal,
	Lyude Paul, Aaron Kling, Danilo Krummrich, Zhang Enpei,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Lyude Paul <lyude@redhat.com>

[ Upstream commit 804cb093b245c752f15d17186e0d404f10303593 ]

That's right! It looks like this never actually got finished, something
which I just noticed today when I saw this fun message spamming one of my
test machine's kernel logs when enabling display debug output for nouveau:

  [drm:drm_crtc_vblank_helper_get_vblank_timestamp_internal] crtc 0 : scanoutpos query failed.

So it looks like we've been falling back to DRM's core fallback for a while
now, whoops.

So, while it seems that we do have the option of doing this through GSP -
that doesn't seem like a great idea. Mainly because reading this from GSP
would involve a lot more latency then we should have for vblank handling
due to the RPC communication. So instead of implementing that, just use
gv100_head_state and gv100_head_rgpos for implementing .state and .rgpos.
It seems to work perfectly fine!

Fixes: 9e9944449023 ("drm/nouveau/disp/r535: initial support")
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Dave Airlie <airlied@redhat.com>
Cc: Timur Tabi <ttabi@nvidia.com>
Cc: Ben Skeggs <bskeggs@nvidia.com>
Cc: James Jones <jajones@nvidia.com>
Cc: Faith Ekstrand <faith.ekstrand@collabora.com>
Cc: Suraj Kandpal <suraj.kandpal@intel.com>
Cc: Lyude Paul <lyude@redhat.com>
Cc: Aaron Kling <webgeek1234@gmail.com>
Cc: Danilo Krummrich <dakr@kernel.org>
Cc: Zhang Enpei <zhang.enpei@zte.com.cn>
Cc: <stable@vger.kernel.org> # v6.7+
Signed-off-by: Lyude Paul <lyude@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Link: https://patch.msgid.link/20260429030348.3930866-1-lyude@redhat.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c |    4 ++--
 drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h  |    2 ++
 drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c  |    8 ++------
 3 files changed, 6 insertions(+), 8 deletions(-)

--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c
@@ -253,7 +253,7 @@ gv100_head_vblank_get(struct nvkm_head *
 	nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000004, 0x00000004);
 }
 
-static void
+void
 gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline)
 {
 	struct nvkm_device *device = head->disp->engine.subdev.device;
@@ -263,7 +263,7 @@ gv100_head_rgpos(struct nvkm_head *head,
 	*hline = nvkm_rd32(device, 0x616334 + hoff) & 0x0000ffff;
 }
 
-static void
+void
 gv100_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
 {
 	struct nvkm_device *device = head->disp->engine.subdev.device;
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h
@@ -53,6 +53,8 @@ void gf119_head_rgclk(struct nvkm_head *
 
 int gv100_head_cnt(struct nvkm_disp *, unsigned long *);
 int gv100_head_new(struct nvkm_disp *, int id);
+void gv100_head_state(struct nvkm_head *head, struct nvkm_head_state *state);
+void gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline);
 
 #define HEAD_MSG(h,l,f,a...) do {                                              \
 	struct nvkm_head *_h = (h);                                            \
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/r535.c
@@ -623,14 +623,10 @@ r535_head_vblank_get(struct nvkm_head *h
 	nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000002, 0x00000002);
 }
 
-static void
-r535_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
-{
-}
-
 static const struct nvkm_head_func
 r535_head = {
-	.state = r535_head_state,
+	.state = gv100_head_state,
+	.rgpos = gv100_head_rgpos,
 	.vblank_get = r535_head_vblank_get,
 	.vblank_put = r535_head_vblank_put,
 };



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 702/877] drm/amd/display: Set gpuvm min page size to 4K on dcn35/36
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (700 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 701/877] drm/nouveau/disp/r535: Add scanline position support + head state support Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 703/877] drm/sysfb: simpledrm: Improve panel-size validation Greg Kroah-Hartman
                   ` (182 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mario Limonciello, Alex Deucher,
	Alex Hung, Roman Li, Dan Wheeler, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Roman Li <Roman.Li@amd.com>

[ Upstream commit 9ce3169430f1db035d491481086e2fae2552569c ]

[WHY]
Splash screen corruption on some 8K monitors.

[HOW]
Set GPUVM min page size to 4K for DCN35/36 to use the correct DML2
calculations, avoiding the corruption path observed during splash.

Fixes: 115009d11ccf ("drm/amd/display: Add DCN35 DML2 support")
Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Roman Li <Roman.Li@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 2cbfb03dead5088a7bdfe2ce392a5caa3d1b3719)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c
@@ -297,6 +297,7 @@ void dml2_init_socbb_params(struct dml2_
 		out->smn_latency_us = 2;
 		out->dispclk_dppclk_vco_speed_mhz = 3600;
 		out->pct_ideal_dram_bw_after_urgent_pixel_only = 65.0;
+		out->gpuvm_min_page_size_kbytes = 4;
 		break;
 
 	case dml_project_dcn401:



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 703/877] drm/sysfb: simpledrm: Improve panel-size validation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (701 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 702/877] drm/amd/display: Set gpuvm min page size to 4K on dcn35/36 Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 704/877] drm/sysfb: simpledrm: Improve stride validation Greg Kroah-Hartman
                   ` (181 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Thomas Zimmermann, Thierry Reding,
	Maxime Ripard, Javier Martinez Canillas, Rayyan Ansari,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Thomas Zimmermann <tzimmermann@suse.de>

[ Upstream commit 3a75a0761914d01c7362adf1f906cc1d1762c189 ]

Validate the panel size from the device-tree node against the
limitations of struct drm_display_mode. The type only stores sizes
in 16-bit fields. Fail transparently on errors; do not warn.

v3:
- move comments to a more prominent place (Thierry)
v2:
- only use initialized values in debugging output (Sashiko)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Fixes: 2a6d731a8f16 ("drm/simpledrm: Allow physical width and height configuration via panel node")
Cc: Rayyan Ansari <rayyan@ansari.sh>
Cc: <stable@vger.kernel.org> # v6.4+
Link: https://patch.msgid.link/20260625094509.157581-3-tzimmermann@suse.de
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/tiny/simpledrm.c |   49 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 46 insertions(+), 3 deletions(-)

--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -212,6 +212,39 @@ simplefb_get_memory_of(struct drm_device
 	return res;
 }
 
+static int __simplefb_get_panel_size_mm_of(struct drm_device *dev,
+					   struct device_node *of_panel_node,
+					   const char *name)
+{
+	int ret;
+	u32 value;
+
+	ret = of_property_read_u32(of_panel_node, name, &value);
+	if (ret) {
+		drm_dbg(dev, "simplefb: cannot parse panel %s: error %d\n",
+			name, ret);
+		return ret;
+	} else if (value > U16_MAX) {
+		drm_dbg(dev, "simplefb: panel %s of %u exceeds maximum value\n",
+			name, value);
+		return -EINVAL;
+	}
+
+	return value;
+}
+
+static int simplefb_get_panel_width_mm_of(struct drm_device *dev,
+					  struct device_node *of_panel_node)
+{
+	return __simplefb_get_panel_size_mm_of(dev, of_panel_node, "width-mm");
+}
+
+static int simplefb_get_panel_height_mm_of(struct drm_device *dev,
+					   struct device_node *of_panel_node)
+{
+	return __simplefb_get_panel_size_mm_of(dev, of_panel_node, "height-mm");
+}
+
 /*
  * Simple Framebuffer device
  */
@@ -781,7 +814,7 @@ static struct simpledrm_device *simpledr
 	struct simpledrm_device *sdev;
 	struct drm_device *dev;
 	int width, height, stride;
-	int width_mm = 0, height_mm = 0;
+	u16 width_mm = 0, height_mm = 0;
 	struct device_node *panel_node;
 	const struct drm_format_info *format;
 	struct resource *res, *mem = NULL;
@@ -844,8 +877,18 @@ static struct simpledrm_device *simpledr
 			return ERR_CAST(mem);
 		panel_node = of_parse_phandle(of_node, "panel", 0);
 		if (panel_node) {
-			simplefb_read_u32_of(dev, panel_node, "width-mm", &width_mm);
-			simplefb_read_u32_of(dev, panel_node, "height-mm", &height_mm);
+			/*
+			 * Ignore errors from parsing the physical panel
+			 * size. Using the pre-initialized sizes of 0 will
+			 * make drm_sysfb_mode() calculate a default physical
+			 * size based on a resolution of 96 dpi.
+			 */
+			ret = simplefb_get_panel_width_mm_of(dev, panel_node);
+			if (ret > 0)
+				width_mm = ret;
+			ret = simplefb_get_panel_height_mm_of(dev, panel_node);
+			if (ret > 0)
+				height_mm = ret;
 			of_node_put(panel_node);
 		}
 	} else {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 704/877] drm/sysfb: simpledrm: Improve stride validation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (702 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 703/877] drm/sysfb: simpledrm: Improve panel-size validation Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 705/877] firmware: sysfb: Move bpp-depth calculation into screen_info helper Greg Kroah-Hartman
                   ` (180 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Thomas Zimmermann, Thierry Reding,
	Maxime Ripard, Javier Martinez Canillas, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Thomas Zimmermann <tzimmermann@suse.de>

[ Upstream commit df6533f11688aa30be3bb883c7637f4ffdbb7cbd ]

Validate the computed stride against the maximum value INT_MAX.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Fixes: 7bfa5c7b28d6 ("drm/simpledrm: Compute linestride with drm_format_info_min_pitch()")
Cc: <stable@vger.kernel.org> # v6.1+
Link: https://patch.msgid.link/20260625094509.157581-5-tzimmermann@suse.de
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/tiny/simpledrm.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -896,9 +896,15 @@ static struct simpledrm_device *simpledr
 		return ERR_PTR(-ENODEV);
 	}
 	if (!stride) {
-		stride = drm_format_info_min_pitch(format, 0, width);
-		if (drm_WARN_ON(dev, !stride))
+		u64 pitch = drm_format_info_min_pitch(format, 0, width);
+
+		if (drm_WARN_ON(dev, !pitch)) {
+			return ERR_PTR(-EINVAL); /* driver bug */
+		} else if (pitch > INT_MAX) {
+			drm_warn(dev, "stride of %llu exceeds maximum\n", pitch);
 			return ERR_PTR(-EINVAL);
+		}
+		stride = pitch;
 	}
 
 	/*



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 705/877] firmware: sysfb: Move bpp-depth calculation into screen_info helper
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (703 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 704/877] drm/sysfb: simpledrm: Improve stride validation Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 706/877] drm/sysfb: simpledrm: Improve framebuffer-size validation Greg Kroah-Hartman
                   ` (179 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Thomas Zimmermann,
	Javier Martinez Canillas, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Thomas Zimmermann <tzimmermann@suse.de>

[ Upstream commit 1ce4c3aeef333be1e6290ec6d1f7891c2bfc7a1f ]

Move the calculation of the bits per pixels for screen_info into a
helper function. This will make it available to other callers besides
the firmware code.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Link: https://lore.kernel.org/r/20250401094056.32904-14-tzimmermann@suse.de
Stable-dep-of: 03f1a3545b72 ("drm/sysfb: simpledrm: Improve framebuffer-size validation")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/firmware/sysfb_simplefb.c   |   31 +------------------------------
 drivers/video/screen_info_generic.c |   36 ++++++++++++++++++++++++++++++++++++
 include/linux/screen_info.h         |    2 ++
 3 files changed, 39 insertions(+), 30 deletions(-)

--- a/drivers/firmware/sysfb_simplefb.c
+++ b/drivers/firmware/sysfb_simplefb.c
@@ -35,36 +35,7 @@ __init bool sysfb_parse_mode(const struc
 	if (type != VIDEO_TYPE_VLFB && type != VIDEO_TYPE_EFI)
 		return false;
 
-	/*
-	 * The meaning of depth and bpp for direct-color formats is
-	 * inconsistent:
-	 *
-	 *  - DRM format info specifies depth as the number of color
-	 *    bits; including alpha, but not including filler bits.
-	 *  - Linux' EFI platform code computes lfb_depth from the
-	 *    individual color channels, including the reserved bits.
-	 *  - VBE 1.1 defines lfb_depth for XRGB1555 as 16, but later
-	 *    versions use 15.
-	 *  - On the kernel command line, 'bpp' of 32 is usually
-	 *    XRGB8888 including the filler bits, but 15 is XRGB1555
-	 *    not including the filler bit.
-	 *
-	 * It's not easily possible to fix this in struct screen_info,
-	 * as this could break UAPI. The best solution is to compute
-	 * bits_per_pixel from the color bits, reserved bits and
-	 * reported lfb_depth, whichever is highest.  In the loop below,
-	 * ignore simplefb formats with alpha bits, as EFI and VESA
-	 * don't specify alpha channels.
-	 */
-	if (si->lfb_depth > 8) {
-		bits_per_pixel = max(max3(si->red_size + si->red_pos,
-					  si->green_size + si->green_pos,
-					  si->blue_size + si->blue_pos),
-				     si->rsvd_size + si->rsvd_pos);
-		bits_per_pixel = max_t(u32, bits_per_pixel, si->lfb_depth);
-	} else {
-		bits_per_pixel = si->lfb_depth;
-	}
+	bits_per_pixel = __screen_info_lfb_bits_per_pixel(si);
 
 	for (i = 0; i < ARRAY_SIZE(formats); ++i) {
 		const struct simplefb_format *f = &formats[i];
--- a/drivers/video/screen_info_generic.c
+++ b/drivers/video/screen_info_generic.c
@@ -144,3 +144,39 @@ ssize_t screen_info_resources(const stru
 	return pos - r;
 }
 EXPORT_SYMBOL(screen_info_resources);
+
+/*
+ * The meaning of depth and bpp for direct-color formats is
+ * inconsistent:
+ *
+ *  - DRM format info specifies depth as the number of color
+ *    bits; including alpha, but not including filler bits.
+ *  - Linux' EFI platform code computes lfb_depth from the
+ *    individual color channels, including the reserved bits.
+ *  - VBE 1.1 defines lfb_depth for XRGB1555 as 16, but later
+ *    versions use 15.
+ *  - On the kernel command line, 'bpp' of 32 is usually
+ *    XRGB8888 including the filler bits, but 15 is XRGB1555
+ *    not including the filler bit.
+ *
+ * It is not easily possible to fix this in struct screen_info,
+ * as this could break UAPI. The best solution is to compute
+ * bits_per_pixel from the color bits, reserved bits and
+ * reported lfb_depth, whichever is highest.
+ */
+
+u32 __screen_info_lfb_bits_per_pixel(const struct screen_info *si)
+{
+	u32 bits_per_pixel = si->lfb_depth;
+
+	if (bits_per_pixel > 8) {
+		bits_per_pixel = max(max3(si->red_size + si->red_pos,
+					  si->green_size + si->green_pos,
+					  si->blue_size + si->blue_pos),
+				     si->rsvd_size + si->rsvd_pos);
+		bits_per_pixel = max_t(u32, bits_per_pixel, si->lfb_depth);
+	}
+
+	return bits_per_pixel;
+}
+EXPORT_SYMBOL(__screen_info_lfb_bits_per_pixel);
--- a/include/linux/screen_info.h
+++ b/include/linux/screen_info.h
@@ -128,6 +128,8 @@ static inline unsigned int screen_info_v
 
 ssize_t screen_info_resources(const struct screen_info *si, struct resource *r, size_t num);
 
+u32 __screen_info_lfb_bits_per_pixel(const struct screen_info *si);
+
 #if defined(CONFIG_PCI)
 void screen_info_apply_fixups(void);
 struct pci_dev *screen_info_pci_dev(const struct screen_info *si);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 706/877] drm/sysfb: simpledrm: Improve framebuffer-size validation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (704 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 705/877] firmware: sysfb: Move bpp-depth calculation into screen_info helper Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 707/877] drm/sysfb: ofdrm: Fix integer overflow in fb_size calculation Greg Kroah-Hartman
                   ` (178 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Thomas Zimmermann, Thierry Reding,
	Maxime Ripard, Javier Martinez Canillas, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Thomas Zimmermann <tzimmermann@suse.de>

[ Upstream commit 03f1a3545b721fa7fdadd00080e237519a286a97 ]

Validate the framebuffer size from the firmware against the
limitations of struct drm_display_mode. The type only stores sizes
in 16-bit fields. Fail probing on errors.

v2:
- remove unused function simplefb_get_validated_int0() (Sashiko)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Maxime Ripard <mripard@kernel.org>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Fixes: 11e8f5fd223b ("drm: Add simpledrm driver")
Cc: <stable@vger.kernel.org> # v5.14+
Fixes: 11e8f5fd223b ("drm: Add simpledrm driver")
Link: https://patch.msgid.link/20260625094509.157581-2-tzimmermann@suse.de
[ adapted shared-validator changes to the existing simplefb_get_validated_int0() helper in drm/tiny/simpledrm.c. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/tiny/simpledrm.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -54,7 +54,7 @@ static int
 simplefb_get_validated_int0(struct drm_device *dev, const char *name,
 			    uint32_t value)
 {
-	if (!value) {
+	if (!value || value > U16_MAX) {
 		drm_err(dev, "simplefb: invalid framebuffer %s of %u\n",
 			name, value);
 		return -EINVAL;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 707/877] drm/sysfb: ofdrm: Fix integer overflow in fb_size calculation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (705 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 706/877] drm/sysfb: simpledrm: Improve framebuffer-size validation Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:26 ` [PATCH 6.12 708/877] drm/sysfb: ofdrm: Fix is_avivo() constant comparison bug Greg Kroah-Hartman
                   ` (177 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Shixiong Ou, Thomas Zimmermann,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Shixiong Ou <oushixiong@kylinos.cn>

[ Upstream commit c6f48e59ece0123f6a11527ad4d89b21c2d65b87 ]

The framebuffer size calculation `fb_size = linebytes * height` can
overflow when both values are large (e.g., 46341 * 46341 > INT_MAX).
Since linebytes and height are both int types, the multiplication is
performed as int * int, which results in undefined behavior on overflow.

Use check_mul_overflow() to detect and prevent this overflow, consistent
with the approach used in simpledrm.c and corebootdrm.c.

Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: c8a17756c425 ("drm/ofdrm: Add ofdrm for Open Firmware framebuffers")
Cc: <stable@vger.kernel.org> # v6.2+
Link: https://patch.msgid.link/20260825104134.669676-1-oushixiong1025@163.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/tiny/ofdrm.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/tiny/ofdrm.c
+++ b/drivers/gpu/drm/tiny/ofdrm.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 
 #include <linux/of_address.h>
+#include <linux/overflow.h>
 #include <linux/pci.h>
 #include <linux/platform_device.h>
 
@@ -1182,7 +1183,10 @@ static struct ofdrm_device *ofdrm_device
 			return ERR_PTR(-EINVAL);
 	}
 
-	fb_size = linebytes * height;
+	if (check_mul_overflow(linebytes, height, &fb_size)) {
+		drm_err(dev, "framebuffer size exceeds maximum\n");
+		return ERR_PTR(-EINVAL);
+	}
 
 	/*
 	 * Try to figure out the address of the framebuffer. Unfortunately, Open



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 708/877] drm/sysfb: ofdrm: Fix is_avivo() constant comparison bug
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (706 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 707/877] drm/sysfb: ofdrm: Fix integer overflow in fb_size calculation Greg Kroah-Hartman
@ 2026-09-30 15:26 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 709/877] configfs:get_target() - release path as soon as we grab configfs_item reference Greg Kroah-Hartman
                   ` (176 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:26 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Shixiong Ou, Thomas Zimmermann,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Shixiong Ou <oushixiong@kylinos.cn>

[ Upstream commit 958f35cbb8955ca3fa439cd9f2092cb42414aa8c ]

The is_avivo() function has a logic error where it compares a constant
to another constant instead of checking the device parameter:

  (PCI_VENDOR_ID_ATI_R600 >= 0x9400)

Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: f496834e1674 ("drm/ofdrm: Add per-model device function")
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Cc: <stable@vger.kernel.org> # v6.2+
Link: https://patch.msgid.link/20260731111729.703116-1-oushixiong1025@163.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/tiny/ofdrm.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/gpu/drm/tiny/ofdrm.c
+++ b/drivers/gpu/drm/tiny/ofdrm.c
@@ -232,7 +232,7 @@ static bool is_avivo(u32 vendor, u32 dev
 	/* This will match most R5xx */
 	return (vendor == PCI_VENDOR_ID_ATI) &&
 	       ((device >= PCI_VENDOR_ID_ATI_R520 && device < 0x7800) ||
-		(PCI_VENDOR_ID_ATI_R600 >= 0x9400));
+		(device >= PCI_VENDOR_ID_ATI_R600));
 }
 
 static enum ofdrm_model display_get_model_of(struct drm_device *dev, struct device_node *of_node)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 709/877] configfs:get_target() - release path as soon as we grab configfs_item reference
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (707 preceding siblings ...)
  2026-09-30 15:26 ` [PATCH 6.12 708/877] drm/sysfb: ofdrm: Fix is_avivo() constant comparison bug Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 710/877] configfs: pin the symlink targets dirent instead of chasing ->ci_dentry Greg Kroah-Hartman
                   ` (175 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jan Kara, Christian Brauner, Al Viro,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Al Viro <viro@zeniv.linux.org.uk>

[ Upstream commit 1b25dea3867abc9bad6f0337d395c6f0ce4e4f6f ]

... and get rid of path argument - it turns into a local variable in get_target()

Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Stable-dep-of: a7c1290eef60 ("configfs: pin the symlink target's dirent instead of chasing ->ci_dentry")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/configfs/symlink.c |   33 +++++++++++++--------------------
 1 file changed, 13 insertions(+), 20 deletions(-)

--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -114,26 +114,21 @@ static int create_link(struct config_ite
 }
 
 
-static int get_target(const char *symname, struct path *path,
-		      struct config_item **target, struct super_block *sb)
+static int get_target(const char *symname, struct config_item **target,
+		      struct super_block *sb)
 {
+	struct path path __free(path_put) = {};
 	int ret;
 
-	ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, path);
-	if (!ret) {
-		if (path->dentry->d_sb == sb) {
-			*target = configfs_get_config_item(path->dentry);
-			if (!*target) {
-				ret = -ENOENT;
-				path_put(path);
-			}
-		} else {
-			ret = -EPERM;
-			path_put(path);
-		}
-	}
-
-	return ret;
+	ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &path);
+	if (ret)
+		return ret;
+	if (path.dentry->d_sb != sb)
+		return -EPERM;
+	*target = configfs_get_config_item(path.dentry);
+	if (!*target)
+		return -ENOENT;
+	return 0;
 }
 
 
@@ -141,7 +136,6 @@ int configfs_symlink(struct mnt_idmap *i
 		     struct dentry *dentry, const char *symname)
 {
 	int ret;
-	struct path path;
 	struct configfs_dirent *sd;
 	struct config_item *parent_item;
 	struct config_item *target_item = NULL;
@@ -188,7 +182,7 @@ int configfs_symlink(struct mnt_idmap *i
 	 *  AV, a thoroughly annoyed bastard.
 	 */
 	inode_unlock(dir);
-	ret = get_target(symname, &path, &target_item, dentry->d_sb);
+	ret = get_target(symname, &target_item, dentry->d_sb);
 	inode_lock(dir);
 	if (ret)
 		goto out_put;
@@ -210,7 +204,6 @@ int configfs_symlink(struct mnt_idmap *i
 	}
 
 	config_item_put(target_item);
-	path_put(&path);
 
 out_put:
 	config_item_put(parent_item);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 710/877] configfs: pin the symlink targets dirent instead of chasing ->ci_dentry
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (708 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 709/877] configfs:get_target() - release path as soon as we grab configfs_item reference Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 711/877] tracing: Fix memory corruption from a "STACKTRACE" histogram key Greg Kroah-Hartman
                   ` (174 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vasileios Almpanis, Breno Leitao,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Vasileios Almpanis <vasilisalmpanis@gmail.com>

[ Upstream commit a7c1290eef60711c10289c056ad32ed1f2b47b12 ]

create_link() reads the target's configfs_dirent from
item->ci_dentry->d_fsdata, relying on the item reference taken by
get_target().  That reference pins the item, not its dentry: the dentry is
pinned by DCACHE_PERSISTENT, which configfs_remove_dir() releases via
simple_rmdir() while the item is still alive.  A symlink racing with rmdir
of its target can therefore find ->ci_dentry freed and its dirent
released, triggering WARN_ON(!atomic_read(&sd->s_count)) in configfs_get().

Take the dirent in get_target() as well, under ->d_lock and atomically
with the item reference, and pass it down to create_link().  A hashed
dentry has not been killed yet, so its ->d_fsdata reference keeps the
dirent alive there.

Cc: stable@vger.kernel.org
Fixes: 7063fbf22611 ("[PATCH] configfs: User-driven configuration filesystem")
Signed-off-by: Vasileios Almpanis <vasilisalmpanis@gmail.com>
Tested-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Breno Leitao <leitao@debian.org>
Link: https://patch.msgid.link/20260730093435.195441-2-vasilisalmpanis@gmail.com
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/configfs/symlink.c |   24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -76,9 +76,9 @@ static int configfs_get_target_path(stru
 
 static int create_link(struct config_item *parent_item,
 		       struct config_item *item,
+		       struct configfs_dirent *target_sd,
 		       struct dentry *dentry)
 {
-	struct configfs_dirent *target_sd = item->ci_dentry->d_fsdata;
 	char *body;
 	int ret;
 
@@ -115,6 +115,7 @@ static int create_link(struct config_ite
 
 
 static int get_target(const char *symname, struct config_item **target,
+		      struct configfs_dirent **target_sd,
 		      struct super_block *sb)
 {
 	struct path path __free(path_put) = {};
@@ -125,7 +126,20 @@ static int get_target(const char *symnam
 		return ret;
 	if (path.dentry->d_sb != sb)
 		return -EPERM;
-	*target = configfs_get_config_item(path.dentry);
+	/*
+	 * A hashed dentry guarantees that neither the item nor the dirent
+	 * have been released yet, as removals unhash before dropping.
+	 * Grab both references here. An item reference alone would not keep
+	 * ->ci_dentry alive.
+	 */
+	spin_lock(&path.dentry->d_lock);
+	if (!d_unhashed(path.dentry)) {
+		struct configfs_dirent *sd = path.dentry->d_fsdata;
+
+		*target = config_item_get(sd->s_element);
+		*target_sd = configfs_get(sd);
+	}
+	spin_unlock(&path.dentry->d_lock);
 	if (!*target)
 		return -ENOENT;
 	return 0;
@@ -139,6 +153,7 @@ int configfs_symlink(struct mnt_idmap *i
 	struct configfs_dirent *sd;
 	struct config_item *parent_item;
 	struct config_item *target_item = NULL;
+	struct configfs_dirent *target_sd = NULL;
 	const struct config_item_type *type;
 
 	sd = dentry->d_parent->d_fsdata;
@@ -182,7 +197,7 @@ int configfs_symlink(struct mnt_idmap *i
 	 *  AV, a thoroughly annoyed bastard.
 	 */
 	inode_unlock(dir);
-	ret = get_target(symname, &target_item, dentry->d_sb);
+	ret = get_target(symname, &target_item, &target_sd, dentry->d_sb);
 	inode_lock(dir);
 	if (ret)
 		goto out_put;
@@ -196,13 +211,14 @@ int configfs_symlink(struct mnt_idmap *i
 		ret = type->ct_item_ops->allow_link(parent_item, target_item);
 	if (!ret) {
 		mutex_lock(&configfs_symlink_mutex);
-		ret = create_link(parent_item, target_item, dentry);
+		ret = create_link(parent_item, target_item, target_sd, dentry);
 		mutex_unlock(&configfs_symlink_mutex);
 		if (ret && type->ct_item_ops->drop_link)
 			type->ct_item_ops->drop_link(parent_item,
 						     target_item);
 	}
 
+	configfs_put(target_sd);
 	config_item_put(target_item);
 
 out_put:



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 711/877] tracing: Fix memory corruption from a "STACKTRACE" histogram key
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (709 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 710/877] configfs: pin the symlink targets dirent instead of chasing ->ci_dentry Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 712/877] ipmr: account multicast table and route memory Greg Kroah-Hartman
                   ` (173 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Steven Rostedt,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>

[ Upstream commit 7f711e62355bb3123a2ca2f97a2facbfebc678c6 ]

"cpu", "CPU", "stacktrace" and "STACKTRACE" are generic fields, defined
with an offset and a size of zero so that the filter code can match them
by name. parse_field() maps them onto their common_* equivalents for
backward compatibility, but unlike the common_* names it hands the
placeholder back to the caller instead of NULL.

create_hist_field() takes a non-NULL field as a promise that the record
carries a stacktrace and picks HIST_FIELD_FN_STACK, so the __data_loc
word is read from offset 0, that is from common_type, and its low 16
bits are followed as an offset into the record. What is found there
becomes the length of an unbounded memcpy. Pick an event whose id is
small enough that the offset stays inside its own record and the length
is a kernel text address:

  # cd /sys/kernel/tracing
  # echo 'hist:keys=STACKTRACE' > events/ftrace/print/trigger
  # echo hello > trace_marker

  Oops: general protection fault, probably for non-canonical address
  RIP: 0010:rb_next+0x23/0x60
   </IRQ>
  RIP: 0010:memcpy+0xc/0x30
   event_hist_trigger+0x2e7/0x12c0
  Kernel panic - not syncing: Fatal exception in interrupt

Leave the field NULL, which is what the comment above the branch says
the code does and what common_stacktrace already does. FILTER_CPU and
FILTER_COMM are left alone, their create_hist_field() branches never
look at the field.

Cc: stable@vger.kernel.org
Fixes: 4b512860bdbd ("tracing: Rename stacktrace field to common_stacktrace")
Link: https://patch.msgid.link/20260907155045.692664-3-donggeunyoo.kernel@gmail.com
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
[ Adjusted context for the missing FILTER_COMM branch in parse_field(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/trace_events_hist.c |    1 +
 1 file changed, 1 insertion(+)

--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -2379,6 +2379,7 @@ parse_field(struct hist_trigger_data *hi
 				*flags |= HIST_FIELD_FL_CPU;
 			} else if (field && field->filter_type == FILTER_STACKTRACE) {
 				*flags |= HIST_FIELD_FL_STACKTRACE;
+				field = NULL;
 			} else {
 				hist_err(tr, HIST_ERR_FIELD_NOT_FOUND,
 					 errpos(field_name));



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 712/877] ipmr: account multicast table and route memory
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (710 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 711/877] tracing: Fix memory corruption from a "STACKTRACE" histogram key Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 713/877] sysctl: move the "cad_pid" entry from pid_table[] to kern_reboot_table[] Greg Kroah-Hartman
                   ` (172 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Zihan Xi, Ido Schimmel,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Zihan Xi <zihanx@nebusec.ai>

[ Upstream commit b7ee18725f2292ab554aa96a101ae42d45f008bd ]

A netadmin in a user+net namespace can create many IPv4 and IPv6
multicast routing tables with MRT_TABLE and MRT6_TABLE. Each unseen
id allocates an mr_table via the shared mr_table_alloc(), links it
into the per-net list, and leaves it until netns teardown. Those
objects were not charged to memcg, so the host unreclaimable slab
grows with the table count.

Account mr_table allocations with GFP_KERNEL_ACCOUNT and mark the
IPv4/IPv6 MFC caches SLAB_ACCOUNT. This matches the established
handling of IP addresses, routes and alternate interface names.

Unresolved MFC entries are still allocated from softIRQ with
GFP_ATOMIC and are not charged. They expire after 10 seconds and are
bounded by the socket receive queue; see commit 0079ad8e8dc3
("ipmr: remove hard code cache_resolve_queue_len limit").

Fixes: f0ad0860d01e ("ipv4: ipmr: support multiple tables")
Fixes: d1db275dd3f6 ("ipv6: ip6mr: support multiple tables")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/050b58f7fc6b45da0fb12768ebb62d18fa46133d.1788784801.git.zihanx@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ changed kzalloc_obj(*mrt, GFP_KERNEL_ACCOUNT) to kzalloc(sizeof(*mrt), GFP_KERNEL_ACCOUNT) ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv4/ipmr.c      |    3 ++-
 net/ipv4/ipmr_base.c |    2 +-
 net/ipv6/ip6mr.c     |    2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -3162,7 +3162,8 @@ int __init ip_mr_init(void)
 {
 	int err;
 
-	mrt_cachep = KMEM_CACHE(mfc_cache, SLAB_HWCACHE_ALIGN | SLAB_PANIC);
+	mrt_cachep = KMEM_CACHE(mfc_cache,
+				SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT);
 
 	err = register_pernet_subsys(&ipmr_net_ops);
 	if (err)
--- a/net/ipv4/ipmr_base.c
+++ b/net/ipv4/ipmr_base.c
@@ -38,7 +38,7 @@ mr_table_alloc(struct net *net, u32 id,
 	struct mr_table *mrt;
 	int err;
 
-	mrt = kzalloc(sizeof(*mrt), GFP_KERNEL);
+	mrt = kzalloc(sizeof(*mrt), GFP_KERNEL_ACCOUNT);
 	if (!mrt)
 		return ERR_PTR(-ENOMEM);
 	mrt->id = id;
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1387,7 +1387,7 @@ int __init ip6_mr_init(void)
 {
 	int err;
 
-	mrt_cachep = KMEM_CACHE(mfc6_cache, SLAB_HWCACHE_ALIGN);
+	mrt_cachep = KMEM_CACHE(mfc6_cache, SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT);
 	if (!mrt_cachep)
 		return -ENOMEM;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 713/877] sysctl: move the "cad_pid" entry from pid_table[] to kern_reboot_table[]
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (711 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 712/877] ipmr: account multicast table and route memory Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 714/877] reboot: fix cad_pid use-after-free race Greg Kroah-Hartman
                   ` (171 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Oleg Nesterov, Alexey Gladkov,
	Bradley Morgan, Pavel Tikhomirov, Joel Granados, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Oleg Nesterov <oleg@redhat.com>

[ Upstream commit 7170ca01623b399c97f2ae9d3e228badc1f25ea3 ]

cad_pid is global, and kill_cad_pid() is only used in the root namespace.

However, due to pid_table_root_permissions(), a non-root user can unshare
pid/user namespaces and modify it from the child namespace. This makes no
sense and is simply wrong.

Move it to kern_reboot_table[] where it logically belongs; this ensures
that only GLOBAL_ROOT_UID can read/modify this sysctl.

Note that this patch doesn't preserve "#ifdef CONFIG_PROC_SYSCTL" around
the "cad_pid"; CONFIG_PROC_SYSCTL selects CONFIG_SYSCTL, so it is always
set when kern_reboot_table[] is compiled.

Cc: stable@vger.kernel.org
Fixes: e054bcbe7e7a ("sysctl: move cad_pid into kernel/pid.c")
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Acked-by: Alexey Gladkov <legion@kernel.org>
Reviewed-by: Bradley Morgan <include@grrlz.net>
Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Signed-off-by: Joel Granados <joel.granados@kernel.org>

[6.12 dependency adaptation]
The stable tree still keeps cad_pid in the global kernel/sysctl.c table;
it does not have the upstream per-PID-namespace table. Move the existing
handler and entry directly from kernel/sysctl.c to kernel/reboot.c, using
proc_dointvec() with a local table copy because __do_proc_dointvec() is
private to sysctl.c. Leave kernel/pid.c unchanged and retain the mutable
ctl_table required by the stable registration API.

Make the existing kernel_reboot_sysctls_init() an independent late initcall
outside CONFIG_SYSFS so cad_pid remains available with PROC_SYSCTL=y and
SYSFS=n, and does not depend on sysfs object allocation succeeding.

Prepare context for 5a88f78df753 without importing newer scheduler or timer
implementations: move the existing kick_process() declaration/stub before
cad_pid and expand the empty stub, and guard the existing POSIX-only
sigqueue helpers with CONFIG_POSIX_TIMERS using the upstream comment.
No new functions are introduced, and the target's RCU fix is left for the
target commit.

[ sashal: Reduced backport -- upstream 7170ca01623b3 touches 2 file(s), this
  backport carries 4. Not backported here:
  kernel/pid.c
  This note is generated from the file lists only; see the resolution record
  for the reasoning. ]

Stable-dep-of: 5a88f78df753 ("reboot: fix cad_pid use-after-free race")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/linux/sched.h |   14 ++++++++------
 kernel/reboot.c       |   40 +++++++++++++++++++++++++++++++++++-----
 kernel/signal.c       |   12 +++++-------
 kernel/sysctl.c       |   31 -------------------------------
 4 files changed, 48 insertions(+), 49 deletions(-)

--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1675,6 +1675,14 @@ static inline char task_state_to_char(st
 	return task_index_to_char(task_state_index(tsk));
 }
 
+#ifdef CONFIG_SMP
+extern void kick_process(struct task_struct *tsk);
+#else
+static inline void kick_process(struct task_struct *tsk)
+{
+}
+#endif
+
 extern struct pid *cad_pid;
 
 /*
@@ -1953,12 +1961,6 @@ extern int wake_up_state(struct task_str
 extern int wake_up_process(struct task_struct *tsk);
 extern void wake_up_new_task(struct task_struct *tsk);
 
-#ifdef CONFIG_SMP
-extern void kick_process(struct task_struct *tsk);
-#else
-static inline void kick_process(struct task_struct *tsk) { }
-#endif
-
 extern void __set_task_comm(struct task_struct *tsk, const char *from, bool exec);
 
 static inline void set_task_comm(struct task_struct *tsk, const char *from)
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -1280,7 +1280,32 @@ static struct attribute *reboot_attrs[]
 	NULL,
 };
 
+#endif /* CONFIG_SYSFS */
+
 #ifdef CONFIG_SYSCTL
+static int proc_do_cad_pid(const struct ctl_table *table, int write, void *buffer,
+			   size_t *lenp, loff_t *ppos)
+{
+	struct ctl_table tmp_table = *table;
+	struct pid *new_pid;
+	pid_t tmp_pid;
+	int r;
+
+	tmp_pid = pid_vnr(cad_pid);
+	tmp_table.data = &tmp_pid;
+
+	r = proc_dointvec(&tmp_table, write, buffer, lenp, ppos);
+	if (r || !write)
+		return r;
+
+	new_pid = find_get_pid(tmp_pid);
+	if (!new_pid)
+		return -ESRCH;
+
+	put_pid(xchg(&cad_pid, new_pid));
+	return 0;
+}
+
 static struct ctl_table kern_reboot_table[] = {
 	{
 		.procname       = "poweroff_cmd",
@@ -1296,16 +1321,23 @@ static struct ctl_table kern_reboot_tabl
 		.mode           = 0644,
 		.proc_handler   = proc_dointvec,
 	},
+	{
+		.procname	= "cad_pid",
+		.maxlen		= sizeof(int),
+		.mode		= 0600,
+		.proc_handler	= proc_do_cad_pid,
+	},
 };
 
-static void __init kernel_reboot_sysctls_init(void)
+static int __init kernel_reboot_sysctls_init(void)
 {
 	register_sysctl_init("kernel", kern_reboot_table);
+	return 0;
 }
-#else
-#define kernel_reboot_sysctls_init() do { } while (0)
+late_initcall(kernel_reboot_sysctls_init);
 #endif /* CONFIG_SYSCTL */
 
+#ifdef CONFIG_SYSFS
 static const struct attribute_group reboot_attr_group = {
 	.attrs = reboot_attrs,
 };
@@ -1325,8 +1357,6 @@ static int __init reboot_ksysfs_init(voi
 		return ret;
 	}
 
-	kernel_reboot_sysctls_init();
-
 	return 0;
 }
 late_initcall(reboot_ksysfs_init);
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1936,14 +1936,10 @@ int kill_pid(struct pid *pid, int sig, i
 }
 EXPORT_SYMBOL(kill_pid);
 
+#ifdef CONFIG_POSIX_TIMERS
 /*
- * These functions support sending signals using preallocated sigqueue
- * structures.  This is needed "because realtime applications cannot
- * afford to lose notifications of asynchronous events, like timer
- * expirations or I/O completions".  In the case of POSIX Timers
- * we allocate the sigqueue structure from the timer_create.  If this
- * allocation fails we are able to report the failure to the application
- * with an EAGAIN error.
+ * These functions handle POSIX timer signals. POSIX timers use
+ * preallocated sigqueue structs for sending signals.
  */
 struct sigqueue *sigqueue_alloc(void)
 {
@@ -2043,6 +2039,8 @@ ret:
 	return ret;
 }
 
+#endif /* CONFIG_POSIX_TIMERS */
+
 void do_notify_pidfd(struct task_struct *task)
 {
 	struct pid *pid = task_pid(task);
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1322,28 +1322,6 @@ int proc_dointvec_ms_jiffies(const struc
 				do_proc_dointvec_ms_jiffies_conv, NULL);
 }
 
-static int proc_do_cad_pid(const struct ctl_table *table, int write, void *buffer,
-		size_t *lenp, loff_t *ppos)
-{
-	struct pid *new_pid;
-	pid_t tmp;
-	int r;
-
-	tmp = pid_vnr(cad_pid);
-
-	r = __do_proc_dointvec(&tmp, table, write, buffer,
-			       lenp, ppos, NULL, NULL);
-	if (r || !write)
-		return r;
-
-	new_pid = find_get_pid(tmp);
-	if (!new_pid)
-		return -ESRCH;
-
-	put_pid(xchg(&cad_pid, new_pid));
-	return 0;
-}
-
 /**
  * proc_do_large_bitmap - read/write from/to a large bitmap
  * @table: the sysctl table
@@ -1761,15 +1739,6 @@ static struct ctl_table kern_table[] = {
 		.proc_handler	= sysrq_sysctl_handler,
 	},
 #endif
-#ifdef CONFIG_PROC_SYSCTL
-	{
-		.procname	= "cad_pid",
-		.data		= NULL,
-		.maxlen		= sizeof (int),
-		.mode		= 0600,
-		.proc_handler	= proc_do_cad_pid,
-	},
-#endif
 	{
 		.procname	= "threads-max",
 		.data		= NULL,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 714/877] reboot: fix cad_pid use-after-free race
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (712 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 713/877] sysctl: move the "cad_pid" entry from pid_table[] to kern_reboot_table[] Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 715/877] configfs: unhash the dentry before dropping the item in rmdir Greg Kroah-Hartman
                   ` (170 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, AutonomousCodeSecurity,
	Mateusz Guzik, Bradley Morgan, Oleg Nesterov, Eric W. Biederman,
	Pavel Tikhomirov, Cen Zhang (Microsoft),
	Christian Brauner (Amutable), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Cen Zhang (Microsoft)" <blbllhy@gmail.com>

[ Upstream commit 5a88f78df753993469dab4d1831f8fb4256a9468 ]

cad_pid is a single kernel-wide struct pid pointer. proc_do_cad_pid()
reads it and passes it to pid_vnr() without protecting the lifetime of
the referenced struct pid. A concurrent writer can replace cad_pid and
drop the final reference to the old struct pid after the reader has
loaded the pointer but before pid_vnr() has finished dereferencing it,
causing a use-after-free.

kill_cad_pid() has the same lifetime race when it passes cad_pid to
kill_pid().

At the time this issue was reported, an unprivileged user could reach the
sysctl through user and PID namespaces because cad_pid was registered in
pid_table[]. Moving cad_pid back to the global reboot sysctl table
corrected that namespace and permission mismatch, but did not fix the
underlying lifetime race.

Fix this by treating cad_pid as an RCU-protected pointer at both read
sites and by waiting for a grace period before dropping the old reference
on the write side.

call_rcu(&old_pid->rcu, ...) cannot be used here because free_pid()
also queues pid->rcu; queueing the same rcu_head twice can corrupt the
RCU callback list.

Original KASAN crash stack:
  kernel/pid.c:545 pid_nr_ns()        # reads freed pid->level
  kernel/pid.c:556 pid_vnr()          # calls pid_nr_ns()
  kernel/pid.c:775 proc_do_cad_pid()  # calls pid_vnr(cad_pid)

Fixes: 9ec52099e4b8 ("[PATCH] replace cad_pid by a struct pid")
Reported-by: AutonomousCodeSecurity@microsoft.com
Closes: https://lore.kernel.org/all/20260717210143.4734-1-blbllhy@gmail.com/
Link: https://lore.kernel.org/all/alz5ZYLE4kaq_v2P@redhat.com/
Link: https://lore.kernel.org/all/al4ICz9biJKtdZc4@redhat.com/
Suggested-by: Mateusz Guzik <mjguzik@gmail.com>
Suggested-by: Bradley Morgan <include@grrlz.net>
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Suggested-by: Eric W. Biederman <ebiederm@xmission.com>
Suggested-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Cc: stable@vger.kernel.org
Signed-off-by: Cen Zhang (Microsoft) <blbllhy@gmail.com>
Link: https://patch.msgid.link/20260814040944.16561-1-blbllhy@gmail.com
Reviewed-by: Bradley Morgan <include@grrlz.net>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/linux/sched.h        |    2 +-
 include/linux/sched/signal.h |    5 +----
 init/main.c                  |    2 +-
 kernel/reboot.c              |   19 +++++++++++++++----
 kernel/signal.c              |   12 ++++++++++++
 5 files changed, 30 insertions(+), 10 deletions(-)

--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1683,7 +1683,7 @@ static inline void kick_process(struct t
 }
 #endif
 
-extern struct pid *cad_pid;
+extern struct pid __rcu *cad_pid;
 
 /*
  * Per process flags
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -558,10 +558,7 @@ static inline sigset_t *sigmask_to_save(
 	return res;
 }
 
-static inline int kill_cad_pid(int sig, int priv)
-{
-	return kill_pid(cad_pid, sig, priv);
-}
+int kill_cad_pid(int sig, int priv);
 
 /* These can be the second arg to send_sig_info/send_group_sig_info.  */
 #define SEND_SIG_NOINFO ((struct kernel_siginfo *) 0)
--- a/init/main.c
+++ b/init/main.c
@@ -1523,7 +1523,7 @@ static noinline void __init kernel_init_
 	 */
 	set_mems_allowed(node_states[N_MEMORY]);
 
-	cad_pid = get_pid(task_pid(current));
+	rcu_assign_pointer(cad_pid, get_pid(task_pid(current)));
 
 	smp_prepare_cpus(setup_max_cpus);
 
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -13,7 +13,9 @@
 #include <linux/kexec.h>
 #include <linux/kmod.h>
 #include <linux/kmsg_dump.h>
+#include <linux/rcupdate.h>
 #include <linux/reboot.h>
+#include <linux/sched/signal.h>
 #include <linux/suspend.h>
 #include <linux/syscalls.h>
 #include <linux/syscore_ops.h>
@@ -24,8 +26,7 @@
  */
 
 static int C_A_D = 1;
-struct pid *cad_pid;
-EXPORT_SYMBOL(cad_pid);
+struct pid __rcu *cad_pid;
 
 #if defined(CONFIG_ARM)
 #define DEFAULT_REBOOT_MODE		= REBOOT_HARD
@@ -1288,10 +1289,14 @@ static int proc_do_cad_pid(const struct
 {
 	struct ctl_table tmp_table = *table;
 	struct pid *new_pid;
+	struct pid *old_pid;
 	pid_t tmp_pid;
 	int r;
 
-	tmp_pid = pid_vnr(cad_pid);
+	rcu_read_lock();
+	tmp_pid = pid_vnr(rcu_dereference(cad_pid));
+	rcu_read_unlock();
+
 	tmp_table.data = &tmp_pid;
 
 	r = proc_dointvec(&tmp_table, write, buffer, lenp, ppos);
@@ -1302,7 +1307,13 @@ static int proc_do_cad_pid(const struct
 	if (!new_pid)
 		return -ESRCH;
 
-	put_pid(xchg(&cad_pid, new_pid));
+	old_pid = unrcu_pointer(xchg(&cad_pid, RCU_INITIALIZER(new_pid)));
+	/*
+	 * Wait for cad_pid readers before put_pid().  We cannot use
+	 * call_rcu() here because free_pid() already owns pid->rcu.
+	 */
+	synchronize_rcu();
+	put_pid(old_pid);
 	return 0;
 }
 
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1936,6 +1936,18 @@ int kill_pid(struct pid *pid, int sig, i
 }
 EXPORT_SYMBOL(kill_pid);
 
+int kill_cad_pid(int sig, int priv)
+{
+	int ret;
+
+	rcu_read_lock();
+	ret = kill_pid(rcu_dereference(cad_pid), sig, priv);
+	rcu_read_unlock();
+
+	return ret;
+}
+EXPORT_SYMBOL(kill_cad_pid);
+
 #ifdef CONFIG_POSIX_TIMERS
 /*
  * These functions handle POSIX timer signals. POSIX timers use



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 715/877] configfs: unhash the dentry before dropping the item in rmdir
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (713 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 714/877] reboot: fix cad_pid use-after-free race Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 716/877] tracing: Constify struct event_trigger_ops Greg Kroah-Hartman
                   ` (169 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+6b16e3d085833cbf3e25,
	Vasileios Almpanis, Breno Leitao, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Vasileios Almpanis <vasilisalmpanis@gmail.com>

[ Upstream commit f06c2d26d1999d37e93299db0ecead04ca7d0b9f ]

configfs_get_config_item() treats a hashed dentry as proof that
sd->s_element is a live config_item.  configfs_rmdir() breaks that:
simple_rmdir() leaves the dentry hashed, the last reference to the item is
dropped right after, and the dentry is only unhashed by d_delete() once
->rmdir() has returned.  configfs_symlink() resolves its target holding no
lock on it, so get_target() can land in that window:

  BUG: KASAN: slab-use-after-free in config_item_get+0x26/0x90
   get_target fs/configfs/symlink.c:128 [inline]
   configfs_symlink+0x4ab/0x1030 fs/configfs/symlink.c:185

Unhash in configfs_remove_dir(), while the item is still guaranteed to be
there.  A reference obtained just before that stays harmless, as
create_link() rechecks CONFIGFS_USET_DROPPING, already set by
configfs_detach_prep().  Both configfs_unregister_subsystem() paths
d_drop() after detaching, so this only makes rmdir match them.

Reported-by: syzbot+6b16e3d085833cbf3e25@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=6b16e3d085833cbf3e25
Fixes: 7063fbf22611 ("[PATCH] configfs: User-driven configuration filesystem")
Cc: stable@vger.kernel.org
Signed-off-by: Vasileios Almpanis <vasilisalmpanis@gmail.com>
Tested-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Breno Leitao <leitao@debian.org>
Link: https://patch.msgid.link/20260730093435.195441-3-vasilisalmpanis@gmail.com
Signed-off-by: Breno Leitao <leitao@debian.org>
[ adapted the configfs_remove_dir() change to the older remove_dir() helper. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/configfs/dir.c |   13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -395,8 +395,17 @@ static void remove_dir(struct dentry * d
 
 	configfs_remove_dirent(d);
 
-	if (d_really_is_positive(d))
-		simple_rmdir(d_inode(parent),d);
+	if (d_really_is_positive(d)) {
+		if (!simple_rmdir(d_inode(parent), d))
+			/*
+			 * configfs_get_config_item() takes a hashed dentry as
+			 * proof that ->s_element is still alive.  Our caller
+			 * is about to drop the last reference to the item and
+			 * the VFS will not unhash until after we return, so
+			 * unhash it here.
+			 */
+			d_drop(d);
+	}
 
 	pr_debug(" o %pd removing done (%d)\n", d, d_count(d));
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 716/877] tracing: Constify struct event_trigger_ops
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (714 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 715/877] configfs: unhash the dentry before dropping the item in rmdir Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 717/877] tracing: Remove get_trigger_ops() and add count_func() from trigger ops Greg Kroah-Hartman
                   ` (168 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Masami Hiramatsu, Mathieu Desnoyers,
	Christophe JAILLET, Steven Rostedt (Google), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>

[ Upstream commit 502d2e71a89fa706843fa9277f4d6de1947072c8 ]

'event_trigger_ops mwifiex_if_ops' are not modified in these drivers.

Constifying these structures moves some data to a read-only section, so
increase overall security, especially when the structure holds some
function pointers.

On a x86_64, with allmodconfig, as an example:
Before:
======
   text	   data	    bss	    dec	    hex	filename
  31368	   9024	   6200	  46592	   b600	kernel/trace/trace_events_trigger.o

After:
=====
   text	   data	    bss	    dec	    hex	filename
  31752	   8608	   6200	  46560	   b5e0	kernel/trace/trace_events_trigger.o

Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://lore.kernel.org/66e8f990e649678e4be37d4d1a19158ca0dea2f4.1741521295.git.christophe.jaillet@wanadoo.fr
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Stable-dep-of: 6ede78d0563a ("tracing: Set the trace clock before registering the histogram trigger")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/trace.h                |    4 +--
 kernel/trace/trace_eprobe.c         |    6 ++---
 kernel/trace/trace_events_hist.c    |   20 +++++++++---------
 kernel/trace/trace_events_trigger.c |   38 ++++++++++++++++++------------------
 4 files changed, 34 insertions(+), 34 deletions(-)

--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1698,7 +1698,7 @@ struct event_trigger_data {
 	unsigned long			count;
 	int				ref;
 	int				flags;
-	struct event_trigger_ops	*ops;
+	const struct event_trigger_ops	*ops;
 	struct event_command		*cmd_ops;
 	struct event_filter __rcu	*filter;
 	char				*filter_str;
@@ -1941,7 +1941,7 @@ struct event_command {
 	int			(*set_filter)(char *filter_str,
 					      struct event_trigger_data *data,
 					      struct trace_event_file *file);
-	struct event_trigger_ops *(*get_trigger_ops)(char *cmd, char *param);
+	const struct event_trigger_ops *(*get_trigger_ops)(char *cmd, char *param);
 };
 
 /**
--- a/kernel/trace/trace_eprobe.c
+++ b/kernel/trace/trace_eprobe.c
@@ -479,7 +479,7 @@ static void eprobe_trigger_func(struct e
 	__eprobe_trace_func(edata, rec);
 }
 
-static struct event_trigger_ops eprobe_trigger_ops = {
+static const struct event_trigger_ops eprobe_trigger_ops = {
 	.trigger		= eprobe_trigger_func,
 	.print			= eprobe_trigger_print,
 	.init			= eprobe_trigger_init,
@@ -508,8 +508,8 @@ static void eprobe_trigger_unreg_func(ch
 
 }
 
-static struct event_trigger_ops *eprobe_trigger_get_ops(char *cmd,
-							char *param)
+static const struct event_trigger_ops *eprobe_trigger_get_ops(char *cmd,
+							      char *param)
 {
 	return &eprobe_trigger_ops;
 }
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -6323,7 +6323,7 @@ static void event_hist_trigger_free(stru
 	free_hist_pad();
 }
 
-static struct event_trigger_ops event_hist_trigger_ops = {
+static const struct event_trigger_ops event_hist_trigger_ops = {
 	.trigger		= event_hist_trigger,
 	.print			= event_hist_trigger_print,
 	.init			= event_hist_trigger_init,
@@ -6353,15 +6353,15 @@ static void event_hist_trigger_named_fre
 	}
 }
 
-static struct event_trigger_ops event_hist_trigger_named_ops = {
+static const struct event_trigger_ops event_hist_trigger_named_ops = {
 	.trigger		= event_hist_trigger,
 	.print			= event_hist_trigger_print,
 	.init			= event_hist_trigger_named_init,
 	.free			= event_hist_trigger_named_free,
 };
 
-static struct event_trigger_ops *event_hist_get_trigger_ops(char *cmd,
-							    char *param)
+static const struct event_trigger_ops *event_hist_get_trigger_ops(char *cmd,
+								  char *param)
 {
 	return &event_hist_trigger_ops;
 }
@@ -6958,38 +6958,38 @@ hist_enable_count_trigger(struct event_t
 	hist_enable_trigger(data, buffer, rec, event);
 }
 
-static struct event_trigger_ops hist_enable_trigger_ops = {
+static const struct event_trigger_ops hist_enable_trigger_ops = {
 	.trigger		= hist_enable_trigger,
 	.print			= event_enable_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_enable_trigger_free,
 };
 
-static struct event_trigger_ops hist_enable_count_trigger_ops = {
+static const struct event_trigger_ops hist_enable_count_trigger_ops = {
 	.trigger		= hist_enable_count_trigger,
 	.print			= event_enable_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_enable_trigger_free,
 };
 
-static struct event_trigger_ops hist_disable_trigger_ops = {
+static const struct event_trigger_ops hist_disable_trigger_ops = {
 	.trigger		= hist_enable_trigger,
 	.print			= event_enable_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_enable_trigger_free,
 };
 
-static struct event_trigger_ops hist_disable_count_trigger_ops = {
+static const struct event_trigger_ops hist_disable_count_trigger_ops = {
 	.trigger		= hist_enable_count_trigger,
 	.print			= event_enable_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_enable_trigger_free,
 };
 
-static struct event_trigger_ops *
+static const struct event_trigger_ops *
 hist_enable_get_trigger_ops(char *cmd, char *param)
 {
-	struct event_trigger_ops *ops;
+	const struct event_trigger_ops *ops;
 	bool enable;
 
 	enable = (strcmp(cmd, ENABLE_HIST_STR) == 0);
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -849,7 +849,7 @@ struct event_trigger_data *trigger_data_
 					      void *private_data)
 {
 	struct event_trigger_data *trigger_data;
-	struct event_trigger_ops *trigger_ops;
+	const struct event_trigger_ops *trigger_ops;
 
 	trigger_ops = cmd_ops->get_trigger_ops(cmd, param);
 
@@ -1391,38 +1391,38 @@ traceoff_trigger_print(struct seq_file *
 				   data->filter_str);
 }
 
-static struct event_trigger_ops traceon_trigger_ops = {
+static const struct event_trigger_ops traceon_trigger_ops = {
 	.trigger		= traceon_trigger,
 	.print			= traceon_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_trigger_free,
 };
 
-static struct event_trigger_ops traceon_count_trigger_ops = {
+static const struct event_trigger_ops traceon_count_trigger_ops = {
 	.trigger		= traceon_count_trigger,
 	.print			= traceon_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_trigger_free,
 };
 
-static struct event_trigger_ops traceoff_trigger_ops = {
+static const struct event_trigger_ops traceoff_trigger_ops = {
 	.trigger		= traceoff_trigger,
 	.print			= traceoff_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_trigger_free,
 };
 
-static struct event_trigger_ops traceoff_count_trigger_ops = {
+static const struct event_trigger_ops traceoff_count_trigger_ops = {
 	.trigger		= traceoff_count_trigger,
 	.print			= traceoff_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_trigger_free,
 };
 
-static struct event_trigger_ops *
+static const struct event_trigger_ops *
 onoff_get_trigger_ops(char *cmd, char *param)
 {
-	struct event_trigger_ops *ops;
+	const struct event_trigger_ops *ops;
 
 	/* we register both traceon and traceoff to this callback */
 	if (strcmp(cmd, "traceon") == 0)
@@ -1515,21 +1515,21 @@ snapshot_trigger_print(struct seq_file *
 				   data->filter_str);
 }
 
-static struct event_trigger_ops snapshot_trigger_ops = {
+static const struct event_trigger_ops snapshot_trigger_ops = {
 	.trigger		= snapshot_trigger,
 	.print			= snapshot_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_trigger_free,
 };
 
-static struct event_trigger_ops snapshot_count_trigger_ops = {
+static const struct event_trigger_ops snapshot_count_trigger_ops = {
 	.trigger		= snapshot_count_trigger,
 	.print			= snapshot_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_trigger_free,
 };
 
-static struct event_trigger_ops *
+static const struct event_trigger_ops *
 snapshot_get_trigger_ops(char *cmd, char *param)
 {
 	return param ? &snapshot_count_trigger_ops : &snapshot_trigger_ops;
@@ -1610,21 +1610,21 @@ stacktrace_trigger_print(struct seq_file
 				   data->filter_str);
 }
 
-static struct event_trigger_ops stacktrace_trigger_ops = {
+static const struct event_trigger_ops stacktrace_trigger_ops = {
 	.trigger		= stacktrace_trigger,
 	.print			= stacktrace_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_trigger_free,
 };
 
-static struct event_trigger_ops stacktrace_count_trigger_ops = {
+static const struct event_trigger_ops stacktrace_count_trigger_ops = {
 	.trigger		= stacktrace_count_trigger,
 	.print			= stacktrace_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_trigger_free,
 };
 
-static struct event_trigger_ops *
+static const struct event_trigger_ops *
 stacktrace_get_trigger_ops(char *cmd, char *param)
 {
 	return param ? &stacktrace_count_trigger_ops : &stacktrace_trigger_ops;
@@ -1735,28 +1735,28 @@ void event_enable_trigger_free(struct ev
 	}
 }
 
-static struct event_trigger_ops event_enable_trigger_ops = {
+static const struct event_trigger_ops event_enable_trigger_ops = {
 	.trigger		= event_enable_trigger,
 	.print			= event_enable_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_enable_trigger_free,
 };
 
-static struct event_trigger_ops event_enable_count_trigger_ops = {
+static const struct event_trigger_ops event_enable_count_trigger_ops = {
 	.trigger		= event_enable_count_trigger,
 	.print			= event_enable_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_enable_trigger_free,
 };
 
-static struct event_trigger_ops event_disable_trigger_ops = {
+static const struct event_trigger_ops event_disable_trigger_ops = {
 	.trigger		= event_enable_trigger,
 	.print			= event_enable_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_enable_trigger_free,
 };
 
-static struct event_trigger_ops event_disable_count_trigger_ops = {
+static const struct event_trigger_ops event_disable_count_trigger_ops = {
 	.trigger		= event_enable_count_trigger,
 	.print			= event_enable_trigger_print,
 	.init			= event_trigger_init,
@@ -1940,10 +1940,10 @@ void event_enable_unregister_trigger(cha
 		data->ops->free(data);
 }
 
-static struct event_trigger_ops *
+static const struct event_trigger_ops *
 event_enable_get_trigger_ops(char *cmd, char *param)
 {
-	struct event_trigger_ops *ops;
+	const struct event_trigger_ops *ops;
 	bool enable;
 
 #ifdef CONFIG_HIST_TRIGGERS



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 717/877] tracing: Remove get_trigger_ops() and add count_func() from trigger ops
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (715 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 716/877] tracing: Constify struct event_trigger_ops Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 718/877] tracing: Merge struct event_trigger_ops into struct event_command Greg Kroah-Hartman
                   ` (167 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Masami Hiramatsu, Mark Rutland,
	Mathieu Desnoyers, Andrew Morton, Tom Zanussi,
	Steven Rostedt (Google), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Steven Rostedt <rostedt@goodmis.org>

[ Upstream commit bdafb4d4cb3bb18b29517eaae09fb49d25f854f0 ]

The struct event_command has a callback function called get_trigger_ops().
This callback returns the "trigger_ops" to use for the trigger. These ops
define the trigger function, how to init the trigger, how to print the
trigger and how to free it.

The only reason there's a callback function to get these ops is because
some triggers have two types of operations. One is an "always on"
operation, and the other is a "count down" operation. If a user passes in
a parameter to say how many times the trigger should execute. For example:

  echo stacktrace:5 > events/kmem/kmem_cache_alloc/trigger

It will trigger the stacktrace for the first 5 times the kmem_cache_alloc
event is hit.

Instead of having two different trigger_ops since the only difference
between them is the tigger itself (the print, init and free functions are
all the same), just use a single ops that the event_command points to and
add a function field to the trigger_ops to have a count_func.

When a trigger is added to an event, if there's a count attached to it and
the trigger ops has the count_func field, the data allocated to represent
this trigger will have a new flag set called COUNT.

Then when the trigger executes, it will check if the COUNT data flag is
set, and if so, it will call the ops count_func(). If that returns false,
it returns without executing the trigger.

This removes the need for duplicate event_trigger_ops structures.

Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Link: https://patch.msgid.link/20251125200932.274566147@kernel.org
Reviewed-by: Tom Zanussi <zanussi@kernel.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Stable-dep-of: 6ede78d0563a ("tracing: Set the trace clock before registering the histogram trigger")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/trace.h                |   26 ++-
 kernel/trace/trace_eprobe.c         |    8 -
 kernel/trace/trace_events_hist.c    |   60 --------
 kernel/trace/trace_events_trigger.c |  257 ++++++++++++------------------------
 4 files changed, 116 insertions(+), 235 deletions(-)

--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1692,6 +1692,7 @@ extern void clear_event_triggers(struct
 
 enum {
 	EVENT_TRIGGER_FL_PROBE		= BIT(0),
+	EVENT_TRIGGER_FL_COUNT		= BIT(1),
 };
 
 struct event_trigger_data {
@@ -1723,6 +1724,10 @@ struct enable_trigger_data {
 	bool				hist;
 };
 
+bool event_trigger_count(struct event_trigger_data *data,
+			 struct trace_buffer *buffer,  void *rec,
+			 struct ring_buffer_event *event);
+
 extern int event_enable_trigger_print(struct seq_file *m,
 				      struct event_trigger_data *data);
 extern void event_enable_trigger_free(struct event_trigger_data *data);
@@ -1810,6 +1815,11 @@ extern void event_file_put(struct trace_
  *	registered the trigger (see struct event_command) along with
  *	the trace record, rec.
  *
+ * @count_func: If defined and a numeric parameter is passed to the
+ *	trigger, then this function will be called before @trigger
+ *	is called. If this function returns false, then @trigger is not
+ *	executed.
+ *
  * @init: An optional initialization function called for the trigger
  *	when the trigger is registered (via the event_command reg()
  *	function).  This can be used to perform per-trigger
@@ -1837,6 +1847,10 @@ struct event_trigger_ops {
 					   struct trace_buffer *buffer,
 					   void *rec,
 					   struct ring_buffer_event *rbe);
+	bool			(*count_func)(struct event_trigger_data *data,
+					      struct trace_buffer *buffer,
+					      void *rec,
+					      struct ring_buffer_event *rbe);
 	int			(*init)(struct event_trigger_data *data);
 	void			(*free)(struct event_trigger_data *data);
 	int			(*print)(struct seq_file *m,
@@ -1863,6 +1877,9 @@ struct event_trigger_ops {
  * @name: The unique name that identifies the event command.  This is
  *	the name used when setting triggers via trigger files.
  *
+ * @trigger_ops: The event_trigger_ops implementation associated with
+ *	the command.
+ *
  * @trigger_type: A unique id that identifies the event command
  *	'type'.  This value has two purposes, the first to ensure that
  *	only one trigger of the same type can be set at a given time
@@ -1914,17 +1931,11 @@ struct event_trigger_ops {
  *	event command, filters set by the user for the command will be
  *	ignored.  This is usually implemented by the generic utility
  *	function @set_trigger_filter() (see trace_event_triggers.c).
- *
- * @get_trigger_ops: The callback function invoked to retrieve the
- *	event_trigger_ops implementation associated with the command.
- *	This callback function allows a single event_command to
- *	support multiple trigger implementations via different sets of
- *	event_trigger_ops, depending on the value of the @param
- *	string.
  */
 struct event_command {
 	struct list_head	list;
 	char			*name;
+	const struct event_trigger_ops *trigger_ops;
 	enum event_trigger_type	trigger_type;
 	int			flags;
 	int			(*parse)(struct event_command *cmd_ops,
@@ -1941,7 +1952,6 @@ struct event_command {
 	int			(*set_filter)(char *filter_str,
 					      struct event_trigger_data *data,
 					      struct trace_event_file *file);
-	const struct event_trigger_ops *(*get_trigger_ops)(char *cmd, char *param);
 };
 
 /**
--- a/kernel/trace/trace_eprobe.c
+++ b/kernel/trace/trace_eprobe.c
@@ -508,21 +508,15 @@ static void eprobe_trigger_unreg_func(ch
 
 }
 
-static const struct event_trigger_ops *eprobe_trigger_get_ops(char *cmd,
-							      char *param)
-{
-	return &eprobe_trigger_ops;
-}
-
 static struct event_command event_trigger_cmd = {
 	.name			= "eprobe",
 	.trigger_type		= ETT_EVENT_EPROBE,
 	.flags			= EVENT_CMD_FL_NEEDS_REC,
+	.trigger_ops		= &eprobe_trigger_ops,
 	.parse			= eprobe_trigger_cmd_parse,
 	.reg			= eprobe_trigger_reg_func,
 	.unreg			= eprobe_trigger_unreg_func,
 	.unreg_all		= NULL,
-	.get_trigger_ops	= eprobe_trigger_get_ops,
 	.set_filter		= NULL,
 };
 
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -6360,12 +6360,6 @@ static const struct event_trigger_ops ev
 	.free			= event_hist_trigger_named_free,
 };
 
-static const struct event_trigger_ops *event_hist_get_trigger_ops(char *cmd,
-								  char *param)
-{
-	return &event_hist_trigger_ops;
-}
-
 static void hist_clear(struct event_trigger_data *data)
 {
 	struct hist_trigger_data *hist_data = data->private_data;
@@ -6907,11 +6901,11 @@ static struct event_command trigger_hist
 	.name			= "hist",
 	.trigger_type		= ETT_EVENT_HIST,
 	.flags			= EVENT_CMD_FL_NEEDS_REC,
+	.trigger_ops		= &event_hist_trigger_ops,
 	.parse			= event_hist_trigger_parse,
 	.reg			= hist_register_trigger,
 	.unreg			= hist_unregister_trigger,
 	.unreg_all		= hist_unreg_all,
-	.get_trigger_ops	= event_hist_get_trigger_ops,
 	.set_filter		= set_trigger_filter,
 };
 
@@ -6944,29 +6938,9 @@ hist_enable_trigger(struct event_trigger
 	}
 }
 
-static void
-hist_enable_count_trigger(struct event_trigger_data *data,
-			  struct trace_buffer *buffer,  void *rec,
-			  struct ring_buffer_event *event)
-{
-	if (!data->count)
-		return;
-
-	if (data->count != -1)
-		(data->count)--;
-
-	hist_enable_trigger(data, buffer, rec, event);
-}
-
 static const struct event_trigger_ops hist_enable_trigger_ops = {
 	.trigger		= hist_enable_trigger,
-	.print			= event_enable_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_enable_trigger_free,
-};
-
-static const struct event_trigger_ops hist_enable_count_trigger_ops = {
-	.trigger		= hist_enable_count_trigger,
+	.count_func		= event_trigger_count,
 	.print			= event_enable_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_enable_trigger_free,
@@ -6974,36 +6948,12 @@ static const struct event_trigger_ops hi
 
 static const struct event_trigger_ops hist_disable_trigger_ops = {
 	.trigger		= hist_enable_trigger,
+	.count_func		= event_trigger_count,
 	.print			= event_enable_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_enable_trigger_free,
 };
 
-static const struct event_trigger_ops hist_disable_count_trigger_ops = {
-	.trigger		= hist_enable_count_trigger,
-	.print			= event_enable_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_enable_trigger_free,
-};
-
-static const struct event_trigger_ops *
-hist_enable_get_trigger_ops(char *cmd, char *param)
-{
-	const struct event_trigger_ops *ops;
-	bool enable;
-
-	enable = (strcmp(cmd, ENABLE_HIST_STR) == 0);
-
-	if (enable)
-		ops = param ? &hist_enable_count_trigger_ops :
-			&hist_enable_trigger_ops;
-	else
-		ops = param ? &hist_disable_count_trigger_ops :
-			&hist_disable_trigger_ops;
-
-	return ops;
-}
-
 static void hist_enable_unreg_all(struct trace_event_file *file)
 {
 	struct event_trigger_data *test, *n;
@@ -7022,22 +6972,22 @@ static void hist_enable_unreg_all(struct
 static struct event_command trigger_hist_enable_cmd = {
 	.name			= ENABLE_HIST_STR,
 	.trigger_type		= ETT_HIST_ENABLE,
+	.trigger_ops		= &hist_enable_trigger_ops,
 	.parse			= event_enable_trigger_parse,
 	.reg			= event_enable_register_trigger,
 	.unreg			= event_enable_unregister_trigger,
 	.unreg_all		= hist_enable_unreg_all,
-	.get_trigger_ops	= hist_enable_get_trigger_ops,
 	.set_filter		= set_trigger_filter,
 };
 
 static struct event_command trigger_hist_disable_cmd = {
 	.name			= DISABLE_HIST_STR,
 	.trigger_type		= ETT_HIST_ENABLE,
+	.trigger_ops		= &hist_disable_trigger_ops,
 	.parse			= event_enable_trigger_parse,
 	.reg			= event_enable_register_trigger,
 	.unreg			= event_enable_unregister_trigger,
 	.unreg_all		= hist_enable_unreg_all,
-	.get_trigger_ops	= hist_enable_get_trigger_ops,
 	.set_filter		= set_trigger_filter,
 };
 
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -31,6 +31,20 @@ void trigger_data_free(struct event_trig
 	kfree(data);
 }
 
+static inline void data_ops_trigger(struct event_trigger_data *data,
+				    struct trace_buffer *buffer,  void *rec,
+				    struct ring_buffer_event *event)
+{
+	const struct event_trigger_ops *ops = data->ops;
+
+	if (data->flags & EVENT_TRIGGER_FL_COUNT) {
+		if (!ops->count_func(data, buffer, rec, event))
+			return;
+	}
+
+	ops->trigger(data, buffer, rec, event);
+}
+
 /**
  * event_triggers_call - Call triggers associated with a trace event
  * @file: The trace_event_file associated with the event
@@ -73,7 +87,7 @@ event_triggers_call(struct trace_event_f
 		if (data->paused)
 			continue;
 		if (!rec) {
-			data->ops->trigger(data, buffer, rec, event);
+			data_ops_trigger(data, buffer, rec, event);
 			continue;
 		}
 		filter = rcu_dereference_sched(data->filter);
@@ -83,7 +97,7 @@ event_triggers_call(struct trace_event_f
 			tt |= data->cmd_ops->trigger_type;
 			continue;
 		}
-		data->ops->trigger(data, buffer, rec, event);
+		data_ops_trigger(data, buffer, rec, event);
 	}
 	return tt;
 }
@@ -125,7 +139,7 @@ event_triggers_post_call(struct trace_ev
 		if (data->paused)
 			continue;
 		if (data->cmd_ops->trigger_type & tt)
-			data->ops->trigger(data, NULL, NULL, NULL);
+			data_ops_trigger(data, NULL, NULL, NULL);
 	}
 }
 EXPORT_SYMBOL_GPL(event_triggers_post_call);
@@ -402,6 +416,36 @@ __init int unregister_event_command(stru
 }
 
 /**
+ * event_trigger_count - Optional count function for event triggers
+ * @data: Trigger-specific data
+ * @buffer: The ring buffer that the event is being written to
+ * @rec: The trace entry for the event, NULL for unconditional invocation
+ * @event: The event meta data in the ring buffer
+ *
+ * For triggers that can take a count parameter that doesn't do anything
+ * special, they can use this function to assign to their .count_func
+ * field.
+ *
+ * This simply does a count down of the @data->count field.
+ *
+ * If the @data->count is greater than zero, it will decrement it.
+ *
+ * Returns false if @data->count is zero, otherwise true.
+ */
+bool event_trigger_count(struct event_trigger_data *data,
+			 struct trace_buffer *buffer,  void *rec,
+			 struct ring_buffer_event *event)
+{
+	if (!data->count)
+		return false;
+
+	if (data->count != -1)
+		(data->count)--;
+
+	return true;
+}
+
+/**
  * event_trigger_print - Generic event_trigger_ops @print implementation
  * @name: The name of the event trigger
  * @m: The seq_file being printed to
@@ -835,9 +879,13 @@ out:
  * @private_data: User data to associate with the event trigger
  *
  * Allocate an event_trigger_data instance and initialize it.  The
- * @cmd_ops are used along with the @cmd and @param to get the
- * trigger_ops to assign to the event_trigger_data.  @private_data can
- * also be passed in and associated with the event_trigger_data.
+ * @cmd_ops defines how the trigger will operate. If @param is set,
+ * and @cmd_ops->trigger_ops->count_func is non NULL, then the
+ * data->count is set to @param and before the trigger is executed, the
+ * @cmd_ops->trigger_ops->count_func() is called. If that function returns
+ * false, the @cmd_ops->trigger_ops->trigger() function will not be called.
+ * @private_data can also be passed in and associated with the
+ * event_trigger_data.
  *
  * Use trigger_data_free() to free an event_trigger_data object.
  *
@@ -849,18 +897,17 @@ struct event_trigger_data *trigger_data_
 					      void *private_data)
 {
 	struct event_trigger_data *trigger_data;
-	const struct event_trigger_ops *trigger_ops;
-
-	trigger_ops = cmd_ops->get_trigger_ops(cmd, param);
 
 	trigger_data = kzalloc(sizeof(*trigger_data), GFP_KERNEL);
 	if (!trigger_data)
 		return NULL;
 
 	trigger_data->count = -1;
-	trigger_data->ops = trigger_ops;
+	trigger_data->ops = cmd_ops->trigger_ops;
 	trigger_data->cmd_ops = cmd_ops;
 	trigger_data->private_data = private_data;
+	if (param && cmd_ops->trigger_ops->count_func)
+		trigger_data->flags |= EVENT_TRIGGER_FL_COUNT;
 
 	INIT_LIST_HEAD(&trigger_data->list);
 	INIT_LIST_HEAD(&trigger_data->named_list);
@@ -1302,31 +1349,28 @@ traceon_trigger(struct event_trigger_dat
 	tracing_on();
 }
 
-static void
-traceon_count_trigger(struct event_trigger_data *data,
-		      struct trace_buffer *buffer, void *rec,
-		      struct ring_buffer_event *event)
+static bool
+traceon_count_func(struct event_trigger_data *data,
+		   struct trace_buffer *buffer, void *rec,
+		   struct ring_buffer_event *event)
 {
 	struct trace_event_file *file = data->private_data;
 
 	if (file) {
 		if (tracer_tracing_is_on(file->tr))
-			return;
+			return false;
 	} else {
 		if (tracing_is_on())
-			return;
+			return false;
 	}
 
 	if (!data->count)
-		return;
+		return false;
 
 	if (data->count != -1)
 		(data->count)--;
 
-	if (file)
-		tracer_tracing_on(file->tr);
-	else
-		tracing_on();
+	return true;
 }
 
 static void
@@ -1350,31 +1394,28 @@ traceoff_trigger(struct event_trigger_da
 	tracing_off();
 }
 
-static void
-traceoff_count_trigger(struct event_trigger_data *data,
-		       struct trace_buffer *buffer, void *rec,
-		       struct ring_buffer_event *event)
+static bool
+traceoff_count_func(struct event_trigger_data *data,
+		    struct trace_buffer *buffer, void *rec,
+		    struct ring_buffer_event *event)
 {
 	struct trace_event_file *file = data->private_data;
 
 	if (file) {
 		if (!tracer_tracing_is_on(file->tr))
-			return;
+			return false;
 	} else {
 		if (!tracing_is_on())
-			return;
+			return false;
 	}
 
 	if (!data->count)
-		return;
+		return false;
 
 	if (data->count != -1)
 		(data->count)--;
 
-	if (file)
-		tracer_tracing_off(file->tr);
-	else
-		tracing_off();
+	return true;
 }
 
 static int
@@ -1393,13 +1434,7 @@ traceoff_trigger_print(struct seq_file *
 
 static const struct event_trigger_ops traceon_trigger_ops = {
 	.trigger		= traceon_trigger,
-	.print			= traceon_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_trigger_free,
-};
-
-static const struct event_trigger_ops traceon_count_trigger_ops = {
-	.trigger		= traceon_count_trigger,
+	.count_func		= traceon_count_func,
 	.print			= traceon_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_trigger_free,
@@ -1407,41 +1442,19 @@ static const struct event_trigger_ops tr
 
 static const struct event_trigger_ops traceoff_trigger_ops = {
 	.trigger		= traceoff_trigger,
+	.count_func		= traceoff_count_func,
 	.print			= traceoff_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_trigger_free,
 };
 
-static const struct event_trigger_ops traceoff_count_trigger_ops = {
-	.trigger		= traceoff_count_trigger,
-	.print			= traceoff_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_trigger_free,
-};
-
-static const struct event_trigger_ops *
-onoff_get_trigger_ops(char *cmd, char *param)
-{
-	const struct event_trigger_ops *ops;
-
-	/* we register both traceon and traceoff to this callback */
-	if (strcmp(cmd, "traceon") == 0)
-		ops = param ? &traceon_count_trigger_ops :
-			&traceon_trigger_ops;
-	else
-		ops = param ? &traceoff_count_trigger_ops :
-			&traceoff_trigger_ops;
-
-	return ops;
-}
-
 static struct event_command trigger_traceon_cmd = {
 	.name			= "traceon",
 	.trigger_type		= ETT_TRACE_ONOFF,
+	.trigger_ops		= &traceon_trigger_ops,
 	.parse			= event_trigger_parse,
 	.reg			= register_trigger,
 	.unreg			= unregister_trigger,
-	.get_trigger_ops	= onoff_get_trigger_ops,
 	.set_filter		= set_trigger_filter,
 };
 
@@ -1449,10 +1462,10 @@ static struct event_command trigger_trac
 	.name			= "traceoff",
 	.trigger_type		= ETT_TRACE_ONOFF,
 	.flags			= EVENT_CMD_FL_POST_TRIGGER,
+	.trigger_ops		= &traceoff_trigger_ops,
 	.parse			= event_trigger_parse,
 	.reg			= register_trigger,
 	.unreg			= unregister_trigger,
-	.get_trigger_ops	= onoff_get_trigger_ops,
 	.set_filter		= set_trigger_filter,
 };
 
@@ -1470,20 +1483,6 @@ snapshot_trigger(struct event_trigger_da
 		tracing_snapshot();
 }
 
-static void
-snapshot_count_trigger(struct event_trigger_data *data,
-		       struct trace_buffer *buffer, void *rec,
-		       struct ring_buffer_event *event)
-{
-	if (!data->count)
-		return;
-
-	if (data->count != -1)
-		(data->count)--;
-
-	snapshot_trigger(data, buffer, rec, event);
-}
-
 static int
 register_snapshot_trigger(char *glob,
 			  struct event_trigger_data *data,
@@ -1517,31 +1516,19 @@ snapshot_trigger_print(struct seq_file *
 
 static const struct event_trigger_ops snapshot_trigger_ops = {
 	.trigger		= snapshot_trigger,
+	.count_func		= event_trigger_count,
 	.print			= snapshot_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_trigger_free,
 };
 
-static const struct event_trigger_ops snapshot_count_trigger_ops = {
-	.trigger		= snapshot_count_trigger,
-	.print			= snapshot_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_trigger_free,
-};
-
-static const struct event_trigger_ops *
-snapshot_get_trigger_ops(char *cmd, char *param)
-{
-	return param ? &snapshot_count_trigger_ops : &snapshot_trigger_ops;
-}
-
 static struct event_command trigger_snapshot_cmd = {
 	.name			= "snapshot",
 	.trigger_type		= ETT_SNAPSHOT,
+	.trigger_ops		= &snapshot_trigger_ops,
 	.parse			= event_trigger_parse,
 	.reg			= register_snapshot_trigger,
 	.unreg			= unregister_snapshot_trigger,
-	.get_trigger_ops	= snapshot_get_trigger_ops,
 	.set_filter		= set_trigger_filter,
 };
 
@@ -1589,20 +1576,6 @@ stacktrace_trigger(struct event_trigger_
 		trace_dump_stack(STACK_SKIP);
 }
 
-static void
-stacktrace_count_trigger(struct event_trigger_data *data,
-			 struct trace_buffer *buffer, void *rec,
-			 struct ring_buffer_event *event)
-{
-	if (!data->count)
-		return;
-
-	if (data->count != -1)
-		(data->count)--;
-
-	stacktrace_trigger(data, buffer, rec, event);
-}
-
 static int
 stacktrace_trigger_print(struct seq_file *m, struct event_trigger_data *data)
 {
@@ -1612,32 +1585,20 @@ stacktrace_trigger_print(struct seq_file
 
 static const struct event_trigger_ops stacktrace_trigger_ops = {
 	.trigger		= stacktrace_trigger,
+	.count_func		= event_trigger_count,
 	.print			= stacktrace_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_trigger_free,
 };
 
-static const struct event_trigger_ops stacktrace_count_trigger_ops = {
-	.trigger		= stacktrace_count_trigger,
-	.print			= stacktrace_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_trigger_free,
-};
-
-static const struct event_trigger_ops *
-stacktrace_get_trigger_ops(char *cmd, char *param)
-{
-	return param ? &stacktrace_count_trigger_ops : &stacktrace_trigger_ops;
-}
-
 static struct event_command trigger_stacktrace_cmd = {
 	.name			= "stacktrace",
 	.trigger_type		= ETT_STACKTRACE,
+	.trigger_ops		= &stacktrace_trigger_ops,
 	.flags			= EVENT_CMD_FL_POST_TRIGGER,
 	.parse			= event_trigger_parse,
 	.reg			= register_trigger,
 	.unreg			= unregister_trigger,
-	.get_trigger_ops	= stacktrace_get_trigger_ops,
 	.set_filter		= set_trigger_filter,
 };
 
@@ -1673,24 +1634,24 @@ event_enable_trigger(struct event_trigge
 		set_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, &enable_data->file->flags);
 }
 
-static void
-event_enable_count_trigger(struct event_trigger_data *data,
-			   struct trace_buffer *buffer,  void *rec,
-			   struct ring_buffer_event *event)
+static bool
+event_enable_count_func(struct event_trigger_data *data,
+			struct trace_buffer *buffer,  void *rec,
+			struct ring_buffer_event *event)
 {
 	struct enable_trigger_data *enable_data = data->private_data;
 
 	if (!data->count)
-		return;
+		return false;
 
 	/* Skip if the event is in a state we want to switch to */
 	if (enable_data->enable == !(enable_data->file->flags & EVENT_FILE_FL_SOFT_DISABLED))
-		return;
+		return false;
 
 	if (data->count != -1)
 		(data->count)--;
 
-	event_enable_trigger(data, buffer, rec, event);
+	return true;
 }
 
 int event_enable_trigger_print(struct seq_file *m,
@@ -1737,13 +1698,7 @@ void event_enable_trigger_free(struct ev
 
 static const struct event_trigger_ops event_enable_trigger_ops = {
 	.trigger		= event_enable_trigger,
-	.print			= event_enable_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_enable_trigger_free,
-};
-
-static const struct event_trigger_ops event_enable_count_trigger_ops = {
-	.trigger		= event_enable_count_trigger,
+	.count_func		= event_enable_count_func,
 	.print			= event_enable_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_enable_trigger_free,
@@ -1751,13 +1706,7 @@ static const struct event_trigger_ops ev
 
 static const struct event_trigger_ops event_disable_trigger_ops = {
 	.trigger		= event_enable_trigger,
-	.print			= event_enable_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_enable_trigger_free,
-};
-
-static const struct event_trigger_ops event_disable_count_trigger_ops = {
-	.trigger		= event_enable_count_trigger,
+	.count_func		= event_enable_count_func,
 	.print			= event_enable_trigger_print,
 	.init			= event_trigger_init,
 	.free			= event_enable_trigger_free,
@@ -1940,45 +1889,23 @@ void event_enable_unregister_trigger(cha
 		data->ops->free(data);
 }
 
-static const struct event_trigger_ops *
-event_enable_get_trigger_ops(char *cmd, char *param)
-{
-	const struct event_trigger_ops *ops;
-	bool enable;
-
-#ifdef CONFIG_HIST_TRIGGERS
-	enable = ((strcmp(cmd, ENABLE_EVENT_STR) == 0) ||
-		  (strcmp(cmd, ENABLE_HIST_STR) == 0));
-#else
-	enable = strcmp(cmd, ENABLE_EVENT_STR) == 0;
-#endif
-	if (enable)
-		ops = param ? &event_enable_count_trigger_ops :
-			&event_enable_trigger_ops;
-	else
-		ops = param ? &event_disable_count_trigger_ops :
-			&event_disable_trigger_ops;
-
-	return ops;
-}
-
 static struct event_command trigger_enable_cmd = {
 	.name			= ENABLE_EVENT_STR,
 	.trigger_type		= ETT_EVENT_ENABLE,
+	.trigger_ops		= &event_enable_trigger_ops,
 	.parse			= event_enable_trigger_parse,
 	.reg			= event_enable_register_trigger,
 	.unreg			= event_enable_unregister_trigger,
-	.get_trigger_ops	= event_enable_get_trigger_ops,
 	.set_filter		= set_trigger_filter,
 };
 
 static struct event_command trigger_disable_cmd = {
 	.name			= DISABLE_EVENT_STR,
 	.trigger_type		= ETT_EVENT_ENABLE,
+	.trigger_ops		= &event_disable_trigger_ops,
 	.parse			= event_enable_trigger_parse,
 	.reg			= event_enable_register_trigger,
 	.unreg			= event_enable_unregister_trigger,
-	.get_trigger_ops	= event_enable_get_trigger_ops,
 	.set_filter		= set_trigger_filter,
 };
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 718/877] tracing: Merge struct event_trigger_ops into struct event_command
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (716 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 717/877] tracing: Remove get_trigger_ops() and add count_func() from trigger ops Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 719/877] tracing: Set the trace clock before registering the histogram trigger Greg Kroah-Hartman
                   ` (166 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Masami Hiramatsu, Mark Rutland,
	Mathieu Desnoyers, Andrew Morton, Tom Zanussi,
	Steven Rostedt (Google), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Steven Rostedt <rostedt@goodmis.org>

[ Upstream commit b052d70f7c9c156409a70e65c10d83b5650e7e78 ]

Now that there's pretty much a one to one mapping between the struct
event_trigger_ops and struct event_command, there's no reason to have two
different structures. Merge the function pointers of event_trigger_ops
into event_command.

There's one exception in trace_events_hist.c for the
event_hist_trigger_named_ops. This has special logic for the init and free
function pointers for "named histograms". In this case, allocate the
cmd_ops of the event_trigger_data and set it to the proper init and free
functions, which are used to initialize and free the event_trigger_data
respectively. Have the free function and the init function (on failure)
free the cmd_ops of the data element.

Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Link: https://patch.msgid.link/20251125200932.446322765@kernel.org
Reviewed-by: Tom Zanussi <zanussi@kernel.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Stable-dep-of: 6ede78d0563a ("tracing: Set the trace clock before registering the histogram trigger")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/trace.h                |  126 ++++++++++++++----------------------
 kernel/trace/trace_eprobe.c         |   13 +--
 kernel/trace/trace_events_hist.c    |   93 +++++++++++++-------------
 kernel/trace/trace_events_trigger.c |  121 +++++++++++++---------------------
 4 files changed, 151 insertions(+), 202 deletions(-)

--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1699,7 +1699,6 @@ struct event_trigger_data {
 	unsigned long			count;
 	int				ref;
 	int				flags;
-	const struct event_trigger_ops	*ops;
 	struct event_command		*cmd_ops;
 	struct event_filter __rcu	*filter;
 	char				*filter_str;
@@ -1791,73 +1790,6 @@ extern void event_file_get(struct trace_
 extern void event_file_put(struct trace_event_file *file);
 
 /**
- * struct event_trigger_ops - callbacks for trace event triggers
- *
- * The methods in this structure provide per-event trigger hooks for
- * various trigger operations.
- *
- * The @init and @free methods are used during trigger setup and
- * teardown, typically called from an event_command's @parse()
- * function implementation.
- *
- * The @print method is used to print the trigger spec.
- *
- * The @trigger method is the function that actually implements the
- * trigger and is called in the context of the triggering event
- * whenever that event occurs.
- *
- * All the methods below, except for @init() and @free(), must be
- * implemented.
- *
- * @trigger: The trigger 'probe' function called when the triggering
- *	event occurs.  The data passed into this callback is the data
- *	that was supplied to the event_command @reg() function that
- *	registered the trigger (see struct event_command) along with
- *	the trace record, rec.
- *
- * @count_func: If defined and a numeric parameter is passed to the
- *	trigger, then this function will be called before @trigger
- *	is called. If this function returns false, then @trigger is not
- *	executed.
- *
- * @init: An optional initialization function called for the trigger
- *	when the trigger is registered (via the event_command reg()
- *	function).  This can be used to perform per-trigger
- *	initialization such as incrementing a per-trigger reference
- *	count, for instance.  This is usually implemented by the
- *	generic utility function @event_trigger_init() (see
- *	trace_event_triggers.c).
- *
- * @free: An optional de-initialization function called for the
- *	trigger when the trigger is unregistered (via the
- *	event_command @reg() function).  This can be used to perform
- *	per-trigger de-initialization such as decrementing a
- *	per-trigger reference count and freeing corresponding trigger
- *	data, for instance.  This is usually implemented by the
- *	generic utility function @event_trigger_free() (see
- *	trace_event_triggers.c).
- *
- * @print: The callback function invoked to have the trigger print
- *	itself.  This is usually implemented by a wrapper function
- *	that calls the generic utility function @event_trigger_print()
- *	(see trace_event_triggers.c).
- */
-struct event_trigger_ops {
-	void			(*trigger)(struct event_trigger_data *data,
-					   struct trace_buffer *buffer,
-					   void *rec,
-					   struct ring_buffer_event *rbe);
-	bool			(*count_func)(struct event_trigger_data *data,
-					      struct trace_buffer *buffer,
-					      void *rec,
-					      struct ring_buffer_event *rbe);
-	int			(*init)(struct event_trigger_data *data);
-	void			(*free)(struct event_trigger_data *data);
-	int			(*print)(struct seq_file *m,
-					 struct event_trigger_data *data);
-};
-
-/**
  * struct event_command - callbacks and data members for event commands
  *
  * Event commands are invoked by users by writing the command name
@@ -1877,9 +1809,6 @@ struct event_trigger_ops {
  * @name: The unique name that identifies the event command.  This is
  *	the name used when setting triggers via trigger files.
  *
- * @trigger_ops: The event_trigger_ops implementation associated with
- *	the command.
- *
  * @trigger_type: A unique id that identifies the event command
  *	'type'.  This value has two purposes, the first to ensure that
  *	only one trigger of the same type can be set at a given time
@@ -1909,7 +1838,7 @@ struct event_trigger_ops {
  *
  * @reg: Adds the trigger to the list of triggers associated with the
  *	event, and enables the event trigger itself, after
- *	initializing it (via the event_trigger_ops @init() function).
+ *	initializing it (via the event_command @init() function).
  *	This is also where commands can use the @trigger_type value to
  *	make the decision as to whether or not multiple instances of
  *	the trigger should be allowed.  This is usually implemented by
@@ -1918,7 +1847,7 @@ struct event_trigger_ops {
  *
  * @unreg: Removes the trigger from the list of triggers associated
  *	with the event, and disables the event trigger itself, after
- *	initializing it (via the event_trigger_ops @free() function).
+ *	initializing it (via the event_command @free() function).
  *	This is usually implemented by the generic utility function
  *	@unregister_trigger() (see trace_event_triggers.c).
  *
@@ -1931,11 +1860,46 @@ struct event_trigger_ops {
  *	event command, filters set by the user for the command will be
  *	ignored.  This is usually implemented by the generic utility
  *	function @set_trigger_filter() (see trace_event_triggers.c).
+ *
+ * All the methods below, except for @init() and @free(), must be
+ * implemented.
+ *
+ * @trigger: The trigger 'probe' function called when the triggering
+ *	event occurs.  The data passed into this callback is the data
+ *	that was supplied to the event_command @reg() function that
+ *	registered the trigger (see struct event_command) along with
+ *	the trace record, rec.
+ *
+ * @count_func: If defined and a numeric parameter is passed to the
+ *	trigger, then this function will be called before @trigger
+ *	is called. If this function returns false, then @trigger is not
+ *	executed.
+ *
+ * @init: An optional initialization function called for the trigger
+ *	when the trigger is registered (via the event_command reg()
+ *	function).  This can be used to perform per-trigger
+ *	initialization such as incrementing a per-trigger reference
+ *	count, for instance.  This is usually implemented by the
+ *	generic utility function @event_trigger_init() (see
+ *	trace_event_triggers.c).
+ *
+ * @free: An optional de-initialization function called for the
+ *	trigger when the trigger is unregistered (via the
+ *	event_command @reg() function).  This can be used to perform
+ *	per-trigger de-initialization such as decrementing a
+ *	per-trigger reference count and freeing corresponding trigger
+ *	data, for instance.  This is usually implemented by the
+ *	generic utility function @event_trigger_free() (see
+ *	trace_event_triggers.c).
+ *
+ * @print: The callback function invoked to have the trigger print
+ *	itself.  This is usually implemented by a wrapper function
+ *	that calls the generic utility function @event_trigger_print()
+ *	(see trace_event_triggers.c).
  */
 struct event_command {
 	struct list_head	list;
 	char			*name;
-	const struct event_trigger_ops *trigger_ops;
 	enum event_trigger_type	trigger_type;
 	int			flags;
 	int			(*parse)(struct event_command *cmd_ops,
@@ -1952,6 +1916,18 @@ struct event_command {
 	int			(*set_filter)(char *filter_str,
 					      struct event_trigger_data *data,
 					      struct trace_event_file *file);
+	void			(*trigger)(struct event_trigger_data *data,
+					   struct trace_buffer *buffer,
+					   void *rec,
+					   struct ring_buffer_event *rbe);
+	bool			(*count_func)(struct event_trigger_data *data,
+					      struct trace_buffer *buffer,
+					      void *rec,
+					      struct ring_buffer_event *rbe);
+	int			(*init)(struct event_trigger_data *data);
+	void			(*free)(struct event_trigger_data *data);
+	int			(*print)(struct seq_file *m,
+					 struct event_trigger_data *data);
 };
 
 /**
@@ -1972,7 +1948,7 @@ struct event_command {
  *	either committed or discarded.  At that point, if any commands
  *	have deferred their triggers, those commands are finally
  *	invoked following the close of the current event.  In other
- *	words, if the event_trigger_ops @func() probe implementation
+ *	words, if the event_command @func() probe implementation
  *	itself logs to the trace buffer, this flag should be set,
  *	otherwise it can be left unspecified.
  *
--- a/kernel/trace/trace_eprobe.c
+++ b/kernel/trace/trace_eprobe.c
@@ -479,13 +479,6 @@ static void eprobe_trigger_func(struct e
 	__eprobe_trace_func(edata, rec);
 }
 
-static const struct event_trigger_ops eprobe_trigger_ops = {
-	.trigger		= eprobe_trigger_func,
-	.print			= eprobe_trigger_print,
-	.init			= eprobe_trigger_init,
-	.free			= eprobe_trigger_free,
-};
-
 static int eprobe_trigger_cmd_parse(struct event_command *cmd_ops,
 				    struct trace_event_file *file,
 				    char *glob, char *cmd,
@@ -512,12 +505,15 @@ static struct event_command event_trigge
 	.name			= "eprobe",
 	.trigger_type		= ETT_EVENT_EPROBE,
 	.flags			= EVENT_CMD_FL_NEEDS_REC,
-	.trigger_ops		= &eprobe_trigger_ops,
 	.parse			= eprobe_trigger_cmd_parse,
 	.reg			= eprobe_trigger_reg_func,
 	.unreg			= eprobe_trigger_unreg_func,
 	.unreg_all		= NULL,
 	.set_filter		= NULL,
+	.trigger		= eprobe_trigger_func,
+	.print			= eprobe_trigger_print,
+	.init			= eprobe_trigger_init,
+	.free			= eprobe_trigger_free,
 };
 
 static struct event_trigger_data *
@@ -537,7 +533,6 @@ new_eprobe_trigger(struct trace_eprobe *
 
 	trigger->flags = EVENT_TRIGGER_FL_PROBE;
 	trigger->count = -1;
-	trigger->ops = &eprobe_trigger_ops;
 
 	/*
 	 * EVENT PROBE triggers are not registered as commands with
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -5693,7 +5693,7 @@ static void hist_trigger_show(struct seq
 		seq_puts(m, "\n\n");
 
 	seq_puts(m, "# event histogram\n#\n# trigger info: ");
-	data->ops->print(m, data);
+	data->cmd_ops->print(m, data);
 	seq_puts(m, "#\n\n");
 
 	hist_data = data->private_data;
@@ -6015,7 +6015,7 @@ static void hist_trigger_debug_show(stru
 		seq_puts(m, "\n\n");
 
 	seq_puts(m, "# event histogram\n#\n# trigger info: ");
-	data->ops->print(m, data);
+	data->cmd_ops->print(m, data);
 	seq_puts(m, "#\n\n");
 
 	hist_data = data->private_data;
@@ -6323,20 +6323,21 @@ static void event_hist_trigger_free(stru
 	free_hist_pad();
 }
 
-static const struct event_trigger_ops event_hist_trigger_ops = {
-	.trigger		= event_hist_trigger,
-	.print			= event_hist_trigger_print,
-	.init			= event_hist_trigger_init,
-	.free			= event_hist_trigger_free,
-};
-
 static int event_hist_trigger_named_init(struct event_trigger_data *data)
 {
+	int ret;
+
 	data->ref++;
 
 	save_named_trigger(data->named_data->name, data);
 
-	return event_hist_trigger_init(data->named_data);
+	ret = event_hist_trigger_init(data->named_data);
+	if (ret < 0) {
+		kfree(data->cmd_ops);
+		data->cmd_ops = &trigger_hist_cmd;
+	}
+
+	return ret;
 }
 
 static void event_hist_trigger_named_free(struct event_trigger_data *data)
@@ -6348,18 +6349,14 @@ static void event_hist_trigger_named_fre
 
 	data->ref--;
 	if (!data->ref) {
+		struct event_command *cmd_ops = data->cmd_ops;
+
 		del_named_trigger(data);
 		trigger_data_free(data);
+		kfree(cmd_ops);
 	}
 }
 
-static const struct event_trigger_ops event_hist_trigger_named_ops = {
-	.trigger		= event_hist_trigger,
-	.print			= event_hist_trigger_print,
-	.init			= event_hist_trigger_named_init,
-	.free			= event_hist_trigger_named_free,
-};
-
 static void hist_clear(struct event_trigger_data *data)
 {
 	struct hist_trigger_data *hist_data = data->private_data;
@@ -6553,13 +6550,24 @@ static int hist_register_trigger(char *g
 		data->paused = true;
 
 	if (named_data) {
+		struct event_command *cmd_ops;
+
 		data->private_data = named_data->private_data;
 		set_named_trigger_data(data, named_data);
-		data->ops = &event_hist_trigger_named_ops;
+		/* Copy the command ops and update some of the functions */
+		cmd_ops = kmalloc(sizeof(*cmd_ops), GFP_KERNEL);
+		if (!cmd_ops) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		*cmd_ops = *data->cmd_ops;
+		cmd_ops->init = event_hist_trigger_named_init;
+		cmd_ops->free = event_hist_trigger_named_free;
+		data->cmd_ops = cmd_ops;
 	}
 
-	if (data->ops->init) {
-		ret = data->ops->init(data);
+	if (data->cmd_ops->init) {
+		ret = data->cmd_ops->init(data);
 		if (ret < 0)
 			goto out;
 	}
@@ -6675,8 +6683,8 @@ static void hist_unregister_trigger(char
 		}
 	}
 
-	if (test && test->ops->free)
-		test->ops->free(test);
+	if (test && test->cmd_ops->free)
+		test->cmd_ops->free(test);
 
 	if (hist_data->enable_timestamps) {
 		if (!hist_data->remove || test)
@@ -6728,8 +6736,8 @@ static void hist_unreg_all(struct trace_
 			update_cond_flag(file);
 			if (hist_data->enable_timestamps)
 				tracing_set_filter_buffering(file->tr, false);
-			if (test->ops->free)
-				test->ops->free(test);
+			if (test->cmd_ops->free)
+				test->cmd_ops->free(test);
 		}
 	}
 }
@@ -6901,12 +6909,15 @@ static struct event_command trigger_hist
 	.name			= "hist",
 	.trigger_type		= ETT_EVENT_HIST,
 	.flags			= EVENT_CMD_FL_NEEDS_REC,
-	.trigger_ops		= &event_hist_trigger_ops,
 	.parse			= event_hist_trigger_parse,
 	.reg			= hist_register_trigger,
 	.unreg			= hist_unregister_trigger,
 	.unreg_all		= hist_unreg_all,
 	.set_filter		= set_trigger_filter,
+	.trigger		= event_hist_trigger,
+	.print			= event_hist_trigger_print,
+	.init			= event_hist_trigger_init,
+	.free			= event_hist_trigger_free,
 };
 
 __init int register_trigger_hist_cmd(void)
@@ -6938,22 +6949,6 @@ hist_enable_trigger(struct event_trigger
 	}
 }
 
-static const struct event_trigger_ops hist_enable_trigger_ops = {
-	.trigger		= hist_enable_trigger,
-	.count_func		= event_trigger_count,
-	.print			= event_enable_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_enable_trigger_free,
-};
-
-static const struct event_trigger_ops hist_disable_trigger_ops = {
-	.trigger		= hist_enable_trigger,
-	.count_func		= event_trigger_count,
-	.print			= event_enable_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_enable_trigger_free,
-};
-
 static void hist_enable_unreg_all(struct trace_event_file *file)
 {
 	struct event_trigger_data *test, *n;
@@ -6963,8 +6958,8 @@ static void hist_enable_unreg_all(struct
 			list_del_rcu(&test->list);
 			update_cond_flag(file);
 			trace_event_trigger_enable_disable(file, 0);
-			if (test->ops->free)
-				test->ops->free(test);
+			if (test->cmd_ops->free)
+				test->cmd_ops->free(test);
 		}
 	}
 }
@@ -6972,23 +6967,31 @@ static void hist_enable_unreg_all(struct
 static struct event_command trigger_hist_enable_cmd = {
 	.name			= ENABLE_HIST_STR,
 	.trigger_type		= ETT_HIST_ENABLE,
-	.trigger_ops		= &hist_enable_trigger_ops,
 	.parse			= event_enable_trigger_parse,
 	.reg			= event_enable_register_trigger,
 	.unreg			= event_enable_unregister_trigger,
 	.unreg_all		= hist_enable_unreg_all,
 	.set_filter		= set_trigger_filter,
+	.trigger		= hist_enable_trigger,
+	.count_func		= event_trigger_count,
+	.print			= event_enable_trigger_print,
+	.init			= event_trigger_init,
+	.free			= event_enable_trigger_free,
 };
 
 static struct event_command trigger_hist_disable_cmd = {
 	.name			= DISABLE_HIST_STR,
 	.trigger_type		= ETT_HIST_ENABLE,
-	.trigger_ops		= &hist_disable_trigger_ops,
 	.parse			= event_enable_trigger_parse,
 	.reg			= event_enable_register_trigger,
 	.unreg			= event_enable_unregister_trigger,
 	.unreg_all		= hist_enable_unreg_all,
 	.set_filter		= set_trigger_filter,
+	.trigger		= hist_enable_trigger,
+	.count_func		= event_trigger_count,
+	.print			= event_enable_trigger_print,
+	.init			= event_trigger_init,
+	.free			= event_enable_trigger_free,
 };
 
 static __init void unregister_trigger_hist_enable_disable_cmds(void)
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -35,14 +35,14 @@ static inline void data_ops_trigger(stru
 				    struct trace_buffer *buffer,  void *rec,
 				    struct ring_buffer_event *event)
 {
-	const struct event_trigger_ops *ops = data->ops;
+	const struct event_command *cmd_ops = data->cmd_ops;
 
 	if (data->flags & EVENT_TRIGGER_FL_COUNT) {
-		if (!ops->count_func(data, buffer, rec, event))
+		if (!cmd_ops->count_func(data, buffer, rec, event))
 			return;
 	}
 
-	ops->trigger(data, buffer, rec, event);
+	cmd_ops->trigger(data, buffer, rec, event);
 }
 
 /**
@@ -208,7 +208,7 @@ static int trigger_show(struct seq_file
 	}
 
 	data = list_entry(v, struct event_trigger_data, list);
-	data->ops->print(m, data);
+	data->cmd_ops->print(m, data);
 
 	return 0;
 }
@@ -446,7 +446,7 @@ bool event_trigger_count(struct event_tr
 }
 
 /**
- * event_trigger_print - Generic event_trigger_ops @print implementation
+ * event_trigger_print - Generic event_command @print implementation
  * @name: The name of the event trigger
  * @m: The seq_file being printed to
  * @data: Trigger-specific data
@@ -481,7 +481,7 @@ event_trigger_print(const char *name, st
 }
 
 /**
- * event_trigger_init - Generic event_trigger_ops @init implementation
+ * event_trigger_init - Generic event_command @init implementation
  * @data: Trigger-specific data
  *
  * Common implementation of event trigger initialization.
@@ -498,7 +498,7 @@ int event_trigger_init(struct event_trig
 }
 
 /**
- * event_trigger_free - Generic event_trigger_ops @free implementation
+ * event_trigger_free - Generic event_command @free implementation
  * @data: Trigger-specific data
  *
  * Common implementation of event trigger de-initialization.
@@ -560,8 +560,8 @@ clear_event_triggers(struct trace_array
 		list_for_each_entry_safe(data, n, &file->triggers, list) {
 			trace_event_trigger_enable_disable(file, 0);
 			list_del_rcu(&data->list);
-			if (data->ops->free)
-				data->ops->free(data);
+			if (data->cmd_ops->free)
+				data->cmd_ops->free(data);
 		}
 	}
 }
@@ -626,8 +626,8 @@ static int register_trigger(char *glob,
 		}
 	}
 
-	if (data->ops->init) {
-		ret = data->ops->init(data);
+	if (data->cmd_ops->init) {
+		ret = data->cmd_ops->init(data);
 		if (ret < 0)
 			goto out;
 	}
@@ -666,8 +666,8 @@ static bool try_unregister_trigger(char
 	}
 
 	if (data) {
-		if (data->ops->free)
-			data->ops->free(data);
+		if (data->cmd_ops->free)
+			data->cmd_ops->free(data);
 
 		return true;
 	}
@@ -903,10 +903,9 @@ struct event_trigger_data *trigger_data_
 		return NULL;
 
 	trigger_data->count = -1;
-	trigger_data->ops = cmd_ops->trigger_ops;
 	trigger_data->cmd_ops = cmd_ops;
 	trigger_data->private_data = private_data;
-	if (param && cmd_ops->trigger_ops->count_func)
+	if (param && cmd_ops->count_func)
 		trigger_data->flags |= EVENT_TRIGGER_FL_COUNT;
 
 	INIT_LIST_HEAD(&trigger_data->list);
@@ -1432,41 +1431,33 @@ traceoff_trigger_print(struct seq_file *
 				   data->filter_str);
 }
 
-static const struct event_trigger_ops traceon_trigger_ops = {
-	.trigger		= traceon_trigger,
-	.count_func		= traceon_count_func,
-	.print			= traceon_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_trigger_free,
-};
-
-static const struct event_trigger_ops traceoff_trigger_ops = {
-	.trigger		= traceoff_trigger,
-	.count_func		= traceoff_count_func,
-	.print			= traceoff_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_trigger_free,
-};
-
 static struct event_command trigger_traceon_cmd = {
 	.name			= "traceon",
 	.trigger_type		= ETT_TRACE_ONOFF,
-	.trigger_ops		= &traceon_trigger_ops,
 	.parse			= event_trigger_parse,
 	.reg			= register_trigger,
 	.unreg			= unregister_trigger,
 	.set_filter		= set_trigger_filter,
+	.trigger		= traceon_trigger,
+	.count_func		= traceon_count_func,
+	.print			= traceon_trigger_print,
+	.init			= event_trigger_init,
+	.free			= event_trigger_free,
 };
 
 static struct event_command trigger_traceoff_cmd = {
 	.name			= "traceoff",
 	.trigger_type		= ETT_TRACE_ONOFF,
 	.flags			= EVENT_CMD_FL_POST_TRIGGER,
-	.trigger_ops		= &traceoff_trigger_ops,
 	.parse			= event_trigger_parse,
 	.reg			= register_trigger,
 	.unreg			= unregister_trigger,
 	.set_filter		= set_trigger_filter,
+	.trigger		= traceoff_trigger,
+	.count_func		= traceoff_count_func,
+	.print			= traceoff_trigger_print,
+	.init			= event_trigger_init,
+	.free			= event_trigger_free,
 };
 
 #ifdef CONFIG_TRACER_SNAPSHOT
@@ -1514,22 +1505,18 @@ snapshot_trigger_print(struct seq_file *
 				   data->filter_str);
 }
 
-static const struct event_trigger_ops snapshot_trigger_ops = {
-	.trigger		= snapshot_trigger,
-	.count_func		= event_trigger_count,
-	.print			= snapshot_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_trigger_free,
-};
-
 static struct event_command trigger_snapshot_cmd = {
 	.name			= "snapshot",
 	.trigger_type		= ETT_SNAPSHOT,
-	.trigger_ops		= &snapshot_trigger_ops,
 	.parse			= event_trigger_parse,
 	.reg			= register_snapshot_trigger,
 	.unreg			= unregister_snapshot_trigger,
 	.set_filter		= set_trigger_filter,
+	.trigger		= snapshot_trigger,
+	.count_func		= event_trigger_count,
+	.print			= snapshot_trigger_print,
+	.init			= event_trigger_init,
+	.free			= event_trigger_free,
 };
 
 static __init int register_trigger_snapshot_cmd(void)
@@ -1583,23 +1570,19 @@ stacktrace_trigger_print(struct seq_file
 				   data->filter_str);
 }
 
-static const struct event_trigger_ops stacktrace_trigger_ops = {
-	.trigger		= stacktrace_trigger,
-	.count_func		= event_trigger_count,
-	.print			= stacktrace_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_trigger_free,
-};
-
 static struct event_command trigger_stacktrace_cmd = {
 	.name			= "stacktrace",
 	.trigger_type		= ETT_STACKTRACE,
-	.trigger_ops		= &stacktrace_trigger_ops,
 	.flags			= EVENT_CMD_FL_POST_TRIGGER,
 	.parse			= event_trigger_parse,
 	.reg			= register_trigger,
 	.unreg			= unregister_trigger,
 	.set_filter		= set_trigger_filter,
+	.trigger		= stacktrace_trigger,
+	.count_func		= event_trigger_count,
+	.print			= stacktrace_trigger_print,
+	.init			= event_trigger_init,
+	.free			= event_trigger_free,
 };
 
 static __init int register_trigger_stacktrace_cmd(void)
@@ -1696,22 +1679,6 @@ void event_enable_trigger_free(struct ev
 	}
 }
 
-static const struct event_trigger_ops event_enable_trigger_ops = {
-	.trigger		= event_enable_trigger,
-	.count_func		= event_enable_count_func,
-	.print			= event_enable_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_enable_trigger_free,
-};
-
-static const struct event_trigger_ops event_disable_trigger_ops = {
-	.trigger		= event_enable_trigger,
-	.count_func		= event_enable_count_func,
-	.print			= event_enable_trigger_print,
-	.init			= event_trigger_init,
-	.free			= event_enable_trigger_free,
-};
-
 int event_enable_trigger_parse(struct event_command *cmd_ops,
 			       struct trace_event_file *file,
 			       char *glob, char *cmd, char *param_and_filter)
@@ -1843,8 +1810,8 @@ int event_enable_register_trigger(char *
 		}
 	}
 
-	if (data->ops->init) {
-		ret = data->ops->init(data);
+	if (data->cmd_ops->init) {
+		ret = data->cmd_ops->init(data);
 		if (ret < 0)
 			goto out;
 	}
@@ -1885,28 +1852,36 @@ void event_enable_unregister_trigger(cha
 		}
 	}
 
-	if (data && data->ops->free)
-		data->ops->free(data);
+	if (data && data->cmd_ops->free)
+		data->cmd_ops->free(data);
 }
 
 static struct event_command trigger_enable_cmd = {
 	.name			= ENABLE_EVENT_STR,
 	.trigger_type		= ETT_EVENT_ENABLE,
-	.trigger_ops		= &event_enable_trigger_ops,
 	.parse			= event_enable_trigger_parse,
 	.reg			= event_enable_register_trigger,
 	.unreg			= event_enable_unregister_trigger,
 	.set_filter		= set_trigger_filter,
+	.trigger		= event_enable_trigger,
+	.count_func		= event_enable_count_func,
+	.print			= event_enable_trigger_print,
+	.init			= event_trigger_init,
+	.free			= event_enable_trigger_free,
 };
 
 static struct event_command trigger_disable_cmd = {
 	.name			= DISABLE_EVENT_STR,
 	.trigger_type		= ETT_EVENT_ENABLE,
-	.trigger_ops		= &event_disable_trigger_ops,
 	.parse			= event_enable_trigger_parse,
 	.reg			= event_enable_register_trigger,
 	.unreg			= event_enable_unregister_trigger,
 	.set_filter		= set_trigger_filter,
+	.trigger		= event_enable_trigger,
+	.count_func		= event_enable_count_func,
+	.print			= event_enable_trigger_print,
+	.init			= event_trigger_init,
+	.free			= event_enable_trigger_free,
 };
 
 static __init void unregister_trigger_enable_disable_cmds(void)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 719/877] tracing: Set the trace clock before registering the histogram trigger
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (717 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 718/877] tracing: Merge struct event_trigger_ops into struct event_command Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 720/877] virtio-mmio: Remove virtqueue list from mmio device Greg Kroah-Hartman
                   ` (165 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Steven Rostedt,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>

[ Upstream commit 6ede78d0563a2a3ae3e46f9c07cedb5d79645429 ]

hist_register_trigger() puts the trigger on the global named_triggers
list in cmd_ops->init(), and only then sets the trace clock:

	if (data->cmd_ops->init) {
		ret = data->cmd_ops->init(data);
		if (ret < 0)
			goto out;
	}

	if (hist_data->enable_timestamps) {
		ret = tracing_set_clock(file->tr, hist_data->attrs->clock);
		if (ret) {
			hist_err(tr, HIST_ERR_SET_CLOCK_FAIL, errpos(clock));
			goto out;
		}

The clock string is not checked anywhere before that call, so a named
trigger using common_timestamp with an unknown clock fails after it has
already become findable. event_hist_trigger_parse() then frees it
without taking it off the list, and the next lookup by name reads the
freed object:

 ~# cd /sys/kernel/tracing/events/sched/sched_switch
 ~# echo 'hist:name=foo:keys=common_pid:ts=common_timestamp:clock=bogus' > trigger
 bash: echo: write error: Invalid argument
 ~# echo 'hist:name=foo:keys=common_pid' > trigger

  BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0
  Read of size 8 at addr ffff88800915d760 by task init/1
   find_named_trigger+0xac/0xc0
   hist_register_trigger+0xc1/0x900
   event_hist_trigger_parse+0x3146/0x6af0
   event_trigger_write+0xce/0x160
  Freed by task 63:
   kfree+0x154/0x420
   trigger_kthread_fn+0xfd/0x160

Set the clock before the trigger is registered, so that nothing which
can fail runs after it is published, the way commit 6f86bdeab633
("tracing: Fix bad hist from corrupting named_triggers list") moved the
registration below the rest of the setup.

tracing_set_filter_buffering() is reference counted, so the init failure
path has to drop the reference that the clock block now takes first.

Cc: stable@vger.kernel.org
Fixes: a4072fe85ba3 ("tracing: Add a clock attribute for hist triggers")
Link: https://patch.msgid.link/20260907091415.554535-1-donggeunyoo.kernel@gmail.com
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/trace_events_hist.c |   15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -6566,12 +6566,6 @@ static int hist_register_trigger(char *g
 		data->cmd_ops = cmd_ops;
 	}
 
-	if (data->cmd_ops->init) {
-		ret = data->cmd_ops->init(data);
-		if (ret < 0)
-			goto out;
-	}
-
 	if (hist_data->enable_timestamps) {
 		char *clock = hist_data->attrs->clock;
 
@@ -6584,6 +6578,15 @@ static int hist_register_trigger(char *g
 		tracing_set_filter_buffering(file->tr, true);
 	}
 
+	if (data->cmd_ops->init) {
+		ret = data->cmd_ops->init(data);
+		if (ret < 0) {
+			if (hist_data->enable_timestamps)
+				tracing_set_filter_buffering(file->tr, false);
+			goto out;
+		}
+	}
+
 	if (named_data) {
 		remove_hist_vars(hist_data);
 		destroy_hist_data(hist_data);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 720/877] virtio-mmio: Remove virtqueue list from mmio device
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (718 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 719/877] tracing: Set the trace clock before registering the histogram trigger Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 721/877] virtio_mmio: disable IRQ wake before free_irq Greg Kroah-Hartman
                   ` (164 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Viresh Kumar, Michael S. Tsirkin,
	Jason Wang, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Viresh Kumar <viresh.kumar@linaro.org>

[ Upstream commit 564a69ad90d15c782176e1a8c9e1c95661e1aed0 ]

The MMIO transport implementation creates a list of virtqueues for a
virtio device, while the same is already available in the struct
virtio_device.

Don't create a duplicate list, and use the other one instead.

While at it, fix the virtio_device_for_each_vq() macro to accept an
argument like "&vm_dev->vdev" (which currently fails to build).

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Message-Id: <3e56c6f74002987e22f364d883cbad177cd9ad9c.1747827066.git.viresh.kumar@linaro.org>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Stable-dep-of: d14d693adb05 ("virtio_mmio: disable IRQ wake before free_irq")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/virtio/virtio_mmio.c |   52 ++-----------------------------------------
 include/linux/virtio.h       |    2 -
 2 files changed, 4 insertions(+), 50 deletions(-)

--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -65,7 +65,6 @@
 #include <linux/platform_device.h>
 #include <linux/pm.h>
 #include <linux/slab.h>
-#include <linux/spinlock.h>
 #include <linux/virtio.h>
 #include <linux/virtio_config.h>
 #include <uapi/linux/virtio_mmio.h>
@@ -88,22 +87,8 @@ struct virtio_mmio_device {
 
 	void __iomem *base;
 	unsigned long version;
-
-	/* a list of queues so we can dispatch IRQs */
-	spinlock_t lock;
-	struct list_head virtqueues;
-};
-
-struct virtio_mmio_vq_info {
-	/* the actual virtqueue */
-	struct virtqueue *vq;
-
-	/* the list node for the virtqueues list */
-	struct list_head node;
 };
 
-
-
 /* Configuration interface */
 
 static u64 vm_get_features(struct virtio_device *vdev)
@@ -300,9 +285,8 @@ static bool vm_notify_with_data(struct v
 static irqreturn_t vm_interrupt(int irq, void *opaque)
 {
 	struct virtio_mmio_device *vm_dev = opaque;
-	struct virtio_mmio_vq_info *info;
+	struct virtqueue *vq;
 	unsigned long status;
-	unsigned long flags;
 	irqreturn_t ret = IRQ_NONE;
 
 	/* Read and acknowledge interrupts */
@@ -315,10 +299,8 @@ static irqreturn_t vm_interrupt(int irq,
 	}
 
 	if (likely(status & VIRTIO_MMIO_INT_VRING)) {
-		spin_lock_irqsave(&vm_dev->lock, flags);
-		list_for_each_entry(info, &vm_dev->virtqueues, node)
-			ret |= vring_interrupt(irq, info->vq);
-		spin_unlock_irqrestore(&vm_dev->lock, flags);
+		virtio_device_for_each_vq(&vm_dev->vdev, vq)
+			ret |= vring_interrupt(irq, vq);
 	}
 
 	return ret;
@@ -329,14 +311,8 @@ static irqreturn_t vm_interrupt(int irq,
 static void vm_del_vq(struct virtqueue *vq)
 {
 	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev);
-	struct virtio_mmio_vq_info *info = vq->priv;
-	unsigned long flags;
 	unsigned int index = vq->index;
 
-	spin_lock_irqsave(&vm_dev->lock, flags);
-	list_del(&info->node);
-	spin_unlock_irqrestore(&vm_dev->lock, flags);
-
 	/* Select and deactivate the queue */
 	writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
 	if (vm_dev->version == 1) {
@@ -347,8 +323,6 @@ static void vm_del_vq(struct virtqueue *
 	}
 
 	vring_del_virtqueue(vq);
-
-	kfree(info);
 }
 
 static void vm_del_vqs(struct virtio_device *vdev)
@@ -375,9 +349,7 @@ static struct virtqueue *vm_setup_vq(str
 {
 	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
 	bool (*notify)(struct virtqueue *vq);
-	struct virtio_mmio_vq_info *info;
 	struct virtqueue *vq;
-	unsigned long flags;
 	unsigned int num;
 	int err;
 
@@ -399,13 +371,6 @@ static struct virtqueue *vm_setup_vq(str
 		goto error_available;
 	}
 
-	/* Allocate and fill out our active queue description */
-	info = kmalloc(sizeof(*info), GFP_KERNEL);
-	if (!info) {
-		err = -ENOMEM;
-		goto error_kmalloc;
-	}
-
 	num = readl(vm_dev->base + VIRTIO_MMIO_QUEUE_NUM_MAX);
 	if (num == 0) {
 		err = -ENOENT;
@@ -463,13 +428,6 @@ static struct virtqueue *vm_setup_vq(str
 		writel(1, vm_dev->base + VIRTIO_MMIO_QUEUE_READY);
 	}
 
-	vq->priv = info;
-	info->vq = vq;
-
-	spin_lock_irqsave(&vm_dev->lock, flags);
-	list_add(&info->node, &vm_dev->virtqueues);
-	spin_unlock_irqrestore(&vm_dev->lock, flags);
-
 	return vq;
 
 error_bad_pfn:
@@ -481,8 +439,6 @@ error_new_virtqueue:
 		writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_READY);
 		WARN_ON(readl(vm_dev->base + VIRTIO_MMIO_QUEUE_READY));
 	}
-	kfree(info);
-error_kmalloc:
 error_available:
 	return ERR_PTR(err);
 }
@@ -627,8 +583,6 @@ static int virtio_mmio_probe(struct plat
 	vm_dev->vdev.dev.release = virtio_mmio_release_dev;
 	vm_dev->vdev.config = &virtio_mmio_config_ops;
 	vm_dev->pdev = pdev;
-	INIT_LIST_HEAD(&vm_dev->virtqueues);
-	spin_lock_init(&vm_dev->lock);
 
 	vm_dev->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(vm_dev->base)) {
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -184,7 +184,7 @@ void virtio_reset_device(struct virtio_d
 size_t virtio_max_dma_size(const struct virtio_device *vdev);
 
 #define virtio_device_for_each_vq(vdev, vq) \
-	list_for_each_entry(vq, &vdev->vqs, list)
+	list_for_each_entry(vq, &(vdev)->vqs, list)
 
 /**
  * struct virtio_driver - operations for a virtio I/O driver



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 721/877] virtio_mmio: disable IRQ wake before free_irq
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (719 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 720/877] virtio-mmio: Remove virtqueue list from mmio device Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 722/877] tools/bootconfig: Cleanup bootconfig footer size calculations Greg Kroah-Hartman
                   ` (163 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Xiong Weimin, Michael S. Tsirkin,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Xiong Weimin <xiongweimin@kylinos.cn>

[ Upstream commit d14d693adb055e98ca705822ba6daebc18602d9a ]

When the DT node has "wakeup-source", vm_find_vqs() calls
enable_irq_wake() on the shared IRQ, but vm_del_vqs() freed that IRQ
without a matching disable_irq_wake(). That leaves a wake reference
behind and can warn on later free_irq()/request_irq() cycles.

Record whether enable_irq_wake() succeeded, and disable it in
vm_del_vqs() before free_irq().

Fixes: 02213273f72a ("virtio_mmio: add support to set IRQ of a virtio device as wakeup source")
Cc: stable@vger.kernel.org
Signed-off-by: Xiong Weimin <xiongweimin@kylinos.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260805032937.1606737-1-xiongweimin@kylinos.cn>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/virtio/virtio_mmio.c |   16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -87,6 +87,9 @@ struct virtio_mmio_device {
 
 	void __iomem *base;
 	unsigned long version;
+
+	/* True if enable_irq_wake() succeeded for the shared IRQ. */
+	bool wake_irq_enabled;
 };
 
 /* Configuration interface */
@@ -329,11 +332,17 @@ static void vm_del_vqs(struct virtio_dev
 {
 	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
 	struct virtqueue *vq, *n;
+	int irq = platform_get_irq(vm_dev->pdev, 0);
 
 	list_for_each_entry_safe(vq, n, &vdev->vqs, list)
 		vm_del_vq(vq);
 
-	free_irq(platform_get_irq(vm_dev->pdev, 0), vm_dev);
+	if (vm_dev->wake_irq_enabled) {
+		disable_irq_wake(irq);
+		vm_dev->wake_irq_enabled = false;
+	}
+
+	free_irq(irq, vm_dev);
 }
 
 static void vm_synchronize_cbs(struct virtio_device *vdev)
@@ -460,8 +469,9 @@ static int vm_find_vqs(struct virtio_dev
 	if (err)
 		return err;
 
-	if (of_property_read_bool(vm_dev->pdev->dev.of_node, "wakeup-source"))
-		enable_irq_wake(irq);
+	if (of_property_read_bool(vm_dev->pdev->dev.of_node, "wakeup-source") &&
+	    !enable_irq_wake(irq))
+		vm_dev->wake_irq_enabled = true;
 
 	for (i = 0; i < nvqs; ++i) {
 		struct virtqueue_info *vqi = &vqs_info[i];



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 722/877] tools/bootconfig: Cleanup bootconfig footer size calculations
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (720 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 721/877] virtio_mmio: disable IRQ wake before free_irq Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 723/877] tools/bootconfig: Fix integer overflow and truncation in size checks Greg Kroah-Hartman
                   ` (162 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Masami Hiramatsu (Google),
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>

[ Upstream commit 26dda57695090e05c1a99c3e8f802f862d1ac474 ]

There are many same pattern of 8 + BOOTCONFIG_MAGIC_LEN for calculating
the size of bootconfig footer. Use BOOTCONFIG_FOOTER_SIZE macro to
clean up those magic numbers.

Link: https://lore.kernel.org/all/175211425693.2591046.16029516706923643510.stgit@mhiramat.tok.corp.google.com/

Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Stable-dep-of: 462d0b066b61 ("tools/bootconfig: Fix integer overflow and truncation in size checks")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 tools/bootconfig/main.c |   19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

--- a/tools/bootconfig/main.c
+++ b/tools/bootconfig/main.c
@@ -16,6 +16,10 @@
 
 #define pr_err(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
 
+/* Bootconfig footer is [size][csum][BOOTCONFIG_MAGIC]. */
+#define BOOTCONFIG_FOOTER_SIZE	\
+	(sizeof(uint32_t) * 2 + BOOTCONFIG_MAGIC_LEN)
+
 static int xbc_show_value(struct xbc_node *node, bool semicolon)
 {
 	const char *val, *eol;
@@ -188,7 +192,7 @@ static int load_xbc_from_initrd(int fd,
 	if (ret < 0)
 		return -errno;
 
-	if (stat.st_size < 8 + BOOTCONFIG_MAGIC_LEN)
+	if (stat.st_size < BOOTCONFIG_FOOTER_SIZE)
 		return 0;
 
 	if (lseek(fd, -BOOTCONFIG_MAGIC_LEN, SEEK_END) < 0)
@@ -201,7 +205,7 @@ static int load_xbc_from_initrd(int fd,
 	if (memcmp(magic, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN) != 0)
 		return 0;
 
-	if (lseek(fd, -(8 + BOOTCONFIG_MAGIC_LEN), SEEK_END) < 0)
+	if (lseek(fd, -BOOTCONFIG_FOOTER_SIZE, SEEK_END) < 0)
 		return pr_errno("Failed to lseek for size", -errno);
 
 	if (read(fd, &size, sizeof(uint32_t)) < 0)
@@ -213,12 +217,12 @@ static int load_xbc_from_initrd(int fd,
 	csum = le32toh(csum);
 
 	/* Wrong size error  */
-	if (stat.st_size < size + 8 + BOOTCONFIG_MAGIC_LEN) {
+	if (stat.st_size < size + BOOTCONFIG_FOOTER_SIZE) {
 		pr_err("bootconfig size is too big\n");
 		return -E2BIG;
 	}
 
-	if (lseek(fd, stat.st_size - (size + 8 + BOOTCONFIG_MAGIC_LEN),
+	if (lseek(fd, stat.st_size - (size + BOOTCONFIG_FOOTER_SIZE),
 		  SEEK_SET) < 0)
 		return pr_errno("Failed to lseek", -errno);
 
@@ -349,7 +353,7 @@ static int delete_xbc(const char *path)
 		ret = fstat(fd, &stat);
 		if (!ret)
 			ret = ftruncate(fd, stat.st_size
-					- size - 8 - BOOTCONFIG_MAGIC_LEN);
+					- size - BOOTCONFIG_FOOTER_SIZE);
 		if (ret)
 			ret = -errno;
 	} /* Ignore if there is no boot config in initrd */
@@ -379,8 +383,7 @@ static int apply_xbc(const char *path, c
 	csum = xbc_calc_checksum(buf, size);
 
 	/* Backup the bootconfig data */
-	data = calloc(size + BOOTCONFIG_ALIGN +
-		      sizeof(uint32_t) + sizeof(uint32_t) + BOOTCONFIG_MAGIC_LEN, 1);
+	data = calloc(size + BOOTCONFIG_ALIGN + BOOTCONFIG_FOOTER_SIZE, 1);
 	if (!data)
 		return -ENOMEM;
 	memcpy(data, buf, size);
@@ -428,7 +431,7 @@ static int apply_xbc(const char *path, c
 	}
 
 	/* To align up the total size to BOOTCONFIG_ALIGN, get padding size */
-	total_size = stat.st_size + size + sizeof(uint32_t) * 2 + BOOTCONFIG_MAGIC_LEN;
+	total_size = stat.st_size + size + BOOTCONFIG_FOOTER_SIZE;
 	pad = ((total_size + BOOTCONFIG_ALIGN - 1) & (~BOOTCONFIG_ALIGN_MASK)) - total_size;
 	size += pad;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 723/877] tools/bootconfig: Fix integer overflow and truncation in size checks
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (721 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 722/877] tools/bootconfig: Cleanup bootconfig footer size calculations Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 724/877] tracing: Take trace_array reference when opening a tracer options file Greg Kroah-Hartman
                   ` (161 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Masami Hiramatsu (Google),
	Sang-Heon Jeon, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>

[ Upstream commit 462d0b066b613103f579793031429db2ca23abc0 ]

Sashiko reported that on 32-bit systems, if an attacker crafts size in
the bootconfig footer such that adding BOOTCONFIG_FOOTER_SIZE wraps around
(for instance, if size is 0xFFFFFFFF), the size check in
load_xbc_from_initrd() can be bypassed:

    if (stat.st_size < size + BOOTCONFIG_FOOTER_SIZE) {
        pr_err("bootconfig size is too big\n");
        return -E2BIG;
    }

Furthermore, on 64-bit systems with an initrd > 4.29 GB, comparing a
corrupted 32-bit size (e.g. 0xFFFFFFFF) against
stat.st_size - BOOTCONFIG_FOOTER_SIZE can also bypass the check if
size is not bounded. Similarly, load_xbc_file() passes 64-bit stat.st_size
directly into the 32-bit int size parameter of load_xbc_fd(), truncating
large standalone files (>= 2GB).

In both cases, passing 0xFFFFFFFF to load_xbc_fd() truncates to -1,
resulting in malloc(0), an integer overflow in read(), and an
out-of-bounds null-byte write.

Fix this by:
1. Rejecting size > XBC_DATA_MAX or
   size > stat.st_size - BOOTCONFIG_FOOTER_SIZE in load_xbc_from_initrd().
2. Rejecting stat.st_size > XBC_DATA_MAX in load_xbc_file() before passing
   it to load_xbc_fd().
3. Checking size < 0 || size > XBC_DATA_MAX defensively in load_xbc_fd().

Link: https://lore.kernel.org/all/178905332413.213925.3179977110281463499.stgit@devnote2/

Fixes: 950313ebf79c ("tools: bootconfig: Add bootconfig command")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260909161113.16C691F00A3A@smtp.kernel.org/
Closes: https://lore.kernel.org/all/20260910010137.EE0431F000FF@smtp.kernel.org/
Assisted-by: Antigravity:gemini-3.8-flash
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Sang-Heon Jeon <ekffu200098@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 tools/bootconfig/main.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

--- a/tools/bootconfig/main.c
+++ b/tools/bootconfig/main.c
@@ -139,6 +139,9 @@ static int load_xbc_fd(int fd, char **bu
 {
 	int ret;
 
+	if (size < 0 || size > XBC_DATA_MAX)
+		return -EINVAL;
+
 	*buf = malloc(size + 1);
 	if (!*buf)
 		return -ENOMEM;
@@ -167,6 +170,13 @@ static int load_xbc_file(const char *pat
 		return ret;
 	}
 
+	if (stat.st_size > XBC_DATA_MAX) {
+		pr_err("%s size is too big\n", path);
+		ret = -E2BIG;
+		close(fd);
+		return ret;
+	}
+
 	ret = load_xbc_fd(fd, buf, stat.st_size);
 
 	close(fd);
@@ -217,7 +227,8 @@ static int load_xbc_from_initrd(int fd,
 	csum = le32toh(csum);
 
 	/* Wrong size error  */
-	if (stat.st_size < size + BOOTCONFIG_FOOTER_SIZE) {
+	if (size > XBC_DATA_MAX ||
+	    size > stat.st_size - BOOTCONFIG_FOOTER_SIZE) {
 		pr_err("bootconfig size is too big\n");
 		return -E2BIG;
 	}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 724/877] tracing: Take trace_array reference when opening a tracer options file
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (722 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 723/877] tools/bootconfig: Fix integer overflow and truncation in size checks Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 725/877] tracing: Take the reference before publishing the named histogram trigger Greg Kroah-Hartman
                   ` (160 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, sashiko-bot, Steven Rostedt,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Steven Rostedt <rostedt@goodmis.org>

[ Upstream commit ed0aff60f83a9bdc2f6556376ac79c96b3ce7e80 ]

When a tracer option file is opened, it is passed a descriptor that points
to an element on the trace_array's topts array. This element has
information to find the trace array and other information. It uses this
element to take a reference of the trace_array so that the trace_array
does not get removed while this file is opened.

Unfortunately, there's a race condition where the element itself could be
freed by the removal of the instance the trace_array represents causing a
use-after-free as this element that is used to find the trace_array to
increment its reference counter is also freed when the instance is
removed.

To solve this, add a trace_array_tracer_options_get() helper function that
will take the address of the element that is passed to the open function
by the inode->i_private pointer and search all the trace_arrays under a
lock to find the one that the element's address is in the range of the
trace_arrays topts array elements. When a match happens, that trace_array's
reference would be increased.

Note, there's a race where if an admin was deleting and creating trace
instances at the same time and the memory of the old trace_array's array
matched the memory of the new trace_array that it could in theory open the
option from the wrong trace array. But we do not care because it would be
stupid to perform that kind of action. As long as the only thing that can
happen is that the option from the wrong trace array is used and doesn't
crash the kernel it will only make the user confused. But if they are
doing something stupid like this, they are already confused, so no harm
done.

Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260910221209.62dad8d3@robin
Fixes: 7e2cfbd2d3c86 ("tracing: Have option files inc the trace array ref count")
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/linux-trace-kernel/20260902121918.5a9e9d1b@gandalf.local.home/
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
[ replaced missing __trace_array_get() with tr->ref++ and return 0 under trace_types_lock. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/trace.c |   48 +++++++++++++++++++++++++++++++++++++++++++++++-
 kernel/trace/trace.h |    1 +
 2 files changed, 48 insertions(+), 1 deletion(-)

--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -8737,12 +8737,57 @@ trace_options_write(struct file *filp, c
 	return cnt;
 }
 
+static bool tr_option_match(struct trace_array *tr, void *topt)
+{
+	for (int i = 0; i < tr->nr_topts; i++) {
+		struct trace_options *tr_topts = &tr->topts[i];
+
+		if (topt >= (void *)&tr_topts->topts[0] &&
+		    topt < (void *)&tr_topts->topts[tr_topts->nr_topts])
+			return true;
+	}
+	return false;
+}
+
+/*
+ * The topt is the address of a trace_array->topts[] element that holds the
+ * the tracer options descriptor. But since the trace_array reference has not
+ * been taken yet, it cannot be dereferenced as it could have been freed by
+ * a rmdir of the instance the trace_array represents.
+ *
+ * Search the list of trace_arrays and compare the topt to the address of
+ * the entire trace_array topts array for each trace_array in the list.
+ * If one is matched, then take the reference and return it. If not, the
+ * trace_array no longer exits.
+ */
+static int trace_array_tracer_options_get(void *topt)
+{
+	struct trace_array *tr;
+	int ret;
+
+	ret = security_locked_down(LOCKDOWN_TRACEFS);
+	if (ret)
+		return ret;
+
+	if (tracing_disabled)
+		return -ENODEV;
+
+	guard(mutex)(&trace_types_lock);
+	list_for_each_entry(tr, &ftrace_trace_arrays, list) {
+		if (tr_option_match(tr, topt)) {
+			tr->ref++;
+			return 0;
+		}
+	}
+	return -ENODEV;
+}
+
 static int tracing_open_options(struct inode *inode, struct file *filp)
 {
 	struct trace_option_dentry *topt = inode->i_private;
 	int ret;
 
-	ret = tracing_check_open_get_tr(topt->tr);
+	ret = trace_array_tracer_options_get(topt);
 	if (ret)
 		return ret;
 
@@ -9026,6 +9071,7 @@ create_trace_option_files(struct trace_a
 	tr->topts = tr_topts;
 	tr->topts[tr->nr_topts].tracer = tracer;
 	tr->topts[tr->nr_topts].topts = topts;
+	tr->topts[tr->nr_topts].nr_topts = cnt;
 	tr->nr_topts++;
 
 	for (cnt = 0; opts[cnt].name; cnt++) {
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -223,6 +223,7 @@ struct array_buffer {
 struct trace_options {
 	struct tracer			*tracer;
 	struct trace_option_dentry	*topts;
+	int				nr_topts;
 };
 
 struct trace_pid_list *trace_pid_list_alloc(void);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 725/877] tracing: Take the reference before publishing the named histogram trigger
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (723 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 724/877] tracing: Take trace_array reference when opening a tracer options file Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 726/877] tracing: Undo the registration when enabling the histogram trigger fails Greg Kroah-Hartman
                   ` (159 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko AI, Donggeun Yoo,
	Tom Zanussi, Steven Rostedt, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>

[ Upstream commit 0fe23b8eaba0d3372c66b7b31204408da0715edc ]

event_hist_trigger_named_init() puts the trigger on the global
named_triggers list and only then takes the reference on the trigger it
shares its histogram with:

	data->ref++;

	save_named_trigger(data->named_data->name, data);

	ret = event_hist_trigger_init(data->named_data);
	if (ret < 0) {
		kfree(data->cmd_ops);
		data->cmd_ops = &trigger_hist_cmd;
	}

	return ret;

event_hist_trigger_init() fails when alloc_hist_pad() cannot allocate, and
nothing takes the trigger back off the list on the way out.
event_hist_trigger_parse() frees it, and the next lookup by name reads the
freed object:

 BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0
 Read of size 8 at addr ffff888009346860 by task init/1
  find_named_trigger+0xac/0xc0
  hist_register_trigger+0xc1/0xa00
  event_hist_trigger_parse+0x3146/0x6af0
  event_trigger_write+0xce/0x160
 Freed by task 67:
  kfree+0x154/0x420
  trigger_kthread_fn+0xfd/0x160

Do the reference first and publish once it has succeeded, so that nothing
which can fail runs after the trigger becomes findable.

Cc: stable@vger.kernel.org
Fixes: 7ab0fc61ce73 ("tracing: Move histogram trigger variables from stack to per CPU structure")
Reported-by: Sashiko AI <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-trace-kernel/20260907092944.3950E1F00A3D@smtp.kernel.org/
Link: https://patch.msgid.link/20260907124420.607097-2-donggeunyoo.kernel@gmail.com
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Acked-by: Tom Zanussi <zanussi@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/trace_events_hist.c |   11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -6327,17 +6327,18 @@ static int event_hist_trigger_named_init
 {
 	int ret;
 
-	data->ref++;
-
-	save_named_trigger(data->named_data->name, data);
-
 	ret = event_hist_trigger_init(data->named_data);
 	if (ret < 0) {
 		kfree(data->cmd_ops);
 		data->cmd_ops = &trigger_hist_cmd;
+		return ret;
 	}
 
-	return ret;
+	data->ref++;
+
+	save_named_trigger(data->named_data->name, data);
+
+	return 0;
 }
 
 static void event_hist_trigger_named_free(struct event_trigger_data *data)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 726/877] tracing: Undo the registration when enabling the histogram trigger fails
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (724 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 725/877] tracing: Take the reference before publishing the named histogram trigger Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 727/877] EDAC/altera: Use ECC manager compatible to select A10/S10 IRQ layout Greg Kroah-Hartman
                   ` (158 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko AI, Donggeun Yoo,
	Steven Rostedt, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>

[ Upstream commit 92383cef66791a0c63a2f27755cadbdb2fbf270b ]

Commit 6f86bdeab633 ("tracing: Fix bad hist from corrupting named_triggers
list") described how a trigger that is registered but not on file->triggers
ends up freed while still on the global named_triggers list, and moved the
registration down so that hist_trigger_enable() follows it immediately. One
path still gets there. hist_trigger_enable() adds the trigger and takes it
straight back out when the event cannot be enabled:

	list_add_tail_rcu(&data->list, &file->triggers);

	update_cond_flag(file);

	if (trace_event_trigger_enable_disable(file, 1) < 0) {
		list_del_rcu(&data->list);
		update_cond_flag(file);
		ret--;
	}

so the list walk in hist_unregister_trigger() matches nothing, test stays
NULL, and the ->free() that would call del_named_trigger() is skipped.
out_unreg falls through to out_free, which frees the trigger anyway:

 BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0
 Read of size 8 at addr ffff8880091d3160 by task init/1
  find_named_trigger+0xac/0xc0
  hist_register_trigger+0xc1/0xa00
  event_hist_trigger_parse+0x3146/0x6af0
  event_trigger_write+0xce/0x160
 Freed by task 69:
  kfree+0x154/0x420
  trigger_kthread_fn+0xfd/0x160

Leave the trigger where hist_unregister_trigger() can find it and let that
undo the registration, which is the only code that knows all of what
cmd_ops->init() took: the named list entry, the hist_pad reference, the
reference on the trigger a named histogram is shared with, and the copied
cmd_ops. It also pairs the failed trace_event_trigger_enable_disable(),
whose sm_ref and buffered event reference are otherwise left behind.

Since ->free() releases trigger_data and, for a trigger that does not share
its histogram, hist_data with it, out_unreg can no longer fall through to
out_free. For a trigger that does share, hist_register_trigger() has
already destroyed the caller's hist_data, so the fall-through was reading
freed memory there as well.

Move the enable_timestamps check in hist_unregister_trigger() above the
->free() call for the same reason: hist_data does not outlive it once the
trigger being removed is the one that owns it.

Cc: stable@vger.kernel.org
Fixes: 067fe038e70f ("tracing: Add variable reference handling to hist triggers")
Reported-by: Sashiko AI <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-trace-kernel/20260907092944.3950E1F00A3D@smtp.kernel.org/
Link: https://patch.msgid.link/20260907124420.607097-3-donggeunyoo.kernel@gmail.com
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/trace_events_hist.c |   17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -6605,11 +6605,12 @@ static int hist_trigger_enable(struct ev
 
 	update_cond_flag(file);
 
-	if (trace_event_trigger_enable_disable(file, 1) < 0) {
-		list_del_rcu(&data->list);
-		update_cond_flag(file);
+	/*
+	 * On failure the caller undoes the registration, and
+	 * hist_unregister_trigger() can only find the trigger here.
+	 */
+	if (trace_event_trigger_enable_disable(file, 1) < 0)
 		ret--;
-	}
 
 	return ret;
 }
@@ -6687,13 +6688,13 @@ static void hist_unregister_trigger(char
 		}
 	}
 
-	if (test && test->cmd_ops->free)
-		test->cmd_ops->free(test);
-
 	if (hist_data->enable_timestamps) {
 		if (!hist_data->remove || test)
 			tracing_set_filter_buffering(file->tr, false);
 	}
+
+	if (test && test->cmd_ops->free)
+		test->cmd_ops->free(test);
 }
 
 static bool hist_file_check_refs(struct trace_event_file *file)
@@ -6898,6 +6899,8 @@ static int event_hist_trigger_parse(stru
 	return ret;
  out_unreg:
 	event_trigger_unregister(cmd_ops, file, glob+1, trigger_data);
+	/* The unregister frees trigger_data, skip out_free */
+	goto out;
  out_free:
 	event_trigger_reset_filter(cmd_ops, trigger_data);
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 727/877] EDAC/altera: Use ECC manager compatible to select A10/S10 IRQ layout
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (725 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 726/877] tracing: Undo the registration when enabling the histogram trigger fails Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 728/877] EDAC/altera: Use parent device for devres in altr_portb_setup() Greg Kroah-Hartman
                   ` (157 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Rounak Das, Borislav Petkov (AMD),
	Dinh Nguyen, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Rounak Das <rounakdas2025@gmail.com>

[ Upstream commit d4486fc3098e176cb4a29fee037216484761f9ca ]

The SDMMC ECC IRQ layout selection uses CONFIG_64BIT to distinguish between
Arria10 and Stratix10 paths.

Detect the SoC once at probe via the device match table (.data) store it in
struct altr_arria10_edac, and use it instead of CONFIG_64BIT.

This keeps the decision correct for every ECC child device (OCRAM, SD/MMC,
etc.) and avoids any runtime compatible lookup.

Signed-off-by: Rounak Das <rounakdas2025@gmail.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Acked-by: Dinh Nguyen <dinguyen@kernel.org>
Link: https://patch.msgid.link/20260708091135.94114-2-rounakdas2025@gmail.com
Stable-dep-of: 9868f5c077df ("EDAC/altera: Use parent device for devres in altr_portb_setup()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/edac/altera_edac.c |  107 ++++++++++++++++++++++-----------------------
 drivers/edac/altera_edac.h |    1 
 2 files changed, 55 insertions(+), 53 deletions(-)

--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -1507,6 +1507,7 @@ static int altr_portb_setup(struct altr_
 	int edac_idx, rc;
 	struct device_node *np;
 	const struct edac_device_prv_data *prv = &a10_sdmmceccb_data;
+	bool is_s10 = device->edac->is_s10;
 
 	rc = altr_check_ecc_deps(device);
 	if (rc)
@@ -1548,15 +1549,14 @@ static int altr_portb_setup(struct altr_
 
 	/*
 	 * Update the PortB IRQs - A10 has 4, S10 has 2, Index accordingly
-	 *
-	 * FIXME: Instead of ifdefs with different architectures the driver
-	 *        should properly use compatibles.
 	 */
-#ifdef CONFIG_64BIT
-	altdev->sb_irq = irq_of_parse_and_map(np, 1);
-#else
-	altdev->sb_irq = irq_of_parse_and_map(np, 2);
-#endif
+
+	/* Using compatibles to determine the IRQ Index */
+	if (is_s10)
+		altdev->sb_irq = irq_of_parse_and_map(np, 1);
+	else
+		altdev->sb_irq = irq_of_parse_and_map(np, 2);
+
 	if (!altdev->sb_irq) {
 		edac_printk(KERN_ERR, EDAC_DEVICE, "Error PortB SBIRQ alloc\n");
 		rc = -ENODEV;
@@ -1570,29 +1570,28 @@ static int altr_portb_setup(struct altr_
 		goto err_release_group_1;
 	}
 
-#ifdef CONFIG_64BIT
-	/* Use IRQ to determine SError origin instead of assigning IRQ */
-	rc = of_property_read_u32_index(np, "interrupts", 1, &altdev->db_irq);
-	if (rc) {
-		edac_printk(KERN_ERR, EDAC_DEVICE,
-			    "Error PortB DBIRQ alloc\n");
-		goto err_release_group_1;
-	}
-#else
-	altdev->db_irq = irq_of_parse_and_map(np, 3);
-	if (!altdev->db_irq) {
-		edac_printk(KERN_ERR, EDAC_DEVICE, "Error PortB DBIRQ alloc\n");
-		rc = -ENODEV;
-		goto err_release_group_1;
-	}
-	rc = devm_request_irq(&altdev->ddev, altdev->db_irq,
-			      prv->ecc_irq_handler, IRQF_TRIGGER_HIGH,
-			      ecc_name, altdev);
-	if (rc) {
-		edac_printk(KERN_ERR, EDAC_DEVICE, "PortB DBERR IRQ error\n");
-		goto err_release_group_1;
+	if (is_s10) {
+		/* Use IRQ to determine SError origin instead of assigning IRQ */
+		rc = of_property_read_u32_index(np, "interrupts", 1, &altdev->db_irq);
+		if (rc) {
+			edac_printk(KERN_ERR, EDAC_DEVICE, "Error PortB DBIRQ alloc\n");
+			goto err_release_group_1;
+		}
+	} else {
+		altdev->db_irq = irq_of_parse_and_map(np, 3);
+		if (!altdev->db_irq) {
+			edac_printk(KERN_ERR, EDAC_DEVICE, "Error PortB DBIRQ alloc\n");
+			rc = -ENODEV;
+			goto err_release_group_1;
+		}
+		rc = devm_request_irq(&altdev->ddev, altdev->db_irq,
+				      prv->ecc_irq_handler, IRQF_TRIGGER_HIGH,
+				      ecc_name, altdev);
+		if (rc) {
+			edac_printk(KERN_ERR, EDAC_DEVICE, "PortB DBERR IRQ error\n");
+			goto err_release_group_1;
+		}
 	}
-#endif
 
 	rc = edac_device_add_device(dci);
 	if (rc) {
@@ -1974,29 +1973,29 @@ static int altr_edac_a10_device_add(stru
 		goto err_release_group1;
 	}
 
-#ifdef CONFIG_64BIT
-	/* Use IRQ to determine SError origin instead of assigning IRQ */
-	rc = of_property_read_u32_index(np, "interrupts", 0, &altdev->db_irq);
-	if (rc) {
-		edac_printk(KERN_ERR, EDAC_DEVICE,
-			    "Unable to parse DB IRQ index\n");
-		goto err_release_group1;
-	}
-#else
-	altdev->db_irq = irq_of_parse_and_map(np, 1);
-	if (!altdev->db_irq) {
-		edac_printk(KERN_ERR, EDAC_DEVICE, "Error allocating DBIRQ\n");
-		rc = -ENODEV;
-		goto err_release_group1;
-	}
-	rc = devm_request_irq(edac->dev, altdev->db_irq, prv->ecc_irq_handler,
-			      IRQF_TRIGGER_HIGH,
-			      ecc_name, altdev);
-	if (rc) {
-		edac_printk(KERN_ERR, EDAC_DEVICE, "No DBERR IRQ resource\n");
-		goto err_release_group1;
+	if (edac->is_s10) {
+		/* Use IRQ to determine SError origin instead of assigning IRQ */
+		rc = of_property_read_u32_index(np, "interrupts", 0, &altdev->db_irq);
+		if (rc) {
+			edac_printk(KERN_ERR, EDAC_DEVICE,
+				    "Unable to parse DB IRQ index\n");
+			goto err_release_group1;
+		}
+	} else {
+		altdev->db_irq = irq_of_parse_and_map(np, 1);
+		if (!altdev->db_irq) {
+			edac_printk(KERN_ERR, EDAC_DEVICE, "Error allocating DBIRQ\n");
+			rc = -ENODEV;
+			goto err_release_group1;
+		}
+		rc = devm_request_irq(edac->dev, altdev->db_irq, prv->ecc_irq_handler,
+				      IRQF_TRIGGER_HIGH,
+				      ecc_name, altdev);
+		if (rc) {
+			edac_printk(KERN_ERR, EDAC_DEVICE, "No DBERR IRQ resource\n");
+			goto err_release_group1;
+		}
 	}
-#endif
 
 	rc = edac_device_add_device(dci);
 	if (rc) {
@@ -2122,6 +2121,8 @@ static int altr_edac_a10_probe(struct pl
 	platform_set_drvdata(pdev, edac);
 	INIT_LIST_HEAD(&edac->a10_ecc_devices);
 
+	edac->is_s10 = !!device_get_match_data(&pdev->dev);
+
 	edac->ecc_mgr_map =
 		altr_sysmgr_regmap_lookup_by_phandle(pdev->dev.of_node,
 						     "altr,sysmgr-syscon");
@@ -2207,7 +2208,7 @@ static int altr_edac_a10_probe(struct pl
 
 static const struct of_device_id altr_edac_a10_of_match[] = {
 	{ .compatible = "altr,socfpga-a10-ecc-manager" },
-	{ .compatible = "altr,socfpga-s10-ecc-manager" },
+	{ .compatible = "altr,socfpga-s10-ecc-manager", .data = (void *)1 },
 	{},
 };
 MODULE_DEVICE_TABLE(of, altr_edac_a10_of_match);
--- a/drivers/edac/altera_edac.h
+++ b/drivers/edac/altera_edac.h
@@ -395,6 +395,7 @@ struct altr_arria10_edac {
 	struct irq_chip		irq_chip;
 	struct list_head	a10_ecc_devices;
 	struct notifier_block	panic_notifier;
+	bool is_s10;
 };
 
 #endif	/* #ifndef _ALTERA_EDAC_H */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 728/877] EDAC/altera: Use parent device for devres in altr_portb_setup()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (726 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 727/877] EDAC/altera: Use ECC manager compatible to select A10/S10 IRQ layout Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 729/877] genetlink: pin family module during policy dump Greg Kroah-Hartman
                   ` (156 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Dinh Nguyen, Borislav Petkov (AMD),
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dinh Nguyen <dinguyen@kernel.org>

[ Upstream commit 9868f5c077dfe0b606331f2e782484f91a5789a5 ]

Anchor the devres group and the devm-managed IRQ requests in altr_portb_setup()
to the actual parent device (device->edac->dev) instead of the embedded struct
device inside the copied per-port altr_edac_device_dev.

This keeps devres_open_group(), devm_request_irq(), devres_remove_group() and
devres_release_group() all referring to the same long-lived device so the
group and the resources allocated inside it are torn down together.

Fixes: 911049845d70 ("EDAC, altera: Add Arria10 SD-MMC EDAC support")
Closes: https://sashiko.dev/#/patchset/20260503212558.2811480-1-dbgh9129%40gmail.com
Assisted-by: LLM
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260617164303.585555-1-dinguyen@kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/edac/altera_edac.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -1534,7 +1534,7 @@ static int altr_portb_setup(struct altr_
 	altdev = dci->pvt_info;
 	*altdev = *device;
 
-	if (!devres_open_group(&altdev->ddev, altr_portb_setup, GFP_KERNEL))
+	if (!devres_open_group(device->edac->dev, altr_portb_setup, GFP_KERNEL))
 		return -ENOMEM;
 
 	/* Update PortB specific values */
@@ -1562,7 +1562,7 @@ static int altr_portb_setup(struct altr_
 		rc = -ENODEV;
 		goto err_release_group_1;
 	}
-	rc = devm_request_irq(&altdev->ddev, altdev->sb_irq,
+	rc = devm_request_irq(device->edac->dev, altdev->sb_irq,
 			      prv->ecc_irq_handler, IRQF_TRIGGER_HIGH,
 			      ecc_name, altdev);
 	if (rc) {
@@ -1584,7 +1584,7 @@ static int altr_portb_setup(struct altr_
 			rc = -ENODEV;
 			goto err_release_group_1;
 		}
-		rc = devm_request_irq(&altdev->ddev, altdev->db_irq,
+		rc = devm_request_irq(device->edac->dev, altdev->db_irq,
 				      prv->ecc_irq_handler, IRQF_TRIGGER_HIGH,
 				      ecc_name, altdev);
 		if (rc) {
@@ -1604,13 +1604,13 @@ static int altr_portb_setup(struct altr_
 
 	list_add(&altdev->next, &altdev->edac->a10_ecc_devices);
 
-	devres_remove_group(&altdev->ddev, altr_portb_setup);
+	devres_remove_group(device->edac->dev, altr_portb_setup);
 
 	return 0;
 
 err_release_group_1:
 	edac_device_free_ctl_info(dci);
-	devres_release_group(&altdev->ddev, altr_portb_setup);
+	devres_release_group(device->edac->dev, altr_portb_setup);
 	edac_printk(KERN_ERR, EDAC_DEVICE,
 		    "%s:Error setting up EDAC device: %d\n", ecc_name, rc);
 	return rc;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 729/877] genetlink: pin family module during policy dump
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (727 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 728/877] EDAC/altera: Use parent device for devres in altr_portb_setup() Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 730/877] drm/bridge: tc358768: Enforce input bus flags via atomic_check Greg Kroah-Hartman
                   ` (155 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, XingWang Xiang, Jakub Kicinski,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: XingWang Xiang <v3rdant.xiang@gmail.com>

[ Upstream commit 6a1094c34d176827b2b173e163dcc964a13af93f ]

The generic netlink controller's policy dump keeps pointers to the target
family's operation and policy tables in its callback state.  A dump may be
split across multiple skbs and remain pending after the initial request.

Netlink pins the module which owns the dump callback, but in this case
that is the controller's owner rather than the target family's owner.  The
target family can consequently be unregistered and its module unloaded
while a policy dump is pending.  Advancing the dump then dereferences
policy memory from the unloaded module.

Take a reference to the target family's module when the dump starts.
Drop it from the error and done paths.  This matches the lifetime for which
the dump context retains the family and policy pointers.

Fixes: d07dcf9aadd6 ("netlink: add infrastructure to expose policies to userspace")
Cc: stable@vger.kernel.org
Signed-off-by: XingWang Xiang <v3rdant.xiang@gmail.com>
Link: https://patch.msgid.link/20260902084317.4092542-1-v3rdant.xiang@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ Adjusted context to retain kmalloc(sizeof(*ctx->op_iter), GFP_KERNEL) instead of kmalloc_obj(*ctx->op_iter). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/netlink/genetlink.c |   21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1514,6 +1514,7 @@ struct ctrl_dump_policy_ctx {
 	struct netlink_policy_dump_state *state;
 	const struct genl_family *rt;
 	struct genl_op_iter *op_iter;
+	struct module *owner;
 	u32 op;
 	u16 fam_id;
 	u8 dump_map:1,
@@ -1556,6 +1557,9 @@ static int ctrl_dumppolicy_start(struct
 		return -ENOENT;
 
 	ctx->rt = rt;
+	ctx->owner = rt->module;
+	if (!try_module_get(ctx->owner))
+		return -ENOENT;
 
 	if (tb[CTRL_ATTR_OP]) {
 		struct genl_split_ops doit, dump;
@@ -1566,7 +1570,7 @@ static int ctrl_dumppolicy_start(struct
 		err = genl_get_cmd_both(ctx->op, rt, &doit, &dump);
 		if (err) {
 			NL_SET_BAD_ATTR(cb->extack, tb[CTRL_ATTR_OP]);
-			return err;
+			goto err_put_owner;
 		}
 
 		if (doit.policy) {
@@ -1584,16 +1588,20 @@ static int ctrl_dumppolicy_start(struct
 				goto err_free_state;
 		}
 
-		if (!ctx->state)
-			return -ENODATA;
+		if (!ctx->state) {
+			err = -ENODATA;
+			goto err_put_owner;
+		}
 
 		ctx->dump_map = 1;
 		return 0;
 	}
 
 	ctx->op_iter = kmalloc(sizeof(*ctx->op_iter), GFP_KERNEL);
-	if (!ctx->op_iter)
-		return -ENOMEM;
+	if (!ctx->op_iter) {
+		err = -ENOMEM;
+		goto err_put_owner;
+	}
 
 	genl_op_iter_init(rt, ctx->op_iter);
 	ctx->dump_map = genl_op_iter_next(ctx->op_iter);
@@ -1625,6 +1633,8 @@ err_free_state:
 	netlink_policy_dump_free(ctx->state);
 err_free_op_iter:
 	kfree(ctx->op_iter);
+err_put_owner:
+	module_put(ctx->owner);
 	return err;
 }
 
@@ -1763,6 +1773,7 @@ static int ctrl_dumppolicy_done(struct n
 
 	kfree(ctx->op_iter);
 	netlink_policy_dump_free(ctx->state);
+	module_put(ctx->owner);
 	return 0;
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 730/877] drm/bridge: tc358768: Enforce input bus flags via atomic_check
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (728 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 729/877] genetlink: pin family module during policy dump Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 731/877] io_uring/rw: end write accounting from ->ki_complete Greg Kroah-Hartman
                   ` (154 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Leonardo Costa, Francesco Dolcini,
	Swamil Jain, Luca Ceresoli, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Leonardo Costa <leonardo.costa@toradex.com>

[ Upstream commit ed761e0693950fcb4f6b0f60387a3961b972adf3 ]

The tc358768 declares static bridge timings requiring pixel data to be
sampled on the positive clock edge.

However, the DRM core default propagation simply copies the output-side
bus flags, coming from the next bridge, connector or panel, to the
input side. If the propagated flags are incompatible with the bridge
ones, the data is wrongly sampled, typically resulting in visual
artifacts on the panel.

Implement the atomic_check hook, replacing the mutually exclusive
mode_fixup, and set the bridge state input bus flags to the ones
required by the tc358768. The sync polarity defaulting previously done
in mode_fixup is carried over into atomic_check unchanged.

Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
Cc: stable@vger.kernel.org
Signed-off-by: Leonardo Costa <leonardo.costa@toradex.com>
Reviewed-by: Francesco Dolcini <francesco.dolcini@toradex.com>
Reviewed-by: Swamil Jain <s-jain1@ti.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Link: https://patch.msgid.link/20260706132440.1594239-1-leoreis.costa@gmail.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
[ Adjusted callback-table context to retain Linux 6.12’s legacy enable/disable callbacks. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/bridge/tc358768.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -1145,10 +1145,13 @@ tc358768_atomic_get_input_bus_fmts(struc
 	return input_fmts;
 }
 
-static bool tc358768_mode_fixup(struct drm_bridge *bridge,
-				const struct drm_display_mode *mode,
-				struct drm_display_mode *adjusted_mode)
+static int tc358768_bridge_atomic_check(struct drm_bridge *bridge,
+					struct drm_bridge_state *bridge_state,
+					struct drm_crtc_state *crtc_state,
+					struct drm_connector_state *conn_state)
 {
+	struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
+
 	/* Default to positive sync */
 
 	if (!(adjusted_mode->flags &
@@ -1159,13 +1162,15 @@ static bool tc358768_mode_fixup(struct d
 	      (DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
 		adjusted_mode->flags |= DRM_MODE_FLAG_PVSYNC;
 
-	return true;
+	bridge_state->input_bus_cfg.flags = bridge->timings->input_bus_flags;
+
+	return 0;
 }
 
 static const struct drm_bridge_funcs tc358768_bridge_funcs = {
 	.attach = tc358768_bridge_attach,
 	.mode_valid = tc358768_bridge_mode_valid,
-	.mode_fixup = tc358768_mode_fixup,
+	.atomic_check = tc358768_bridge_atomic_check,
 	.pre_enable = tc358768_bridge_pre_enable,
 	.enable = tc358768_bridge_enable,
 	.disable = tc358768_bridge_disable,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 731/877] io_uring/rw: end write accounting from ->ki_complete
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (729 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 730/877] drm/bridge: tc358768: Enforce input bus flags via atomic_check Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 732/877] io_uring/net: dont overconsume buffers when using MSG_TRUNC Greg Kroah-Hartman
                   ` (153 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+2eb3d983669d3e49d4fa,
	Jens Axboe, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jens Axboe <axboe@kernel.dk>

[ Upstream commit 796aa0547557e63338657ed1c487906f9fac4c73 ]

Commit b000145e9907 moved both the fsnotify calls and the write
accounting out of the kiocb completion handler and into the
io_req_rw_complete() task_work. However, only the fsnotify part actually
needed to move as it may sleep. Ending the write accounting is just a
percpu_up_read() on the superblock writers sem.

Deferring it is a problem, because it makes dropping SB_FREEZE_WRITE
protection depend on the ring owner getting to running task_work. But
the task may be blocked in freeze_super(), causing it to never get to
that:

  task                             io-wq worker
  --------------------------------------------------------------
  io_write()
    io_kiocb_start_write()         (takes sb_writers, hidden from
                                    lockdep by __sb_writers_release)
    write_iter() -> -EIOCBQUEUED
  ioctl(FS_IOC_SHUTDOWN)
    bdev_freeze()
      freeze_super()
        percpu_down_write()        <- waits for the reader above
                                   io_write()
                                     kiocb_start_write()
                                       percpu_down_read()  <- queued
                                                              behind the
                                                              writer
  <bio completes>
    io_complete_rw()
      queues io_req_rw_complete()  <- never runs, task is in D state

End the write from io_complete_rw() instead, and leave only the fsnotify
calls in task_work.

Reported-by: syzbot+2eb3d983669d3e49d4fa@syzkaller.appspotmail.com
Cc: stable@vger.kernel.org
Fixes: b000145e9907 ("io_uring/rw: defer fsnotify calls to task context")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
[ adapted accounting cleanup to the older completion helper’s retry early return. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 io_uring/rw.c |   32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

--- a/io_uring/rw.c
+++ b/io_uring/rw.c
@@ -460,31 +460,23 @@ static void io_req_end_write(struct io_k
 	}
 }
 
-/*
- * Trigger the notifications after having done some IO, and finish the write
- * accounting, if any.
- */
-static void io_req_io_end(struct io_kiocb *req)
+/* Trigger the notifications after having done some IO. */
+static void io_req_io_notify(struct io_kiocb *req)
 {
 	struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
 
-	if (rw->kiocb.ki_flags & IOCB_WRITE) {
-		io_req_end_write(req);
+	if (rw->kiocb.ki_flags & IOCB_WRITE)
 		fsnotify_modify(req->file);
-	} else {
+	else
 		fsnotify_access(req->file);
-	}
 }
 
 static bool __io_complete_rw_common(struct io_kiocb *req, long res)
 {
 	if (unlikely(res != req->cqe.res)) {
 		if ((res == -EOPNOTSUPP || res == -EAGAIN) && io_rw_should_reissue(req)) {
-			/*
-			 * Reissue will start accounting again, finish the
-			 * current cycle.
-			 */
-			io_req_io_end(req);
+			/* Reissue bypasses task_work, so notify here. */
+			io_req_io_notify(req);
 			req->flags |= REQ_F_REISSUE | REQ_F_BL_NO_RECYCLE;
 			return true;
 		}
@@ -519,7 +511,7 @@ void io_req_rw_complete(struct io_kiocb
 		io_req_set_res(req, io_fixup_rw_res(req, res), 0);
 	}
 
-	io_req_io_end(req);
+	io_req_io_notify(req);
 
 	if (req->flags & (REQ_F_BUFFER_SELECTED|REQ_F_BUFFER_RING))
 		req->cqe.flags |= io_put_kbuf(req, req->cqe.res, NULL);
@@ -533,6 +525,10 @@ static void io_complete_rw(struct kiocb
 	struct io_rw *rw = container_of(kiocb, struct io_rw, kiocb);
 	struct io_kiocb *req = cmd_to_io_kiocb(rw);
 
+	/* ring owner may block in freeze_super() before task_work runs */
+	if (kiocb->ki_flags & IOCB_WRITE)
+		io_req_end_write(req);
+
 	if (!kiocb->dio_complete || !(kiocb->ki_flags & IOCB_DIO_CALLER_COMP)) {
 		if (__io_complete_rw_common(req, res))
 			return;
@@ -604,11 +600,13 @@ static int kiocb_done(struct io_kiocb *r
 		if (!__io_complete_rw_common(req, ret)) {
 			u32 cflags = 0;
 
+			if (rw->kiocb.ki_flags & IOCB_WRITE)
+				io_req_end_write(req);
 			/*
-			 * Safe to call io_end from here as we're inline
+			 * Safe to notify from here as we're inline
 			 * from the submission path.
 			 */
-			io_req_io_end(req);
+			io_req_io_notify(req);
 			if (sel)
 				cflags = io_put_kbuf(req, ret, sel->buf_list);
 			io_req_set_res(req, final_ret, cflags);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 732/877] io_uring/net: dont overconsume buffers when using MSG_TRUNC
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (730 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 731/877] io_uring/rw: end write accounting from ->ki_complete Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 733/877] bootconfig: Fix integer overflow in initrd size check Greg Kroah-Hartman
                   ` (152 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Gabriel Krisman Bertazi, Jens Axboe,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Gabriel Krisman Bertazi <krisman@suse.de>

[ Upstream commit 6028b543884f8735e057ec9eea4908cd61cab230 ]

When a recv/recvmsg is issued with MSG_TRUNC and the incoming packet is
larger than the provided buffer, the net layer returns the full length
of the packet rather than the number of bytes actually copied into the
buffer.  As a result, io_uring advances more of the provided buffer ring
than was actually filled.  Use the actual filled region size to consume
the buffer, but still return the full size to preserve MSG_TRUNC
semantics.

Take care with multishot, because that seems to already truncate the
consumption based on the available payload size.

This was reported in https://github.com/axboe/liburing/issues/1619.

Fixes: ae98dbf43d75 ("io_uring/kbuf: add support for incremental buffer consumption")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260728191454.1850326-1-krisman@suse.de
Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de>
Link: https://patch.msgid.link/20260902230041.1320658-3-krisman@suse.de
[axboe: fold in size_t unsigned fix]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
[ replaced `len = ret` with `len = iov_iter_count(&kmsg->msg.msg_iter)` because the older buffer-selection helper returns zero on success. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 io_uring/net.c |   41 +++++++++++++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 8 deletions(-)

--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -858,7 +858,7 @@ int io_recvmsg_prep(struct io_kiocb *req
 static inline bool io_recv_finish(struct io_kiocb *req,
 				  struct io_async_msghdr *kmsg,
 				  struct io_br_sel *sel, bool mshot_finished,
-				  unsigned issue_flags)
+				  unsigned issue_flags, int consumed)
 {
 	struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
 	unsigned int cflags = 0;
@@ -869,7 +869,7 @@ static inline bool io_recv_finish(struct
 	if (sr->flags & IORING_RECVSEND_BUNDLE) {
 		size_t this_ret = sel->val - sr->done_io;
 
-		cflags |= io_put_kbufs(req, this_ret, sel->buf_list, io_bundle_nbufs(kmsg, this_ret));
+		cflags |= io_put_kbufs(req, consumed, sel->buf_list, io_bundle_nbufs(kmsg, consumed));
 		if (sr->retry_flags & IO_SR_MSG_RETRY)
 			cflags = req->cqe.flags | (cflags & CQE_F_MASK);
 		/* bundle with no more immediate buffers, we're done */
@@ -888,7 +888,7 @@ static inline bool io_recv_finish(struct
 			return false;
 		}
 	} else {
-		cflags |= io_put_kbuf(req, sel->val, sel->buf_list);
+		cflags |= io_put_kbuf(req, consumed, sel->buf_list);
 	}
 
 	/*
@@ -1021,6 +1021,8 @@ int io_recvmsg(struct io_kiocb *req, uns
 	int ret, min_ret = 0;
 	bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
 	bool mshot_finished = true;
+	int consumed = 0;
+	size_t len;
 
 	sock = sock_from_file(req->file);
 	if (unlikely(!sock))
@@ -1036,9 +1038,8 @@ int io_recvmsg(struct io_kiocb *req, uns
 
 retry_multishot:
 	sel.buf_list = NULL;
+	len = sr->len;
 	if (io_do_buffer_select(req)) {
-		size_t len = sr->len;
-
 		sel = io_buffer_select(req, &len, issue_flags);
 		if (!sel.addr)
 			return -ENOBUFS;
@@ -1059,6 +1060,7 @@ retry_multishot:
 	if (req->flags & REQ_F_APOLL_MULTISHOT) {
 		ret = io_recvmsg_multishot(sock, sr, kmsg, flags,
 					   &mshot_finished);
+		consumed = ret;
 	} else {
 		/* disable partial retry for recvmsg with cmsg attached */
 		if (flags & MSG_WAITALL && !kmsg->msg.msg_controllen)
@@ -1066,6 +1068,15 @@ retry_multishot:
 
 		ret = __sys_recvmsg_sock(sock, &kmsg->msg, sr->umsg,
 					 kmsg->uaddr, flags);
+		/*
+		 * With MSG_TRUNC, the net layer will return the full size of
+		 * the packet, even if we only filled part of it in the buffers.
+		 * Adjust the returned size to consume only the real part of the
+		 * buffer.
+		 */
+		consumed = ret;
+		if (ret > 0)
+			consumed = min_t(size_t, ret, len);
 	}
 
 	if (ret < min_ret) {
@@ -1094,7 +1105,7 @@ retry_multishot:
 		io_kbuf_recycle(req, sel.buf_list, issue_flags);
 
 	sel.val = ret;
-	if (!io_recv_finish(req, kmsg, &sel, mshot_finished, issue_flags))
+	if (!io_recv_finish(req, kmsg, &sel, mshot_finished, issue_flags, consumed))
 		goto retry_multishot;
 
 	return sel.val;
@@ -1177,9 +1188,10 @@ int io_recv(struct io_kiocb *req, unsign
 	struct io_br_sel sel;
 	struct socket *sock;
 	unsigned flags;
-	int ret, min_ret = 0;
+	int ret, min_ret = 0, consumed = 0;
 	bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
 	bool mshot_finished;
+	size_t len = 0;
 
 	if (!(req->flags & REQ_F_POLLED) &&
 	    (sr->flags & IORING_RECVSEND_POLL_FIRST))
@@ -1195,6 +1207,7 @@ int io_recv(struct io_kiocb *req, unsign
 
 retry_multishot:
 	sel.buf_list = NULL;
+	len = sr->len;
 	if (io_do_buffer_select(req)) {
 		sel.val = sr->len;
 		ret = io_recv_buf_select(req, kmsg, &sel, issue_flags);
@@ -1202,6 +1215,7 @@ retry_multishot:
 			kmsg->msg.msg_inq = -1;
 			goto out_free;
 		}
+		len = iov_iter_count(&kmsg->msg.msg_iter);
 		sr->buf = NULL;
 	}
 
@@ -1234,6 +1248,17 @@ out_free:
 	}
 
 	mshot_finished = ret <= 0;
+
+	/*
+	 * With MSG_TRUNC, the net layer will return the full size of
+	 * the packet, even if we only filled part of it in the buffers.
+	 * Adjust the returned size to consume only the real part of the
+	 * buffer.
+	 */
+	consumed = ret;
+	if (ret > 0)
+		consumed = min_t(size_t, ret, len);
+
 	if (ret > 0)
 		ret += sr->done_io;
 	else if (sr->done_io)
@@ -1242,7 +1267,7 @@ out_free:
 		io_kbuf_recycle(req, sel.buf_list, issue_flags);
 
 	sel.val = ret;
-	if (!io_recv_finish(req, kmsg, &sel, mshot_finished, issue_flags))
+	if (!io_recv_finish(req, kmsg, &sel, mshot_finished, issue_flags, consumed))
 		goto retry_multishot;
 
 	return sel.val;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 733/877] bootconfig: Fix integer overflow in initrd size check
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (731 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 732/877] io_uring/net: dont overconsume buffers when using MSG_TRUNC Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 734/877] net: bridge: use option bits for CFM/MRP frame handlers Greg Kroah-Hartman
                   ` (151 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Masami Hiramatsu (Google),
	Sang-Heon Jeon, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>

[ Upstream commit 7812d6dab0698001e50e8c2f901e17da3eb6f429 ]

Sashiko reported that in get_boot_config_from_initrd(), a crafted initrd
with a huge bootconfig size (such as 0xFFFFFFFF) can cause the pointer
arithmetic:

    data = ((void *)hdr) - size;

to wrap around on 32-bit systems (or when pointer subtraction overflows).
Because data wraps around, the subsequent bounds check:

    if ((unsigned long)data < initrd_start)

evaluates to false, bypassing the check. The kernel then calls
xbc_calc_checksum(data, size), which attempts to read 4GB of memory,
hitting unmapped pages and triggering a fatal kernel page fault during
early boot. Furthermore, on 64-bit systems with an initrd > 4.29 GB, an
unbounded 32-bit size can similarly bypass the initrd_start check.

Fix this by:
1. Ensuring the initrd is at least large enough to contain the bootconfig
   footer and verifying hdr is within the initrd bounds.
2. Checking that size does not exceed XBC_DATA_MAX and does not exceed
   the available space between initrd_start and hdr before performing
   pointer subtraction.

Link: https://lore.kernel.org/all/178905333479.213925.1358412668943562406.stgit@devnote2/

Fixes: de462e5f1071 ("bootconfig: Fix to remove bootconfig data from initrd while boot")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260910010137.EE0431F000FF@smtp.kernel.org/
Assisted-by: Antigravity:gemini-3.8-flash
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Sang-Heon Jeon <ekffu200098@gmail.com>
[ Adjusted context to preserve the existing u32 *hdr pointer and le32_to_cpu() header reads. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 init/main.c |   25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

--- a/init/main.c
+++ b/init/main.c
@@ -270,7 +270,8 @@ static void * __init get_boot_config_fro
 	u32 *hdr;
 	int i;
 
-	if (!initrd_end)
+	if (!initrd_end || initrd_end < initrd_start ||
+	    initrd_end - initrd_start < BOOTCONFIG_MAGIC_LEN + 8)
 		return NULL;
 
 	data = (char *)initrd_end - BOOTCONFIG_MAGIC_LEN;
@@ -287,16 +288,26 @@ static void * __init get_boot_config_fro
 
 found:
 	hdr = (u32 *)(data - 8);
+	if ((unsigned long)hdr < initrd_start)
+		return NULL;
+
 	size = le32_to_cpu(hdr[0]);
 	csum = le32_to_cpu(hdr[1]);
 
-	data = ((void *)hdr) - size;
-	if ((unsigned long)data < initrd_start) {
-		pr_err("bootconfig size %d is greater than initrd size %ld\n",
+	if (size > XBC_DATA_MAX) {
+		pr_err("bootconfig size %u is greater than max size %d\n",
+			size, XBC_DATA_MAX);
+		return NULL;
+	}
+
+	if (size > ((unsigned long)hdr - initrd_start)) {
+		pr_err("bootconfig size %u is greater than initrd size %lu\n",
 			size, initrd_end - initrd_start);
 		return NULL;
 	}
 
+	data = ((void *)hdr) - size;
+
 	if (xbc_calc_checksum(data, size) != csum) {
 		pr_err("bootconfig checksum failed\n");
 		return NULL;
@@ -399,12 +410,6 @@ static void __init setup_boot_config(voi
 		return;
 	}
 
-	if (size >= XBC_DATA_MAX) {
-		pr_err("bootconfig size %ld greater than max size %d\n",
-			(long)size, XBC_DATA_MAX);
-		return;
-	}
-
 	ret = xbc_init(data, size, &msg, &pos);
 	if (ret < 0) {
 		if (pos < 0)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 734/877] net: bridge: use option bits for CFM/MRP frame handlers
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (732 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 733/877] bootconfig: Fix integer overflow in initrd size check Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 735/877] drm/xe: Flush LSC untyped L1 dataport cache after rcs/ccs batches Greg Kroah-Hartman
                   ` (150 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Nikolay Aleksandrov, Yilin Zhu,
	Zhiling Zou, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Zhiling Zou <zhilinz@nebusec.ai>

[ Upstream commit 7a49e6b16f36b8e085521699adbca3e321b6dd0c ]

CFM and MRP register a global br_frame_type whose hlist_node is linked
into the per-bridge frame_type_list when the first MEP/MRP instance is
created. Enabling the protocol on multiple bridges therefore inserts the
same node into multiple lists. Unregistering it on one bridge then
corrupts list state belonging to another.

These handlers can only be installed once per bridge, and they are
uncommon. Track their per-bridge enable state with net_bridge option
bits, which already live on the Rx hot cache line, and dispatch the
matching handler directly from the receive path. Check both bits
together first as an unlikely case.

Remove the generic frame_type_list and br_frame_type helpers, which
have had no other users since CFM and MRP were added. That shrinks
struct net_bridge by 8 bytes and drops the list walk from the fast
path. When neither protocol is compiled in, BR_CFM_MRP_OPTS is 0 and
the compiler prunes the branch.

Fixes: 90c628dd47ff ("net: bridge: extend the process of special frames")
Fixes: dc32cbb3dbd7 ("bridge: cfm: Kernel space implementation of CFM. CCM frame RX added.")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Suggested-by: Nikolay Aleksandrov <razor@blackwall.org>
Co-developed-by: Yilin Zhu <zylzyl2333@gmail.com>
Signed-off-by: Yilin Zhu <zylzyl2333@gmail.com>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/0345b9d5aa60ba416f6738ff1b87140f0a749cb8.1788417901.git.zhilinz@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ Adjusted bridge option enum context because BROPT_MDB_OFFLOAD_FAIL_NOTIFICATION and BROPT_FDB_LOCAL_VLAN_0 are absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/bridge/br_cfm.c     |   11 +++--------
 net/bridge/br_device.c  |    1 -
 net/bridge/br_input.c   |   35 ++++++++++++++---------------------
 net/bridge/br_mrp.c     |   13 +++----------
 net/bridge/br_private.h |   26 +++++++++++++++-----------
 5 files changed, 35 insertions(+), 51 deletions(-)

--- a/net/bridge/br_cfm.c
+++ b/net/bridge/br_cfm.c
@@ -367,7 +367,7 @@ static u32 ccm_tlv_extract(struct sk_buf
 }
 
 /* note: already called with rcu_read_lock */
-static int br_cfm_frame_rx(struct net_bridge_port *port, struct sk_buff *skb)
+int br_cfm_frame_rx(struct net_bridge_port *port, struct sk_buff *skb)
 {
 	u32 mdlevel, interval, size, index, max;
 	const struct br_cfm_common_hdr *hdr;
@@ -489,11 +489,6 @@ static int br_cfm_frame_rx(struct net_br
 	return 1;
 }
 
-static struct br_frame_type cfm_frame_type __read_mostly = {
-	.type = cpu_to_be16(ETH_P_CFM),
-	.frame_handler = br_cfm_frame_rx,
-};
-
 int br_cfm_mep_create(struct net_bridge *br,
 		      const u32 instance,
 		      struct br_cfm_mep_create *const create,
@@ -559,7 +554,7 @@ int br_cfm_mep_create(struct net_bridge
 	INIT_DELAYED_WORK(&mep->ccm_tx_dwork, ccm_tx_work_expired);
 
 	if (hlist_empty(&br->mep_list))
-		br_add_frame(br, &cfm_frame_type);
+		br_opt_toggle(br, BROPT_CFM_ENABLED, true);
 
 	hlist_add_tail_rcu(&mep->head, &br->mep_list);
 
@@ -588,7 +583,7 @@ static void mep_delete_implementation(st
 	kfree_rcu(mep, rcu);
 
 	if (hlist_empty(&br->mep_list))
-		br_del_frame(br, &cfm_frame_type);
+		br_opt_toggle(br, BROPT_CFM_ENABLED, false);
 }
 
 int br_cfm_mep_delete(struct net_bridge *br,
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -501,7 +501,6 @@ void br_dev_setup(struct net_device *dev
 	spin_lock_init(&br->lock);
 	INIT_LIST_HEAD(&br->port_list);
 	INIT_HLIST_HEAD(&br->fdb_list);
-	INIT_HLIST_HEAD(&br->frame_type_list);
 #if IS_ENABLED(CONFIG_BRIDGE_MRP)
 	INIT_HLIST_HEAD(&br->mrp_list);
 #endif
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -303,17 +303,25 @@ frame_finish:
 	return RX_HANDLER_CONSUMED;
 }
 
+#define BR_CFM_MRP_OPTS \
+	((IS_ENABLED(CONFIG_BRIDGE_CFM) ? BIT(BROPT_CFM_ENABLED) : 0UL) | \
+	 (IS_ENABLED(CONFIG_BRIDGE_MRP) ? BIT(BROPT_MRP_ENABLED) : 0UL))
+
 /* Return 0 if the frame was not processed otherwise 1
  * note: already called with rcu_read_lock
  */
 static int br_process_frame_type(struct net_bridge_port *p,
 				 struct sk_buff *skb)
 {
-	struct br_frame_type *tmp;
+	struct net_bridge *br = p->br;
 
-	hlist_for_each_entry_rcu(tmp, &p->br->frame_type_list, list)
-		if (unlikely(tmp->type == skb->protocol))
-			return tmp->frame_handler(p, skb);
+	if (skb->protocol == htons(ETH_P_CFM) &&
+	    br_opt_get(br, BROPT_CFM_ENABLED))
+		return br_cfm_frame_rx(p, skb);
+
+	if (skb->protocol == htons(ETH_P_MRP) &&
+	    br_opt_get(br, BROPT_MRP_ENABLED))
+		return br_mrp_process(p, skb);
 
 	return 0;
 }
@@ -407,7 +415,8 @@ static rx_handler_result_t br_handle_fra
 		}
 	}
 
-	if (unlikely(br_process_frame_type(p, skb)))
+	if (unlikely((READ_ONCE(p->br->options) & BR_CFM_MRP_OPTS) &&
+		     br_process_frame_type(p, skb)))
 		return RX_HANDLER_PASS;
 
 forward:
@@ -448,19 +457,3 @@ rx_handler_func_t *br_get_rx_handler(con
 
 	return br_handle_frame;
 }
-
-void br_add_frame(struct net_bridge *br, struct br_frame_type *ft)
-{
-	hlist_add_head_rcu(&ft->list, &br->frame_type_list);
-}
-
-void br_del_frame(struct net_bridge *br, struct br_frame_type *ft)
-{
-	struct br_frame_type *tmp;
-
-	hlist_for_each_entry(tmp, &br->frame_type_list, list)
-		if (ft == tmp) {
-			hlist_del_rcu(&ft->list);
-			return;
-		}
-}
--- a/net/bridge/br_mrp.c
+++ b/net/bridge/br_mrp.c
@@ -6,13 +6,6 @@
 static const u8 mrp_test_dmac[ETH_ALEN] = { 0x1, 0x15, 0x4e, 0x0, 0x0, 0x1 };
 static const u8 mrp_in_test_dmac[ETH_ALEN] = { 0x1, 0x15, 0x4e, 0x0, 0x0, 0x3 };
 
-static int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb);
-
-static struct br_frame_type mrp_frame_type __read_mostly = {
-	.type = cpu_to_be16(ETH_P_MRP),
-	.frame_handler = br_mrp_process,
-};
-
 static bool br_mrp_is_ring_port(struct net_bridge_port *p_port,
 				struct net_bridge_port *s_port,
 				struct net_bridge_port *port)
@@ -486,7 +479,7 @@ static void br_mrp_del_impl(struct net_b
 	kfree_rcu(mrp, rcu);
 
 	if (hlist_empty(&br->mrp_list))
-		br_del_frame(br, &mrp_frame_type);
+		br_opt_toggle(br, BROPT_MRP_ENABLED, false);
 }
 
 /* Adds a new MRP instance.
@@ -536,7 +529,7 @@ int br_mrp_add(struct net_bridge *br, st
 	rcu_assign_pointer(mrp->s_port, p);
 
 	if (hlist_empty(&br->mrp_list))
-		br_add_frame(br, &mrp_frame_type);
+		br_opt_toggle(br, BROPT_MRP_ENABLED, true);
 
 	INIT_DELAYED_WORK(&mrp->test_work, br_mrp_test_work_expired);
 	INIT_DELAYED_WORK(&mrp->in_test_work, br_mrp_in_test_work_expired);
@@ -1241,7 +1234,7 @@ no_forward:
  * normal forwarding.
  * note: already called with rcu_read_lock
  */
-static int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
+int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
 {
 	/* If there is no MRP instance do normal forwarding */
 	if (likely(!(p->flags & BR_MRP_AWARE)))
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -486,12 +486,13 @@ enum net_bridge_opts {
 	BROPT_VLAN_BRIDGE_BINDING,
 	BROPT_MCAST_VLAN_SNOOPING_ENABLED,
 	BROPT_MST_ENABLED,
+	BROPT_CFM_ENABLED,
+	BROPT_MRP_ENABLED,
 };
 
 struct net_bridge {
 	spinlock_t			lock;
 	spinlock_t			hash_lock;
-	struct hlist_head		frame_type_list;
 	struct net_device		*dev;
 	unsigned long			options;
 	/* These fields are accessed on each packet */
@@ -919,16 +920,6 @@ int nbp_backup_change(struct net_bridge_
 int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
 rx_handler_func_t *br_get_rx_handler(const struct net_device *dev);
 
-struct br_frame_type {
-	__be16			type;
-	int			(*frame_handler)(struct net_bridge_port *port,
-						 struct sk_buff *skb);
-	struct hlist_node	list;
-};
-
-void br_add_frame(struct net_bridge *br, struct br_frame_type *ft);
-void br_del_frame(struct net_bridge *br, struct br_frame_type *ft);
-
 static inline bool br_rx_handler_check_rcu(const struct net_device *dev)
 {
 	return rcu_dereference(dev->rx_handler) == br_get_rx_handler(dev);
@@ -2033,6 +2024,7 @@ int br_mrp_parse(struct net_bridge *br,
 bool br_mrp_enabled(struct net_bridge *br);
 void br_mrp_port_del(struct net_bridge *br, struct net_bridge_port *p);
 int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br);
+int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb);
 #else
 static inline int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
 			       struct nlattr *attr, int cmd,
@@ -2056,6 +2048,11 @@ static inline int br_mrp_fill_info(struc
 	return 0;
 }
 
+static inline int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
+{
+	return 0;
+}
+
 #endif
 
 /* br_cfm.c */
@@ -2064,6 +2061,7 @@ int br_cfm_parse(struct net_bridge *br,
 		 struct nlattr *attr, int cmd, struct netlink_ext_ack *extack);
 bool br_cfm_created(struct net_bridge *br);
 void br_cfm_port_del(struct net_bridge *br, struct net_bridge_port *p);
+int br_cfm_frame_rx(struct net_bridge_port *port, struct sk_buff *skb);
 int br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br);
 int br_cfm_status_fill_info(struct sk_buff *skb,
 			    struct net_bridge *br,
@@ -2088,6 +2086,12 @@ static inline void br_cfm_port_del(struc
 {
 }
 
+static inline int br_cfm_frame_rx(struct net_bridge_port *port,
+				  struct sk_buff *skb)
+{
+	return 0;
+}
+
 static inline int br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br)
 {
 	return -EOPNOTSUPP;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 735/877] drm/xe: Flush LSC untyped L1 dataport cache after rcs/ccs batches
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (733 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 734/877] net: bridge: use option bits for CFM/MRP frame handlers Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 736/877] netfilter: cttimeout: detach dataplane timeout policy and repurpose refcount Greg Kroah-Hartman
                   ` (149 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Lionel Landwerlin,
	José Roberto de Souza, intel-xe, Thomas Hellström,
	Matthew Auld, Rodrigo Vivi, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Thomas Hellström <thomas.hellstrom@linux.intel.com>

[ Upstream commit f5fcf7e638b904397ec0f66d3ea6766ef0cfe25b ]

emit_render_cache_flush() sets PIPE_CONTROL0_HDC_PIPELINE_FLUSH to
flush the L2/HDC data cache before fence signalling, but it never
requests a flush of the LSC untyped L1 data cache via the 'Untyped
Data-Port Cache Flush Enable' bit in PIPE_CONTROL DWord0[11].

Per the Bspec, in 3D pipeline mode HDC Pipeline Flush is documented to
also flush/invalidate the untyped L1 cache, but only depending on how
HDC_CHICKEN0[13:11] is programmed. Starting with MTL, this coupling
between HDC Pipeline Flush and the untyped L1 cache flush no longer
holds in practice, regardless of how HDC_CHICKEN0 is programmed, so
relying on it is not safe on newer platforms such as BMG. Mesa's Vulkan
driver (anv) has been assuming the kernel flushes both caches between
submissions, and hit user-visible corruption in apps such as Llama.cpp
because of this gap; it now works around it by flushing both caches
again from userspace at the end of every command buffer.

Correctness between submissions on the same queue is userspace's
responsibility and belongs in Mesa, not the kernel. However, for
security we must ensure stale data can't leak through the untyped L1
dataport cache once memory is reclaimed or evicted, which requires the
KMD to flush it before releasing memory for reuse.

Prior to MTL, HDC_CHICKEN0 could be programmed (as already done for
DG2 via Wa_22010960976/Wa_14013347512) to reliably keep HDC Pipeline
Flush coupled to the untyped L1 cache flush, so those platforms are
unaffected. Mesa's own anv driver found that on MTL the HW
disconnected the two independently of how HDC_CHICKEN0 is programmed,
and could not bring the old behavior back even by writing the register
by hand; see Mesa commit 7c2ff46a4fc3 ("anv: don't prevent L1 untyped
cache flush in 3D mode"). The kernel can't reliably request the flush
from the CS on MTL either, so restrict the new PIPE_CONTROL bit to
GRAPHICS_VERx100 >= 2000 (Xe2 and later), where it can be relied on.

Explicitly set PIPE_CONTROL0_UNTYPED_DATAPORT_CACHE_FLUSH together
with PIPE_CONTROL0_HDC_PIPELINE_FLUSH in emit_render_cache_flush() on
Xe2 and later, so the L1 data cache is known clean before memory is
released for reuse, without depending on undocumented
platform-specific HDC_CHICKEN0 behavior.

Bspec: 56551
Link: https://gitlab.freedesktop.org/mesa/mesa/-/commit/7c2ff46a4fc3e537573ac9503057e0cd29b6fff3
Fixes: 9f8f93bee3ef ("drm/xe: Emit a render cache flush after each rcs/ccs batch")
Reported-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/8909
Cc: José Roberto de Souza <jose.souza@intel.com>
Cc: intel-xe@lists.freedesktop.org
Cc: <stable@vger.kernel.org> # v6.8+
Assisted-by: GitHub_Copilot:claude-sonnet-5
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patch.msgid.link/20260903114552.48634-1-thomas.hellstrom@linux.intel.com
(cherry picked from commit 434514b6fe731e873808297c268fc52cdf4a1ce6)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
[ replaced the inline HDC flush argument to emit_pipe_control() with a new flags0 variable. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/xe/instructions/xe_gpu_commands.h |    1 +
 drivers/gpu/drm/xe/xe_ring_ops.c                  |   16 ++++++++++++++--
 2 files changed, 15 insertions(+), 2 deletions(-)

--- a/drivers/gpu/drm/xe/instructions/xe_gpu_commands.h
+++ b/drivers/gpu/drm/xe/instructions/xe_gpu_commands.h
@@ -41,6 +41,7 @@
 
 #define GFX_OP_PIPE_CONTROL(len)	((0x3<<29)|(0x3<<27)|(0x2<<24)|((len)-2))
 
+#define	  PIPE_CONTROL0_UNTYPED_DATAPORT_CACHE_FLUSH	BIT(11)	/* gen12 */
 #define	  PIPE_CONTROL0_HDC_PIPELINE_FLUSH		BIT(9)	/* gen12 */
 
 #define   PIPE_CONTROL_COMMAND_CACHE_INVALIDATE		(1<<29)
--- a/drivers/gpu/drm/xe/xe_ring_ops.c
+++ b/drivers/gpu/drm/xe/xe_ring_ops.c
@@ -174,9 +174,21 @@ static int emit_store_imm_ppgtt_posted(u
 static int emit_render_cache_flush(struct xe_sched_job *job, u32 *dw, int i)
 {
 	struct xe_gt *gt = job->q->gt;
+	struct xe_device *xe = gt_to_xe(gt);
 	bool lacks_render = !(gt->info.engine_mask & XE_HW_ENGINE_RCS_MASK);
-	u32 flags;
+	u32 flags0, flags;
 
+	flags0 = PIPE_CONTROL0_HDC_PIPELINE_FLUSH;
+	/*
+	 * Prior to MTL, HDC Pipeline Flush reliably also flushes the LSC
+	 * untyped L1 dataport cache, provided HDC_CHICKEN0 is programmed
+	 * correctly. Starting with MTL that coupling no longer holds
+	 * regardless of how HDC_CHICKEN0 is programmed, but explicitly
+	 * requesting the flush via PIPE_CONTROL is itself only reliable
+	 * from Xe2 onward, so only gate it in on Xe2+.
+	 */
+	if (GRAPHICS_VERx100(xe) >= 2000)
+		flags0 |= PIPE_CONTROL0_UNTYPED_DATAPORT_CACHE_FLUSH;
 	flags = (PIPE_CONTROL_CS_STALL |
 		 PIPE_CONTROL_TILE_CACHE_FLUSH |
 		 PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH |
@@ -192,7 +204,7 @@ static int emit_render_cache_flush(struc
 	else if (job->q->class == XE_ENGINE_CLASS_COMPUTE)
 		flags &= ~PIPE_CONTROL_3D_ENGINE_FLAGS;
 
-	return emit_pipe_control(dw, i, PIPE_CONTROL0_HDC_PIPELINE_FLUSH, flags, 0, 0);
+	return emit_pipe_control(dw, i, flags0, flags, 0, 0);
 }
 
 static int emit_pipe_control_to_ring_end(struct xe_hw_engine *hwe, u32 *dw, int i)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 736/877] netfilter: cttimeout: detach dataplane timeout policy and repurpose refcount
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (734 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 735/877] drm/xe: Flush LSC untyped L1 dataport cache after rcs/ccs batches Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 737/877] netfilter: cttimeout: prevent UAF during module unload Greg Kroah-Hartman
                   ` (148 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Pablo Neira Ayuso, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pablo Neira Ayuso <pablo@netfilter.org>

[ Upstream commit 7d6a9cdb8d3a51d9cfe546a09a518ab3d2671549 ]

Add a refcount for struct nf_ct_timeout which is used by ct extension to
set the custom ct timeout policy, this tells us that the ct timeout is
being used by a conntrack entry. When the last conntrack entry drops the
refcount on the ct timeout, the ct timeout is released.

Remove the refcount for control plane which controls if the ruleset
refers to the timeout policy. After this update, it is possible to
remove the ct timeout policy from nfnetlink_cttimeout immediately.
This is for simplicity not to handle two refcounts on a single object.

Remove nf_queue_nf_hook_drop(): a packet sitting in nfqueue will just
hold a reference to the nf_ct_timeout object until packet is reinjected,
since this is part of the ct extension, this will be released by the
time the conntrack is freed.

nf_ct_untimeout() is still called to clean up in a best effort basis:
the ct timeout on existing entries gets removed when the ct timeout goes
away, but as long as the iptables ruleset still refers to the ct timeout
through a template, new conntracks may keep attaching it and extend its
lifetime until the rule is removed.

nf_ct_untimeout() is not called anymore from module removal path, this
is unlikely to find timeouts give module refcount is bumped, and the new
refcount already tracks the ct timeout policy use so it is released when
unused.

Fixes: 50978462300f ("netfilter: add cttimeout infrastructure for fine timeout tuning")
Fixes: 7e0b2b57f01d ("netfilter: nft_ct: add ct timeout support")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Stable-dep-of: fec9b1de0d02 ("netfilter: cttimeout: prevent UAF during module unload")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/net/netfilter/nf_conntrack_timeout.h |   27 ++++++
 net/netfilter/nf_conntrack_core.c            |    6 -
 net/netfilter/nf_conntrack_timeout.c         |   27 +++++-
 net/netfilter/nfnetlink_cttimeout.c          |  112 ++++++++++++---------------
 net/netfilter/nft_ct.c                       |    7 -
 net/netfilter/xt_CT.c                        |    2 
 6 files changed, 107 insertions(+), 74 deletions(-)

--- a/include/net/netfilter/nf_conntrack_timeout.h
+++ b/include/net/netfilter/nf_conntrack_timeout.h
@@ -12,6 +12,7 @@
 #define CTNL_TIMEOUT_NAME_MAX	32
 
 struct nf_ct_timeout {
+	refcount_t		refcnt;
 	__u16			l3num;
 	const struct nf_conntrack_l4proto *l4proto;
 	struct rcu_head		rcu;
@@ -22,6 +23,22 @@ struct nf_conn_timeout {
 	struct nf_ct_timeout __rcu *timeout;
 };
 
+static inline void nf_ct_timeout_put(const struct nf_conn *ct)
+{
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
+	struct nf_conn_timeout *timeout_ext;
+	struct nf_ct_timeout *timeout;
+
+	timeout_ext = nf_ct_ext_find(ct, NF_CT_EXT_TIMEOUT);
+	if (!timeout_ext)
+		return;
+
+	timeout = rcu_dereference(timeout_ext->timeout);
+	if (timeout && refcount_dec_and_test(&timeout->refcnt))
+		kfree_rcu(timeout, rcu);
+#endif
+}
+
 static inline unsigned int *
 nf_ct_timeout_data(const struct nf_conn_timeout *t)
 {
@@ -56,8 +73,14 @@ struct nf_conn_timeout *nf_ct_timeout_ex
 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT
 	struct nf_conn_timeout *timeout_ext;
 
+	if (!timeout)
+		return NULL;
+
 	timeout_ext = nf_ct_ext_add(ct, NF_CT_EXT_TIMEOUT, gfp);
-	if (timeout_ext == NULL)
+	if (!timeout_ext || timeout_ext->timeout)
+		return NULL;
+
+	if (!refcount_inc_not_zero(&timeout->refcnt))
 		return NULL;
 
 	rcu_assign_pointer(timeout_ext->timeout, timeout);
@@ -75,7 +98,7 @@ static inline unsigned int *nf_ct_timeou
 	struct nf_conn_timeout *timeout_ext;
 
 	timeout_ext = nf_ct_timeout_find(ct);
-	if (timeout_ext)
+	if (timeout_ext && rcu_access_pointer(timeout_ext->timeout))
 		timeouts = nf_ct_timeout_data(timeout_ext);
 #endif
 	return timeouts;
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1692,16 +1692,18 @@ void nf_conntrack_free(struct nf_conn *c
 	 */
 	WARN_ON(refcount_read(&ct->ct_general.use) != 0);
 
+	rcu_read_lock();
 	if (ct->status & IPS_SRC_NAT_DONE) {
 		const struct nf_nat_hook *nat_hook;
 
-		rcu_read_lock();
 		nat_hook = rcu_dereference(nf_nat_hook);
 		if (nat_hook)
 			nat_hook->remove_nat_bysrc(ct);
-		rcu_read_unlock();
 	}
 
+	nf_ct_timeout_put(ct);
+	rcu_read_unlock();
+
 	kfree(ct->ext);
 	kmem_cache_free(nf_conntrack_cachep, ct);
 	cnet = nf_ct_pernet(net);
--- a/net/netfilter/nf_conntrack_timeout.c
+++ b/net/netfilter/nf_conntrack_timeout.c
@@ -25,17 +25,32 @@
 const struct nf_ct_timeout_hooks __rcu *nf_ct_timeout_hook __read_mostly;
 EXPORT_SYMBOL_GPL(nf_ct_timeout_hook);
 
+/* nf_ct_iterate_cleanup() holds the conntrack lock. */
 static int untimeout(struct nf_conn *ct, void *timeout)
 {
 	struct nf_conn_timeout *timeout_ext = nf_ct_timeout_find(ct);
 
 	if (timeout_ext) {
-		const struct nf_ct_timeout *t;
+		struct nf_ct_timeout *t;
 
-		t = rcu_access_pointer(timeout_ext->timeout);
+		rcu_read_lock();
+		t = rcu_dereference(timeout_ext->timeout);
+		if (!t) {
+			rcu_read_unlock();
+			return 0;
+		}
 
-		if (!timeout || t == timeout)
+		if (!timeout || t == timeout) {
 			RCU_INIT_POINTER(timeout_ext->timeout, NULL);
+
+			/* No race with nf_conntrack_free() which is called
+			 * only after the conntrack has been removed from
+			 * the hashes.
+			 */
+			if (refcount_dec_and_test(&t->refcnt))
+				kfree_rcu(t, rcu);
+		}
+		rcu_read_unlock();
 	}
 
 	/* We are not intended to delete this conntrack. */
@@ -70,6 +85,8 @@ int nf_ct_set_timeout(struct net *net, s
 	const char *errmsg = NULL;
 	int ret = 0;
 
+	WARN_ON_ONCE(!nf_ct_is_template(ct));
+
 	rcu_read_lock();
 	h = rcu_dereference(nf_ct_timeout_hook);
 	if (!h) {
@@ -127,6 +144,8 @@ void nf_ct_destroy_timeout(struct nf_con
 	struct nf_conn_timeout *timeout_ext;
 	const struct nf_ct_timeout_hooks *h;
 
+	WARN_ON_ONCE(!nf_ct_is_template(ct));
+
 	rcu_read_lock();
 	h = rcu_dereference(nf_ct_timeout_hook);
 
@@ -139,6 +158,8 @@ void nf_ct_destroy_timeout(struct nf_con
 			if (t)
 				h->timeout_put(t);
 			RCU_INIT_POINTER(timeout_ext->timeout, NULL);
+			if (t && refcount_dec_and_test(&t->refcnt))
+				kfree_rcu(t, rcu);
 		}
 	}
 	rcu_read_unlock();
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -37,11 +37,8 @@ struct ctnl_timeout {
 	struct list_head	head;
 	struct list_head	free_head;
 	struct rcu_head		rcu_head;
-	refcount_t		refcnt;
 	char			name[CTNL_TIMEOUT_NAME_MAX];
-
-	/* must be at the end */
-	struct nf_ct_timeout	timeout;
+	struct nf_ct_timeout	*timeout;
 };
 
 struct nfct_timeout_pernet {
@@ -133,12 +130,12 @@ static int cttimeout_new_timeout(struct
 			/* You cannot replace one timeout policy by another of
 			 * different kind, sorry.
 			 */
-			if (matching->timeout.l3num != l3num ||
-			    matching->timeout.l4proto->l4proto != l4num)
+			if (matching->timeout->l3num != l3num ||
+			    matching->timeout->l4proto->l4proto != l4num)
 				return -EINVAL;
 
-			return ctnl_timeout_parse_policy(&matching->timeout.data,
-							 matching->timeout.l4proto,
+			return ctnl_timeout_parse_policy(&matching->timeout->data,
+							 matching->timeout->l4proto,
 							 info->net,
 							 cda[CTA_TIMEOUT_DATA]);
 		}
@@ -154,26 +151,35 @@ static int cttimeout_new_timeout(struct
 		goto err_proto_put;
 	}
 
-	timeout = kzalloc(sizeof(struct ctnl_timeout) +
-			  l4proto->ctnl_timeout.obj_size, GFP_KERNEL);
+	timeout = kzalloc(sizeof(*timeout), GFP_KERNEL);
 	if (timeout == NULL) {
 		ret = -ENOMEM;
 		goto err_proto_put;
 	}
 
-	ret = ctnl_timeout_parse_policy(&timeout->timeout.data, l4proto,
+	timeout->timeout = kzalloc(sizeof(*timeout->timeout) +
+				   l4proto->ctnl_timeout.obj_size, GFP_KERNEL);
+	if (!timeout->timeout) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ret = ctnl_timeout_parse_policy(&timeout->timeout->data, l4proto,
 					info->net, cda[CTA_TIMEOUT_DATA]);
 	if (ret < 0)
-		goto err;
+		goto err_free_timeout_policy;
 
 	strcpy(timeout->name, nla_data(cda[CTA_TIMEOUT_NAME]));
-	timeout->timeout.l3num = l3num;
-	timeout->timeout.l4proto = l4proto;
-	refcount_set(&timeout->refcnt, 1);
+	timeout->timeout->l3num = l3num;
+	timeout->timeout->l4proto = l4proto;
+	refcount_set(&timeout->timeout->refcnt, 1);
 	__module_get(THIS_MODULE);
 	list_add_tail_rcu(&timeout->head, &pernet->nfct_timeout_list);
 
 	return 0;
+
+err_free_timeout_policy:
+	kfree(timeout->timeout);
 err:
 	kfree(timeout);
 err_proto_put:
@@ -186,7 +192,7 @@ ctnl_timeout_fill_info(struct sk_buff *s
 {
 	struct nlmsghdr *nlh;
 	unsigned int flags = portid ? NLM_F_MULTI : 0;
-	const struct nf_conntrack_l4proto *l4proto = timeout->timeout.l4proto;
+	const struct nf_conntrack_l4proto *l4proto = timeout->timeout->l4proto;
 	struct nlattr *nest_parms;
 	int ret;
 
@@ -198,17 +204,17 @@ ctnl_timeout_fill_info(struct sk_buff *s
 
 	if (nla_put_string(skb, CTA_TIMEOUT_NAME, timeout->name) ||
 	    nla_put_be16(skb, CTA_TIMEOUT_L3PROTO,
-			 htons(timeout->timeout.l3num)) ||
+			 htons(timeout->timeout->l3num)) ||
 	    nla_put_u8(skb, CTA_TIMEOUT_L4PROTO, l4proto->l4proto) ||
 	    nla_put_be32(skb, CTA_TIMEOUT_USE,
-			 htonl(refcount_read(&timeout->refcnt))))
+			 htonl(refcount_read(&timeout->timeout->refcnt))))
 		goto nla_put_failure;
 
 	nest_parms = nla_nest_start(skb, CTA_TIMEOUT_DATA);
 	if (!nest_parms)
 		goto nla_put_failure;
 
-	ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, &timeout->timeout.data);
+	ret = l4proto->ctnl_timeout.obj_to_nlattr(skb, &timeout->timeout->data);
 	if (ret < 0)
 		goto nla_put_failure;
 
@@ -308,23 +314,17 @@ static int cttimeout_get_timeout(struct
 	return ret;
 }
 
-/* try to delete object, fail if it is still in use. */
-static int ctnl_timeout_try_del(struct net *net, struct ctnl_timeout *timeout)
+static void ctnl_timeout_del(struct net *net, struct ctnl_timeout *timeout)
 {
-	int ret = 0;
+	/* We are protected by nfnl mutex. */
+	list_del_rcu(&timeout->head);
+	nf_ct_untimeout(net, timeout->timeout);
 
-	/* We want to avoid races with ctnl_timeout_put. So only when the
-	 * current refcnt is 1, we decrease it to 0.
-	 */
-	if (refcount_dec_if_one(&timeout->refcnt)) {
-		/* We are protected by nfnl mutex. */
-		list_del_rcu(&timeout->head);
-		nf_ct_untimeout(net, &timeout->timeout);
-		kfree_rcu(timeout, rcu_head);
-	} else {
-		ret = -EBUSY;
-	}
-	return ret;
+	if (refcount_dec_and_test(&timeout->timeout->refcnt))
+		kfree_rcu(timeout->timeout, rcu);
+
+	kfree_rcu(timeout, rcu_head);
+	module_put(THIS_MODULE);
 }
 
 static int cttimeout_del_timeout(struct sk_buff *skb,
@@ -339,7 +339,7 @@ static int cttimeout_del_timeout(struct
 	if (!cda[CTA_TIMEOUT_NAME]) {
 		list_for_each_entry_safe(cur, tmp, &pernet->nfct_timeout_list,
 					 head)
-			ctnl_timeout_try_del(info->net, cur);
+			ctnl_timeout_del(info->net, cur);
 
 		return 0;
 	}
@@ -349,10 +349,8 @@ static int cttimeout_del_timeout(struct
 		if (strncmp(cur->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
 			continue;
 
-		ret = ctnl_timeout_try_del(info->net, cur);
-		if (ret < 0)
-			return ret;
-
+		ctnl_timeout_del(info->net, cur);
+		ret = 0;
 		break;
 	}
 	return ret;
@@ -518,24 +516,22 @@ static struct nf_ct_timeout *ctnl_timeou
 		if (strncmp(timeout->name, name, CTNL_TIMEOUT_NAME_MAX) != 0)
 			continue;
 
-		if (!refcount_inc_not_zero(&timeout->refcnt))
+		if (!refcount_inc_not_zero(&timeout->timeout->refcnt))
 			goto err;
 		matching = timeout;
+		__module_get(THIS_MODULE);
 		break;
 	}
 err:
-	return matching ? &matching->timeout : NULL;
+	return matching ? matching->timeout : NULL;
 }
 
-static void ctnl_timeout_put(struct nf_ct_timeout *t)
+static void ctnl_timeout_put(struct nf_ct_timeout *timeout)
 {
-	struct ctnl_timeout *timeout =
-		container_of(t, struct ctnl_timeout, timeout);
+	if (refcount_dec_and_test(&timeout->refcnt))
+		kfree_rcu(timeout, rcu);
 
-	if (refcount_dec_and_test(&timeout->refcnt)) {
-		kfree_rcu(timeout, rcu_head);
-		module_put(THIS_MODULE);
-	}
+	module_put(THIS_MODULE);
 }
 
 static const struct nfnl_callback cttimeout_cb[IPCTNL_MSG_TIMEOUT_MAX] = {
@@ -616,8 +612,11 @@ static void __net_exit cttimeout_net_exi
 	list_for_each_entry_safe(cur, tmp, &pernet->nfct_timeout_freelist, free_head) {
 		list_del(&cur->free_head);
 
-		if (refcount_dec_and_test(&cur->refcnt))
-			kfree_rcu(cur, rcu_head);
+		if (refcount_dec_and_test(&cur->timeout->refcnt))
+			kfree_rcu(cur->timeout, rcu);
+
+		kfree_rcu(cur, rcu_head);
+		module_put(THIS_MODULE);
 	}
 }
 
@@ -656,24 +655,13 @@ err_out:
 	return ret;
 }
 
-static int untimeout(struct nf_conn *ct, void *timeout)
-{
-	struct nf_conn_timeout *timeout_ext = nf_ct_timeout_find(ct);
-
-	if (timeout_ext)
-		RCU_INIT_POINTER(timeout_ext->timeout, NULL);
-
-	return 0;
-}
-
 static void __exit cttimeout_exit(void)
 {
 	nfnetlink_subsys_unregister(&cttimeout_subsys);
 
 	unregister_pernet_subsys(&cttimeout_ops);
 	RCU_INIT_POINTER(nf_ct_timeout_hook, NULL);
-
-	nf_ct_iterate_destroy(untimeout, NULL);
+	synchronize_net();
 }
 
 module_init(cttimeout_init);
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -879,8 +879,6 @@ static void nft_ct_timeout_obj_eval(stru
 		}
 	}
 
-	rcu_assign_pointer(timeout->timeout, priv->timeout);
-
 	/* adjust the timeout as per 'new' state. ct is unconfirmed,
 	 * so the current timestamp must not be added.
 	 */
@@ -931,6 +929,7 @@ static int nft_ct_timeout_obj_init(const
 
 	timeout->l3num = l3num;
 	timeout->l4proto = l4proto;
+	refcount_set(&timeout->refcnt, 1);
 
 	ret = nf_ct_netns_get(ctx->net, ctx->family);
 	if (ret < 0)
@@ -951,10 +950,10 @@ static void nft_ct_timeout_obj_destroy(c
 	struct nft_ct_timeout_obj *priv = nft_obj_data(obj);
 	struct nf_ct_timeout *timeout = priv->timeout;
 
-	nf_queue_nf_hook_drop(ctx->net);
 	nf_ct_untimeout(ctx->net, timeout);
 	nf_ct_netns_put(ctx->net, ctx->family);
-	kfree_rcu(priv->timeout, rcu);
+	if (refcount_dec_and_test(&timeout->refcnt))
+		kfree_rcu(priv->timeout, rcu);
 }
 
 static int nft_ct_timeout_obj_dump(struct sk_buff *skb,
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -284,7 +284,7 @@ static void xt_ct_tg_destroy(const struc
 	struct nf_conn_help *help;
 
 	if (ct) {
-		if (info->helper[0] || info->timeout[0])
+		if (info->helper[0])
 			nf_queue_nf_hook_drop(par->net);
 
 		help = nfct_help(ct);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 737/877] netfilter: cttimeout: prevent UAF during module unload
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (735 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 736/877] netfilter: cttimeout: detach dataplane timeout policy and repurpose refcount Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 738/877] net: macb: Replace open-coded implementation with napi_schedule() Greg Kroah-Hartman
                   ` (147 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Pablo Neira Ayuso,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Chengfeng Ye <nicoyip.dev@gmail.com>

[ Upstream commit fec9b1de0d02de8dafa3cc344bcb91cf28660643 ]

nf_ct_set_timeout() protects the timeout hook dereference and policy lookup
with rcu_read_lock(). cttimeout_exit(), however, unregisters the per-net
operations before it clears the hook.

This allows the following interleaving:

  CPU 0                              CPU 1
  cttimeout_exit()                   nf_ct_set_timeout()
    unregister_pernet_subsys()         rcu_read_lock()
      kfree(pernet)                     h = nf_ct_timeout_hook
                                        h->timeout_find_get()
                                          nfct_timeout_pernet()

The hook still points to ctnl_timeout_find_get() when CPU 1 looks up the
already freed per-net timeout list. KASAN reported:

  BUG: KASAN: slab-use-after-free in ctnl_timeout_find_get
  Read of size 8 by task poc/90
  Call Trace:
   ctnl_timeout_find_get+0x271/0x2a0 [nfnetlink_cttimeout]
   nf_ct_set_timeout+0x7b/0x3c0
   xt_ct_tg_check+0x724/0xb20
   xt_check_target+0x234/0xa90
   do_ipt_set_ctl+0x570/0x1270
  Allocated by task 89:
   __kmalloc_noprof+0x16e/0x460
   ops_init+0x6d/0x420
   register_pernet_operations+0x2f6/0x670
  Freed by task 91:
   kfree+0x131/0x390
   ops_undo_list+0x3d4/0x730
   unregister_pernet_operations+0x232/0x490
   unregister_pernet_subsys+0x1c/0x30
   cttimeout_exit+0x52/0x970 [nfnetlink_cttimeout]

Clear the hook and wait for existing readers before unregistering the
per-net operations. This blocks new policy lookups and ensures readers that
observed the hook finish before the per-net storage is freed.

Fixes: ebfbe67568a7 ("netfilter: cttimeout: use net_generic infra")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/netfilter/nfnetlink_cttimeout.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -659,9 +659,9 @@ static void __exit cttimeout_exit(void)
 {
 	nfnetlink_subsys_unregister(&cttimeout_subsys);
 
-	unregister_pernet_subsys(&cttimeout_ops);
 	RCU_INIT_POINTER(nf_ct_timeout_hook, NULL);
 	synchronize_net();
+	unregister_pernet_subsys(&cttimeout_ops);
 }
 
 module_init(cttimeout_init);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 738/877] net: macb: Replace open-coded implementation with napi_schedule()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (736 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 737/877] netfilter: cttimeout: prevent UAF during module unload Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 739/877] net: macb: Use netif_napi_add_tx() instead of netif_napi_add() for TX NAPI Greg Kroah-Hartman
                   ` (146 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Kevin Hao, Jakub Kicinski,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Kevin Hao <haokexin@gmail.com>

[ Upstream commit dc3bd465ea36af7fd6f9197c05353effc616145c ]

The driver currently duplicates the logic of napi_schedule() primarily
to include additional debug information. However, these debug details
are not essential for a specific driver and can be effectively obtained
through existing tracepoints in the networking core, such as
/sys/kernel/tracing/events/napi/napi_poll. Therefore, this patch
replaces the open-coded implementation with napi_schedule() to
simplify the driver's code.

Signed-off-by: Kevin Hao <haokexin@gmail.com>
Link: https://patch.msgid.link/20260402-macb-irq-v2-1-942d98ab1154@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: e1406330d70e ("net: macb: initialize PTP state before registering clock")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/cadence/macb_main.c |   10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -2020,10 +2020,7 @@ static irqreturn_t macb_interrupt(int ir
 			if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE)
 				queue_writel(queue, ISR, MACB_BIT(RCOMP));
 
-			if (napi_schedule_prep(&queue->napi_rx)) {
-				netdev_vdbg(bp->dev, "scheduling RX softirq\n");
-				__napi_schedule(&queue->napi_rx);
-			}
+			napi_schedule(&queue->napi_rx);
 		}
 
 		if (status & (MACB_BIT(TCOMP) |
@@ -2038,10 +2035,7 @@ static irqreturn_t macb_interrupt(int ir
 				wmb(); // ensure softirq can see update
 			}
 
-			if (napi_schedule_prep(&queue->napi_tx)) {
-				netdev_vdbg(bp->dev, "scheduling TX softirq\n");
-				__napi_schedule(&queue->napi_tx);
-			}
+			napi_schedule(&queue->napi_tx);
 		}
 
 		if (unlikely(status & (MACB_TX_ERR_FLAGS))) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 739/877] net: macb: Use netif_napi_add_tx() instead of netif_napi_add() for TX NAPI
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (737 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 738/877] net: macb: Replace open-coded implementation with napi_schedule() Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 740/877] net: macb: unify device pointer naming convention Greg Kroah-Hartman
                   ` (145 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Kevin Hao, Jakub Kicinski,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Kevin Hao <haokexin@gmail.com>

[ Upstream commit c321b5676d0c41de9155c1966aa6af8b7ca35091 ]

The TX NAPI should be registered via netif_napi_add_tx() to avoid
unnecessarily polluting the napi_hash table.

Signed-off-by: Kevin Hao <haokexin@gmail.com>
Link: https://patch.msgid.link/20260403-macb-napi-tx-v1-1-08126a60c65e@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: e1406330d70e ("net: macb: initialize PTP state before registering clock")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/cadence/macb_main.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4240,7 +4240,7 @@ static int macb_init(struct platform_dev
 		queue->bp = bp;
 		spin_lock_init(&queue->tx_ptr_lock);
 		netif_napi_add(dev, &queue->napi_rx, macb_rx_poll);
-		netif_napi_add(dev, &queue->napi_tx, macb_tx_poll);
+		netif_napi_add_tx(dev, &queue->napi_tx, macb_tx_poll);
 		if (hw_q) {
 			queue->ISR  = GEM_ISR(hw_q - 1);
 			queue->IER  = GEM_IER(hw_q - 1);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 740/877] net: macb: unify device pointer naming convention
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (738 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 739/877] net: macb: Use netif_napi_add_tx() instead of netif_napi_add() for TX NAPI Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 741/877] net: macb: initialize PTP state before registering clock Greg Kroah-Hartman
                   ` (144 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Conor Dooley, Nicolai Buchwitz,
	Théo Lebrun, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Théo Lebrun <theo.lebrun@bootlin.com>

[ Upstream commit 07362f68e61d82ee53da0e9ae2c7f981c3538861 ]

Here are all device pointer variable permutations inside MACB:

   struct device *dev;
   struct net_device *dev;
   struct net_device *ndev;
   struct net_device *netdev;
   struct pci_dev *pdev;              // inside macb_pci.c
   struct phy_device *phy;
   struct phy_device *phydev;
   struct platform_device *pdev;
   struct platform_device *plat_dev;  // inside macb_pci.c

Unify to this convention:

   struct device *dev;
   struct net_device *netdev;
   struct pci_dev *pci;
   struct phy_device *phydev;
   struct platform_device *pdev;

Ensure nothing slipped through using ctags tooling:

⟩ ctags -o - --kinds-c='{local}{member}{parameter}' \
    --fields='{typeref}' drivers/net/ethernet/cadence/* | \
  awk -F"\t" '
    $NF~/struct:.*(device|dev) / {print $NF, $1}' | \
  sort -u
typeref:struct:device * dev
typeref:struct:in_device * idev        // ignored
typeref:struct:net_device * netdev
typeref:struct:pci_dev * pci
typeref:struct:phy_device * phydev
typeref:struct:platform_device * pdev

Also fix some printk() calls to use __func__ instead of hardcoding.
This silences some checkpatch.pl warnings and doesn't deserve a
separate commit.

Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
Link: https://patch.msgid.link/20260812-macb-context-v9-2-7ddbf5f715e0@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Backport note: retain only the dev-to-netdev rename in gem_ptp_init().
The target e1406330d70e ("net: macb: initialize PTP state before
registering clock") needs this spelling in its ptp_clock_register()
context; its macb_probe() hunk already applies to this stable tree.
Drop the unrelated driver-wide renames and logging cleanup. In
particular, do not import newer EEE, interrupt, DMA, queue, or probe
changes absent from this branch. This limited rename changes no
behavior and adds no functions.

[ sashal: Reduced backport -- upstream 07362f68e61d8 touches 4 file(s), this
  backport carries 1. Not backported here:
  drivers/net/ethernet/cadence/macb.h
  drivers/net/ethernet/cadence/macb_main.c
  drivers/net/ethernet/cadence/macb_pci.c
  This note is generated from the file lists only; see the resolution record
  for the reasoning. ]

Stable-dep-of: e1406330d70e ("net: macb: initialize PTP state before registering clock")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/cadence/macb_ptp.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

--- a/drivers/net/ethernet/cadence/macb_ptp.c
+++ b/drivers/net/ethernet/cadence/macb_ptp.c
@@ -331,9 +331,9 @@ void gem_ptp_txstamp(struct macb *bp, st
 	skb_tstamp_tx(skb, &shhwtstamps);
 }
 
-void gem_ptp_init(struct net_device *dev)
+void gem_ptp_init(struct net_device *netdev)
 {
-	struct macb *bp = netdev_priv(dev);
+	struct macb *bp = netdev_priv(netdev);
 
 	bp->ptp_clock_info = gem_ptp_caps_template;
 
@@ -341,7 +341,7 @@ void gem_ptp_init(struct net_device *dev
 	bp->tsu_rate = bp->ptp_info->get_tsu_rate(bp);
 	bp->ptp_clock_info.max_adj = bp->ptp_info->get_ptp_max_adj();
 	gem_ptp_init_timer(bp);
-	bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &dev->dev);
+	bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &netdev->dev);
 	if (IS_ERR(bp->ptp_clock)) {
 		pr_err("ptp clock register failed: %ld\n",
 			PTR_ERR(bp->ptp_clock));



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 741/877] net: macb: initialize PTP state before registering clock
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (739 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 740/877] net: macb: unify device pointer naming convention Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 742/877] erofs: add sysfs feature entry for xattr prefixes Greg Kroah-Hartman
                   ` (143 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Théo Lebrun, Vadim Fedorenko,
	Runyu Xiao, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Runyu Xiao <runyu.xiao@seu.edu.cn>

[ Upstream commit e1406330d70e56dd44fa6fbafc86e77e5c80c122 ]

gem_ptp_init() registers the PTP clock before initializing
bp->tsu_clk_lock and the TSU hardware. Since ptp_clock_register()
publishes the PTP character device, userspace may invoke PTP callbacks
before the lock and hardware are ready.

In addition, gem_ptp_init() is called from both the interface open and
resume paths. Reinitializing tsu_clk_lock there can reset the lock while
timestamp processing is using it.

This race is theoretical and has not been observed in practice.

Initialize tsu_clk_lock once during probe and initialize the TSU before
registering the PTP clock.

Fixes: ab91f0a9b5f4 ("net: macb: Add hardware PTP support")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/netdev/20260904030439.3994047-1-runyu.xiao@seu.edu.cn/
Reviewed-by: Théo Lebrun <theo.lebrun@bootlin.com>
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Link: https://patch.msgid.link/20260908103924.607033-1-runyu.xiao@seu.edu.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/cadence/macb_main.c |    1 +
 drivers/net/ethernet/cadence/macb_ptp.c  |    5 +----
 2 files changed, 2 insertions(+), 4 deletions(-)

--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -5227,6 +5227,7 @@ static int macb_probe(struct platform_de
 	}
 	spin_lock_init(&bp->lock);
 	spin_lock_init(&bp->stats_lock);
+	spin_lock_init(&bp->tsu_clk_lock);
 
 	/* setup capabilities */
 	macb_configure_caps(bp, macb_config);
--- a/drivers/net/ethernet/cadence/macb_ptp.c
+++ b/drivers/net/ethernet/cadence/macb_ptp.c
@@ -341,6 +341,7 @@ void gem_ptp_init(struct net_device *net
 	bp->tsu_rate = bp->ptp_info->get_tsu_rate(bp);
 	bp->ptp_clock_info.max_adj = bp->ptp_info->get_ptp_max_adj();
 	gem_ptp_init_timer(bp);
+	gem_ptp_init_tsu(bp);
 	bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &netdev->dev);
 	if (IS_ERR(bp->ptp_clock)) {
 		pr_err("ptp clock register failed: %ld\n",
@@ -352,10 +353,6 @@ void gem_ptp_init(struct net_device *net
 		return;
 	}
 
-	spin_lock_init(&bp->tsu_clk_lock);
-
-	gem_ptp_init_tsu(bp);
-
 	dev_info(&bp->pdev->dev, "%s ptp clock registered.\n",
 		 GEM_PTP_TIMER_NAME);
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 742/877] erofs: add sysfs feature entry for xattr prefixes
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (740 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 741/877] net: macb: initialize PTP state before registering clock Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 743/877] idpf: Fix kernel-doc descriptions to avoid warnings Greg Kroah-Hartman
                   ` (142 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Gao Xiang, Jingbo Xu, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jingbo Xu <jefflexu@linux.alibaba.com>

[ Upstream commit 839f075aabdf5c21048f9801b87c0b841dd3d064 ]

Let /sys/fs/erofs/features/xattr_prefixes advertise that this kernel
supports the EROFS_FEATURE_INCOMPAT_XATTR_PREFIXES on-disk format.

Fixes: 6a318ccd7e08 ("erofs: enable long extended attribute name prefixes")
Cc: stable@vger.kernel.org # 6.4+
Reviewed-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Signed-off-by: Gao Xiang <xiang@kernel.org>
[ adjusted feature-list context for missing 48bit and metabox entries while retaining zero_padding. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/ABI/testing/sysfs-fs-erofs |    2 +-
 fs/erofs/sysfs.c                         |    2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

--- a/Documentation/ABI/testing/sysfs-fs-erofs
+++ b/Documentation/ABI/testing/sysfs-fs-erofs
@@ -5,7 +5,7 @@ Description:	Shows all enabled kernel fe
 		Supported features:
 		zero_padding, compr_cfgs, big_pcluster, chunked_file,
 		device_table, compr_head2, sb_chksum, ztailpacking,
-		dedupe, fragments.
+		dedupe, fragments, xattr_prefixes.
 
 What:		/sys/fs/erofs/<disk>/sync_decompress
 Date:		November 2021
--- a/fs/erofs/sysfs.c
+++ b/fs/erofs/sysfs.c
@@ -81,6 +81,7 @@ EROFS_ATTR_FEATURE(sb_chksum);
 EROFS_ATTR_FEATURE(ztailpacking);
 EROFS_ATTR_FEATURE(fragments);
 EROFS_ATTR_FEATURE(dedupe);
+EROFS_ATTR_FEATURE(xattr_prefixes);
 
 static struct attribute *erofs_feat_attrs[] = {
 	ATTR_LIST(zero_padding),
@@ -93,6 +94,7 @@ static struct attribute *erofs_feat_attr
 	ATTR_LIST(ztailpacking),
 	ATTR_LIST(fragments),
 	ATTR_LIST(dedupe),
+	ATTR_LIST(xattr_prefixes),
 	NULL,
 };
 ATTRIBUTE_GROUPS(erofs_feat);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 743/877] idpf: Fix kernel-doc descriptions to avoid warnings
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (741 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 742/877] erofs: add sysfs feature entry for xattr prefixes Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 744/877] idpf: introduce idpf_q_vec_rsrc struct and move vector resources to it Greg Kroah-Hartman
                   ` (141 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Przemek Kitszel, Aleksandr Loktionov,
	Andy Shevchenko, Paul Menzel, Krishneil Singh, Tony Nguyen,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

[ Upstream commit 7fe9c81aa24a2374b1a9a2160d44f4afbf8ab80d ]

In many functions the Return section is missing. Fix kernel-doc
descriptions to address that and other warnings.

Before the change:

$ scripts/kernel-doc -none -Wreturn drivers/net/ethernet/intel/idpf/idpf_txrx.c 2>&1 | wc -l
85

Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Tested-by: Krishneil Singh <krishneil.k.singh@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Stable-dep-of: 7dd4c829bac2 ("idpf: disable DIM work before freeing q_vectors")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/intel/idpf/idpf_txrx.c |   94 +++++++++++++++++-----------
 1 file changed, 58 insertions(+), 36 deletions(-)

--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
@@ -19,6 +19,8 @@ LIBETH_SQE_CHECK_PRIV(u32);
  * Make sure we don't exceed maximum scatter gather buffers for a single
  * packet.
  * TSO case has been handled earlier from idpf_features_check().
+ *
+ * Return: %true if skb exceeds max descriptors per packet, %false otherwise.
  */
 static bool idpf_chk_linearize(const struct sk_buff *skb,
 			       unsigned int max_bufs,
@@ -148,7 +150,7 @@ static void idpf_tx_desc_rel_all(struct
  * idpf_tx_buf_alloc_all - Allocate memory for all buffer resources
  * @tx_q: queue for which the buffers are allocated
  *
- * Returns 0 on success, negative on failure
+ * Return: 0 on success, negative on failure
  */
 static int idpf_tx_buf_alloc_all(struct idpf_tx_queue *tx_q)
 {
@@ -172,7 +174,7 @@ static int idpf_tx_buf_alloc_all(struct
  * @vport: vport to allocate resources for
  * @tx_q: the tx ring to set up
  *
- * Returns 0 on success, negative on failure
+ * Return: 0 on success, negative on failure
  */
 static int idpf_tx_desc_alloc(const struct idpf_vport *vport,
 			      struct idpf_tx_queue *tx_q)
@@ -264,7 +266,7 @@ static int idpf_compl_desc_alloc(const s
  * idpf_tx_desc_alloc_all - allocate all queues Tx resources
  * @vport: virtual port private structure
  *
- * Returns 0 on success, negative on failure
+ * Return: 0 on success, negative on failure
  */
 static int idpf_tx_desc_alloc_all(struct idpf_vport *vport)
 {
@@ -509,7 +511,7 @@ static void idpf_rx_buf_hw_update(struct
  * idpf_rx_hdr_buf_alloc_all - Allocate memory for header buffers
  * @bufq: ring to use
  *
- * Returns 0 on success, negative on failure.
+ * Return: 0 on success, negative on failure.
  */
 static int idpf_rx_hdr_buf_alloc_all(struct idpf_buf_queue *bufq)
 {
@@ -560,7 +562,7 @@ static void idpf_post_buf_refill(struct
  * @bufq: buffer queue to post to
  * @buf_id: buffer id to post
  *
- * Returns false if buffer could not be allocated, true otherwise.
+ * Return: %false if buffer could not be allocated, %true otherwise.
  */
 static bool idpf_rx_post_buf_desc(struct idpf_buf_queue *bufq, u16 buf_id)
 {
@@ -609,7 +611,7 @@ static bool idpf_rx_post_buf_desc(struct
  * @bufq: buffer queue to post working set to
  * @working_set: number of buffers to put in working set
  *
- * Returns true if @working_set bufs were posted successfully, false otherwise.
+ * Return: %true if @working_set bufs were posted successfully, %false otherwise.
  */
 static bool idpf_rx_post_init_bufs(struct idpf_buf_queue *bufq,
 				   u16 working_set)
@@ -678,7 +680,7 @@ static int idpf_rx_bufs_init_singleq(str
  * idpf_rx_buf_alloc_all - Allocate memory for all buffer resources
  * @rxbufq: queue for which the buffers are allocated
  *
- * Returns 0 on success, negative on failure
+ * Return: 0 on success, negative on failure
  */
 static int idpf_rx_buf_alloc_all(struct idpf_buf_queue *rxbufq)
 {
@@ -706,7 +708,7 @@ rx_buf_alloc_all_out:
  * @bufq: buffer queue to create page pool for
  * @type: type of Rx buffers to allocate
  *
- * Returns 0 on success, negative on failure
+ * Return: 0 on success, negative on failure
  */
 static int idpf_rx_bufs_init(struct idpf_buf_queue *bufq,
 			     enum libeth_fqe_type type)
@@ -737,7 +739,7 @@ static int idpf_rx_bufs_init(struct idpf
  * idpf_rx_bufs_init_all - Initialize all RX bufs
  * @vport: virtual port struct
  *
- * Returns 0 on success, negative on failure
+ * Return: 0 on success, negative on failure
  */
 int idpf_rx_bufs_init_all(struct idpf_vport *vport)
 {
@@ -790,7 +792,7 @@ int idpf_rx_bufs_init_all(struct idpf_vp
  * @vport: vport to allocate resources for
  * @rxq: Rx queue for which the resources are setup
  *
- * Returns 0 on success, negative on failure
+ * Return: 0 on success, negative on failure
  */
 static int idpf_rx_desc_alloc(const struct idpf_vport *vport,
 			      struct idpf_rx_queue *rxq)
@@ -849,7 +851,7 @@ static int idpf_bufq_desc_alloc(const st
  * idpf_rx_desc_alloc_all - allocate all RX queues resources
  * @vport: virtual port structure
  *
- * Returns 0 on success, negative on failure
+ * Return: 0 on success, negative on failure
  */
 static int idpf_rx_desc_alloc_all(struct idpf_vport *vport)
 {
@@ -1038,7 +1040,7 @@ void idpf_vport_queues_rel(struct idpf_v
  * dereference the queue from queue groups.  This allows us to quickly pull a
  * txq based on a queue index.
  *
- * Returns 0 on success, negative on failure
+ * Return: 0 on success, negative on failure
  */
 static int idpf_vport_init_fast_path_txqs(struct idpf_vport *vport)
 {
@@ -1151,7 +1153,7 @@ void idpf_vport_calc_num_q_desc(struct i
  * @vport_msg: message to fill with data
  * @max_q: vport max queue info
  *
- * Return 0 on success, error value on failure.
+ * Return: 0 on success, error value on failure.
  */
 int idpf_vport_calc_total_qs(struct idpf_adapter *adapter, u16 vport_idx,
 			     struct virtchnl2_create_vport *vport_msg,
@@ -1274,7 +1276,7 @@ static void idpf_rxq_set_descids(const s
  * @vport: vport to allocate txq groups for
  * @num_txq: number of txqs to allocate for each group
  *
- * Returns 0 on success, negative on failure
+ * Return: 0 on success, negative on failure
  */
 static int idpf_txq_group_alloc(struct idpf_vport *vport, u16 num_txq)
 {
@@ -1365,7 +1367,7 @@ err_alloc:
  * @vport: vport to allocate rxq groups for
  * @num_rxq: number of rxqs to allocate for each group
  *
- * Returns 0 on success, negative on failure
+ * Return: 0 on success, negative on failure
  */
 static int idpf_rxq_group_alloc(struct idpf_vport *vport, u16 num_rxq)
 {
@@ -1495,7 +1497,7 @@ err_alloc:
  * idpf_vport_queue_grp_alloc_all - Allocate all queue groups/resources
  * @vport: vport with qgrps to allocate
  *
- * Returns 0 on success, negative on failure
+ * Return: 0 on success, negative on failure
  */
 static int idpf_vport_queue_grp_alloc_all(struct idpf_vport *vport)
 {
@@ -1524,8 +1526,9 @@ err_out:
  * idpf_vport_queues_alloc - Allocate memory for all queues
  * @vport: virtual port
  *
- * Allocate memory for queues associated with a vport.  Returns 0 on success,
- * negative on failure.
+ * Allocate memory for queues associated with a vport.
+ *
+ * Return: 0 on success, negative on failure.
  */
 int idpf_vport_queues_alloc(struct idpf_vport *vport)
 {
@@ -1737,7 +1740,7 @@ static void idpf_tx_handle_rs_completion
  * @budget: Used to determine if we are in netpoll
  * @cleaned: returns number of packets cleaned
  *
- * Returns true if there's any budget left (e.g. the clean is finished)
+ * Return: %true if there's any budget left (e.g. the clean is finished)
  */
 static bool idpf_tx_clean_complq(struct idpf_compl_queue *complq, int budget,
 				 int *cleaned)
@@ -1903,7 +1906,7 @@ void idpf_tx_splitq_build_flow_desc(unio
 }
 
 /**
- * idpf_tx_splitq_has_room - check if enough Tx splitq resources are available
+ * idpf_txq_has_room - check if enough Tx splitq resources are available
  * @tx_q: the queue to be checked
  * @descs_needed: number of descriptors required for this packet
  * @bufs_needed: number of Tx buffers required for this packet
@@ -2034,6 +2037,8 @@ unsigned int idpf_tx_res_count_required(
  * idpf_tx_splitq_bump_ntu - adjust NTU and generation
  * @txq: the tx ring to wrap
  * @ntu: ring index to bump
+ *
+ * Return: the next ring index hopping to 0 when wraps around
  */
 static unsigned int idpf_tx_splitq_bump_ntu(struct idpf_tx_queue *txq, u16 ntu)
 {
@@ -2302,7 +2307,7 @@ static void idpf_tx_splitq_map(struct id
  * @skb: pointer to skb
  * @off: pointer to struct that holds offload parameters
  *
- * Returns error (negative) if TSO was requested but cannot be applied to the
+ * Return: error (negative) if TSO was requested but cannot be applied to the
  * given skb, 0 if TSO does not apply to the given skb, or 1 otherwise.
  */
 int idpf_tso(struct sk_buff *skb, struct idpf_tx_offload_params *off)
@@ -2380,6 +2385,8 @@ int idpf_tso(struct sk_buff *skb, struct
  *
  * Since the TX buffer rings mimics the descriptor ring, update the tx buffer
  * ring entry to reflect that this index is a context descriptor
+ *
+ * Return: pointer to the next descriptor
  */
 static struct idpf_flex_tx_ctx_desc *
 idpf_tx_splitq_get_ctx_desc(struct idpf_tx_queue *txq)
@@ -2398,6 +2405,8 @@ idpf_tx_splitq_get_ctx_desc(struct idpf_
  * idpf_tx_drop_skb - free the SKB and bump tail if necessary
  * @tx_q: queue to send buffer on
  * @skb: pointer to skb
+ *
+ * Return: always NETDEV_TX_OK
  */
 netdev_tx_t idpf_tx_drop_skb(struct idpf_tx_queue *tx_q, struct sk_buff *skb)
 {
@@ -2432,7 +2441,7 @@ static bool idpf_tx_splitq_need_re(struc
  * @skb: send buffer
  * @tx_q: queue to send buffer on
  *
- * Returns NETDEV_TX_OK if sent, else an error code
+ * Return: NETDEV_TX_OK if sent, else an error code
  */
 static netdev_tx_t idpf_tx_splitq_frame(struct sk_buff *skb,
 					struct idpf_tx_queue *tx_q)
@@ -2549,7 +2558,7 @@ static netdev_tx_t idpf_tx_splitq_frame(
  * @skb: send buffer
  * @netdev: network interface device structure
  *
- * Returns NETDEV_TX_OK if sent, else an error code
+ * Return: NETDEV_TX_OK if sent, else an error code
  */
 netdev_tx_t idpf_tx_start(struct sk_buff *skb, struct net_device *netdev)
 {
@@ -2698,10 +2707,10 @@ idpf_rx_splitq_extract_csum_bits(const s
  * @rx_desc: Receive descriptor
  * @decoded: Decoded Rx packet type related fields
  *
- * Return 0 on success and error code on failure
- *
  * Populate the skb fields with the total number of RSC segments, RSC payload
  * length and packet type.
+ *
+ * Return: 0 on success and error code on failure
  */
 static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
 		       const struct virtchnl2_rx_flex_desc_adv_nic_3 *rx_desc,
@@ -2776,6 +2785,8 @@ static int idpf_rx_rsc(struct idpf_rx_qu
  * This function checks the ring, descriptor, and packet information in
  * order to populate the hash, checksum, protocol, and
  * other fields within the skb.
+ *
+ * Return: 0 on success and error code on failure
  */
 static int
 idpf_rx_process_skb_fields(struct idpf_rx_queue *rxq, struct sk_buff *skb,
@@ -2894,6 +2905,7 @@ struct sk_buff *idpf_rx_build_skb(const
  * @stat_err_field: field from descriptor to test bits in
  * @stat_err_bits: value to mask
  *
+ * Return: %true if any of given @stat_err_bits are set, %false otherwise.
  */
 static bool idpf_rx_splitq_test_staterr(const u8 stat_err_field,
 					const u8 stat_err_bits)
@@ -2905,8 +2917,8 @@ static bool idpf_rx_splitq_test_staterr(
  * idpf_rx_splitq_is_eop - process handling of EOP buffers
  * @rx_desc: Rx descriptor for current buffer
  *
- * If the buffer is an EOP buffer, this function exits returning true,
- * otherwise return false indicating that this is in fact a non-EOP buffer.
+ * Return: %true if the buffer is an EOP buffer, %false otherwise, indicating
+ * that this is in fact a non-EOP buffer.
  */
 static bool idpf_rx_splitq_is_eop(struct virtchnl2_rx_flex_desc_adv_nic_3 *rx_desc)
 {
@@ -2925,7 +2937,7 @@ static bool idpf_rx_splitq_is_eop(struct
  * expensive overhead for IOMMU access this provides a means of avoiding
  * it by maintaining the mapping of the page to the system.
  *
- * Returns amount of work completed
+ * Return: amount of work completed
  */
 static int idpf_rx_splitq_clean(struct idpf_rx_queue *rxq, int budget)
 {
@@ -3087,7 +3099,7 @@ skip_data:
  * @buf_id: buffer ID
  * @buf_desc: Buffer queue descriptor
  *
- * Return 0 on success and negative on failure.
+ * Return: 0 on success and negative on failure.
  */
 static int idpf_rx_update_bufq_desc(struct idpf_buf_queue *bufq, u32 buf_id,
 				    struct virtchnl2_splitq_rx_buf_desc *buf_desc)
@@ -3214,6 +3226,7 @@ static void idpf_rx_clean_refillq_all(st
  * @irq: interrupt number
  * @data: pointer to a q_vector
  *
+ * Return: always IRQ_HANDLED
  */
 static irqreturn_t idpf_vport_intr_clean_queues(int __always_unused irq,
 						void *data)
@@ -3320,6 +3333,8 @@ static void idpf_vport_intr_dis_irq_all(
 /**
  * idpf_vport_intr_buildreg_itr - Enable default interrupt generation settings
  * @q_vector: pointer to q_vector
+ *
+ * Return: value to be written back to HW to enable interrupt generation
  */
 static u32 idpf_vport_intr_buildreg_itr(struct idpf_q_vector *q_vector)
 {
@@ -3451,6 +3466,8 @@ void idpf_vport_intr_update_itr_ena_irq(
 /**
  * idpf_vport_intr_req_irq - get MSI-X vectors from the OS for the vport
  * @vport: main vport structure
+ *
+ * Return: 0 on success, negative on failure
  */
 static int idpf_vport_intr_req_irq(struct idpf_vport *vport)
 {
@@ -3659,7 +3676,7 @@ static void idpf_vport_intr_napi_ena_all
  * @budget: Used to determine if we are in netpoll
  * @cleaned: returns number of packets cleaned
  *
- * Returns false if clean is not complete else returns true
+ * Return: %false if clean is not complete else returns %true
  */
 static bool idpf_tx_splitq_clean_all(struct idpf_q_vector *q_vec,
 				     int budget, int *cleaned)
@@ -3686,7 +3703,7 @@ static bool idpf_tx_splitq_clean_all(str
  * @budget: Used to determine if we are in netpoll
  * @cleaned: returns number of packets cleaned
  *
- * Returns false if clean is not complete else returns true
+ * Return: %false if clean is not complete else returns %true
  */
 static bool idpf_rx_splitq_clean_all(struct idpf_q_vector *q_vec, int budget,
 				     int *cleaned)
@@ -3725,6 +3742,8 @@ static bool idpf_rx_splitq_clean_all(str
  * idpf_vport_splitq_napi_poll - NAPI handler
  * @napi: struct from which you get q_vector
  * @budget: budget provided by stack
+ *
+ * Return: how many packets were cleaned
  */
 static int idpf_vport_splitq_napi_poll(struct napi_struct *napi, int budget)
 {
@@ -3861,7 +3880,9 @@ static void idpf_vport_intr_map_vector_t
  * idpf_vport_intr_init_vec_idx - Initialize the vector indexes
  * @vport: virtual port
  *
- * Initialize vector indexes with values returened over mailbox
+ * Initialize vector indexes with values returned over mailbox.
+ *
+ * Return: 0 on success, negative on failure
  */
 static int idpf_vport_intr_init_vec_idx(struct idpf_vport *vport)
 {
@@ -3922,8 +3943,9 @@ static void idpf_vport_intr_napi_add_all
  * idpf_vport_intr_alloc - Allocate memory for interrupt vectors
  * @vport: virtual port
  *
- * We allocate one q_vector per queue interrupt. If allocation fails we
- * return -ENOMEM.
+ * Allocate one q_vector per queue interrupt.
+ *
+ * Return: 0 on success, if allocation fails we return -ENOMEM.
  */
 int idpf_vport_intr_alloc(struct idpf_vport *vport)
 {
@@ -4004,7 +4026,7 @@ error:
  * idpf_vport_intr_init - Setup all vectors for the given vport
  * @vport: virtual port
  *
- * Returns 0 on success or negative on failure
+ * Return: 0 on success or negative on failure
  */
 int idpf_vport_intr_init(struct idpf_vport *vport)
 {
@@ -4043,7 +4065,7 @@ void idpf_vport_intr_ena(struct idpf_vpo
  * idpf_config_rss - Send virtchnl messages to configure RSS
  * @vport: virtual port
  *
- * Return 0 on success, negative on failure
+ * Return: 0 on success, negative on failure
  */
 int idpf_config_rss(struct idpf_vport *vport)
 {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 744/877] idpf: introduce idpf_q_vec_rsrc struct and move vector resources to it
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (742 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 743/877] idpf: Fix kernel-doc descriptions to avoid warnings Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 745/877] idpf: disable DIM work before freeing q_vectors Greg Kroah-Hartman
                   ` (140 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Anton Nadezhdin, Pavan Kumar Linga,
	Joshua Hay, Samuel Salin, Tony Nguyen, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pavan Kumar Linga <pavan.kumar.linga@intel.com>

[ Upstream commit d1061502f353d5e1a8937181b84b722e75fabf11 ]

To group all the vector and queue resources, introduce idpf_q_vec_rsrc
structure. This helps to reuse the same config path functions by other
features. For example, PTP implementation can use the existing config
infrastructure to configure secondary mailbox by passing its queue and
vector info. It also helps to avoid any duplication of code.

Existing queue and vector resources are grouped as default resources.
This patch moves vector info to the newly introduced structure.
Following patch moves the queue resources.

While at it, declare the loop iterator for 'num_q_vectors' in loop and
use the correct type.

Include idpf_q_vec_rsrc backpointer in idpf_alloc_queue_set along with
vport.

Reviewed-by: Anton Nadezhdin <anton.nadezhdin@intel.com>
Signed-off-by: Pavan Kumar Linga <pavan.kumar.linga@intel.com>
Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
Tested-by: Samuel Salin <Samuel.salin@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>

[Backport to 6.12: retain the vector-resource grouping and convert the
existing PF/VF register, interrupt, vport lifecycle and vector-allocation
paths. Also convert the stable-only NAPI scheduling in
idpf_send_disable_queues_msg().

Drop changes to the unavailable queue-set, AF_XDP and NOIRQ support;
retain the stable queue/vector counts, mailbox interface and vport state
handling. Keep the resource member at the original vector fields' location.
No functions are added. This prepares the existing interrupt lifecycle
for 7dd4c829bac2 ("idpf: disable DIM work before freeing q_vectors").]

Stable-dep-of: 7dd4c829bac2 ("idpf: disable DIM work before freeing q_vectors")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/intel/idpf/idpf.h          |   24 ++-
 drivers/net/ethernet/intel/idpf/idpf_dev.c      |   10 -
 drivers/net/ethernet/intel/idpf/idpf_lib.c      |   35 ++--
 drivers/net/ethernet/intel/idpf/idpf_txrx.c     |  183 ++++++++++++------------
 drivers/net/ethernet/intel/idpf/idpf_txrx.h     |   14 +
 drivers/net/ethernet/intel/idpf/idpf_vf_dev.c   |   10 -
 drivers/net/ethernet/intel/idpf/idpf_virtchnl.c |   20 +-
 drivers/net/ethernet/intel/idpf/idpf_virtchnl.h |    3 
 8 files changed, 167 insertions(+), 132 deletions(-)

--- a/drivers/net/ethernet/intel/idpf/idpf.h
+++ b/drivers/net/ethernet/intel/idpf/idpf.h
@@ -8,6 +8,7 @@
 struct idpf_adapter;
 struct idpf_vport;
 struct idpf_vport_max_q;
+struct idpf_q_vec_rsrc;
 
 #include <net/pkt_sched.h>
 #include <linux/aer.h>
@@ -196,7 +197,8 @@ struct idpf_vport_max_q {
  */
 struct idpf_reg_ops {
 	void (*ctlq_reg_init)(struct idpf_ctlq_create_info *cq);
-	int (*intr_reg_init)(struct idpf_vport *vport);
+	int (*intr_reg_init)(struct idpf_vport *vport,
+			     struct idpf_q_vec_rsrc *rsrc);
 	void (*mb_intr_reg_init)(struct idpf_adapter *adapter);
 	void (*reset_reg_init)(struct idpf_adapter *adapter);
 	void (*trigger_reset)(struct idpf_adapter *adapter,
@@ -252,6 +254,18 @@ struct idpf_port_stats {
 };
 
 /**
+ * struct idpf_q_vec_rsrc - handle for queue and vector resources
+ * @q_vectors: array of queue vectors
+ * @q_vector_idxs: starting index of queue vectors
+ * @num_q_vectors: number of IRQ vectors allocated
+ */
+struct idpf_q_vec_rsrc {
+	struct idpf_q_vector	*q_vectors;
+	u16			*q_vector_idxs;
+	u16			num_q_vectors;
+};
+
+/**
  * struct idpf_vport - Handle for netdevices and queue resources
  * @num_txq: Number of allocated TX queues
  * @num_complq: Number of allocated completion queues
@@ -284,9 +298,7 @@ struct idpf_port_stats {
  * @idx: Software index in adapter vports struct
  * @default_vport: Use this vport if one isn't specified
  * @base_rxd: True if the driver should use base descriptors instead of flex
- * @num_q_vectors: Number of IRQ vectors allocated
- * @q_vectors: Array of queue vectors
- * @q_vector_idxs: Starting index of queue vectors
+ * @dflt_qv_rsrc: contains default queue and vector resources
  * @max_mtu: device given max possible MTU
  * @default_mac_addr: device will give a default MAC to use
  * @rx_itr_profile: RX profiles for Dynamic Interrupt Moderation
@@ -326,9 +338,7 @@ struct idpf_vport {
 	bool default_vport;
 	bool base_rxd;
 
-	u16 num_q_vectors;
-	struct idpf_q_vector *q_vectors;
-	u16 *q_vector_idxs;
+	struct idpf_q_vec_rsrc dflt_qv_rsrc;
 	u16 max_mtu;
 	u8 default_mac_addr[ETH_ALEN];
 	u16 rx_itr_profile[IDPF_DIM_PROFILE_SLOTS];
--- a/drivers/net/ethernet/intel/idpf/idpf_dev.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_dev.c
@@ -66,11 +66,13 @@ static void idpf_mb_intr_reg_init(struct
 /**
  * idpf_intr_reg_init - Initialize interrupt registers
  * @vport: virtual port structure
+ * @rsrc: pointer to queue and vector resources
  */
-static int idpf_intr_reg_init(struct idpf_vport *vport)
+static int idpf_intr_reg_init(struct idpf_vport *vport,
+			      struct idpf_q_vec_rsrc *rsrc)
 {
 	struct idpf_adapter *adapter = vport->adapter;
-	int num_vecs = vport->num_q_vectors;
+	u16 num_vecs = rsrc->num_q_vectors;
 	struct idpf_vec_regs *reg_vals;
 	int num_regs, i, err = 0;
 	u32 rx_itr, tx_itr;
@@ -89,8 +91,8 @@ static int idpf_intr_reg_init(struct idp
 	}
 
 	for (i = 0; i < num_vecs; i++) {
-		struct idpf_q_vector *q_vector = &vport->q_vectors[i];
-		u16 vec_id = vport->q_vector_idxs[i] - IDPF_MBX_Q_VEC;
+		struct idpf_q_vector *q_vector = &rsrc->q_vectors[i];
+		u16 vec_id = rsrc->q_vector_idxs[i] - IDPF_MBX_Q_VEC;
 		struct idpf_intr_reg *intr = &q_vector->intr_reg;
 		u32 spacing;
 
--- a/drivers/net/ethernet/intel/idpf/idpf_lib.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c
@@ -908,6 +908,7 @@ static void idpf_remove_features(struct
 static void idpf_vport_stop(struct idpf_vport *vport)
 {
 	struct idpf_netdev_priv *np = netdev_priv(vport->netdev);
+	struct idpf_q_vec_rsrc *rsrc = &vport->dflt_qv_rsrc;
 
 	if (np->state <= __IDPF_VPORT_DOWN)
 		return;
@@ -929,9 +930,9 @@ static void idpf_vport_stop(struct idpf_
 	idpf_remove_features(vport);
 
 	vport->link_up = false;
-	idpf_vport_intr_deinit(vport);
+	idpf_vport_intr_deinit(vport, rsrc);
 	idpf_vport_queues_rel(vport);
-	idpf_vport_intr_rel(vport);
+	idpf_vport_intr_rel(rsrc);
 	np->state = __IDPF_VPORT_DOWN;
 }
 
@@ -991,6 +992,7 @@ static void idpf_decfg_netdev(struct idp
  */
 static void idpf_vport_rel(struct idpf_vport *vport)
 {
+	struct idpf_q_vec_rsrc *rsrc = &vport->dflt_qv_rsrc;
 	struct idpf_adapter *adapter = vport->adapter;
 	struct idpf_vport_config *vport_config;
 	struct idpf_vector_info vec_info;
@@ -1015,13 +1017,13 @@ static void idpf_vport_rel(struct idpf_v
 
 	/* Release all the allocated vectors on the stack */
 	vec_info.num_req_vecs = 0;
-	vec_info.num_curr_vecs = vport->num_q_vectors;
+	vec_info.num_curr_vecs = rsrc->num_q_vectors;
 	vec_info.default_vport = vport->default_vport;
 
-	idpf_req_rel_vector_indexes(adapter, vport->q_vector_idxs, &vec_info);
+	idpf_req_rel_vector_indexes(adapter, rsrc->q_vector_idxs, &vec_info);
 
-	kfree(vport->q_vector_idxs);
-	vport->q_vector_idxs = NULL;
+	kfree(rsrc->q_vector_idxs);
+	rsrc->q_vector_idxs = NULL;
 
 	kfree(adapter->vport_params_recvd[idx]);
 	adapter->vport_params_recvd[idx] = NULL;
@@ -1146,6 +1148,7 @@ static struct idpf_vport *idpf_vport_all
 {
 	struct idpf_rss_data *rss_data;
 	u16 idx = adapter->next_vport;
+	struct idpf_q_vec_rsrc *rsrc;
 	struct idpf_vport *vport;
 	u16 num_max_q;
 	int err;
@@ -1193,8 +1196,9 @@ static struct idpf_vport *idpf_vport_all
 	vport->default_vport = adapter->num_alloc_vports <
 			       idpf_get_default_vports(adapter);
 
-	vport->q_vector_idxs = kcalloc(num_max_q, sizeof(u16), GFP_KERNEL);
-	if (!vport->q_vector_idxs)
+	rsrc = &vport->dflt_qv_rsrc;
+	rsrc->q_vector_idxs = kcalloc(num_max_q, sizeof(u16), GFP_KERNEL);
+	if (!rsrc->q_vector_idxs)
 		goto free_vport;
 
 	idpf_vport_init(vport, max_q);
@@ -1232,7 +1236,7 @@ free_rss_key:
 	kfree(rss_data->rss_key);
 	rss_data->rss_key = NULL;
 free_vector_idxs:
-	kfree(vport->q_vector_idxs);
+	kfree(rsrc->q_vector_idxs);
 free_vport:
 	kfree(vport);
 
@@ -1405,6 +1409,7 @@ static void idpf_rx_init_buf_tail(struct
 static int idpf_vport_open(struct idpf_vport *vport)
 {
 	struct idpf_netdev_priv *np = netdev_priv(vport->netdev);
+	struct idpf_q_vec_rsrc *rsrc = &vport->dflt_qv_rsrc;
 	struct idpf_adapter *adapter = vport->adapter;
 	int err;
 
@@ -1414,7 +1419,7 @@ static int idpf_vport_open(struct idpf_v
 	/* we do not allow interface up just yet */
 	netif_carrier_off(vport->netdev);
 
-	err = idpf_vport_intr_alloc(vport);
+	err = idpf_vport_intr_alloc(vport, rsrc);
 	if (err) {
 		dev_err(&adapter->pdev->dev, "Failed to allocate interrupts for vport %u: %d\n",
 			vport->vport_id, err);
@@ -1432,7 +1437,7 @@ static int idpf_vport_open(struct idpf_v
 		goto queues_rel;
 	}
 
-	err = idpf_vport_intr_init(vport);
+	err = idpf_vport_intr_init(vport, rsrc);
 	if (err) {
 		dev_err(&adapter->pdev->dev, "Failed to initialize interrupts for vport %u: %d\n",
 			vport->vport_id, err);
@@ -1454,7 +1459,7 @@ static int idpf_vport_open(struct idpf_v
 	}
 
 	idpf_rx_init_buf_tail(vport);
-	idpf_vport_intr_ena(vport);
+	idpf_vport_intr_ena(vport, rsrc);
 
 	err = idpf_send_config_queues_msg(vport);
 	if (err) {
@@ -1510,11 +1515,11 @@ disable_queues:
 unmap_queue_vectors:
 	idpf_send_map_unmap_queue_vector_msg(vport, false);
 intr_deinit:
-	idpf_vport_intr_deinit(vport);
+	idpf_vport_intr_deinit(vport, rsrc);
 queues_rel:
 	idpf_vport_queues_rel(vport);
 intr_rel:
-	idpf_vport_intr_rel(vport);
+	idpf_vport_intr_rel(rsrc);
 
 	return err;
 }
@@ -1958,7 +1963,7 @@ int idpf_initiate_soft_reset(struct idpf
 	memcpy(vport, new_vport, offsetof(struct idpf_vport, link_up));
 
 	if (reset_cause == IDPF_SR_Q_CHANGE)
-		idpf_vport_alloc_vec_indexes(vport);
+		idpf_vport_alloc_vec_indexes(vport, &vport->dflt_qv_rsrc);
 
 	err = idpf_set_real_num_queues(vport);
 	if (err)
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
@@ -3241,39 +3241,34 @@ static irqreturn_t idpf_vport_intr_clean
 
 /**
  * idpf_vport_intr_napi_del_all - Unregister napi for all q_vectors in vport
- * @vport: virtual port structure
- *
+ * @rsrc: pointer to queue and vector resources
  */
-static void idpf_vport_intr_napi_del_all(struct idpf_vport *vport)
+static void idpf_vport_intr_napi_del_all(struct idpf_q_vec_rsrc *rsrc)
 {
-	u16 v_idx;
-
-	for (v_idx = 0; v_idx < vport->num_q_vectors; v_idx++)
-		netif_napi_del(&vport->q_vectors[v_idx].napi);
+	for (u16 v_idx = 0; v_idx < rsrc->num_q_vectors; v_idx++)
+		netif_napi_del(&rsrc->q_vectors[v_idx].napi);
 }
 
 /**
  * idpf_vport_intr_napi_dis_all - Disable NAPI for all q_vectors in the vport
- * @vport: main vport structure
+ * @rsrc: pointer to queue and vector resources
  */
-static void idpf_vport_intr_napi_dis_all(struct idpf_vport *vport)
+static void idpf_vport_intr_napi_dis_all(struct idpf_q_vec_rsrc *rsrc)
 {
-	int v_idx;
-
-	for (v_idx = 0; v_idx < vport->num_q_vectors; v_idx++)
-		napi_disable(&vport->q_vectors[v_idx].napi);
+	for (u16 v_idx = 0; v_idx < rsrc->num_q_vectors; v_idx++)
+		napi_disable(&rsrc->q_vectors[v_idx].napi);
 }
 
 /**
  * idpf_vport_intr_rel - Free memory allocated for interrupt vectors
- * @vport: virtual port
+ * @rsrc: pointer to queue and vector resources
  *
  * Free the memory allocated for interrupt vectors  associated to a vport
  */
-void idpf_vport_intr_rel(struct idpf_vport *vport)
+void idpf_vport_intr_rel(struct idpf_q_vec_rsrc *rsrc)
 {
-	for (u32 v_idx = 0; v_idx < vport->num_q_vectors; v_idx++) {
-		struct idpf_q_vector *q_vector = &vport->q_vectors[v_idx];
+	for (u16 v_idx = 0; v_idx < rsrc->num_q_vectors; v_idx++) {
+		struct idpf_q_vector *q_vector = &rsrc->q_vectors[v_idx];
 
 		kfree(q_vector->complq);
 		q_vector->complq = NULL;
@@ -3287,28 +3282,29 @@ void idpf_vport_intr_rel(struct idpf_vpo
 		free_cpumask_var(q_vector->affinity_mask);
 	}
 
-	kfree(vport->q_vectors);
-	vport->q_vectors = NULL;
+	kfree(rsrc->q_vectors);
+	rsrc->q_vectors = NULL;
 }
 
 /**
  * idpf_vport_intr_rel_irq - Free the IRQ association with the OS
  * @vport: main vport structure
+ * @rsrc: pointer to queue and vector resources
  */
-static void idpf_vport_intr_rel_irq(struct idpf_vport *vport)
+static void idpf_vport_intr_rel_irq(struct idpf_vport *vport,
+				    struct idpf_q_vec_rsrc *rsrc)
 {
 	struct idpf_adapter *adapter = vport->adapter;
-	int vector;
 
-	for (vector = 0; vector < vport->num_q_vectors; vector++) {
-		struct idpf_q_vector *q_vector = &vport->q_vectors[vector];
+	for (u16 vector = 0; vector < rsrc->num_q_vectors; vector++) {
+		struct idpf_q_vector *q_vector = &rsrc->q_vectors[vector];
 		int irq_num, vidx;
 
 		/* free only the irqs that were actually requested */
 		if (!q_vector)
 			continue;
 
-		vidx = vport->q_vector_idxs[vector];
+		vidx = rsrc->q_vector_idxs[vector];
 		irq_num = adapter->msix_entries[vidx].vector;
 
 		/* clear the affinity_mask in the IRQ descriptor */
@@ -3319,14 +3315,13 @@ static void idpf_vport_intr_rel_irq(stru
 
 /**
  * idpf_vport_intr_dis_irq_all - Disable all interrupt
- * @vport: main vport structure
+ * @rsrc: pointer to queue and vector resources
  */
-static void idpf_vport_intr_dis_irq_all(struct idpf_vport *vport)
+static void idpf_vport_intr_dis_irq_all(struct idpf_q_vec_rsrc *rsrc)
 {
-	struct idpf_q_vector *q_vector = vport->q_vectors;
-	int q_idx;
+	struct idpf_q_vector *q_vector = rsrc->q_vectors;
 
-	for (q_idx = 0; q_idx < vport->num_q_vectors; q_idx++)
+	for (u16 q_idx = 0; q_idx < rsrc->num_q_vectors; q_idx++)
 		writel(0, q_vector[q_idx].intr_reg.dyn_ctl);
 }
 
@@ -3466,10 +3461,12 @@ void idpf_vport_intr_update_itr_ena_irq(
 /**
  * idpf_vport_intr_req_irq - get MSI-X vectors from the OS for the vport
  * @vport: main vport structure
+ * @rsrc: pointer to queue and vector resources
  *
  * Return: 0 on success, negative on failure
  */
-static int idpf_vport_intr_req_irq(struct idpf_vport *vport)
+static int idpf_vport_intr_req_irq(struct idpf_vport *vport,
+				   struct idpf_q_vec_rsrc *rsrc)
 {
 	struct idpf_adapter *adapter = vport->adapter;
 	const char *drv_name, *if_name, *vec_name;
@@ -3478,11 +3475,11 @@ static int idpf_vport_intr_req_irq(struc
 	drv_name = dev_driver_string(&adapter->pdev->dev);
 	if_name = netdev_name(vport->netdev);
 
-	for (vector = 0; vector < vport->num_q_vectors; vector++) {
-		struct idpf_q_vector *q_vector = &vport->q_vectors[vector];
+	for (vector = 0; vector < rsrc->num_q_vectors; vector++) {
+		struct idpf_q_vector *q_vector = &rsrc->q_vectors[vector];
 		char *name;
 
-		vidx = vport->q_vector_idxs[vector];
+		vidx = rsrc->q_vector_idxs[vector];
 		irq_num = adapter->msix_entries[vidx].vector;
 
 		if (q_vector->num_rxq && q_vector->num_txq)
@@ -3512,9 +3509,9 @@ static int idpf_vport_intr_req_irq(struc
 
 free_q_irqs:
 	while (--vector >= 0) {
-		vidx = vport->q_vector_idxs[vector];
+		vidx = rsrc->q_vector_idxs[vector];
 		irq_num = adapter->msix_entries[vidx].vector;
-		kfree(free_irq(irq_num, &vport->q_vectors[vector]));
+		kfree(free_irq(irq_num, &rsrc->q_vectors[vector]));
 	}
 
 	return err;
@@ -3543,15 +3540,16 @@ void idpf_vport_intr_write_itr(struct id
 /**
  * idpf_vport_intr_ena_irq_all - Enable IRQ for the given vport
  * @vport: main vport structure
+ * @rsrc: pointer to queue and vector resources
  */
-static void idpf_vport_intr_ena_irq_all(struct idpf_vport *vport)
+static void idpf_vport_intr_ena_irq_all(struct idpf_vport *vport,
+					struct idpf_q_vec_rsrc *rsrc)
 {
 	bool dynamic;
-	int q_idx;
 	u16 itr;
 
-	for (q_idx = 0; q_idx < vport->num_q_vectors; q_idx++) {
-		struct idpf_q_vector *qv = &vport->q_vectors[q_idx];
+	for (u16 q_idx = 0; q_idx < rsrc->num_q_vectors; q_idx++) {
+		struct idpf_q_vector *qv = &rsrc->q_vectors[q_idx];
 
 		/* Set the initial ITR values */
 		if (qv->num_txq) {
@@ -3578,13 +3576,15 @@ static void idpf_vport_intr_ena_irq_all(
 /**
  * idpf_vport_intr_deinit - Release all vector associations for the vport
  * @vport: main vport structure
+ * @rsrc: pointer to queue and vector resources
  */
-void idpf_vport_intr_deinit(struct idpf_vport *vport)
+void idpf_vport_intr_deinit(struct idpf_vport *vport,
+			    struct idpf_q_vec_rsrc *rsrc)
 {
-	idpf_vport_intr_dis_irq_all(vport);
-	idpf_vport_intr_napi_dis_all(vport);
-	idpf_vport_intr_napi_del_all(vport);
-	idpf_vport_intr_rel_irq(vport);
+	idpf_vport_intr_dis_irq_all(rsrc);
+	idpf_vport_intr_napi_dis_all(rsrc);
+	idpf_vport_intr_napi_del_all(rsrc);
+	idpf_vport_intr_rel_irq(vport, rsrc);
 }
 
 /**
@@ -3656,14 +3656,12 @@ static void idpf_init_dim(struct idpf_q_
 
 /**
  * idpf_vport_intr_napi_ena_all - Enable NAPI for all q_vectors in the vport
- * @vport: main vport structure
+ * @rsrc: pointer to queue and vector resources
  */
-static void idpf_vport_intr_napi_ena_all(struct idpf_vport *vport)
+static void idpf_vport_intr_napi_ena_all(struct idpf_q_vec_rsrc *rsrc)
 {
-	int q_idx;
-
-	for (q_idx = 0; q_idx < vport->num_q_vectors; q_idx++) {
-		struct idpf_q_vector *q_vector = &vport->q_vectors[q_idx];
+	for (u16 q_idx = 0; q_idx < rsrc->num_q_vectors; q_idx++) {
+		struct idpf_q_vector *q_vector = &rsrc->q_vectors[q_idx];
 
 		idpf_init_dim(q_vector);
 		napi_enable(&q_vector->napi);
@@ -3792,10 +3790,12 @@ static int idpf_vport_splitq_napi_poll(s
 /**
  * idpf_vport_intr_map_vector_to_qs - Map vectors to queues
  * @vport: virtual port
+ * @rsrc: pointer to queue and vector resources
  *
  * Mapping for vectors to queues
  */
-static void idpf_vport_intr_map_vector_to_qs(struct idpf_vport *vport)
+static void idpf_vport_intr_map_vector_to_qs(struct idpf_vport *vport,
+					     struct idpf_q_vec_rsrc *rsrc)
 {
 	bool split = idpf_is_queue_model_split(vport->rxq_model);
 	u16 num_txq_grp = vport->num_txq_grp;
@@ -3806,7 +3806,7 @@ static void idpf_vport_intr_map_vector_t
 	for (i = 0, qv_idx = 0; i < vport->num_rxq_grp; i++) {
 		u16 num_rxq;
 
-		if (qv_idx >= vport->num_q_vectors)
+		if (qv_idx >= rsrc->num_q_vectors)
 			qv_idx = 0;
 
 		rx_qgrp = &vport->rxq_grps[i];
@@ -3822,7 +3822,7 @@ static void idpf_vport_intr_map_vector_t
 				q = &rx_qgrp->splitq.rxq_sets[j]->rxq;
 			else
 				q = rx_qgrp->singleq.rxqs[j];
-			q->q_vector = &vport->q_vectors[qv_idx];
+			q->q_vector = &rsrc->q_vectors[qv_idx];
 			q_index = q->q_vector->num_rxq;
 			q->q_vector->rx[q_index] = q;
 			q->q_vector->num_rxq++;
@@ -3836,7 +3836,7 @@ static void idpf_vport_intr_map_vector_t
 				struct idpf_buf_queue *bufq;
 
 				bufq = &rx_qgrp->splitq.bufq_sets[j].bufq;
-				bufq->q_vector = &vport->q_vectors[qv_idx];
+				bufq->q_vector = &rsrc->q_vectors[qv_idx];
 				q_index = bufq->q_vector->num_bufq;
 				bufq->q_vector->bufq[q_index] = bufq;
 				bufq->q_vector->num_bufq++;
@@ -3851,7 +3851,7 @@ static void idpf_vport_intr_map_vector_t
 	for (i = 0, qv_idx = 0; i < num_txq_grp; i++) {
 		u16 num_txq;
 
-		if (qv_idx >= vport->num_q_vectors)
+		if (qv_idx >= rsrc->num_q_vectors)
 			qv_idx = 0;
 
 		tx_qgrp = &vport->txq_grps[i];
@@ -3861,14 +3861,14 @@ static void idpf_vport_intr_map_vector_t
 			struct idpf_tx_queue *q;
 
 			q = tx_qgrp->txqs[j];
-			q->q_vector = &vport->q_vectors[qv_idx];
+			q->q_vector = &rsrc->q_vectors[qv_idx];
 			q->q_vector->tx[q->q_vector->num_txq++] = q;
 		}
 
 		if (split) {
 			struct idpf_compl_queue *q = tx_qgrp->complq;
 
-			q->q_vector = &vport->q_vectors[qv_idx];
+			q->q_vector = &rsrc->q_vectors[qv_idx];
 			q->q_vector->complq[q->q_vector->num_complq++] = q;
 		}
 
@@ -3879,12 +3879,14 @@ static void idpf_vport_intr_map_vector_t
 /**
  * idpf_vport_intr_init_vec_idx - Initialize the vector indexes
  * @vport: virtual port
+ * @rsrc: pointer to queue and vector resources
  *
  * Initialize vector indexes with values returned over mailbox.
  *
  * Return: 0 on success, negative on failure
  */
-static int idpf_vport_intr_init_vec_idx(struct idpf_vport *vport)
+static int idpf_vport_intr_init_vec_idx(struct idpf_vport *vport,
+					struct idpf_q_vec_rsrc *rsrc)
 {
 	struct idpf_adapter *adapter = vport->adapter;
 	struct virtchnl2_alloc_vectors *ac;
@@ -3893,8 +3895,8 @@ static int idpf_vport_intr_init_vec_idx(
 
 	ac = adapter->req_vec_chunks;
 	if (!ac) {
-		for (i = 0; i < vport->num_q_vectors; i++)
-			vport->q_vectors[i].v_idx = vport->q_vector_idxs[i];
+		for (i = 0; i < rsrc->num_q_vectors; i++)
+			rsrc->q_vectors[i].v_idx = rsrc->q_vector_idxs[i];
 
 		return 0;
 	}
@@ -3906,8 +3908,8 @@ static int idpf_vport_intr_init_vec_idx(
 
 	idpf_get_vec_ids(adapter, vecids, total_vecs, &ac->vchunks);
 
-	for (i = 0; i < vport->num_q_vectors; i++)
-		vport->q_vectors[i].v_idx = vecids[vport->q_vector_idxs[i]];
+	for (i = 0; i < rsrc->num_q_vectors; i++)
+		rsrc->q_vectors[i].v_idx = vecids[rsrc->q_vector_idxs[i]];
 
 	kfree(vecids);
 
@@ -3917,19 +3919,20 @@ static int idpf_vport_intr_init_vec_idx(
 /**
  * idpf_vport_intr_napi_add_all- Register napi handler for all qvectors
  * @vport: virtual port structure
+ * @rsrc: pointer to queue and vector resources
  */
-static void idpf_vport_intr_napi_add_all(struct idpf_vport *vport)
+static void idpf_vport_intr_napi_add_all(struct idpf_vport *vport,
+					 struct idpf_q_vec_rsrc *rsrc)
 {
 	int (*napi_poll)(struct napi_struct *napi, int budget);
-	u16 v_idx;
 
 	if (idpf_is_queue_model_split(vport->txq_model))
 		napi_poll = idpf_vport_splitq_napi_poll;
 	else
 		napi_poll = idpf_vport_singleq_napi_poll;
 
-	for (v_idx = 0; v_idx < vport->num_q_vectors; v_idx++) {
-		struct idpf_q_vector *q_vector = &vport->q_vectors[v_idx];
+	for (u16 v_idx = 0; v_idx < rsrc->num_q_vectors; v_idx++) {
+		struct idpf_q_vector *q_vector = &rsrc->q_vectors[v_idx];
 
 		netif_napi_add(vport->netdev, &q_vector->napi, napi_poll);
 
@@ -3942,38 +3945,41 @@ static void idpf_vport_intr_napi_add_all
 /**
  * idpf_vport_intr_alloc - Allocate memory for interrupt vectors
  * @vport: virtual port
+ * @rsrc: pointer to queue and vector resources
  *
  * Allocate one q_vector per queue interrupt.
  *
  * Return: 0 on success, if allocation fails we return -ENOMEM.
  */
-int idpf_vport_intr_alloc(struct idpf_vport *vport)
+int idpf_vport_intr_alloc(struct idpf_vport *vport,
+			  struct idpf_q_vec_rsrc *rsrc)
 {
 	u16 txqs_per_vector, rxqs_per_vector, bufqs_per_vector;
 	struct idpf_vport_user_config_data *user_config;
 	struct idpf_q_vector *q_vector;
 	struct idpf_q_coalesce *q_coal;
-	u32 complqs_per_vector, v_idx;
+	u32 complqs_per_vector;
 	u16 idx = vport->idx;
 
 	user_config = &vport->adapter->vport_config[idx]->user_config;
-	vport->q_vectors = kcalloc(vport->num_q_vectors,
-				   sizeof(struct idpf_q_vector), GFP_KERNEL);
-	if (!vport->q_vectors)
+
+	rsrc->q_vectors = kcalloc(rsrc->num_q_vectors,
+				  sizeof(struct idpf_q_vector), GFP_KERNEL);
+	if (!rsrc->q_vectors)
 		return -ENOMEM;
 
 	txqs_per_vector = DIV_ROUND_UP(vport->num_txq_grp,
-				       vport->num_q_vectors);
+				       rsrc->num_q_vectors);
 	rxqs_per_vector = DIV_ROUND_UP(vport->num_rxq_grp,
-				       vport->num_q_vectors);
+				       rsrc->num_q_vectors);
 	bufqs_per_vector = vport->num_bufqs_per_qgrp *
 			   DIV_ROUND_UP(vport->num_rxq_grp,
-					vport->num_q_vectors);
+					rsrc->num_q_vectors);
 	complqs_per_vector = DIV_ROUND_UP(vport->num_txq_grp,
-					  vport->num_q_vectors);
+					  rsrc->num_q_vectors);
 
-	for (v_idx = 0; v_idx < vport->num_q_vectors; v_idx++) {
-		q_vector = &vport->q_vectors[v_idx];
+	for (u16 v_idx = 0; v_idx < rsrc->num_q_vectors; v_idx++) {
+		q_vector = &rsrc->q_vectors[v_idx];
 		q_coal = &user_config->q_coalesce[v_idx];
 		q_vector->vport = vport;
 
@@ -4017,7 +4023,7 @@ int idpf_vport_intr_alloc(struct idpf_vp
 	return 0;
 
 error:
-	idpf_vport_intr_rel(vport);
+	idpf_vport_intr_rel(rsrc);
 
 	return -ENOMEM;
 }
@@ -4025,40 +4031,41 @@ error:
 /**
  * idpf_vport_intr_init - Setup all vectors for the given vport
  * @vport: virtual port
+ * @rsrc: pointer to queue and vector resources
  *
  * Return: 0 on success or negative on failure
  */
-int idpf_vport_intr_init(struct idpf_vport *vport)
+int idpf_vport_intr_init(struct idpf_vport *vport, struct idpf_q_vec_rsrc *rsrc)
 {
 	int err;
 
-	err = idpf_vport_intr_init_vec_idx(vport);
+	err = idpf_vport_intr_init_vec_idx(vport, rsrc);
 	if (err)
 		return err;
 
-	idpf_vport_intr_map_vector_to_qs(vport);
-	idpf_vport_intr_napi_add_all(vport);
+	idpf_vport_intr_map_vector_to_qs(vport, rsrc);
+	idpf_vport_intr_napi_add_all(vport, rsrc);
 
-	err = vport->adapter->dev_ops.reg_ops.intr_reg_init(vport);
+	err = vport->adapter->dev_ops.reg_ops.intr_reg_init(vport, rsrc);
 	if (err)
 		goto unroll_vectors_alloc;
 
-	err = idpf_vport_intr_req_irq(vport);
+	err = idpf_vport_intr_req_irq(vport, rsrc);
 	if (err)
 		goto unroll_vectors_alloc;
 
 	return 0;
 
 unroll_vectors_alloc:
-	idpf_vport_intr_napi_del_all(vport);
+	idpf_vport_intr_napi_del_all(rsrc);
 
 	return err;
 }
 
-void idpf_vport_intr_ena(struct idpf_vport *vport)
+void idpf_vport_intr_ena(struct idpf_vport *vport, struct idpf_q_vec_rsrc *rsrc)
 {
-	idpf_vport_intr_napi_ena_all(vport);
-	idpf_vport_intr_ena_irq_all(vport);
+	idpf_vport_intr_napi_ena_all(rsrc);
+	idpf_vport_intr_ena_irq_all(vport, rsrc);
 }
 
 /**
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.h
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.h
@@ -1011,12 +1011,16 @@ int idpf_vport_calc_total_qs(struct idpf
 void idpf_vport_calc_num_q_groups(struct idpf_vport *vport);
 int idpf_vport_queues_alloc(struct idpf_vport *vport);
 void idpf_vport_queues_rel(struct idpf_vport *vport);
-void idpf_vport_intr_rel(struct idpf_vport *vport);
-int idpf_vport_intr_alloc(struct idpf_vport *vport);
+void idpf_vport_intr_rel(struct idpf_q_vec_rsrc *rsrc);
+int idpf_vport_intr_alloc(struct idpf_vport *vport,
+			  struct idpf_q_vec_rsrc *rsrc);
 void idpf_vport_intr_update_itr_ena_irq(struct idpf_q_vector *q_vector);
-void idpf_vport_intr_deinit(struct idpf_vport *vport);
-int idpf_vport_intr_init(struct idpf_vport *vport);
-void idpf_vport_intr_ena(struct idpf_vport *vport);
+void idpf_vport_intr_deinit(struct idpf_vport *vport,
+			    struct idpf_q_vec_rsrc *rsrc);
+int idpf_vport_intr_init(struct idpf_vport *vport,
+			 struct idpf_q_vec_rsrc *rsrc);
+void idpf_vport_intr_ena(struct idpf_vport *vport,
+			 struct idpf_q_vec_rsrc *rsrc);
 void idpf_fill_dflt_rss_lut(struct idpf_vport *vport);
 int idpf_config_rss(struct idpf_vport *vport);
 int idpf_init_rss_lut(struct idpf_vport *vport);
--- a/drivers/net/ethernet/intel/idpf/idpf_vf_dev.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_vf_dev.c
@@ -66,11 +66,13 @@ static void idpf_vf_mb_intr_reg_init(str
 /**
  * idpf_vf_intr_reg_init - Initialize interrupt registers
  * @vport: virtual port structure
+ * @rsrc: pointer to queue and vector resources
  */
-static int idpf_vf_intr_reg_init(struct idpf_vport *vport)
+static int idpf_vf_intr_reg_init(struct idpf_vport *vport,
+				 struct idpf_q_vec_rsrc *rsrc)
 {
 	struct idpf_adapter *adapter = vport->adapter;
-	int num_vecs = vport->num_q_vectors;
+	u16 num_vecs = rsrc->num_q_vectors;
 	struct idpf_vec_regs *reg_vals;
 	int num_regs, i, err = 0;
 	u32 rx_itr, tx_itr;
@@ -89,8 +91,8 @@ static int idpf_vf_intr_reg_init(struct
 	}
 
 	for (i = 0; i < num_vecs; i++) {
-		struct idpf_q_vector *q_vector = &vport->q_vectors[i];
-		u16 vec_id = vport->q_vector_idxs[i] - IDPF_MBX_Q_VEC;
+		struct idpf_q_vector *q_vector = &rsrc->q_vectors[i];
+		u16 vec_id = rsrc->q_vector_idxs[i] - IDPF_MBX_Q_VEC;
 		struct idpf_intr_reg *intr = &q_vector->intr_reg;
 		u32 spacing;
 
--- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c
@@ -1993,6 +1993,7 @@ int idpf_send_enable_queues_msg(struct i
  */
 int idpf_send_disable_queues_msg(struct idpf_vport *vport)
 {
+	struct idpf_q_vec_rsrc *rsrc = &vport->dflt_qv_rsrc;
 	int err, i;
 
 	err = idpf_send_ena_dis_queues_msg(vport, false);
@@ -2007,8 +2008,8 @@ int idpf_send_disable_queues_msg(struct
 
 	/* schedule the napi to receive all the marker packets */
 	local_bh_disable();
-	for (i = 0; i < vport->num_q_vectors; i++)
-		napi_schedule(&vport->q_vectors[i].napi);
+	for (u16 i = 0; i < rsrc->num_q_vectors; i++)
+		napi_schedule(&rsrc->q_vectors[i].napi);
 	local_bh_enable();
 
 	return idpf_wait_for_marker_event(vport);
@@ -3118,25 +3119,27 @@ void idpf_vc_core_deinit(struct idpf_ada
 /**
  * idpf_vport_alloc_vec_indexes - Get relative vector indexes
  * @vport: virtual port data struct
+ * @rsrc: pointer to queue and vector resources
  *
  * This function requests the vector information required for the vport and
  * stores the vector indexes received from the 'global vector distribution'
  * in the vport's queue vectors array.
  *
- * Return 0 on success, error on failure
+ * Return: 0 on success, error on failure
  */
-int idpf_vport_alloc_vec_indexes(struct idpf_vport *vport)
+int idpf_vport_alloc_vec_indexes(struct idpf_vport *vport,
+				 struct idpf_q_vec_rsrc *rsrc)
 {
 	struct idpf_vector_info vec_info;
 	int num_alloc_vecs;
 
-	vec_info.num_curr_vecs = vport->num_q_vectors;
+	vec_info.num_curr_vecs = rsrc->num_q_vectors;
 	vec_info.num_req_vecs = max(vport->num_txq, vport->num_rxq);
 	vec_info.default_vport = vport->default_vport;
 	vec_info.index = vport->idx;
 
 	num_alloc_vecs = idpf_req_rel_vector_indexes(vport->adapter,
-						     vport->q_vector_idxs,
+						     rsrc->q_vector_idxs,
 						     &vec_info);
 	if (num_alloc_vecs <= 0) {
 		dev_err(&vport->adapter->pdev->dev, "Vector distribution failed: %d\n",
@@ -3144,7 +3147,7 @@ int idpf_vport_alloc_vec_indexes(struct
 		return -EINVAL;
 	}
 
-	vport->num_q_vectors = num_alloc_vecs;
+	rsrc->num_q_vectors = num_alloc_vecs;
 
 	return 0;
 }
@@ -3158,6 +3161,7 @@ int idpf_vport_alloc_vec_indexes(struct
  */
 void idpf_vport_init(struct idpf_vport *vport, struct idpf_vport_max_q *max_q)
 {
+	struct idpf_q_vec_rsrc *rsrc = &vport->dflt_qv_rsrc;
 	struct idpf_adapter *adapter = vport->adapter;
 	struct virtchnl2_create_vport *vport_msg;
 	struct idpf_vport_config *vport_config;
@@ -3196,7 +3200,7 @@ void idpf_vport_init(struct idpf_vport *
 	idpf_vport_init_num_qs(vport, vport_msg);
 	idpf_vport_calc_num_q_desc(vport);
 	idpf_vport_calc_num_q_groups(vport);
-	idpf_vport_alloc_vec_indexes(vport);
+	idpf_vport_alloc_vec_indexes(vport, rsrc);
 
 	vport->crc_enable = adapter->crc_enable;
 }
--- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h
+++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.h
@@ -45,7 +45,8 @@ int idpf_send_enable_queues_msg(struct i
 int idpf_send_disable_queues_msg(struct idpf_vport *vport);
 int idpf_send_config_queues_msg(struct idpf_vport *vport);
 
-int idpf_vport_alloc_vec_indexes(struct idpf_vport *vport);
+int idpf_vport_alloc_vec_indexes(struct idpf_vport *vport,
+				 struct idpf_q_vec_rsrc *rsrc);
 int idpf_get_vec_ids(struct idpf_adapter *adapter,
 		     u16 *vecids, int num_vecids,
 		     struct virtchnl2_vector_chunks *chunks);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 745/877] idpf: disable DIM work before freeing q_vectors
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (743 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 744/877] idpf: introduce idpf_q_vec_rsrc struct and move vector resources to it Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 746/877] ipv4: remove fib_devindex_hashfn() Greg Kroah-Hartman
                   ` (139 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak,
	Samuel Salin, Tony Nguyen, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Myeonghun Pak <mhun512@gmail.com>

[ Upstream commit 7dd4c829bac2916be98a3e34b41daaba7f42b4c4 ]

idpf never drains the Tx/Rx DIM works before freeing the memory they
live in.  tx_dim and rx_dim are embedded in struct idpf_q_vector, they
are queued from the NAPI poll via net_dim(), and idpf_vport_intr_rel()
ends with kfree(rsrc->q_vectors).  Nothing in the driver cancels them.

idpf_tx_dim_work() and idpf_rx_dim_work() then run on freed memory:
idpf_vport_intr_write_itr() writes the ITR register through
q_vector->intr_reg.tx_itr / rx_itr, void __iomem pointers loaded out of
the freed q_vector.  No configuration is needed to get there --
IDPF_ITR_IS_DYNAMIC() is defined as (itr_mode) and idpf_vport_alloc()
initialises both modes to IDPF_ITR_DYNAMIC.

Draining after idpf_vport_intr_napi_dis_all() is not enough on its own.
idpf_net_dim() is called from inside the
"if (napi_complete_done(napi, work_done))" branch of the poll, and
napi_complete_done() has already cleared NAPIF_STATE_SCHED by then.
napi_disable_locked() waits only while (val & (NAPIF_STATE_SCHED |
NAPIF_STATE_NPSVC)), so napi_disable() can return while the poll tail is
still queueing the work, and a plain cancel_work_sync() would be
re-armed behind the drain.

Use disable_work_sync(): schedule_work() on a work with a non-zero
disable count is dropped by clear_pending_if_disabled() before
__queue_work() is reached.

Move idpf_init_dim() to idpf_vport_intr_alloc() so the works are
initialised on every path that can reach the drain -- the three
"goto intr_deinit" sites between idpf_vport_intr_init() and
idpf_vport_intr_ena() get there without the enable side having run.
Nothing re-enables them: rsrc->q_vectors is freed on every exit from
idpf_vport_open() and on every idpf_vport_stop(), so the count dies with
the object.

It is a race, not a deterministic failure -- net_dim() only schedules
once DIM_NEVENTS events have accumulated and the profile index changes.
A KASAN ifup/ifdown loop under load is the way to see it.

Fixes: c2d548cad150 ("idpf: add TX splitq napi poll support")
Fixes: 3a8845af66ed ("idpf: add RX splitq napi poll support")
Cc: <stable@vger.kernel.org> # see patch description, needs adjustments for <= 6.9
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Tested-by: Samuel Salin <Samuel.salin@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/intel/idpf/idpf_txrx.c |   24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
@@ -3574,6 +3574,26 @@ static void idpf_vport_intr_ena_irq_all(
 }
 
 /**
+ * idpf_vport_intr_dis_dim_all - Disable DIM work for all q_vectors
+ * @rsrc: pointer to queue and vector resources
+ *
+ * The DIM works are embedded in the q_vector array that
+ * idpf_vport_intr_rel() frees, and the poll arms them after
+ * napi_complete_done() has already cleared NAPI_STATE_SCHED.  Disable
+ * rather than just cancel, so that a poll tail still running past
+ * napi_disable() cannot queue them again behind the drain.
+ */
+static void idpf_vport_intr_dis_dim_all(struct idpf_q_vec_rsrc *rsrc)
+{
+	for (u16 v_idx = 0; v_idx < rsrc->num_q_vectors; v_idx++) {
+		struct idpf_q_vector *q_vector = &rsrc->q_vectors[v_idx];
+
+		disable_work_sync(&q_vector->tx_dim.work);
+		disable_work_sync(&q_vector->rx_dim.work);
+	}
+}
+
+/**
  * idpf_vport_intr_deinit - Release all vector associations for the vport
  * @vport: main vport structure
  * @rsrc: pointer to queue and vector resources
@@ -3583,6 +3603,7 @@ void idpf_vport_intr_deinit(struct idpf_
 {
 	idpf_vport_intr_dis_irq_all(rsrc);
 	idpf_vport_intr_napi_dis_all(rsrc);
+	idpf_vport_intr_dis_dim_all(rsrc);
 	idpf_vport_intr_napi_del_all(rsrc);
 	idpf_vport_intr_rel_irq(vport, rsrc);
 }
@@ -3663,7 +3684,6 @@ static void idpf_vport_intr_napi_ena_all
 	for (u16 q_idx = 0; q_idx < rsrc->num_q_vectors; q_idx++) {
 		struct idpf_q_vector *q_vector = &rsrc->q_vectors[q_idx];
 
-		idpf_init_dim(q_vector);
 		napi_enable(&q_vector->napi);
 	}
 }
@@ -3983,6 +4003,8 @@ int idpf_vport_intr_alloc(struct idpf_vp
 		q_coal = &user_config->q_coalesce[v_idx];
 		q_vector->vport = vport;
 
+		idpf_init_dim(q_vector);
+
 		q_vector->tx_itr_value = q_coal->tx_coalesce_usecs;
 		q_vector->tx_intr_mode = q_coal->tx_intr_mode;
 		q_vector->tx_itr_idx = VIRTCHNL2_ITR_IDX_1;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 746/877] ipv4: remove fib_devindex_hashfn()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (744 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 745/877] idpf: disable DIM work before freeing q_vectors Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-10-01 20:24   ` Harshit Mogalapalli
  2026-09-30 15:27 ` [PATCH 6.12 747/877] ipv4: use rcu in ip_fib_check_default() Greg Kroah-Hartman
                   ` (138 subsequent siblings)
  884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Kuniyuki Iwashima,
	David Ahern, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit 8a0f62fdeb9ea66ad3d0e959c7c4addbabeac1be ]

fib_devindex_hashfn() converts a 32bit ifindex value to a 8bit hash.

It makes no sense doing this from fib_info_hashfn() and
fib_find_info_nh().

It is better to keep as many bits as possible to let
fib_info_hashfn_result() have better spread.

Only fib_info_devhash_bucket() needs to make this operation,
we can 'inline' trivial fib_devindex_hashfn() in it.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20241004134720.579244-2-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 8d6cd1885085 ("ipv6: flowlabel: cap duplicate leases per socket")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv4/fib_semantics.c |   13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -322,17 +322,12 @@ static inline int nh_comp(struct fib_inf
 	return 0;
 }
 
-static inline unsigned int fib_devindex_hashfn(unsigned int val)
-{
-	return hash_32(val, DEVINDEX_HASHBITS);
-}
-
 static struct hlist_head *
 fib_info_devhash_bucket(const struct net_device *dev)
 {
 	u32 val = net_hash_mix(dev_net(dev)) ^ dev->ifindex;
 
-	return &fib_info_devhash[fib_devindex_hashfn(val)];
+	return &fib_info_devhash[hash_32(val, DEVINDEX_HASHBITS)];
 }
 
 static unsigned int fib_info_hashfn_1(int init_val, u8 protocol, u8 scope,
@@ -363,10 +358,10 @@ static inline unsigned int fib_info_hash
 				fi->fib_priority);
 
 	if (fi->nh) {
-		val ^= fib_devindex_hashfn(fi->nh->id);
+		val ^= fi->nh->id;
 	} else {
 		for_nexthops(fi) {
-			val ^= fib_devindex_hashfn(nh->fib_nh_oif);
+			val ^= nh->fib_nh_oif;
 		} endfor_nexthops(fi)
 	}
 
@@ -381,7 +376,7 @@ static struct fib_info *fib_find_info_nh
 	struct fib_info *fi;
 	unsigned int hash;
 
-	hash = fib_info_hashfn_1(fib_devindex_hashfn(cfg->fc_nh_id),
+	hash = fib_info_hashfn_1(cfg->fc_nh_id,
 				 cfg->fc_protocol, cfg->fc_scope,
 				 (__force u32)cfg->fc_prefsrc,
 				 cfg->fc_priority);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 747/877] ipv4: use rcu in ip_fib_check_default()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (745 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 746/877] ipv4: remove fib_devindex_hashfn() Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 748/877] ipv4: remove fib_info_devhash[] Greg Kroah-Hartman
                   ` (137 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Kuniyuki Iwashima,
	David Ahern, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit fc38b28365e5f1396209d2878a34065468765087 ]

fib_info_devhash[] is not resized in fib_info_hash_move().

fib_nh structs are already freed after an rcu grace period.

This will allow to remove fib_info_lock in the following patch.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20241004134720.579244-3-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 8d6cd1885085 ("ipv6: flowlabel: cap duplicate leases per socket")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv4/fib_semantics.c |   13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -275,7 +275,7 @@ void fib_release_info(struct fib_info *f
 			change_nexthops(fi) {
 				if (!nexthop_nh->fib_nh_dev)
 					continue;
-				hlist_del(&nexthop_nh->nh_hash);
+				hlist_del_rcu(&nexthop_nh->nh_hash);
 			} endfor_nexthops(fi)
 		}
 		/* Paired with READ_ONCE() from fib_table_lookup() */
@@ -432,28 +432,23 @@ static struct fib_info *fib_find_info(st
 }
 
 /* Check, that the gateway is already configured.
- * Used only by redirect accept routine.
+ * Used only by redirect accept routine, under rcu_read_lock();
  */
 int ip_fib_check_default(__be32 gw, struct net_device *dev)
 {
 	struct hlist_head *head;
 	struct fib_nh *nh;
 
-	spin_lock(&fib_info_lock);
-
 	head = fib_info_devhash_bucket(dev);
 
-	hlist_for_each_entry(nh, head, nh_hash) {
+	hlist_for_each_entry_rcu(nh, head, nh_hash) {
 		if (nh->fib_nh_dev == dev &&
 		    nh->fib_nh_gw4 == gw &&
 		    !(nh->fib_nh_flags & RTNH_F_DEAD)) {
-			spin_unlock(&fib_info_lock);
 			return 0;
 		}
 	}
 
-	spin_unlock(&fib_info_lock);
-
 	return -1;
 }
 
@@ -1638,7 +1633,7 @@ link_it:
 			if (!nexthop_nh->fib_nh_dev)
 				continue;
 			head = fib_info_devhash_bucket(nexthop_nh->fib_nh_dev);
-			hlist_add_head(&nexthop_nh->nh_hash, head);
+			hlist_add_head_rcu(&nexthop_nh->nh_hash, head);
 		} endfor_nexthops(fi)
 	}
 	spin_unlock_bh(&fib_info_lock);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 748/877] ipv4: remove fib_info_devhash[]
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (746 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 747/877] ipv4: use rcu in ip_fib_check_default() Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 749/877] ipv6: make ipv6_pinfo.saddr_cache a boolean Greg Kroah-Hartman
                   ` (136 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Kuniyuki Iwashima,
	David Ahern, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit a3f5f4c2f9b6bc2aa6f5a3e8e23b7519e4f2e3e3 ]

Upcoming per-netns RTNL conversion needs to get rid
of shared hash tables.

fib_info_devhash[] is one of them.

It is unclear why we used a hash table, because
a single hlist_head per net device was cheaper and scalable.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20241004134720.579244-5-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 8d6cd1885085 ("ipv6: flowlabel: cap duplicate leases per socket")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/networking/net_cachelines/net_device.rst |    1 
 include/linux/netdevice.h                              |    3 +
 net/ipv4/fib_semantics.c                               |   35 +++++++----------
 3 files changed, 19 insertions(+), 20 deletions(-)

--- a/Documentation/networking/net_cachelines/net_device.rst
+++ b/Documentation/networking/net_cachelines/net_device.rst
@@ -83,6 +83,7 @@ unsigned_int                        allm
 bool                                uc_promisc                                                      
 unsigned_char                       nested_level                                                    
 struct_in_device*                   ip_ptr                  read_mostly         read_mostly         __in_dev_get
+struct hlist_head                   fib_nh_head
 struct_inet6_dev*                   ip6_ptr                 read_mostly         read_mostly         __in6_dev_get
 struct_vlan_info*                   vlan_info                                                       
 struct_dsa_port*                    dsa_ptr                                                         
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2217,6 +2217,9 @@ struct net_device {
 
 	/* Protocol-specific pointers */
 	struct in_device __rcu	*ip_ptr;
+	/** @fib_nh_head: nexthops associated with this netdev */
+	struct hlist_head	fib_nh_head;
+
 #if IS_ENABLED(CONFIG_VLAN_8021Q)
 	struct vlan_info __rcu	*vlan_info;
 #endif
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -57,10 +57,6 @@ static unsigned int fib_info_hash_size;
 static unsigned int fib_info_hash_bits;
 static unsigned int fib_info_cnt;
 
-#define DEVINDEX_HASHBITS 8
-#define DEVINDEX_HASHSIZE (1U << DEVINDEX_HASHBITS)
-static struct hlist_head fib_info_devhash[DEVINDEX_HASHSIZE];
-
 /* for_nexthops and change_nexthops only used when nexthop object
  * is not set in a fib_info. The logic within can reference fib_nh.
  */
@@ -322,12 +318,9 @@ static inline int nh_comp(struct fib_inf
 	return 0;
 }
 
-static struct hlist_head *
-fib_info_devhash_bucket(const struct net_device *dev)
+static struct hlist_head *fib_nh_head(struct net_device *dev)
 {
-	u32 val = net_hash_mix(dev_net(dev)) ^ dev->ifindex;
-
-	return &fib_info_devhash[hash_32(val, DEVINDEX_HASHBITS)];
+	return &dev->fib_nh_head;
 }
 
 static unsigned int fib_info_hashfn_1(int init_val, u8 protocol, u8 scope,
@@ -439,11 +432,11 @@ int ip_fib_check_default(__be32 gw, stru
 	struct hlist_head *head;
 	struct fib_nh *nh;
 
-	head = fib_info_devhash_bucket(dev);
+	head = fib_nh_head(dev);
 
 	hlist_for_each_entry_rcu(nh, head, nh_hash) {
-		if (nh->fib_nh_dev == dev &&
-		    nh->fib_nh_gw4 == gw &&
+		DEBUG_NET_WARN_ON_ONCE(nh->fib_nh_dev != dev);
+		if (nh->fib_nh_gw4 == gw &&
 		    !(nh->fib_nh_flags & RTNH_F_DEAD)) {
 			return 0;
 		}
@@ -1632,7 +1625,7 @@ link_it:
 
 			if (!nexthop_nh->fib_nh_dev)
 				continue;
-			head = fib_info_devhash_bucket(nexthop_nh->fib_nh_dev);
+			head = fib_nh_head(nexthop_nh->fib_nh_dev);
 			hlist_add_head_rcu(&nexthop_nh->nh_hash, head);
 		} endfor_nexthops(fi)
 	}
@@ -1974,12 +1967,12 @@ out:
 
 void fib_sync_mtu(struct net_device *dev, u32 orig_mtu)
 {
-	struct hlist_head *head = fib_info_devhash_bucket(dev);
+	struct hlist_head *head = fib_nh_head(dev);
 	struct fib_nh *nh;
 
 	hlist_for_each_entry(nh, head, nh_hash) {
-		if (nh->fib_nh_dev == dev)
-			fib_nhc_update_mtu(&nh->nh_common, dev->mtu, orig_mtu);
+		DEBUG_NET_WARN_ON_ONCE(nh->fib_nh_dev != dev);
+		fib_nhc_update_mtu(&nh->nh_common, dev->mtu, orig_mtu);
 	}
 }
 
@@ -1993,7 +1986,7 @@ void fib_sync_mtu(struct net_device *dev
  */
 int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force)
 {
-	struct hlist_head *head = fib_info_devhash_bucket(dev);
+	struct hlist_head *head = fib_nh_head(dev);
 	struct fib_info *prev_fi = NULL;
 	int scope = RT_SCOPE_NOWHERE;
 	struct fib_nh *nh;
@@ -2007,7 +2000,8 @@ int fib_sync_down_dev(struct net_device
 		int dead;
 
 		BUG_ON(!fi->fib_nhs);
-		if (nh->fib_nh_dev != dev || fi == prev_fi)
+		DEBUG_NET_WARN_ON_ONCE(nh->fib_nh_dev != dev);
+		if (fi == prev_fi)
 			continue;
 		prev_fi = fi;
 		dead = 0;
@@ -2157,7 +2151,7 @@ int fib_sync_up(struct net_device *dev,
 	}
 
 	prev_fi = NULL;
-	head = fib_info_devhash_bucket(dev);
+	head = fib_nh_head(dev);
 	ret = 0;
 
 	hlist_for_each_entry(nh, head, nh_hash) {
@@ -2165,7 +2159,8 @@ int fib_sync_up(struct net_device *dev,
 		int alive;
 
 		BUG_ON(!fi->fib_nhs);
-		if (nh->fib_nh_dev != dev || fi == prev_fi)
+		DEBUG_NET_WARN_ON_ONCE(nh->fib_nh_dev != dev);
+		if (fi == prev_fi)
 			continue;
 
 		prev_fi = fi;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 749/877] ipv6: make ipv6_pinfo.saddr_cache a boolean
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (747 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 748/877] ipv4: remove fib_info_devhash[] Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 750/877] ipv6: reorganise struct ipv6_pinfo Greg Kroah-Hartman
                   ` (135 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Willem de Bruijn,
	David Ahern, Kuniyuki Iwashima, Jakub Kicinski, Paolo Abeni,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit 3fbb2a6f3a70c27a6a2be80d131970608c0f84d0 ]

ipv6_pinfo.saddr_cache is either NULL or &np->saddr.

We do not need 8 bytes, a boolean is enough.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250916160951.541279-2-edumazet@google.com
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Stable-dep-of: 8d6cd1885085 ("ipv6: flowlabel: cap duplicate leases per socket")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/linux/ipv6.h             |    4 ++--
 include/net/ip6_route.h          |    4 ++--
 net/ipv6/af_inet6.c              |    2 +-
 net/ipv6/inet6_connection_sock.c |    2 +-
 net/ipv6/ip6_output.c            |    3 ++-
 net/ipv6/route.c                 |    4 ++--
 net/ipv6/tcp_ipv6.c              |    4 ++--
 7 files changed, 12 insertions(+), 11 deletions(-)

--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -214,10 +214,10 @@ struct inet6_cork {
 struct ipv6_pinfo {
 	struct in6_addr 	saddr;
 	struct in6_pktinfo	sticky_pktinfo;
-	const struct in6_addr		*daddr_cache;
 #ifdef CONFIG_IPV6_SUBTREES
-	const struct in6_addr		*saddr_cache;
+	bool			saddr_cache;
 #endif
+	const struct in6_addr		*daddr_cache;
 
 	__be32			flow_label;
 	__u32			frag_size;
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -230,7 +230,7 @@ static inline const struct rt6_info *skb
  */
 static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
 				 const struct in6_addr *daddr,
-				 const struct in6_addr *saddr)
+				 bool saddr_set)
 {
 	struct ipv6_pinfo *np = inet6_sk(sk);
 
@@ -238,7 +238,7 @@ static inline void ip6_dst_store(struct
 	sk_setup_caps(sk, dst);
 	np->daddr_cache = daddr;
 #ifdef CONFIG_IPV6_SUBTREES
-	np->saddr_cache = saddr;
+	np->saddr_cache = saddr_set;
 #endif
 }
 
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -856,7 +856,7 @@ int inet6_sk_rebuild_header(struct sock
 			return PTR_ERR(dst);
 		}
 
-		ip6_dst_store(sk, dst, NULL, NULL);
+		ip6_dst_store(sk, dst, NULL, false);
 	}
 
 	return 0;
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -106,7 +106,7 @@ static struct dst_entry *inet6_csk_route
 		dst = ip6_dst_lookup_flow(sock_net(sk), sk, fl6, final_p);
 
 		if (!IS_ERR(dst))
-			ip6_dst_store(sk, dst, NULL, NULL);
+			ip6_dst_store(sk, dst, NULL, false);
 	}
 	return dst;
 }
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1103,7 +1103,8 @@ static struct dst_entry *ip6_sk_dst_chec
 	 */
 	if (ip6_rt_check(&rt->rt6i_dst, &fl6->daddr, np->daddr_cache) ||
 #ifdef CONFIG_IPV6_SUBTREES
-	    ip6_rt_check(&rt->rt6i_src, &fl6->saddr, np->saddr_cache) ||
+	    ip6_rt_check(&rt->rt6i_src, &fl6->saddr,
+			 np->saddr_cache ? &np->saddr : NULL) ||
 #endif
 	   (fl6->flowi6_oif && fl6->flowi6_oif != dst_dev(dst)->ifindex)) {
 		dst_release(dst);
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -3049,9 +3049,9 @@ void ip6_sk_dst_store_flow(struct sock *
 		      &sk->sk_v6_daddr : NULL,
 #ifdef CONFIG_IPV6_SUBTREES
 		      ipv6_addr_equal(&fl6->saddr, &np->saddr) ?
-		      &np->saddr :
+		      true :
 #endif
-		      NULL);
+		      false);
 }
 
 static bool ip6_redirect_nh_match(const struct fib6_result *res,
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -293,7 +293,7 @@ static int tcp_v6_connect(struct sock *s
 	inet->inet_rcv_saddr = LOOPBACK4_IPV6;
 
 	sk->sk_gso_type = SKB_GSO_TCPV6;
-	ip6_dst_store(sk, dst, NULL, NULL);
+	ip6_dst_store(sk, dst, NULL, false);
 
 	icsk->icsk_ext_hdr_len = 0;
 	if (opt)
@@ -1435,7 +1435,7 @@ static struct sock *tcp_v6_syn_recv_sock
 
 	memcpy(newnp, np, sizeof(struct ipv6_pinfo));
 
-	ip6_dst_store(newsk, dst, NULL, NULL);
+	ip6_dst_store(newsk, dst, NULL, false);
 
 	newsk->sk_v6_daddr = ireq->ir_v6_rmt_addr;
 	newnp->saddr = ireq->ir_v6_loc_addr;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 750/877] ipv6: reorganise struct ipv6_pinfo
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (748 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 749/877] ipv6: make ipv6_pinfo.saddr_cache a boolean Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 751/877] ipv6: Move ipv6_fl_list from ipv6_pinfo to inet_sock Greg Kroah-Hartman
                   ` (134 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Willem de Bruijn,
	David Ahern, Kuniyuki Iwashima, Jakub Kicinski, Paolo Abeni,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit b76543b21fbcfbb96332fd80cc0d85bbcd72d8f0 ]

Move fields used in tx fast path at the beginning of the structure,
and seldom used ones at the end.

Note that rxopt is also in the first cache line.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20250916160951.541279-5-edumazet@google.com
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Stable-dep-of: 8d6cd1885085 ("ipv6: flowlabel: cap duplicate leases per socket")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/linux/ipv6.h |   33 ++++++++++++++++-----------------
 1 file changed, 16 insertions(+), 17 deletions(-)

--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -212,18 +212,21 @@ struct inet6_cork {
 
 /* struct ipv6_pinfo - ipv6 private area */
 struct ipv6_pinfo {
+	/* Used in tx path (inet6_csk_route_socket(), ip6_xmit()) */
 	struct in6_addr 	saddr;
-	struct in6_pktinfo	sticky_pktinfo;
+	__be32			flow_label;
+	u32			dst_cookie;
+	struct ipv6_txoptions __rcu	*opt;
+	s16			hop_limit;
+	u8			pmtudisc;
+	u8			tclass;
 #ifdef CONFIG_IPV6_SUBTREES
 	bool			saddr_cache;
 #endif
 	const struct in6_addr		*daddr_cache;
 
-	__be32			flow_label;
-	__u32			frag_size;
-
-	s16			hop_limit;
 	u8			mcast_hops;
+	u32			frag_size;
 
 	int			ucast_oif;
 	int			mcast_oif;
@@ -231,7 +234,7 @@ struct ipv6_pinfo {
 	/* pktoption flags */
 	union {
 		struct {
-			__u16	srcrt:1,
+			u16	srcrt:1,
 				osrcrt:1,
 			        rxinfo:1,
 			        rxoinfo:1,
@@ -248,29 +251,25 @@ struct ipv6_pinfo {
 				recvfragsize:1;
 				/* 1 bits hole */
 		} bits;
-		__u16		all;
+		u16		all;
 	} rxopt;
 
 	/* sockopt flags */
-	__u8			srcprefs;	/* 001: prefer temporary address
+	u8			srcprefs;	/* 001: prefer temporary address
 						 * 010: prefer public address
 						 * 100: prefer care-of address
 						 */
-	__u8			pmtudisc;
-	__u8			min_hopcount;
-	__u8			tclass;
+	u8			min_hopcount;
 	__be32			rcv_flowinfo;
+	struct in6_pktinfo	sticky_pktinfo;
 
-	__u32			dst_cookie;
+	struct sk_buff		*pktoptions;
+	struct sk_buff		*rxpmtu;
+	struct inet6_cork	cork;
 
 	struct ipv6_mc_socklist	__rcu *ipv6_mc_list;
 	struct ipv6_ac_socklist	*ipv6_ac_list;
 	struct ipv6_fl_socklist __rcu *ipv6_fl_list;
-
-	struct ipv6_txoptions __rcu	*opt;
-	struct sk_buff		*pktoptions;
-	struct sk_buff		*rxpmtu;
-	struct inet6_cork	cork;
 };
 
 /* We currently use available bits from inet_sk(sk)->inet_flags,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 751/877] ipv6: Move ipv6_fl_list from ipv6_pinfo to inet_sock.
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (749 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 750/877] ipv6: reorganise struct ipv6_pinfo Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 752/877] ipv6: flowlabel: cap duplicate leases per socket Greg Kroah-Hartman
                   ` (133 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Kuniyuki Iwashima,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Kuniyuki Iwashima <kuniyu@google.com>

[ Upstream commit 1c17f4373d4db1e1f0ebd3ddcd8e7a642927a826 ]

In {tcp6,udp6,raw6}_sock, struct ipv6_pinfo is always placed at
the beginning of a new cache line because

  1. __alignof__(struct tcp_sock) is 64 due to ____cacheline_aligned
     of __cacheline_group_begin(tcp_sock_write_tx)

  2. __alignof__(struct udp_sock) is 64 due to ____cacheline_aligned
     of struct numa_drop_counters

  3. in raw6_sock, struct numa_drop_counters is placed before
     struct ipv6_pinfo

.  struct ipv6_pinfo is 136 bytes, but the last cache line is
only used by ipv6_fl_list:

  $ pahole -C ipv6_pinfo vmlinux
  struct ipv6_pinfo {
  ...
  	/* --- cacheline 2 boundary (128 bytes) --- */
  	struct ipv6_fl_socklist *  ipv6_fl_list;         /*   128     8 */

  	/* size: 136, cachelines: 3, members: 23 */

Let's move ipv6_fl_list from struct ipv6_pinfo to struct inet_sock
to save a full cache line for {tcp6,udp6,raw6}_sock.

Now, struct ipv6_pinfo is 128 bytes, and {tcp6,udp6,raw6}_sock have
64 bytes less, while {tcp,udp,raw}_sock retain the same size.

Before:

  # grep -E "^(RAW|UDP[^L\-]|TCP)" /proc/slabinfo | awk '{print $1, "\t", $4}'
  RAWv6 	 1408
  UDPv6 	 1472
  TCPv6 	 2560
  RAW 		 1152
  UDP	 	 1280
  TCP 		 2368

After:

  # grep -E "^(RAW|UDP[^L\-]|TCP)" /proc/slabinfo | awk '{print $1, "\t", $4}'
  RAWv6 	 1344
  UDPv6 	 1408
  TCPv6 	 2496
  RAW 		 1152
  UDP	 	 1280
  TCP 		 2368

Also, ipv6_fl_list and inet_flags (SNDFLOW bit) are placed in the
same cache line.

  $ pahole -C inet_sock vmlinux
  ...
  	/* --- cacheline 11 boundary (704 bytes) was 56 bytes ago --- */
  	struct ipv6_pinfo *        pinet6;               /*   760     8 */
  	/* --- cacheline 12 boundary (768 bytes) --- */
  	struct ipv6_fl_socklist *  ipv6_fl_list;         /*   768     8 */
  	unsigned long              inet_flags;           /*   776     8 */

Doc churn is due to the insufficient Type column (only 1 space short).

Suggested-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20251014224210.2964778-1-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Stable adaptation:

Keep the stable TCP mapped-child initialization callback introduced by
9ed654e340f4c ("tcp: fix potential race in tcp_v6_syn_recv_sock()") and
reset the relocated flowlabel list in that existing helper. Update both
DCCP child paths too, since DCCP is still present in this tree. Preserve
the existing cacheline-documentation format and add only the new field.

Name the existing unprivileged total limit in mem_check() and use it in
an algebraically equivalent room check. This supplies the context needed
by 8d6cd1885085 ("ipv6: flowlabel: cap duplicate leases per socket")
without importing the later per-netns accounting or changing admission
policy. No new functions are introduced by this dependency.

Stable-dep-of: 8d6cd1885085 ("ipv6: flowlabel: cap duplicate leases per socket")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/networking/net_cachelines/inet_sock.rst       |    1 
 drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c |    4 -
 include/linux/ipv6.h                                        |    1 
 include/net/inet_sock.h                                     |    1 
 net/dccp/ipv6.c                                             |    4 -
 net/ipv6/ip6_flowlabel.c                                    |   48 ++++++------
 net/ipv6/tcp_ipv6.c                                         |   10 +-
 net/sctp/ipv6.c                                             |    8 +-
 8 files changed, 40 insertions(+), 37 deletions(-)

--- a/Documentation/networking/net_cachelines/inet_sock.rst
+++ b/Documentation/networking/net_cachelines/inet_sock.rst
@@ -9,6 +9,7 @@ Type                    Name
 ..struct                ..inet_sock                                                     
 struct_sock             sk                    read_mostly         read_mostly         tcp_init_buffer_space,tcp_init_transfer,tcp_finish_connect,tcp_connect,tcp_send_rcvq,tcp_send_syn_data
 struct_ipv6_pinfo*      pinet6                -                   -                   
+struct_ipv6_fl_socklist* ipv6_fl_list         read_mostly         -                   tcp_v6_connect,__ip6_datagram_connect,udpv6_sendmsg,rawv6_sendmsg
 be16                    inet_sport            read_mostly         -                   __tcp_transmit_skb
 be32                    inet_daddr            read_mostly         -                   ip_select_ident_segs
 be32                    inet_rcv_saddr        -                   -                   
--- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
+++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c
@@ -1197,12 +1197,12 @@ static struct sock *chtls_recv_sock(stru
 		struct ipv6_pinfo *newnp = inet6_sk(newsk);
 		struct ipv6_pinfo *np = inet6_sk(lsk);
 
-		inet_sk(newsk)->pinet6 = &newtcp6sk->inet6;
+		newinet->pinet6 = &newtcp6sk->inet6;
+		newinet->ipv6_fl_list = NULL;
 		memcpy(newnp, np, sizeof(struct ipv6_pinfo));
 		newsk->sk_v6_daddr = treq->ir_v6_rmt_addr;
 		newsk->sk_v6_rcv_saddr = treq->ir_v6_loc_addr;
 		inet6_sk(newsk)->saddr = treq->ir_v6_loc_addr;
-		newnp->ipv6_fl_list = NULL;
 		newnp->pktoptions = NULL;
 		newsk->sk_bound_dev_if = treq->ir_iif;
 		newinet->inet_opt = NULL;
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -269,7 +269,6 @@ struct ipv6_pinfo {
 
 	struct ipv6_mc_socklist	__rcu *ipv6_mc_list;
 	struct ipv6_ac_socklist	*ipv6_ac_list;
-	struct ipv6_fl_socklist __rcu *ipv6_fl_list;
 };
 
 /* We currently use available bits from inet_sk(sk)->inet_flags,
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -212,6 +212,7 @@ struct inet_sock {
 	struct sock		sk;
 #if IS_ENABLED(CONFIG_IPV6)
 	struct ipv6_pinfo	*pinet6;
+	struct ipv6_fl_socklist __rcu *ipv6_fl_list;
 #endif
 	/* Socket demultiplex comparisons on incoming packets. */
 #define inet_daddr		sk.__sk_common.skc_daddr
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -456,7 +456,7 @@ static struct sock *dccp_v6_request_recv
 		newnp->opt	   = NULL;
 		newnp->ipv6_mc_list = NULL;
 		newnp->ipv6_ac_list = NULL;
-		newnp->ipv6_fl_list = NULL;
+		newinet->ipv6_fl_list = NULL;
 		newnp->mcast_oif   = inet_iif(skb);
 		newnp->mcast_hops  = ip_hdr(skb)->ttl;
 
@@ -523,7 +523,7 @@ static struct sock *dccp_v6_request_recv
 
 	newnp->ipv6_mc_list = NULL;
 	newnp->ipv6_ac_list = NULL;
-	newnp->ipv6_fl_list = NULL;
+	newinet->ipv6_fl_list = NULL;
 	newnp->pktoptions = NULL;
 	newnp->opt	  = NULL;
 	newnp->mcast_oif  = inet6_iif(skb);
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -66,8 +66,8 @@ EXPORT_SYMBOL(ipv6_flowlabel_exclusive);
 	     fl != NULL;					\
 	     fl = rcu_dereference(fl->next))
 
-#define for_each_sk_fl_rcu(np, sfl)				\
-	for (sfl = rcu_dereference(np->ipv6_fl_list);	\
+#define for_each_sk_fl_rcu(sk, sfl)				\
+	for (sfl = rcu_dereference(inet_sk(sk)->ipv6_fl_list);	\
 	     sfl != NULL;					\
 	     sfl = rcu_dereference(sfl->next))
 
@@ -257,12 +257,11 @@ static struct ip6_flowlabel *fl_intern(s
 struct ip6_flowlabel *__fl6_sock_lookup(struct sock *sk, __be32 label)
 {
 	struct ipv6_fl_socklist *sfl;
-	struct ipv6_pinfo *np = inet6_sk(sk);
 
 	label &= IPV6_FLOWLABEL_MASK;
 
 	rcu_read_lock();
-	for_each_sk_fl_rcu(np, sfl) {
+	for_each_sk_fl_rcu(sk, sfl) {
 		struct ip6_flowlabel *fl = sfl->fl;
 
 		if (fl->label == label && atomic_inc_not_zero(&fl->users)) {
@@ -278,16 +277,16 @@ EXPORT_SYMBOL_GPL(__fl6_sock_lookup);
 
 void fl6_free_socklist(struct sock *sk)
 {
-	struct ipv6_pinfo *np = inet6_sk(sk);
+	struct inet_sock *inet = inet_sk(sk);
 	struct ipv6_fl_socklist *sfl;
 
-	if (!rcu_access_pointer(np->ipv6_fl_list))
+	if (!rcu_access_pointer(inet->ipv6_fl_list))
 		return;
 
 	spin_lock_bh(&ip6_sk_fl_lock);
-	while ((sfl = rcu_dereference_protected(np->ipv6_fl_list,
+	while ((sfl = rcu_dereference_protected(inet->ipv6_fl_list,
 						lockdep_is_held(&ip6_sk_fl_lock))) != NULL) {
-		np->ipv6_fl_list = sfl->next;
+		inet->ipv6_fl_list = sfl->next;
 		spin_unlock_bh(&ip6_sk_fl_lock);
 
 		fl_release(sfl->fl);
@@ -465,35 +464,38 @@ done:
 
 static int mem_check(struct sock *sk)
 {
-	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct ipv6_fl_socklist *sfl;
+	const int unpriv_total_limit = FL_MAX_SIZE - (FL_MAX_SIZE / 4);
 	int room = FL_MAX_SIZE - atomic_read(&fl_size);
+	struct ipv6_fl_socklist *sfl;
 	int count = 0;
 
 	if (room > FL_MAX_SIZE - FL_MAX_PER_SOCK)
 		return 0;
 
 	rcu_read_lock();
-	for_each_sk_fl_rcu(np, sfl)
+	for_each_sk_fl_rcu(sk, sfl)
 		count++;
 	rcu_read_unlock();
 
 	if (room <= 0 ||
 	    ((count >= FL_MAX_PER_SOCK ||
-	      (count > 0 && room < FL_MAX_SIZE/2) || room < FL_MAX_SIZE/4) &&
+	      (count > 0 && room < FL_MAX_SIZE / 2) ||
+	      room < FL_MAX_SIZE - unpriv_total_limit) &&
 	     !capable(CAP_NET_ADMIN)))
 		return -ENOBUFS;
 
 	return 0;
 }
 
-static inline void fl_link(struct ipv6_pinfo *np, struct ipv6_fl_socklist *sfl,
-		struct ip6_flowlabel *fl)
+static inline void fl_link(struct sock *sk, struct ipv6_fl_socklist *sfl,
+			   struct ip6_flowlabel *fl)
 {
+	struct inet_sock *inet = inet_sk(sk);
+
 	spin_lock_bh(&ip6_sk_fl_lock);
 	sfl->fl = fl;
-	sfl->next = np->ipv6_fl_list;
-	rcu_assign_pointer(np->ipv6_fl_list, sfl);
+	sfl->next = inet->ipv6_fl_list;
+	rcu_assign_pointer(inet->ipv6_fl_list, sfl);
 	spin_unlock_bh(&ip6_sk_fl_lock);
 }
 
@@ -515,7 +517,7 @@ int ipv6_flowlabel_opt_get(struct sock *
 
 	rcu_read_lock();
 
-	for_each_sk_fl_rcu(np, sfl) {
+	for_each_sk_fl_rcu(sk, sfl) {
 		if (sfl->fl->label == (np->flow_label & IPV6_FLOWLABEL_MASK)) {
 			spin_lock_bh(&ip6_fl_lock);
 			freq->flr_label = sfl->fl->label;
@@ -554,7 +556,7 @@ static int ipv6_flowlabel_put(struct soc
 	}
 
 	spin_lock_bh(&ip6_sk_fl_lock);
-	for (sflp = &np->ipv6_fl_list;
+	for (sflp = &inet_sk(sk)->ipv6_fl_list;
 	     (sfl = socklist_dereference(*sflp)) != NULL;
 	     sflp = &sfl->next) {
 		if (sfl->fl->label == freq->flr_label)
@@ -574,13 +576,12 @@ found:
 
 static int ipv6_flowlabel_renew(struct sock *sk, struct in6_flowlabel_req *freq)
 {
-	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct net *net = sock_net(sk);
 	struct ipv6_fl_socklist *sfl;
 	int err;
 
 	rcu_read_lock();
-	for_each_sk_fl_rcu(np, sfl) {
+	for_each_sk_fl_rcu(sk, sfl) {
 		if (sfl->fl->label == freq->flr_label) {
 			err = fl6_renew(sfl->fl, freq->flr_linger,
 					freq->flr_expires);
@@ -609,7 +610,6 @@ static int ipv6_flowlabel_get(struct soc
 {
 	struct ipv6_fl_socklist *sfl, *sfl1 = NULL;
 	struct ip6_flowlabel *fl, *fl1 = NULL;
-	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct net *net = sock_net(sk);
 	int err;
 
@@ -640,7 +640,7 @@ static int ipv6_flowlabel_get(struct soc
 	if (freq->flr_label) {
 		err = -EEXIST;
 		rcu_read_lock();
-		for_each_sk_fl_rcu(np, sfl) {
+		for_each_sk_fl_rcu(sk, sfl) {
 			if (sfl->fl->label == freq->flr_label) {
 				if (freq->flr_flags & IPV6_FL_F_EXCL) {
 					rcu_read_unlock();
@@ -677,7 +677,7 @@ recheck:
 				fl1->linger = fl->linger;
 			if ((long)(fl->expires - fl1->expires) > 0)
 				fl1->expires = fl->expires;
-			fl_link(np, sfl1, fl1);
+			fl_link(sk, sfl1, fl1);
 			fl_free(fl);
 			return 0;
 
@@ -711,7 +711,7 @@ release:
 		}
 	}
 
-	fl_link(np, sfl1, fl);
+	fl_link(sk, sfl1, fl);
 	return 0;
 done:
 	fl_free(fl);
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1349,6 +1349,7 @@ static void tcp_v6_mapped_child_init(str
 	struct ipv6_pinfo *newnp;
 
 	newinet->pinet6 = newnp = tcp_inet6_sk(newsk);
+	newinet->ipv6_fl_list = NULL;
 
 	memcpy(newnp, tcp_inet6_sk(sk), sizeof(struct ipv6_pinfo));
 
@@ -1364,7 +1365,6 @@ static void tcp_v6_mapped_child_init(str
 
 	newnp->ipv6_mc_list = NULL;
 	newnp->ipv6_ac_list = NULL;
-	newnp->ipv6_fl_list = NULL;
 	newnp->pktoptions  = NULL;
 	newnp->opt	   = NULL;
 
@@ -1427,10 +1427,12 @@ static struct sock *tcp_v6_syn_recv_sock
 	newsk->sk_gso_type = SKB_GSO_TCPV6;
 	inet6_sk_rx_dst_set(newsk, skb);
 
-	inet_sk(newsk)->pinet6 = tcp_inet6_sk(newsk);
+	newinet = inet_sk(newsk);
+	newinet->pinet6 = tcp_inet6_sk(newsk);
+	newinet->ipv6_fl_list = NULL;
+	newinet->inet_opt = NULL;
 
 	newtp = tcp_sk(newsk);
-	newinet = inet_sk(newsk);
 	newnp = tcp_inet6_sk(newsk);
 
 	memcpy(newnp, np, sizeof(struct ipv6_pinfo));
@@ -1446,10 +1448,8 @@ static struct sock *tcp_v6_syn_recv_sock
 
 	   First: no IPv4 options.
 	 */
-	newinet->inet_opt = NULL;
 	newnp->ipv6_mc_list = NULL;
 	newnp->ipv6_ac_list = NULL;
-	newnp->ipv6_fl_list = NULL;
 
 	/* Clone RX bits */
 	newnp->rxopt.all = np->rxopt.all;
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -784,9 +784,10 @@ static struct sock *sctp_v6_create_accep
 					     struct sctp_association *asoc,
 					     bool kern)
 {
-	struct sock *newsk;
 	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
 	struct sctp6_sock *newsctp6sk;
+	struct inet_sock *newinet;
+	struct sock *newsk;
 
 	newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot, kern);
 	if (!newsk)
@@ -798,7 +799,9 @@ static struct sock *sctp_v6_create_accep
 	sock_reset_flag(sk, SOCK_ZAPPED);
 
 	newsctp6sk = (struct sctp6_sock *)newsk;
-	inet_sk(newsk)->pinet6 = &newsctp6sk->inet6;
+	newinet = inet_sk(newsk);
+	newinet->pinet6 = &newsctp6sk->inet6;
+	newinet->ipv6_fl_list = NULL;
 
 	sctp_sk(newsk)->v4mapped = sctp_sk(sk)->v4mapped;
 
@@ -807,7 +810,6 @@ static struct sock *sctp_v6_create_accep
 	memcpy(newnp, np, sizeof(struct ipv6_pinfo));
 	newnp->ipv6_mc_list = NULL;
 	newnp->ipv6_ac_list = NULL;
-	newnp->ipv6_fl_list = NULL;
 
 	sctp_v6_copy_ip_options(sk, newsk);
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 752/877] ipv6: flowlabel: cap duplicate leases per socket
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (750 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 751/877] ipv6: Move ipv6_fl_list from ipv6_pinfo to inet_sock Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 753/877] landlock: Clarify documentation for the IOCTL access right Greg Kroah-Hartman
                   ` (132 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Ido Schimmel, Zhiling Zou,
	Eric Dumazet, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Zhiling Zou <zhilinz@nebusec.ai>

[ Upstream commit 8d6cd188508513503805c156165de38e4e4a8615 ]

ipv6_flowlabel_get() allocates an ipv6_fl_socklist entry for every
successful GET. The recheck path for a compatible existing flowlabel
links another lease without applying any lease admission check. Repeated
GET requests for one shareable label can therefore grow a socket's lease
list without bound.

Reject a new unprivileged lease once the socket already holds
FL_MAX_PER_SOCK leases. Check this on the shared recheck path so reuse
of a globally interned label, including the fl_intern() collision path,
is covered as well. New-label admission remains under the existing
mem_check() policy.

Use capable(CAP_NET_ADMIN) rather than ns_capable(), matching
mem_check(). An unprivileged user must not bypass the cap by creating a
user namespace and a netns where they have CAP_NET_ADMIN, which would
still consume host memory.

Check the capability only when the socket reaches the limit, so
successful unprivileged GET requests below the cap do not generate a
capability audit. Do the admission check before updating linger and
expires so a rejected GET does not refresh the shared label, matching
the existing socket-list allocation failure path.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/83f8535972ff6e3741548476a1d50dec24c758be.1788415194.git.zhilinz@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv6/ip6_flowlabel.c |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -462,6 +462,21 @@ done:
 	return NULL;
 }
 
+static bool fl_sock_at_lease_limit(const struct sock *sk)
+{
+	const struct ipv6_fl_socklist *sfl;
+	int count = 0;
+
+	rcu_read_lock();
+	for_each_sk_fl_rcu(sk, sfl) {
+		if (++count >= FL_MAX_PER_SOCK)
+			break;
+	}
+	rcu_read_unlock();
+
+	return count >= FL_MAX_PER_SOCK;
+}
+
 static int mem_check(struct sock *sk)
 {
 	const int unpriv_total_limit = FL_MAX_SIZE - (FL_MAX_SIZE / 4);
@@ -673,6 +688,10 @@ recheck:
 			err = -ENOMEM;
 			if (!sfl1)
 				goto release;
+			err = -ENOBUFS;
+			if (fl_sock_at_lease_limit(sk) &&
+			    !capable(CAP_NET_ADMIN))
+				goto release;
 			if (fl->linger > fl1->linger)
 				fl1->linger = fl->linger;
 			if ((long)(fl->expires - fl1->expires) > 0)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 753/877] landlock: Clarify documentation for the IOCTL access right
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (751 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 752/877] ipv6: flowlabel: cap duplicate leases per socket Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 754/877] landlock: Fix use-after-free of the sources parent directory Greg Kroah-Hartman
                   ` (131 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Günther Noack,
	Mickaël Salaün, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Günther Noack <gnoack3000@gmail.com>

[ Upstream commit 6abbb8703aeeb645a681ab6ad155e0b450413787 ]

Move the description of the LANDLOCK_ACCESS_FS_IOCTL_DEV access right
together with the file access rights.

This group of access rights applies to files (in this case device
files), and they can be added to file or directory inodes using
landlock_add_rule(2).  The check for that works the same for all file
access rights, including LANDLOCK_ACCESS_FS_IOCTL_DEV.

Invoking ioctl(2) on directory FDs can not currently be restricted
with Landlock.  Having it grouped separately in the documentation is a
remnant from earlier revisions of the LANDLOCK_ACCESS_FS_IOCTL_DEV
patch set.

Link: https://lore.kernel.org/all/20260108.Thaex5ruach2@digikod.net/
Signed-off-by: Günther Noack <gnoack3000@gmail.com>
Link: https://lore.kernel.org/r/20260111175203.6545-2-gnoack3000@gmail.com
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Stable-dep-of: 2c6dc7925382 ("landlock: Fix use-after-free of the source's parent directory")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/uapi/linux/landlock.h |   37 +++++++++++++++++--------------------
 1 file changed, 17 insertions(+), 20 deletions(-)

--- a/include/uapi/linux/landlock.h
+++ b/include/uapi/linux/landlock.h
@@ -156,6 +156,23 @@ struct landlock_net_port_attr {
  *   :manpage:`ftruncate(2)`, :manpage:`creat(2)`, or :manpage:`open(2)` with
  *   ``O_TRUNC``.  This access right is available since the third version of the
  *   Landlock ABI.
+ * - %LANDLOCK_ACCESS_FS_IOCTL_DEV: Invoke :manpage:`ioctl(2)` commands on an opened
+ *   character or block device.
+ *
+ *   This access right applies to all `ioctl(2)` commands implemented by device
+ *   drivers.  However, the following common IOCTL commands continue to be
+ *   invokable independent of the %LANDLOCK_ACCESS_FS_IOCTL_DEV right:
+ *
+ *   * IOCTL commands targeting file descriptors (``FIOCLEX``, ``FIONCLEX``),
+ *   * IOCTL commands targeting file descriptions (``FIONBIO``, ``FIOASYNC``),
+ *   * IOCTL commands targeting file systems (``FIFREEZE``, ``FITHAW``,
+ *     ``FIGETBSZ``, ``FS_IOC_GETFSUUID``, ``FS_IOC_GETFSSYSFSPATH``)
+ *   * Some IOCTL commands which do not make sense when used with devices, but
+ *     whose implementations are safe and return the right error codes
+ *     (``FS_IOC_FIEMAP``, ``FICLONE``, ``FICLONERANGE``, ``FIDEDUPERANGE``)
+ *
+ *   This access right is available since the fifth version of the Landlock
+ *   ABI.
  *
  * Whether an opened file can be truncated with :manpage:`ftruncate(2)` or used
  * with `ioctl(2)` is determined during :manpage:`open(2)`, in the same way as
@@ -216,26 +233,6 @@ struct landlock_net_port_attr {
  *   If multiple requirements are not met, the ``EACCES`` error code takes
  *   precedence over ``EXDEV``.
  *
- * The following access right applies both to files and directories:
- *
- * - %LANDLOCK_ACCESS_FS_IOCTL_DEV: Invoke :manpage:`ioctl(2)` commands on an opened
- *   character or block device.
- *
- *   This access right applies to all `ioctl(2)` commands implemented by device
- *   drivers.  However, the following common IOCTL commands continue to be
- *   invokable independent of the %LANDLOCK_ACCESS_FS_IOCTL_DEV right:
- *
- *   * IOCTL commands targeting file descriptors (``FIOCLEX``, ``FIONCLEX``),
- *   * IOCTL commands targeting file descriptions (``FIONBIO``, ``FIOASYNC``),
- *   * IOCTL commands targeting file systems (``FIFREEZE``, ``FITHAW``,
- *     ``FIGETBSZ``, ``FS_IOC_GETFSUUID``, ``FS_IOC_GETFSSYSFSPATH``)
- *   * Some IOCTL commands which do not make sense when used with devices, but
- *     whose implementations are safe and return the right error codes
- *     (``FS_IOC_FIEMAP``, ``FICLONE``, ``FICLONERANGE``, ``FIDEDUPERANGE``)
- *
- *   This access right is available since the fifth version of the Landlock
- *   ABI.
- *
  * .. warning::
  *
  *   It is currently not possible to restrict some file-related actions



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 754/877] landlock: Fix use-after-free of the sources parent directory
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (752 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 753/877] landlock: Clarify documentation for the IOCTL access right Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 755/877] netmem: add a couple of page helper wrappers Greg Kroah-Hartman
                   ` (130 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Günther Noack,
	Mickaël Salaün, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Norbert Szetei <norbert@doyensec.com>

[ Upstream commit 2c6dc792538260a8087ac5b22c31b3b8e47c85d6 ]

current_check_refer_path() reads old_dentry->d_parent without holding a
reference nor a lock on it, and then dereferences it in
collect_domain_accesses() and in the audit record.

A reference on a child does not pin its parent: __d_move() reassigns
dentry->d_parent and drops the reference the child held on its former
parent.  hook_path_rename() is not affected because the rename path
calls lock_rename() before the hook, so the source cannot be reparented
under it.  hook_path_link() has no such protection: filename_linkat()
holds a reference on the source dentry but neither locks nor references
its parent, so a concurrent rename(2) can reparent the source while
security_path_link() runs, and the former parent can then be removed and
freed while the hook walks it.

A process can trigger this after entering a Landlock domain that handles
at least one filesystem access right.  The process can then race a
linkat(2) loop against rename(2) and rmdir(2):

  BUG: KASAN: slab-use-after-free in collect_domain_accesses+0x278/0x290
  Read of size 4 at addr ffff888160bd53f4 by task llrepro2/549
   collect_domain_accesses+0x278/0x290
   current_check_refer_path+0x952/0x1120
   security_path_link+0x1be/0x320
   filename_linkat+0x342/0x6d0
   __x64_sys_linkat+0xfa/0x150
  Freed by task 562:
   kmem_cache_free+0x139/0x4c0
   i_callback+0x4b/0x80
   rcu_core+0x7dc/0x10a0

Take a reference on the dentry selected as the source parent, using
dget() for the common-mount-root case and dget_parent() otherwise.
Release it after the hierarchy walk and synchronous audit logging.

Cc: stable@vger.kernel.org
Fixes: b91c3e4ea756 ("landlock: Add support for file reparenting with LANDLOCK_ACCESS_FS_REFER")
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Reviewed-by: Günther Noack <gnoack3000@gmail.com>
Tested-by: Günther Noack <gnoack3000@gmail.com>
Link: https://patch.msgid.link/E9CDD9E6-E960-4DE2-B1AC-5667D52ABB3E@doyensec.com
[mic: Clarify the caller, reachability, and reference handling]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
[ adapted to older Landlock helpers using dom and lacking audit arguments. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 security/landlock/fs.c |   18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

--- a/security/landlock/fs.c
+++ b/security/landlock/fs.c
@@ -1192,11 +1192,12 @@ static int current_check_refer_path(stru
 	/*
 	 * old_dentry may be the root of the common mount point and
 	 * !IS_ROOT(old_dentry) at the same time (e.g. with open_tree() and
-	 * OPEN_TREE_CLONE).  We do not need to call dget(old_parent) because
-	 * we keep a reference to old_dentry.
+	 * OPEN_TREE_CLONE).  Pin the dentry used as old_parent in either case.
+	 * Otherwise, dget_parent() safely fetches and pins the current parent
+	 * against a concurrent rename(2).
 	 */
-	old_parent = (old_dentry == mnt_dir.dentry) ? old_dentry :
-						      old_dentry->d_parent;
+	old_parent = (old_dentry == mnt_dir.dentry) ? dget(old_dentry) :
+						      dget_parent(old_dentry);
 
 	/* new_dir->dentry is equal to new_dentry->d_parent */
 	allow_parent1 = collect_domain_accesses(dom, mnt_dir.dentry, old_parent,
@@ -1204,8 +1205,10 @@ static int current_check_refer_path(stru
 	allow_parent2 = collect_domain_accesses(
 		dom, mnt_dir.dentry, new_dir->dentry, &layer_masks_parent2);
 
-	if (allow_parent1 && allow_parent2)
+	if (allow_parent1 && allow_parent2) {
+		dput(old_parent);
 		return 0;
+	}
 
 	/*
 	 * To be able to compare source and destination domain access rights,
@@ -1216,8 +1219,11 @@ static int current_check_refer_path(stru
 	if (is_access_to_paths_allowed(
 		    dom, &mnt_dir, access_request_parent1, &layer_masks_parent1,
 		    old_dentry, access_request_parent2, &layer_masks_parent2,
-		    exchange ? new_dentry : NULL))
+		    exchange ? new_dentry : NULL)) {
+		dput(old_parent);
 		return 0;
+	}
+	dput(old_parent);
 
 	/*
 	 * This prioritizes EACCES over EXDEV for all actions, including



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 755/877] netmem: add a couple of page helper wrappers
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (753 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 754/877] landlock: Fix use-after-free of the sources parent directory Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 756/877] net: page_pool: rename page_pool_alloc_netmem to *_netmems Greg Kroah-Hartman
                   ` (129 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Alexander Lobakin,
	Toke Høiland-Jørgensen, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Alexander Lobakin <aleksander.lobakin@intel.com>

[ Upstream commit 9bd9f72a74344b54cfb6fcabf1173e6c6e5c6952 ]

Add the following netmem counterparts:

* virt_to_netmem() -- simple page_to_netmem(virt_to_page()) wrapper;
* netmem_is_pfmemalloc() -- page_is_pfmemalloc() for page-backed
			    netmems, false otherwise;

and the following "unsafe" versions:

* __netmem_to_page()
* __netmem_get_pp()
* __netmem_address()

They do the same as their non-underscored buddies, but assume the netmem
is always page-backed. When working with header &page_pools, you don't
need to check whether netmem belongs to the host memory and you can
never get NULL instead of &page. Checks for the LSB, clearing the LSB,
branches take cycles and increase object code size, sometimes
significantly. When you're sure your PP is always host, you can avoid
this by using the underscored counterparts.

Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Link: https://patch.msgid.link/20241203173733.3181246-8-aleksander.lobakin@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: b814dfbfeb0a ("bnxt_en: Propagate TPA buffer allocation failures in bnxt_queue_mem_alloc()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/net/netmem.h |   78 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 76 insertions(+), 2 deletions(-)

--- a/include/net/netmem.h
+++ b/include/net/netmem.h
@@ -72,6 +72,22 @@ static inline bool netmem_is_net_iov(con
 	return (__force unsigned long)netmem & NET_IOV;
 }
 
+/**
+ * __netmem_to_page - unsafely get pointer to the &page backing @netmem
+ * @netmem: netmem reference to convert
+ *
+ * Unsafe version of netmem_to_page(). When @netmem is always page-backed,
+ * e.g. when it's a header buffer, performs faster and generates smaller
+ * object code (no check for the LSB, no WARN). When @netmem points to IOV,
+ * provokes undefined behaviour.
+ *
+ * Return: pointer to the &page (garbage if @netmem is not page-backed).
+ */
+static inline struct page *__netmem_to_page(netmem_ref netmem)
+{
+	return (__force struct page *)netmem;
+}
+
 /* This conversion fails (returns NULL) if the netmem_ref is not struct page
  * backed.
  */
@@ -80,7 +96,7 @@ static inline struct page *netmem_to_pag
 	if (WARN_ON_ONCE(netmem_is_net_iov(netmem)))
 		return NULL;
 
-	return (__force struct page *)netmem;
+	return __netmem_to_page(netmem);
 }
 
 static inline struct net_iov *netmem_to_net_iov(netmem_ref netmem)
@@ -103,6 +119,17 @@ static inline netmem_ref page_to_netmem(
 	return (__force netmem_ref)page;
 }
 
+/**
+ * virt_to_netmem - convert virtual memory pointer to a netmem reference
+ * @data: host memory pointer to convert
+ *
+ * Return: netmem reference to the &page backing this virtual address.
+ */
+static inline netmem_ref virt_to_netmem(const void *data)
+{
+	return page_to_netmem(virt_to_page(data));
+}
+
 static inline int netmem_ref_count(netmem_ref netmem)
 {
 	/* The non-pp refcount of net_iov is always 1. On net_iov, we only
@@ -127,6 +154,22 @@ static inline struct net_iov *__netmem_c
 	return (struct net_iov *)((__force unsigned long)netmem & ~NET_IOV);
 }
 
+/**
+ * __netmem_get_pp - unsafely get pointer to the &page_pool backing @netmem
+ * @netmem: netmem reference to get the pointer from
+ *
+ * Unsafe version of netmem_get_pp(). When @netmem is always page-backed,
+ * e.g. when it's a header buffer, performs faster and generates smaller
+ * object code (avoids clearing the LSB). When @netmem points to IOV,
+ * provokes invalid memory access.
+ *
+ * Return: pointer to the &page_pool (garbage if @netmem is not page-backed).
+ */
+static inline struct page_pool *__netmem_get_pp(netmem_ref netmem)
+{
+	return __netmem_to_page(netmem)->pp;
+}
+
 static inline struct page_pool *netmem_get_pp(netmem_ref netmem)
 {
 	return __netmem_clear_lsb(netmem)->pp;
@@ -158,12 +201,43 @@ static inline netmem_ref netmem_compound
 	return page_to_netmem(compound_head(netmem_to_page(netmem)));
 }
 
+/**
+ * __netmem_address - unsafely get pointer to the memory backing @netmem
+ * @netmem: netmem reference to get the pointer for
+ *
+ * Unsafe version of netmem_address(). When @netmem is always page-backed,
+ * e.g. when it's a header buffer, performs faster and generates smaller
+ * object code (no check for the LSB). When @netmem points to IOV, provokes
+ * undefined behaviour.
+ *
+ * Return: pointer to the memory (garbage if @netmem is not page-backed).
+ */
+static inline void *__netmem_address(netmem_ref netmem)
+{
+	return page_address(__netmem_to_page(netmem));
+}
+
 static inline void *netmem_address(netmem_ref netmem)
 {
 	if (netmem_is_net_iov(netmem))
 		return NULL;
 
-	return page_address(netmem_to_page(netmem));
+	return __netmem_address(netmem);
+}
+
+/**
+ * netmem_is_pfmemalloc - check if @netmem was allocated under memory pressure
+ * @netmem: netmem reference to check
+ *
+ * Return: true if @netmem is page-backed and the page was allocated under
+ * memory pressure, false otherwise.
+ */
+static inline bool netmem_is_pfmemalloc(netmem_ref netmem)
+{
+	if (netmem_is_net_iov(netmem))
+		return false;
+
+	return page_is_pfmemalloc(netmem_to_page(netmem));
 }
 
 static inline unsigned long netmem_get_dma_addr(netmem_ref netmem)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 756/877] net: page_pool: rename page_pool_alloc_netmem to *_netmems
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (754 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 755/877] netmem: add a couple of page helper wrappers Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 757/877] page_pool: disable sync for cpu for dmabuf memory provider Greg Kroah-Hartman
                   ` (128 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mina Almasry, Stanislav Fomichev,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mina Almasry <almasrymina@google.com>

[ Upstream commit 91a152cbb49c26609d217cf2f116d46143b9b8be ]

page_pool_alloc_netmem (without an s) was the mirror of
page_pool_alloc_pages (with an s), which was confusing.

Rename to page_pool_alloc_netmems so it's the mirror of
page_pool_alloc_pages.

Signed-off-by: Mina Almasry <almasrymina@google.com>
Acked-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20241211212033.1684197-2-almasrymina@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: b814dfbfeb0a ("bnxt_en: Propagate TPA buffer allocation failures in bnxt_queue_mem_alloc()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/net/page_pool/types.h |    2 +-
 net/core/page_pool.c          |    8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

--- a/include/net/page_pool/types.h
+++ b/include/net/page_pool/types.h
@@ -252,7 +252,7 @@ struct page_pool {
 };
 
 struct page *page_pool_alloc_pages(struct page_pool *pool, gfp_t gfp);
-netmem_ref page_pool_alloc_netmem(struct page_pool *pool, gfp_t gfp);
+netmem_ref page_pool_alloc_netmems(struct page_pool *pool, gfp_t gfp);
 struct page *page_pool_alloc_frag(struct page_pool *pool, unsigned int *offset,
 				  unsigned int size, gfp_t gfp);
 netmem_ref page_pool_alloc_frag_netmem(struct page_pool *pool,
--- a/net/core/page_pool.c
+++ b/net/core/page_pool.c
@@ -673,7 +673,7 @@ static noinline netmem_ref __page_pool_a
 /* For using page_pool replace: alloc_pages() API calls, but provide
  * synchronization guarantee for allocation side.
  */
-netmem_ref page_pool_alloc_netmem(struct page_pool *pool, gfp_t gfp)
+netmem_ref page_pool_alloc_netmems(struct page_pool *pool, gfp_t gfp)
 {
 	netmem_ref netmem;
 
@@ -689,11 +689,11 @@ netmem_ref page_pool_alloc_netmem(struct
 		netmem = __page_pool_alloc_pages_slow(pool, gfp);
 	return netmem;
 }
-EXPORT_SYMBOL(page_pool_alloc_netmem);
+EXPORT_SYMBOL(page_pool_alloc_netmems);
 
 struct page *page_pool_alloc_pages(struct page_pool *pool, gfp_t gfp)
 {
-	return netmem_to_page(page_pool_alloc_netmem(pool, gfp));
+	return netmem_to_page(page_pool_alloc_netmems(pool, gfp));
 }
 EXPORT_SYMBOL(page_pool_alloc_pages);
 ALLOW_ERROR_INJECTION(page_pool_alloc_pages, NULL);
@@ -1051,7 +1051,7 @@ netmem_ref page_pool_alloc_frag_netmem(s
 	}
 
 	if (!netmem) {
-		netmem = page_pool_alloc_netmem(pool, gfp);
+		netmem = page_pool_alloc_netmems(pool, gfp);
 		if (unlikely(!netmem)) {
 			pool->frag_page = 0;
 			return 0;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 757/877] page_pool: disable sync for cpu for dmabuf memory provider
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (755 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 756/877] net: page_pool: rename page_pool_alloc_netmem to *_netmems Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 758/877] bnxt_en: Propagate TPA buffer allocation failures in bnxt_queue_mem_alloc() Greg Kroah-Hartman
                   ` (127 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Alexander Lobakin, Jason Gunthorpe,
	Mina Almasry, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mina Almasry <almasrymina@google.com>

[ Upstream commit 7dba339faae991a23c54f7b93a58798c58f8c16f ]

dmabuf dma-addresses should not be dma_sync'd for CPU/device. Typically
its the driver responsibility to dma_sync for CPU, but the driver should
not dma_sync for CPU if the netmem is actually coming from a dmabuf
memory provider.

The page_pool already exposes a helper for dma_sync_for_cpu:
page_pool_dma_sync_for_cpu. Upgrade this existing helper to handle
netmem, and have it skip dma_sync if the memory is from a dmabuf memory
provider. Drivers should migrate to using this helper when adding
support for netmem.

Also minimize the impact on the dma syncing performance for pages. Special
case the dma-sync path for pages to not go through the overhead checks
for dma-syncing and conversion to netmem.

Cc: Alexander Lobakin <aleksander.lobakin@intel.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Signed-off-by: Mina Almasry <almasrymina@google.com>
Link: https://patch.msgid.link/20241211212033.1684197-5-almasrymina@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: b814dfbfeb0a ("bnxt_en: Propagate TPA buffer allocation failures in bnxt_queue_mem_alloc()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/net/page_pool/helpers.h |   35 ++++++++++++++++++++++++++++++-----
 include/net/page_pool/types.h   |    3 ++-
 net/core/devmem.c               |    1 +
 net/core/page_pool.c            |    1 +
 4 files changed, 34 insertions(+), 6 deletions(-)

--- a/include/net/page_pool/helpers.h
+++ b/include/net/page_pool/helpers.h
@@ -418,7 +418,21 @@ static inline dma_addr_t page_pool_get_d
  */
 static inline dma_addr_t page_pool_get_dma_addr(const struct page *page)
 {
-	return page_pool_get_dma_addr_netmem(page_to_netmem((struct page *)page));
+	dma_addr_t ret = page->dma_addr;
+
+	if (PAGE_POOL_32BIT_ARCH_WITH_64BIT_DMA)
+		ret <<= PAGE_SHIFT;
+
+	return ret;
+}
+
+static inline void __page_pool_dma_sync_for_cpu(const struct page_pool *pool,
+						const dma_addr_t dma_addr,
+						u32 offset, u32 dma_sync_size)
+{
+	dma_sync_single_range_for_cpu(pool->p.dev, dma_addr,
+				      offset + pool->p.offset, dma_sync_size,
+				      page_pool_get_dma_dir(pool));
 }
 
 /**
@@ -437,10 +451,21 @@ static inline void page_pool_dma_sync_fo
 					      const struct page *page,
 					      u32 offset, u32 dma_sync_size)
 {
-	dma_sync_single_range_for_cpu(pool->p.dev,
-				      page_pool_get_dma_addr(page),
-				      offset + pool->p.offset, dma_sync_size,
-				      page_pool_get_dma_dir(pool));
+	__page_pool_dma_sync_for_cpu(pool, page_pool_get_dma_addr(page), offset,
+				     dma_sync_size);
+}
+
+static inline void
+page_pool_dma_sync_netmem_for_cpu(const struct page_pool *pool,
+				  const netmem_ref netmem, u32 offset,
+				  u32 dma_sync_size)
+{
+	if (!pool->dma_sync_for_cpu)
+		return;
+
+	__page_pool_dma_sync_for_cpu(pool,
+				     page_pool_get_dma_addr_netmem(netmem),
+				     offset, dma_sync_size);
 }
 
 static inline bool page_pool_put(struct page_pool *pool)
--- a/include/net/page_pool/types.h
+++ b/include/net/page_pool/types.h
@@ -171,7 +171,8 @@ struct page_pool {
 
 	bool has_init_callback:1;	/* slow::init_callback is set */
 	bool dma_map:1;			/* Perform DMA mapping */
-	bool dma_sync:1;		/* Perform DMA sync */
+	bool dma_sync:1;		/* Perform DMA sync for device */
+	bool dma_sync_for_cpu:1;	/* Perform DMA sync for cpu */
 #ifdef CONFIG_PAGE_POOL_STATS
 	bool system:1;			/* This is a global percpu pool */
 #endif
--- a/net/core/devmem.c
+++ b/net/core/devmem.c
@@ -343,6 +343,7 @@ int mp_dmabuf_devmem_init(struct page_po
 	 * dma_sync_for_cpu/device. Force disable dma_sync.
 	 */
 	pool->dma_sync = false;
+	pool->dma_sync_for_cpu = false;
 
 	if (pool->p.order != 0)
 		return -E2BIG;
--- a/net/core/page_pool.c
+++ b/net/core/page_pool.c
@@ -203,6 +203,7 @@ static int page_pool_init(struct page_po
 	memcpy(&pool->slow, &params->slow, sizeof(pool->slow));
 
 	pool->cpuid = cpuid;
+	pool->dma_sync_for_cpu = true;
 
 	/* Validate only known flags were used */
 	if (pool->slow.flags & ~PP_FLAG_ALL)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 758/877] bnxt_en: Propagate TPA buffer allocation failures in bnxt_queue_mem_alloc()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (756 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 757/877] page_pool: disable sync for cpu for dmabuf memory provider Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 759/877] mptcp: pm: drop match in userspace_pm_append_new_local_addr Greg Kroah-Hartman
                   ` (126 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Joe Damato, Paolo Abeni,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Joe Damato <joe@dama.to>

[ Upstream commit b814dfbfeb0a68c9a52073f2caa05a2d5247a329 ]

bnxt_alloc_one_tpa_info_data() returns -ENOMEM as soon as one allocation
fails. This leaves the remaining rxr->rx_tpa[] entries zeroed.

bnxt_queue_mem_alloc() discards that return value, so the partially
initialized ring is installed by bnxt_queue_start().

Since the agg_id is picked by the hardware and bnxt_alloc_agg_idx maps
it to a SW index in rxr->rx_tpa[], it is possible that an uninitialized
slot can be chosen which would hand a zero DMA address to the device.

Fix this by checking the return value of bnxt_alloc_one_tpa_info_data
and unwinding, freeing the ring buffers.

Fixes: bd649c5cc958 ("bnxt_en: handle tpa_info in queue API implementation")
Reported-by: Sashiko <sashiko-bot+sashiko@kernel.org>
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260828190900.1767611-1-joe%40dama.to
Cc: stable@vger.kernel.org
Signed-off-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260902015652.2421609-4-joe@dama.to
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
[ Retained bnxt_alloc_one_rx_ring_page() instead of upstream bnxt_alloc_one_rx_ring_netmem(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -15430,11 +15430,16 @@ static int bnxt_queue_mem_alloc(struct n
 	bnxt_alloc_one_rx_ring_skb(bp, clone, idx);
 	if (bp->flags & BNXT_FLAG_AGG_RINGS)
 		bnxt_alloc_one_rx_ring_page(bp, clone, idx);
-	if (bp->flags & BNXT_FLAG_TPA)
-		bnxt_alloc_one_tpa_info_data(bp, clone);
+	if (bp->flags & BNXT_FLAG_TPA) {
+		rc = bnxt_alloc_one_tpa_info_data(bp, clone);
+		if (rc)
+			goto err_free_rx_ring_skbs;
+	}
 
 	return 0;
 
+err_free_rx_ring_skbs:
+	bnxt_free_one_rx_ring_skbs(bp, clone);
 err_free_tpa_info:
 	bnxt_free_one_tpa_info(bp, clone);
 err_free_rx_agg_ring:



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 759/877] mptcp: pm: drop match in userspace_pm_append_new_local_addr
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (757 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 758/877] bnxt_en: Propagate TPA buffer allocation failures in bnxt_queue_mem_alloc() Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 760/877] sock: add sock_kmemdup helper Greg Kroah-Hartman
                   ` (125 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Geliang Tang, Matthieu Baerts (NGI0),
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Geliang Tang <tanggeliang@kylinos.cn>

[ Upstream commit 640e3d69d0bc70d7d3de34800a1640793262bd08 ]

The variable 'match' in mptcp_userspace_pm_append_new_local_addr() is a
redundant one, and this patch drops it.

No need to define 'match' as 'struct mptcp_pm_addr_entry *' type. In this
function, it's only used to check whether it's NULL. It can be defined as
a Boolean one.

Also other variables 'addr_match' and 'id_match' make 'match' a redundant
one, which can be replaced by directly checking 'addr_match && id_match'.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20250221-net-next-mptcp-pm-misc-cleanup-3-v1-5-2b70ab1cee79@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: f9f0068e8813 ("mptcp: pm: userspace: fix address ID overflow")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mptcp/pm_userspace.c |   11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -41,7 +41,6 @@ static int mptcp_userspace_pm_append_new
 						    bool needs_id)
 {
 	DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
-	struct mptcp_pm_addr_entry *match = NULL;
 	struct sock *sk = (struct sock *)msk;
 	struct mptcp_pm_addr_entry *e;
 	bool addr_match = false;
@@ -60,16 +59,12 @@ static int mptcp_userspace_pm_append_new
 		if (addr_match && entry->addr.id == 0 && needs_id)
 			entry->addr.id = e->addr.id;
 		id_match = (e->addr.id == entry->addr.id);
-		if (addr_match && id_match) {
-			match = e;
+		if (addr_match || id_match)
 			break;
-		} else if (addr_match || id_match) {
-			break;
-		}
 		__set_bit(e->addr.id, id_bitmap);
 	}
 
-	if (!match && !addr_match && !id_match) {
+	if (!addr_match && !id_match) {
 		/* Memory for the entry is allocated from the
 		 * sock option buffer.
 		 */
@@ -87,7 +82,7 @@ static int mptcp_userspace_pm_append_new
 		list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list);
 		msk->pm.local_addr_used++;
 		ret = e->addr.id;
-	} else if (match) {
+	} else if (addr_match && id_match) {
 		ret = entry->addr.id;
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 760/877] sock: add sock_kmemdup helper
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (758 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 759/877] mptcp: pm: drop match in userspace_pm_append_new_local_addr Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 761/877] mptcp: use sock_kmemdup for address entry Greg Kroah-Hartman
                   ` (124 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Geliang Tang, Kuniyuki Iwashima,
	Matthieu Baerts (NGI0), Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Geliang Tang <tanggeliang@kylinos.cn>

[ Upstream commit 456cc675b6d4cadd4872a477d8976ff56eef4b6f ]

This patch adds the sock version of kmemdup() helper, named sock_kmemdup(),
to duplicate the input "src" memory block using the socket's option memory
buffer.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Acked-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/f828077394c7d1f3560123497348b438c875b510.1740735165.git.tanggeliang@kylinos.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: f9f0068e8813 ("mptcp: pm: userspace: fix address ID overflow")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/net/sock.h |    2 ++
 net/core/sock.c    |   16 ++++++++++++++++
 2 files changed, 18 insertions(+)

--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1840,6 +1840,8 @@ static inline struct sk_buff *sock_alloc
 }
 
 void *sock_kmalloc(struct sock *sk, int size, gfp_t priority);
+void *sock_kmemdup(struct sock *sk, const void *src,
+		   int size, gfp_t priority);
 void sock_kfree_s(struct sock *sk, void *mem, int size);
 void sock_kzfree_s(struct sock *sk, void *mem, int size);
 void sk_send_sigurg(struct sock *sk);
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2837,6 +2837,22 @@ void *sock_kmalloc(struct sock *sk, int
 }
 EXPORT_SYMBOL(sock_kmalloc);
 
+/*
+ * Duplicate the input "src" memory block using the socket's
+ * option memory buffer.
+ */
+void *sock_kmemdup(struct sock *sk, const void *src,
+		   int size, gfp_t priority)
+{
+	void *mem;
+
+	mem = sock_kmalloc(sk, size, priority);
+	if (mem)
+		memcpy(mem, src, size);
+	return mem;
+}
+EXPORT_SYMBOL(sock_kmemdup);
+
 /* Free an option memory block. Note, we actually want the inline
  * here as this allows gcc to detect the nullify and fold away the
  * condition entirely.



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 761/877] mptcp: use sock_kmemdup for address entry
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (759 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 760/877] sock: add sock_kmemdup helper Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 762/877] mptcp: pm: userspace: fix address ID overflow Greg Kroah-Hartman
                   ` (123 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Geliang Tang, Matthieu Baerts (NGI0),
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Geliang Tang <tanggeliang@kylinos.cn>

[ Upstream commit 52f83c0b5f857dbe24f66fc9a7f035523e9ffbc9 ]

Instead of using sock_kmalloc() to allocate an address
entry "e" and then immediately duplicate the input "entry"
to it, the newly added sock_kmemdup() helper can be used in
mptcp_userspace_pm_append_new_local_addr() to simplify the code.

More importantly, the code "*e = *entry;" that assigns "entry"
to "e" is not easy to implemented in BPF if we use the same code
to implement an append_new_local_addr() helper of a BFP path
manager. This patch avoids this type of memory assignment
operation.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
Acked-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/3e5a307aed213038a87e44ff93b5793229b16279.1740735165.git.tanggeliang@kylinos.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: f9f0068e8813 ("mptcp: pm: userspace: fix address ID overflow")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mptcp/pm_userspace.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -68,13 +68,12 @@ static int mptcp_userspace_pm_append_new
 		/* Memory for the entry is allocated from the
 		 * sock option buffer.
 		 */
-		e = sock_kmalloc(sk, sizeof(*e), GFP_ATOMIC);
+		e = sock_kmemdup(sk, entry, sizeof(*entry), GFP_ATOMIC);
 		if (!e) {
 			ret = -ENOMEM;
 			goto append_err;
 		}
 
-		*e = *entry;
 		if (!e->addr.id && needs_id)
 			e->addr.id = find_next_zero_bit(id_bitmap,
 							MPTCP_PM_MAX_ADDR_ID + 1,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 762/877] mptcp: pm: userspace: fix address ID overflow
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (760 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 761/877] mptcp: use sock_kmemdup for address entry Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 763/877] bnxt_en: Do not set EOP on RX AGG BDs on 5760X chips Greg Kroah-Hartman
                   ` (122 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Qing Luo, Matthieu Baerts (NGI0),
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Qing Luo <luoqing@kylinos.cn>

[ Upstream commit f9f0068e8813d8c10d016b030fc3a320d0b6767c ]

When all MPTCP address IDs (1-255) are exhausted in the userspace PM,
find_next_zero_bit() returns MPTCP_PM_MAX_ADDR_ID + 1 (256). This value
overflows when stored in the u8 field e->addr.id, resulting in ID 0
being stored and the entry being incorrectly added to the list.

ID 0 is reserved for the initial connection in MPTCP, so this overflow
can cause address conflicts.

Note: the in-kernel PM already has an 'endpoints == MPTCP_PM_MAX_ADDR_ID'
check in mptcp_pm_nl_append_new_local_addr() that returns -ERANGE before
reaching find_next_zero_bit(), preventing this overflow. So this fix only
addresses the userspace PM path.

Check the find_next_zero_bit() result against MPTCP_PM_MAX_ADDR_ID and
return -ENOSPC if all IDs are truly exhausted. Move the ID allocation
check before the memory allocation so that the error path does not need
to free the allocated entry.

Fixes: 4638de5aefe5 ("mptcp: handle local addrs announced by userspace PMs")
Cc: stable@vger.kernel.org
Signed-off-by: Qing Luo <luoqing@kylinos.cn>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-8-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mptcp/pm_userspace.c |   18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -65,6 +65,19 @@ static int mptcp_userspace_pm_append_new
 	}
 
 	if (!addr_match && !id_match) {
+		unsigned int id;
+
+		if (!entry->addr.id && needs_id) {
+			id = find_next_zero_bit(id_bitmap,
+						MPTCP_PM_MAX_ADDR_ID + 1, 1);
+			if (id > MPTCP_PM_MAX_ADDR_ID) {
+				ret = -ENOSPC;
+				goto append_err;
+			}
+		} else {
+			id = entry->addr.id;
+		}
+
 		/* Memory for the entry is allocated from the
 		 * sock option buffer.
 		 */
@@ -74,10 +87,7 @@ static int mptcp_userspace_pm_append_new
 			goto append_err;
 		}
 
-		if (!e->addr.id && needs_id)
-			e->addr.id = find_next_zero_bit(id_bitmap,
-							MPTCP_PM_MAX_ADDR_ID + 1,
-							1);
+		e->addr.id = id;
 		list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list);
 		msk->pm.local_addr_used++;
 		ret = e->addr.id;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 763/877] bnxt_en: Do not set EOP on RX AGG BDs on 5760X chips
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (761 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 762/877] mptcp: pm: userspace: fix address ID overflow Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 764/877] eth: bnxt: store rx buffer size per queue Greg Kroah-Hartman
                   ` (121 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Andy Gospodarek, Somnath Kotur,
	Michael Chan, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Michael Chan <michael.chan@broadcom.com>

[ Upstream commit 30f253f8d9a01d532fdb7ec6c8a9d4c15fe29241 ]

With End-of-Packet padding (EOP) set, the chip will disable Relaxed
Ordering (RO) of TPA data packets.  A TPA segment with EOP set will be
padded to the next cache boundary and can potentially overwrite the
beginning bytes of the next TPA segment when RO is enabled on 5760X.
To prevent that, the chip disables RO for TPA when EOP is set.

To take advantge of RO and higher performance, do not set EOP on
5760X chips when TPA is enabled.  Define a proper RX_BD_FLAGS_AGG_EOP
constant to make it clear that we are setting EOP.

Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20251126215648.1885936-6-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 5ce7f36c334d ("bnxt_en: Don't free the live ring's TPA state on queue restart failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c |    9 ++++++++-
 drivers/net/ethernet/broadcom/bnxt/bnxt.h |    1 +
 2 files changed, 9 insertions(+), 1 deletion(-)

--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -4300,7 +4300,14 @@ static void bnxt_init_one_rx_agg_ring_rx
 	ring->fw_ring_id = INVALID_HW_RING_ID;
 	if ((bp->flags & BNXT_FLAG_AGG_RINGS)) {
 		type = ((u32)BNXT_RX_PAGE_SIZE << RX_BD_LEN_SHIFT) |
-			RX_BD_TYPE_RX_AGG_BD | RX_BD_FLAGS_SOP;
+			RX_BD_TYPE_RX_AGG_BD;
+
+		/* On P7, setting EOP will cause the chip to disable
+		 * Relaxed Ordering (RO) for TPA data.  Disable EOP for
+		 * potentially higher performance with RO.
+		 */
+		if (BNXT_CHIP_P5_AND_MINUS(bp) || !(bp->flags & BNXT_FLAG_TPA))
+			type |= RX_BD_FLAGS_AGG_EOP;
 
 		bnxt_init_rxbd_pages(ring, type);
 	}
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -124,6 +124,7 @@ struct rx_bd {
 	 #define RX_BD_TYPE_48B_BD_SIZE				 (2 << 4)
 	 #define RX_BD_TYPE_64B_BD_SIZE				 (3 << 4)
 	#define RX_BD_FLAGS_SOP					(1 << 6)
+	#define RX_BD_FLAGS_AGG_EOP				(1 << 6)
 	#define RX_BD_FLAGS_EOP					(1 << 7)
 	#define RX_BD_FLAGS_BUFFERS				(3 << 8)
 	 #define RX_BD_FLAGS_1_BUFFER_PACKET			 (0 << 8)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 764/877] eth: bnxt: store rx buffer size per queue
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (762 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 763/877] bnxt_en: Do not set EOP on RX AGG BDs on 5760X chips Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 765/877] bnxt: fix memory leak in bnxt_queue_mem_alloc error cases Greg Kroah-Hartman
                   ` (120 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jakub Kicinski, Pavel Begunkov,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pavel Begunkov <asml.silence@gmail.com>

[ Upstream commit f57efb32aae1da5c0a25acf473ef4ab559894adf ]

Instead of using a constant buffer length, allow configuring the size
for each queue separately. There is no way to change the length yet, and
it'll be passed from memory providers in a later patch.

Suggested-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>

Stable adaptation for 6.12:

Keep the per-queue buffer size change using the existing page-based RX
and XDP interfaces. Apply aggregation truesize accounting in
bnxt_rx_agg_pages_skb(), and program the size in the existing firmware
ring allocation path instead of adding the newer helper functions.

This tree has no unreadable netmem pools. Derive head-pool separation
from the queue buffer size, keep head allocations at order zero, and
use the same queue-specific decision for allocation and cleanup. Keep
the existing pool sizing and NAPI association. Queue sizes start at
BNXT_RX_PAGE_SIZE and are inherited by restart clones.

Initialize the clone's rx_agg_bmap to NULL to separate it from the live
ring and provide the common initialization context needed to cherry-pick
5ce7f36c334d ("bnxt_en: Don't free the live ring's TPA state on queue
restart failure") cleanly. The target's TPA pointer resets are left to
that commit. No functions are added.

Stable-dep-of: 5ce7f36c334d ("bnxt_en: Don't free the live ring's TPA state on queue restart failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c     |   60 ++++++++++++++------------
 drivers/net/ethernet/broadcom/bnxt/bnxt.h     |    1 
 drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c |    6 +-
 drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h |    2 
 4 files changed, 39 insertions(+), 30 deletions(-)

--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -867,9 +867,9 @@ static void bnxt_tx_int(struct bnxt *bp,
 		bnapi->events &= ~BNXT_TX_CMP_EVENT;
 }
 
-static bool bnxt_separate_head_pool(void)
+static bool bnxt_separate_head_pool(struct bnxt_rx_ring_info *rxr)
 {
-	return PAGE_SIZE > BNXT_RX_PAGE_SIZE;
+	return rxr->rx_page_size != PAGE_SIZE;
 }
 
 static struct page *__bnxt_alloc_rx_page(struct bnxt *bp, dma_addr_t *mapping,
@@ -879,9 +879,9 @@ static struct page *__bnxt_alloc_rx_page
 {
 	struct page *page;
 
-	if (PAGE_SIZE > BNXT_RX_PAGE_SIZE) {
+	if (rxr->rx_page_size < PAGE_SIZE) {
 		page = page_pool_dev_alloc_frag(rxr->page_pool, offset,
-						BNXT_RX_PAGE_SIZE);
+						rxr->rx_page_size);
 	} else {
 		page = page_pool_dev_alloc_pages(rxr->page_pool);
 		*offset = 0;
@@ -1101,9 +1101,9 @@ static struct sk_buff *bnxt_rx_multi_pag
 		return NULL;
 	}
 	dma_addr -= bp->rx_dma_offset;
-	dma_sync_single_for_cpu(&bp->pdev->dev, dma_addr, BNXT_RX_PAGE_SIZE,
+	dma_sync_single_for_cpu(&bp->pdev->dev, dma_addr, rxr->rx_page_size,
 				bp->rx_dir);
-	skb = napi_build_skb(data_ptr - bp->rx_offset, BNXT_RX_PAGE_SIZE);
+	skb = napi_build_skb(data_ptr - bp->rx_offset, rxr->rx_page_size);
 	if (!skb) {
 		page_pool_recycle_direct(rxr->page_pool, page);
 		return NULL;
@@ -1135,7 +1135,7 @@ static struct sk_buff *bnxt_rx_page_skb(
 		return NULL;
 	}
 	dma_addr -= bp->rx_dma_offset;
-	dma_sync_single_for_cpu(&bp->pdev->dev, dma_addr, BNXT_RX_PAGE_SIZE,
+	dma_sync_single_for_cpu(&bp->pdev->dev, dma_addr, rxr->rx_page_size,
 				bp->rx_dir);
 
 	if (unlikely(!payload))
@@ -1149,7 +1149,7 @@ static struct sk_buff *bnxt_rx_page_skb(
 
 	skb_mark_for_recycle(skb);
 	off = (void *)data_ptr - page_address(page);
-	skb_add_rx_frag(skb, 0, page, off, len, BNXT_RX_PAGE_SIZE);
+	skb_add_rx_frag(skb, 0, page, off, len, rxr->rx_page_size);
 	memcpy(skb->data - NET_IP_ALIGN, data_ptr - NET_IP_ALIGN,
 	       payload + NET_IP_ALIGN);
 
@@ -1253,7 +1253,7 @@ static u32 __bnxt_rx_agg_pages(struct bn
 			return 0;
 		}
 
-		dma_sync_single_for_cpu(&pdev->dev, mapping, BNXT_RX_PAGE_SIZE,
+		dma_sync_single_for_cpu(&pdev->dev, mapping, rxr->rx_page_size,
 					bp->rx_dir);
 
 		total_frag_len += frag_len;
@@ -1268,6 +1268,7 @@ static struct sk_buff *bnxt_rx_agg_pages
 					     struct sk_buff *skb, u16 idx,
 					     u32 agg_bufs, bool tpa)
 {
+	struct bnxt_rx_ring_info *rxr = cpr->bnapi->rx_ring;
 	struct skb_shared_info *shinfo = skb_shinfo(skb);
 	u32 total_frag_len = 0;
 
@@ -1281,7 +1282,7 @@ static struct sk_buff *bnxt_rx_agg_pages
 
 	skb->data_len += total_frag_len;
 	skb->len += total_frag_len;
-	skb->truesize += BNXT_RX_PAGE_SIZE * agg_bufs;
+	skb->truesize += rxr->rx_page_size * agg_bufs;
 	return skb;
 }
 
@@ -2222,8 +2223,7 @@ static int bnxt_rx_pkt(struct bnxt *bp,
 			if (!skb)
 				goto oom_next_rx;
 		} else {
-			skb = bnxt_xdp_build_skb(bp, skb, agg_bufs,
-						 rxr->page_pool, &xdp);
+			skb = bnxt_xdp_build_skb(bp, skb, agg_bufs, rxr, &xdp);
 			if (!skb) {
 				/* we should be able to free the old skb here */
 				bnxt_xdp_buff_frags_free(rxr, &xdp);
@@ -3647,7 +3647,7 @@ static void bnxt_free_rx_rings(struct bn
 			xdp_rxq_info_unreg(&rxr->xdp_rxq);
 
 		page_pool_destroy(rxr->page_pool);
-		if (bnxt_separate_head_pool())
+		if (bnxt_separate_head_pool(rxr))
 			page_pool_destroy(rxr->head_pool);
 		rxr->page_pool = rxr->head_pool = NULL;
 
@@ -3672,12 +3672,14 @@ static int bnxt_alloc_rx_page_pool(struc
 	pp.pool_size = bp->rx_agg_ring_size;
 	if (BNXT_RX_PAGE_MODE(bp))
 		pp.pool_size += bp->rx_ring_size;
+
+	pp.order = get_order(rxr->rx_page_size);
 	pp.nid = numa_node;
 	pp.napi = &rxr->bnapi->napi;
 	pp.netdev = bp->dev;
 	pp.dev = &bp->pdev->dev;
 	pp.dma_dir = bp->rx_dir;
-	pp.max_len = PAGE_SIZE;
+	pp.max_len = PAGE_SIZE << pp.order;
 	pp.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV;
 
 	pool = page_pool_create(&pp);
@@ -3685,7 +3687,9 @@ static int bnxt_alloc_rx_page_pool(struc
 		return PTR_ERR(pool);
 	rxr->page_pool = pool;
 
-	if (bnxt_separate_head_pool()) {
+	if (bnxt_separate_head_pool(rxr)) {
+		pp.order = 0;
+		pp.max_len = PAGE_SIZE;
 		pp.pool_size = max(bp->rx_ring_size, 1024);
 		pool = page_pool_create(&pp);
 		if (IS_ERR(pool))
@@ -4140,6 +4144,8 @@ static void bnxt_init_ring_struct(struct
 		if (!rxr)
 			goto skip_rx;
 
+		rxr->rx_page_size = BNXT_RX_PAGE_SIZE;
+
 		ring = &rxr->rx_ring_struct;
 		rmem = &ring->ring_mem;
 		rmem->nr_pages = bp->rx_nr_pages;
@@ -4299,7 +4305,7 @@ static void bnxt_init_one_rx_agg_ring_rx
 	ring = &rxr->rx_agg_ring_struct;
 	ring->fw_ring_id = INVALID_HW_RING_ID;
 	if ((bp->flags & BNXT_FLAG_AGG_RINGS)) {
-		type = ((u32)BNXT_RX_PAGE_SIZE << RX_BD_LEN_SHIFT) |
+		type = ((u32)rxr->rx_page_size << RX_BD_LEN_SHIFT) |
 			RX_BD_TYPE_RX_AGG_BD;
 
 		/* On P7, setting EOP will cause the chip to disable
@@ -6865,6 +6871,7 @@ static void bnxt_hwrm_ring_grp_free(stru
 }
 
 static int hwrm_ring_alloc_send_msg(struct bnxt *bp,
+				    struct bnxt_rx_ring_info *rxr,
 				    struct bnxt_ring_struct *ring,
 				    u32 ring_type, u32 map_index)
 {
@@ -6937,7 +6944,7 @@ static int hwrm_ring_alloc_send_msg(stru
 			/* Association of agg ring with rx ring */
 			grp_info = &bp->grp_info[ring->grp_idx];
 			req->rx_ring_id = cpu_to_le16(grp_info->rx_fw_ring_id);
-			req->rx_buf_size = cpu_to_le16(BNXT_RX_PAGE_SIZE);
+			req->rx_buf_size = cpu_to_le16(rxr->rx_page_size);
 			req->stat_ctx_id = cpu_to_le32(grp_info->fw_stats_ctx);
 			req->enables |= cpu_to_le32(
 				RING_ALLOC_REQ_ENABLES_RX_RING_ID_VALID |
@@ -7093,7 +7100,7 @@ static int bnxt_hwrm_rx_ring_alloc(struc
 	u32 map_idx = bnapi->index;
 	int rc;
 
-	rc = hwrm_ring_alloc_send_msg(bp, ring, type, map_idx);
+	rc = hwrm_ring_alloc_send_msg(bp, rxr, ring, type, map_idx);
 	if (rc)
 		return rc;
 
@@ -7113,7 +7120,7 @@ static int bnxt_hwrm_rx_agg_ring_alloc(s
 	int rc;
 
 	map_idx = grp_idx + bp->rx_nr_rings;
-	rc = hwrm_ring_alloc_send_msg(bp, ring, type, map_idx);
+	rc = hwrm_ring_alloc_send_msg(bp, rxr, ring, type, map_idx);
 	if (rc)
 		return rc;
 
@@ -7145,7 +7152,7 @@ static int bnxt_hwrm_ring_alloc(struct b
 
 		vector = bp->irq_tbl[map_idx].vector;
 		disable_irq_nosync(vector);
-		rc = hwrm_ring_alloc_send_msg(bp, ring, type, map_idx);
+		rc = hwrm_ring_alloc_send_msg(bp, NULL, ring, type, map_idx);
 		if (rc) {
 			enable_irq(vector);
 			goto err_out;
@@ -7176,7 +7183,7 @@ static int bnxt_hwrm_ring_alloc(struct b
 			ring = &cpr2->cp_ring_struct;
 			ring->handle = BNXT_SET_NQ_HDL(cpr2);
 			map_idx = bnapi->index;
-			rc = hwrm_ring_alloc_send_msg(bp, ring, type2, map_idx);
+			rc = hwrm_ring_alloc_send_msg(bp, NULL, ring, type2, map_idx);
 			if (rc)
 				goto err_out;
 			bnxt_set_db(bp, &cpr2->cp_db, type2, map_idx,
@@ -7185,7 +7192,7 @@ static int bnxt_hwrm_ring_alloc(struct b
 		}
 		ring = &txr->tx_ring_struct;
 		map_idx = i;
-		rc = hwrm_ring_alloc_send_msg(bp, ring, type, map_idx);
+		rc = hwrm_ring_alloc_send_msg(bp, NULL, ring, type, map_idx);
 		if (rc)
 			goto err_out;
 		bnxt_set_db(bp, &txr->tx_db, type, map_idx, ring->fw_ring_id);
@@ -7209,7 +7216,7 @@ static int bnxt_hwrm_ring_alloc(struct b
 
 			ring = &cpr2->cp_ring_struct;
 			ring->handle = BNXT_SET_NQ_HDL(cpr2);
-			rc = hwrm_ring_alloc_send_msg(bp, ring, type2, map_idx);
+			rc = hwrm_ring_alloc_send_msg(bp, NULL, ring, type2, map_idx);
 			if (rc)
 				goto err_out;
 			bnxt_set_db(bp, &cpr2->cp_db, type2, map_idx,
@@ -15394,6 +15401,7 @@ static int bnxt_queue_mem_alloc(struct n
 	clone->rx_agg_prod = 0;
 	clone->rx_sw_agg_prod = 0;
 	clone->rx_next_cons = 0;
+	clone->rx_agg_bmap = NULL;
 
 	rc = bnxt_alloc_rx_page_pool(bp, clone, rxr->page_pool->p.nid);
 	if (rc)
@@ -15457,7 +15465,7 @@ err_rxq_info_unreg:
 	xdp_rxq_info_unreg(&clone->xdp_rxq);
 err_page_pool_destroy:
 	page_pool_destroy(clone->page_pool);
-	if (bnxt_separate_head_pool())
+	if (bnxt_separate_head_pool(clone))
 		page_pool_destroy(clone->head_pool);
 	clone->page_pool = NULL;
 	clone->head_pool = NULL;
@@ -15476,7 +15484,7 @@ static void bnxt_queue_mem_free(struct n
 	xdp_rxq_info_unreg(&rxr->xdp_rxq);
 
 	page_pool_destroy(rxr->page_pool);
-	if (bnxt_separate_head_pool())
+	if (bnxt_separate_head_pool(rxr))
 		page_pool_destroy(rxr->head_pool);
 	rxr->page_pool = NULL;
 	rxr->head_pool = NULL;
@@ -15620,7 +15628,7 @@ static int bnxt_queue_stop(struct net_de
 	bnxt_hwrm_rx_agg_ring_free(bp, rxr, false);
 	rxr->rx_next_cons = 0;
 	page_pool_disable_direct_recycling(rxr->page_pool);
-	if (bnxt_separate_head_pool())
+	if (bnxt_separate_head_pool(rxr))
 		page_pool_disable_direct_recycling(rxr->head_pool);
 
 	memcpy(qmem, rxr, sizeof(*rxr));
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -1098,6 +1098,7 @@ struct bnxt_rx_ring_info {
 
 	unsigned long		*rx_agg_bmap;
 	u16			rx_agg_bmap_size;
+	u32			rx_page_size;
 
 	dma_addr_t		rx_desc_mapping[MAX_RX_PAGES];
 	dma_addr_t		rx_agg_desc_mapping[MAX_RX_AGG_PAGES];
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -182,7 +182,7 @@ void bnxt_xdp_buff_init(struct bnxt *bp,
 			u16 cons, u8 *data_ptr, unsigned int len,
 			struct xdp_buff *xdp)
 {
-	u32 buflen = BNXT_RX_PAGE_SIZE;
+	u32 buflen = rxr->rx_page_size;
 	struct bnxt_sw_rx_bd *rx_buf;
 	struct pci_dev *pdev;
 	dma_addr_t mapping;
@@ -454,7 +454,7 @@ int bnxt_xdp(struct net_device *dev, str
 
 struct sk_buff *
 bnxt_xdp_build_skb(struct bnxt *bp, struct sk_buff *skb, u8 num_frags,
-		   struct page_pool *pool, struct xdp_buff *xdp)
+		   struct bnxt_rx_ring_info *rxr, struct xdp_buff *xdp)
 {
 	struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp);
 
@@ -463,7 +463,7 @@ bnxt_xdp_build_skb(struct bnxt *bp, stru
 
 	xdp_update_skb_shared_info(skb, num_frags,
 				   sinfo->xdp_frags_size,
-				   BNXT_RX_PAGE_SIZE * num_frags,
+				   rxr->rx_page_size * num_frags,
 				   xdp_buff_is_frag_pfmemalloc(xdp));
 	return skb;
 }
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.h
@@ -32,6 +32,6 @@ void bnxt_xdp_buff_init(struct bnxt *bp,
 void bnxt_xdp_buff_frags_free(struct bnxt_rx_ring_info *rxr,
 			      struct xdp_buff *xdp);
 struct sk_buff *bnxt_xdp_build_skb(struct bnxt *bp, struct sk_buff *skb,
-				   u8 num_frags, struct page_pool *pool,
+				   u8 num_frags, struct bnxt_rx_ring_info *rxr,
 				   struct xdp_buff *xdp);
 #endif



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 765/877] bnxt: fix memory leak in bnxt_queue_mem_alloc error cases
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (763 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 764/877] eth: bnxt: store rx buffer size per queue Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 766/877] bnxt_en: Dont free the live rings TPA state on queue restart failure Greg Kroah-Hartman
                   ` (119 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Will Chen, Joe Damato, Michael Chan,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Will Chen <will.chen.tty@gmail.com>

[ Upstream commit d1000fd7995e51deec872d154e0a40d82f7a539f ]

There is a small memory leak in bnxt_queue_mem_alloc:
when bnxt_alloc_rx_agg_bmap() succeeds
but bnxt_alloc_one_tpa_info() later fails,
the rx_agg_bmap allocated by bnxt_alloc_rx_agg_bmap()
is not freed in the fallthrough cleanup cases.

Free the rx_agg_bmap in the err_free_rx_agg_ring case
and initialize clone->rx_agg_bmap = NULL earlier in the function
to allow for safe fallthrough.

Fixes: bd649c5cc958 ("bnxt_en: handle tpa_info in queue API implementation")
Signed-off-by: Will Chen <will.chen.tty@gmail.com>
Reviewed-by: Joe Damato <joe@dama.to>
Reviewed-by: Michael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20260729220132.1256924-1-will.chen.tty@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Stable adaptation for 6.12:

The preceding per-queue buffer-size backport already initializes the
clone's rx_agg_bmap to NULL. Retain that initialization and apply the
missing bitmap cleanup to err_free_rx_agg_ring. This frees the clone's
bitmap when TPA allocation fails, while earlier allocation failures
can safely fall through with a NULL bitmap.

Keep the existing queue allocation interface and inherited RX page
size: this tree has neither qcfg nor need_head_pool. Leave the TPA
pointer resets to target commit 5ce7f36c334d. No functions are added.

Stable-dep-of: 5ce7f36c334d ("bnxt_en: Don't free the live ring's TPA state on queue restart failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -15459,6 +15459,8 @@ err_free_tpa_info:
 	bnxt_free_one_tpa_info(bp, clone);
 err_free_rx_agg_ring:
 	bnxt_free_ring(bp, &clone->rx_agg_ring_struct.ring_mem);
+	kfree(clone->rx_agg_bmap);
+	clone->rx_agg_bmap = NULL;
 err_free_rx_ring:
 	bnxt_free_ring(bp, &clone->rx_ring_struct.ring_mem);
 err_rxq_info_unreg:



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 766/877] bnxt_en: Dont free the live rings TPA state on queue restart failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (764 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 765/877] bnxt: fix memory leak in bnxt_queue_mem_alloc error cases Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 767/877] mptcp: pm: reset retrans_time when ADD_ADDR entry is reused Greg Kroah-Hartman
                   ` (118 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Joe Damato, Paolo Abeni,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Joe Damato <joe@dama.to>

[ Upstream commit 5ce7f36c334d723954855ac769ede2fe0e8f89c8 ]

bnxt_queue_mem_alloc() shallow copies the live RX ring into the clone:

  memcpy(clone, rxr, sizeof(*rxr));

the code currently clears pointers that the clone owns (such as
rx_agg_bmap), but rx_tpa and rx_tpa_idx_map are left pointing at memory
of the live ring that was cloned.

If an allocation failure happens later and the err_free_tpa_info label
is taken, the live ring's memory can be freed while still in use.

Fix this by initializing the clone's pointers to NULL to prevent live
ring state from being freed inadvertently.

Fixes: bd649c5cc958 ("bnxt_en: handle tpa_info in queue API implementation")
Reported-by: Sashiko <sashiko-bot+sashiko@kernel.org>
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260828190900.1767611-1-joe%40dama.to
Cc: stable@vger.kernel.org
Signed-off-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260902015652.2421609-3-joe@dama.to
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c |    2 ++
 1 file changed, 2 insertions(+)

--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -15402,6 +15402,8 @@ static int bnxt_queue_mem_alloc(struct n
 	clone->rx_sw_agg_prod = 0;
 	clone->rx_next_cons = 0;
 	clone->rx_agg_bmap = NULL;
+	clone->rx_tpa = NULL;
+	clone->rx_tpa_idx_map = NULL;
 
 	rc = bnxt_alloc_rx_page_pool(bp, clone, rxr->page_pool->p.nid);
 	if (rc)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 767/877] mptcp: pm: reset retrans_time when ADD_ADDR entry is reused
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (765 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 766/877] bnxt_en: Dont free the live rings TPA state on queue restart failure Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:27 ` [PATCH 6.12 768/877] mptcp: pm: use for_each_subflow helper Greg Kroah-Hartman
                   ` (117 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mat Martineau,
	Matthieu Baerts (NGI0), Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>

[ Upstream commit f968190c0b42ea2004dc1426359a53ec365a7a37 ]

When an ADD_ADDR entry is reused, the timer is re-armed, because the
goal is to re-announce an ADD_ADDR, and eventually retransmit it if
needed.

In this case, the retransmission counter should be reset as well, so the
re-announced address gets its retransmissions back instead of relying on
what was left before, and possibly not being able to retransmit it.

Fixes: 304ab97f4c7c ("mptcp: allow ADD_ADDR reissuance by userspace PMs")
Cc: stable@vger.kernel.org
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260803-net-mptcp-misc-fixes-7-2-rc6-v2-0-b8f496d71664%40kernel.org?part=4
Reviewed-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-9-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ adapted mptcp_pm_announced_alloc() in pm.c to mptcp_pm_alloc_anno_list() in pm_netlink.c. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mptcp/pm_netlink.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -417,10 +417,10 @@ bool mptcp_pm_alloc_anno_list(struct mpt
 
 	add_entry->addr = *addr;
 	add_entry->sock = msk;
-	add_entry->retrans_times = 0;
 
 	timer_setup(&add_entry->add_timer, mptcp_pm_add_timer, 0);
 reset_timer:
+	add_entry->retrans_times = 0;
 	add_entry->timer_done = false;
 	timeout = mptcp_get_add_addr_timeout(net);
 	if (timeout)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 768/877] mptcp: pm: use for_each_subflow helper
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (766 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 767/877] mptcp: pm: reset retrans_time when ADD_ADDR entry is reused Greg Kroah-Hartman
@ 2026-09-30 15:27 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 769/877] mptcp: pm: rename add_entry structure to add_addr Greg Kroah-Hartman
                   ` (116 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:27 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mat Martineau,
	Matthieu Baerts (NGI0), Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>

[ Upstream commit f81689172429885d6c2c7c3dd4926ec626e794bb ]

Similar to most places in the MPTCP code. So instead of passing the
subflow list and use list_for_each_entry(subflow, list, node), pass the
msk and use mptcp_for_each_subflow(msk, subflow).

That's clearer and more uniform with the rest.

While at it, add 'pm_' prefix for the exported one to easily identify
the origin. Plus replace 'lookup' by 'has', because a bool is returned.

Reviewed-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260605-net-next-mptcp-add-addr6-port-ts-v2-9-758e7ca73f4d@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Stable backport adaptation for 2ac7d6e620764f1fc79eb4edd3610a7a661981ca:

The stable tree keeps both subflow lookups and their callers in
pm_netlink.c. Apply the iterator conversion there, retaining private
helpers and using has_subflow_saddr() for the source-address lookup.
Drop the upstream pm.c, pm_userspace.c and protocol.h hunks, which assume
helper moves and a userspace callback not present on this branch.

Rename pm_netlink.c to pm_kernel.c and update the Makefile so the target
patch finds its existing ID0 removal function at the upstream path.
Rename the existing remove_anno_list_by_saddr() and
mptcp_pm_nl_rm_subflow_received() helpers to mptcp_pm_announced_remove()
and mptcp_pm_rm_subflow(), updating all callers, to provide the target's
helper name and patch context. Keep their stable implementations and
static linkage. No functions are added and the ID0 fix itself remains
for the target commit.

[ sashal: Reduced backport -- upstream f816891724298 touches 4 file(s), this
  backport carries 2. Not backported here:
  net/mptcp/pm.c
  net/mptcp/pm_userspace.c
  net/mptcp/protocol.h
  This note is generated from the file lists only; see the resolution record
  for the reasoning. ]

Stable-dep-of: 2ac7d6e62076 ("mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mptcp/Makefile     |    2 
 net/mptcp/pm_kernel.c  | 2602 ++++++++++++++++++++++++++++++++++++++++++++++++
 net/mptcp/pm_netlink.c | 2603 -------------------------------------------------
 3 files changed, 2603 insertions(+), 2604 deletions(-)
 rename net/mptcp/{pm_netlink.c => pm_kernel.c} (98%)

--- a/net/mptcp/Makefile
+++ b/net/mptcp/Makefile
@@ -2,7 +2,7 @@
 obj-$(CONFIG_MPTCP) += mptcp.o
 
 mptcp-y := protocol.o subflow.o options.o token.o crypto.o ctrl.o pm.o diag.o \
-	   mib.o pm_netlink.o sockopt.o pm_userspace.o fastopen.o sched.o \
+	   mib.o pm_kernel.o sockopt.o pm_userspace.o fastopen.o sched.o \
 	   mptcp_pm_gen.o
 
 obj-$(CONFIG_SYN_COOKIES) += syncookies.o
--- /dev/null
+++ b/net/mptcp/pm_kernel.c
@@ -0,0 +1,2602 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Multipath TCP
+ *
+ * Copyright (c) 2020, Red Hat, Inc.
+ */
+
+#define pr_fmt(fmt) "MPTCP: " fmt
+
+#include <linux/inet.h>
+#include <linux/kernel.h>
+#include <net/inet_common.h>
+#include <net/netns/generic.h>
+#include <net/mptcp.h>
+
+#include "protocol.h"
+#include "mib.h"
+#include "mptcp_pm_gen.h"
+
+static int pm_nl_pernet_id;
+
+struct mptcp_pm_add_entry {
+	struct list_head	list;
+	struct mptcp_addr_info	addr;
+	u8			retrans_times;
+	bool			timer_done;
+	struct timer_list	add_timer;
+	struct mptcp_sock	*sock;
+	struct rcu_head		rcu;
+};
+
+struct pm_nl_pernet {
+	/* protects pernet updates */
+	spinlock_t		lock;
+	struct list_head	local_addr_list;
+	unsigned int		addrs;
+	unsigned int		stale_loss_cnt;
+	unsigned int		add_addr_signal_max;
+	unsigned int		add_addr_accept_max;
+	unsigned int		local_addr_max;
+	unsigned int		subflows_max;
+	unsigned int		next_id;
+	DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
+};
+
+#define MPTCP_PM_ADDR_MAX	8
+#define ADD_ADDR_RETRANS_MAX	3
+
+static struct pm_nl_pernet *pm_nl_get_pernet(const struct net *net)
+{
+	return net_generic(net, pm_nl_pernet_id);
+}
+
+static struct pm_nl_pernet *
+pm_nl_get_pernet_from_msk(const struct mptcp_sock *msk)
+{
+	return pm_nl_get_pernet(sock_net((struct sock *)msk));
+}
+
+bool mptcp_addresses_equal(const struct mptcp_addr_info *a,
+			   const struct mptcp_addr_info *b, bool use_port)
+{
+	bool addr_equals = false;
+
+	if (a->family == b->family) {
+		if (a->family == AF_INET)
+			addr_equals = a->addr.s_addr == b->addr.s_addr;
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+		else
+			addr_equals = !ipv6_addr_cmp(&a->addr6, &b->addr6);
+	} else if (a->family == AF_INET) {
+		if (ipv6_addr_v4mapped(&b->addr6))
+			addr_equals = a->addr.s_addr == b->addr6.s6_addr32[3];
+	} else if (b->family == AF_INET) {
+		if (ipv6_addr_v4mapped(&a->addr6))
+			addr_equals = a->addr6.s6_addr32[3] == b->addr.s_addr;
+#endif
+	}
+
+	if (!addr_equals)
+		return false;
+	if (!use_port)
+		return true;
+
+	return a->port == b->port;
+}
+
+void mptcp_local_address(const struct sock_common *skc, struct mptcp_addr_info *addr)
+{
+	addr->family = skc->skc_family;
+	addr->port = htons(skc->skc_num);
+	if (addr->family == AF_INET)
+		addr->addr.s_addr = skc->skc_rcv_saddr;
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	else if (addr->family == AF_INET6)
+		addr->addr6 = skc->skc_v6_rcv_saddr;
+#endif
+}
+
+static void remote_address(const struct sock_common *skc,
+			   struct mptcp_addr_info *addr)
+{
+	addr->family = skc->skc_family;
+	addr->port = skc->skc_dport;
+	if (addr->family == AF_INET)
+		addr->addr.s_addr = skc->skc_daddr;
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	else if (addr->family == AF_INET6)
+		addr->addr6 = skc->skc_v6_daddr;
+#endif
+}
+
+static bool has_subflow_saddr(const struct mptcp_sock *msk,
+			      const struct mptcp_addr_info *saddr)
+{
+	struct mptcp_subflow_context *subflow;
+	struct mptcp_addr_info cur;
+	struct sock_common *skc;
+
+	mptcp_for_each_subflow(msk, subflow) {
+		skc = (struct sock_common *)mptcp_subflow_tcp_sock(subflow);
+
+		mptcp_local_address(skc, &cur);
+		if (mptcp_addresses_equal(&cur, saddr, saddr->port))
+			return true;
+	}
+
+	return false;
+}
+
+static bool has_subflow_daddr(const struct mptcp_sock *msk,
+			      const struct mptcp_addr_info *daddr)
+{
+	struct mptcp_subflow_context *subflow;
+	struct mptcp_addr_info cur;
+
+	mptcp_for_each_subflow(msk, subflow) {
+		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+
+		if (!((1 << inet_sk_state_load(ssk)) &
+		      (TCPF_ESTABLISHED | TCPF_SYN_SENT | TCPF_SYN_RECV)))
+			continue;
+
+		remote_address((struct sock_common *)ssk, &cur);
+		if (mptcp_addresses_equal(&cur, daddr, daddr->port))
+			return true;
+	}
+
+	return false;
+}
+
+static bool
+select_local_address(const struct pm_nl_pernet *pernet,
+		     const struct mptcp_sock *msk,
+		     struct mptcp_pm_local *new_local)
+{
+	struct mptcp_pm_addr_entry *entry;
+	bool found = false;
+
+	msk_owned_by_me(msk);
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
+		if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW))
+			continue;
+
+		if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
+			continue;
+
+		new_local->addr = entry->addr;
+		new_local->flags = entry->flags;
+		new_local->ifindex = entry->ifindex;
+		found = true;
+		break;
+	}
+	rcu_read_unlock();
+
+	return found;
+}
+
+static bool
+select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk,
+		     struct mptcp_pm_local *new_local)
+{
+	struct mptcp_pm_addr_entry *entry;
+	bool found = false;
+
+	rcu_read_lock();
+	/* do not keep any additional per socket state, just signal
+	 * the address list in order.
+	 * Note: removal from the local address list during the msk life-cycle
+	 * can lead to additional addresses not being announced.
+	 */
+	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
+		if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
+			continue;
+
+		if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
+			continue;
+
+		new_local->addr = entry->addr;
+		new_local->flags = entry->flags;
+		new_local->ifindex = entry->ifindex;
+		found = true;
+		break;
+	}
+	rcu_read_unlock();
+
+	return found;
+}
+
+unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk)
+{
+	const struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
+
+	return READ_ONCE(pernet->add_addr_signal_max);
+}
+EXPORT_SYMBOL_GPL(mptcp_pm_get_add_addr_signal_max);
+
+unsigned int mptcp_pm_get_add_addr_accept_max(const struct mptcp_sock *msk)
+{
+	struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
+
+	return READ_ONCE(pernet->add_addr_accept_max);
+}
+EXPORT_SYMBOL_GPL(mptcp_pm_get_add_addr_accept_max);
+
+unsigned int mptcp_pm_get_subflows_max(const struct mptcp_sock *msk)
+{
+	struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
+
+	return READ_ONCE(pernet->subflows_max);
+}
+EXPORT_SYMBOL_GPL(mptcp_pm_get_subflows_max);
+
+unsigned int mptcp_pm_get_local_addr_max(const struct mptcp_sock *msk)
+{
+	struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
+
+	return READ_ONCE(pernet->local_addr_max);
+}
+EXPORT_SYMBOL_GPL(mptcp_pm_get_local_addr_max);
+
+bool mptcp_pm_nl_check_work_pending(struct mptcp_sock *msk)
+{
+	struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
+
+	if (msk->pm.subflows == mptcp_pm_get_subflows_max(msk) ||
+	    (find_next_and_bit(pernet->id_bitmap, msk->pm.id_avail_bitmap,
+			       MPTCP_PM_MAX_ADDR_ID + 1, 0) == MPTCP_PM_MAX_ADDR_ID + 1)) {
+		WRITE_ONCE(msk->pm.work_pending, false);
+		return false;
+	}
+	return true;
+}
+
+struct mptcp_pm_add_entry *
+mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
+				const struct mptcp_addr_info *addr)
+{
+	struct mptcp_pm_add_entry *entry;
+
+	lockdep_assert_held(&msk->pm.lock);
+
+	list_for_each_entry(entry, &msk->pm.anno_list, list) {
+		if (mptcp_addresses_equal(&entry->addr, addr, true))
+			return entry;
+	}
+
+	return NULL;
+}
+
+bool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk)
+{
+	struct mptcp_pm_add_entry *entry;
+	struct mptcp_addr_info saddr;
+	bool ret = false;
+
+	mptcp_local_address((struct sock_common *)sk, &saddr);
+
+	spin_lock_bh(&msk->pm.lock);
+	list_for_each_entry(entry, &msk->pm.anno_list, list) {
+		if (mptcp_addresses_equal(&entry->addr, &saddr, true)) {
+			ret = true;
+			goto out;
+		}
+	}
+
+out:
+	spin_unlock_bh(&msk->pm.lock);
+	return ret;
+}
+
+static void mptcp_pm_add_timer(struct timer_list *timer)
+{
+	struct mptcp_pm_add_entry *entry = from_timer(entry, timer, add_timer);
+	struct mptcp_sock *msk = entry->sock;
+	struct sock *sk = (struct sock *)msk;
+	unsigned int timeout = 0;
+	bool retransmit;
+
+	pr_debug("msk=%p\n", msk);
+
+	bh_lock_sock(sk);
+	if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE))
+		goto out;
+
+	if (sock_owned_by_user(sk)) {
+		/* Try again later. */
+		timeout = HZ / 20;
+		goto out;
+	}
+
+	if (mptcp_pm_should_add_signal_addr(msk)) {
+		timeout = HZ;
+		goto out;
+	}
+
+	timeout = mptcp_get_add_addr_timeout(sock_net(sk));
+	if (!timeout)
+		goto out;
+
+	spin_lock_bh(&msk->pm.lock);
+
+	/* The cancel path (mptcp_pm_del_add_timer()) can race with this
+	 * callback. Once cancel updates retrans_times to MAX, suppress further
+	 * retransmissions here. If this callback acquires pm.lock first, one
+	 * final transmit attempt is still possible.
+	 */
+	if (entry->retrans_times < ADD_ADDR_RETRANS_MAX &&
+	    !mptcp_pm_should_add_signal_addr(msk)) {
+		pr_debug("retransmit ADD_ADDR id=%d\n", entry->addr.id);
+		mptcp_pm_announce_addr(msk, &entry->addr, false);
+		mptcp_pm_add_addr_send_ack(msk);
+		entry->retrans_times++;
+	}
+
+	retransmit = entry->retrans_times < ADD_ADDR_RETRANS_MAX;
+	if (!retransmit)
+		timeout = 0;
+
+	spin_unlock_bh(&msk->pm.lock);
+
+	if (!retransmit)
+		mptcp_pm_subflow_established(msk);
+
+out:
+	if (timeout)
+		sk_reset_timer(sk, timer, jiffies + timeout);
+	else
+		/* if sock_put calls sk_free: avoid waiting for this timer */
+		entry->timer_done = true;
+	bh_unlock_sock(sk);
+	sock_put(sk);
+}
+
+struct mptcp_pm_add_entry *
+mptcp_pm_del_add_timer(struct mptcp_sock *msk,
+		       const struct mptcp_addr_info *addr, bool check_id)
+{
+	struct mptcp_pm_add_entry *entry;
+	struct sock *sk = (struct sock *)msk;
+	bool stop_timer = false;
+
+	rcu_read_lock();
+
+	spin_lock_bh(&msk->pm.lock);
+	entry = mptcp_lookup_anno_list_by_saddr(msk, addr);
+	if (entry && (!check_id || entry->addr.id == addr->id)) {
+		entry->retrans_times = ADD_ADDR_RETRANS_MAX;
+		stop_timer = true;
+	}
+	if (!check_id && entry)
+		list_del(&entry->list);
+	spin_unlock_bh(&msk->pm.lock);
+
+	/* Note: entry might have been removed by another thread.
+	 * We hold rcu_read_lock() to ensure it is not freed under us.
+	 */
+	if (stop_timer) {
+		if (check_id)
+			sk_stop_timer(sk, &entry->add_timer);
+		else
+			sk_stop_timer_sync(sk, &entry->add_timer);
+	}
+
+	rcu_read_unlock();
+	return entry;
+}
+
+bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
+			      const struct mptcp_addr_info *addr)
+{
+	struct mptcp_pm_add_entry *add_entry = NULL;
+	struct sock *sk = (struct sock *)msk;
+	struct net *net = sock_net(sk);
+	unsigned int timeout;
+
+	lockdep_assert_held(&msk->pm.lock);
+
+	if (msk->pm.status & BIT(MPTCP_PM_DESTROYING))
+		return false;
+
+	add_entry = mptcp_lookup_anno_list_by_saddr(msk, addr);
+
+	if (add_entry) {
+		if (WARN_ON_ONCE(mptcp_pm_is_kernel(msk)))
+			return false;
+
+		goto reset_timer;
+	}
+
+	add_entry = kmalloc(sizeof(*add_entry), GFP_ATOMIC);
+	if (!add_entry)
+		return false;
+
+	list_add(&add_entry->list, &msk->pm.anno_list);
+
+	add_entry->addr = *addr;
+	add_entry->sock = msk;
+
+	timer_setup(&add_entry->add_timer, mptcp_pm_add_timer, 0);
+reset_timer:
+	add_entry->retrans_times = 0;
+	add_entry->timer_done = false;
+	timeout = mptcp_get_add_addr_timeout(net);
+	if (timeout)
+		sk_reset_timer(sk, &add_entry->add_timer, jiffies + timeout);
+
+	return true;
+}
+
+void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
+{
+	struct mptcp_pm_add_entry *entry, *tmp;
+	struct sock *sk = (struct sock *)msk;
+	LIST_HEAD(free_list);
+
+	pr_debug("msk=%p\n", msk);
+
+	spin_lock_bh(&msk->pm.lock);
+	list_splice_init(&msk->pm.anno_list, &free_list);
+	spin_unlock_bh(&msk->pm.lock);
+
+	list_for_each_entry_safe(entry, tmp, &free_list, list) {
+		if (!entry->timer_done)
+			sk_stop_timer_sync(sk, &entry->add_timer);
+		kfree_rcu(entry, rcu);
+	}
+}
+
+/* Fill all the remote addresses into the array addrs[],
+ * and return the array size.
+ */
+static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk,
+					      struct mptcp_addr_info *local,
+					      bool fullmesh,
+					      struct mptcp_addr_info *addrs)
+{
+	bool deny_id0 = READ_ONCE(msk->pm.remote_deny_join_id0);
+	struct sock *sk = (struct sock *)msk, *ssk;
+	struct mptcp_subflow_context *subflow;
+	struct mptcp_addr_info remote = { 0 };
+	unsigned int subflows_max;
+	int i = 0;
+
+	subflows_max = mptcp_pm_get_subflows_max(msk);
+	remote_address((struct sock_common *)sk, &remote);
+
+	/* Non-fullmesh endpoint, fill in the single entry
+	 * corresponding to the primary MPC subflow remote address
+	 */
+	if (!fullmesh) {
+		if (deny_id0)
+			return 0;
+
+		if (!mptcp_pm_addr_families_match(sk, local, &remote))
+			return 0;
+
+		msk->pm.subflows++;
+		addrs[i++] = remote;
+	} else {
+		DECLARE_BITMAP(unavail_id, MPTCP_PM_MAX_ADDR_ID + 1);
+
+		/* Forbid creation of new subflows matching existing
+		 * ones, possibly already created by incoming ADD_ADDR
+		 */
+		bitmap_zero(unavail_id, MPTCP_PM_MAX_ADDR_ID + 1);
+		mptcp_for_each_subflow(msk, subflow)
+			if (READ_ONCE(subflow->local_id) == local->id)
+				__set_bit(subflow->remote_id, unavail_id);
+
+		mptcp_for_each_subflow(msk, subflow) {
+			ssk = mptcp_subflow_tcp_sock(subflow);
+			remote_address((struct sock_common *)ssk, &addrs[i]);
+			addrs[i].id = READ_ONCE(subflow->remote_id);
+			if (deny_id0 && !addrs[i].id)
+				continue;
+
+			if (test_bit(addrs[i].id, unavail_id))
+				continue;
+
+			if (!mptcp_pm_addr_families_match(sk, local, &addrs[i]))
+				continue;
+
+			if (msk->pm.subflows < subflows_max) {
+				/* forbid creating multiple address towards
+				 * this id
+				 */
+				__set_bit(addrs[i].id, unavail_id);
+				msk->pm.subflows++;
+				i++;
+			}
+		}
+	}
+
+	return i;
+}
+
+static void __mptcp_pm_send_ack(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
+				bool prio, bool backup)
+{
+	struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+	bool slow;
+
+	pr_debug("send ack for %s\n",
+		 prio ? "mp_prio" : (mptcp_pm_should_add_signal(msk) ? "add_addr" : "rm_addr"));
+
+	slow = lock_sock_fast(ssk);
+	if (prio) {
+		subflow->send_mp_prio = 1;
+		subflow->request_bkup = backup;
+	}
+
+	__mptcp_subflow_send_ack(ssk);
+	unlock_sock_fast(ssk, slow);
+}
+
+static void mptcp_pm_send_ack(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
+			      bool prio, bool backup)
+{
+	spin_unlock_bh(&msk->pm.lock);
+	__mptcp_pm_send_ack(msk, subflow, prio, backup);
+	spin_lock_bh(&msk->pm.lock);
+}
+
+static struct mptcp_pm_addr_entry *
+__lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id)
+{
+	struct mptcp_pm_addr_entry *entry;
+
+	list_for_each_entry(entry, &pernet->local_addr_list, list) {
+		if (entry->addr.id == id)
+			return entry;
+	}
+	return NULL;
+}
+
+static struct mptcp_pm_addr_entry *
+__lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info)
+{
+	struct mptcp_pm_addr_entry *entry;
+
+	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list,
+				lockdep_is_held(&pernet->lock)) {
+		if (mptcp_addresses_equal(&entry->addr, info, entry->addr.port))
+			return entry;
+	}
+	return NULL;
+}
+
+static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
+{
+	struct sock *sk = (struct sock *)msk;
+	unsigned int add_addr_signal_max;
+	bool signal_and_subflow = false;
+	unsigned int local_addr_max;
+	struct pm_nl_pernet *pernet;
+	struct mptcp_pm_local local;
+	unsigned int subflows_max;
+
+	pernet = pm_nl_get_pernet(sock_net(sk));
+
+	add_addr_signal_max = mptcp_pm_get_add_addr_signal_max(msk);
+	local_addr_max = mptcp_pm_get_local_addr_max(msk);
+	subflows_max = mptcp_pm_get_subflows_max(msk);
+
+	/* do lazy endpoint usage accounting for the MPC subflows */
+	if (unlikely(!(msk->pm.status & BIT(MPTCP_PM_MPC_ENDPOINT_ACCOUNTED))) && msk->first) {
+		struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(msk->first);
+		struct mptcp_pm_addr_entry *entry;
+		struct mptcp_addr_info mpc_addr;
+		bool backup = false;
+
+		mptcp_local_address((struct sock_common *)msk->first, &mpc_addr);
+		rcu_read_lock();
+		entry = __lookup_addr(pernet, &mpc_addr);
+		if (entry) {
+			__clear_bit(entry->addr.id, msk->pm.id_avail_bitmap);
+			msk->mpc_endpoint_id = entry->addr.id;
+			backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
+		}
+		rcu_read_unlock();
+
+		if (backup)
+			mptcp_pm_send_ack(msk, subflow, true, backup);
+
+		msk->pm.status |= BIT(MPTCP_PM_MPC_ENDPOINT_ACCOUNTED);
+	}
+
+	pr_debug("local %d:%d signal %d:%d subflows %d:%d\n",
+		 msk->pm.local_addr_used, local_addr_max,
+		 msk->pm.add_addr_signaled, add_addr_signal_max,
+		 msk->pm.subflows, subflows_max);
+
+	/* check first for announce */
+	if (msk->pm.add_addr_signaled < add_addr_signal_max) {
+		u8 endp_id;
+
+		/* due to racing events on both ends we can reach here while
+		 * previous add address is still running: if we invoke now
+		 * mptcp_pm_announce_addr(), that will fail and the
+		 * corresponding id will be marked as used.
+		 * Instead let the PM machinery reschedule us when the
+		 * current address announce will be completed.
+		 */
+		if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL))
+			return;
+
+		if (!select_signal_address(pernet, msk, &local))
+			goto subflow;
+
+		/* Special case for ID0: set the correct ID */
+		endp_id = local.addr.id;
+		if (endp_id == msk->mpc_endpoint_id)
+			local.addr.id = 0;
+
+		/* If the alloc fails, we are on memory pressure, not worth
+		 * continuing, and trying to create subflows.
+		 */
+		if (!mptcp_pm_alloc_anno_list(msk, &local.addr))
+			return;
+
+		__clear_bit(endp_id, msk->pm.id_avail_bitmap);
+		msk->pm.add_addr_signaled++;
+
+		mptcp_pm_announce_addr(msk, &local.addr, false);
+		mptcp_pm_nl_addr_send_ack(msk);
+
+		if (local.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
+			signal_and_subflow = true;
+	}
+
+subflow:
+	/* No need to try establishing subflows to remote id0 if not allowed */
+	if (mptcp_pm_add_addr_c_flag_case(msk))
+		goto exit;
+
+	/* check if should create a new subflow */
+	while (msk->pm.local_addr_used < local_addr_max &&
+	       msk->pm.subflows < subflows_max) {
+		struct mptcp_addr_info addrs[MPTCP_PM_ADDR_MAX];
+		bool fullmesh;
+		int i, nr;
+
+		if (signal_and_subflow)
+			signal_and_subflow = false;
+		else if (!select_local_address(pernet, msk, &local))
+			break;
+
+		fullmesh = !!(local.flags & MPTCP_PM_ADDR_FLAG_FULLMESH);
+
+		__clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
+
+		/* Special case for ID0: set the correct ID */
+		if (local.addr.id == msk->mpc_endpoint_id)
+			local.addr.id = 0;
+		else /* local_addr_used is not decr for ID 0 */
+			msk->pm.local_addr_used++;
+
+		nr = fill_remote_addresses_vec(msk, &local.addr, fullmesh, addrs);
+		if (nr == 0)
+			continue;
+
+		spin_unlock_bh(&msk->pm.lock);
+		for (i = 0; i < nr; i++)
+			__mptcp_subflow_connect(sk, &local, &addrs[i]);
+		spin_lock_bh(&msk->pm.lock);
+	}
+
+exit:
+	/* If an endpoint has both the signal and subflow flags, but it is not
+	 * possible to create subflows -- the 'while' loop body above never
+	 * executed --  then still mark the endp as used, which is somehow the
+	 * case. This avoids issues later when removing the endpoint and calling
+	 * __mark_subflow_endp_available(), which expects the increment here.
+	 */
+	if (signal_and_subflow && local.addr.id != msk->mpc_endpoint_id)
+		msk->pm.local_addr_used++;
+
+	mptcp_pm_nl_check_work_pending(msk);
+}
+
+static void mptcp_pm_nl_fully_established(struct mptcp_sock *msk)
+{
+	mptcp_pm_create_subflow_or_signal_addr(msk);
+}
+
+static void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk)
+{
+	mptcp_pm_create_subflow_or_signal_addr(msk);
+}
+
+/* Fill all the local addresses into the array addrs[],
+ * and return the array size.
+ */
+static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
+					     struct mptcp_addr_info *remote,
+					     struct mptcp_pm_local *locals)
+{
+	struct sock *sk = (struct sock *)msk;
+	struct mptcp_pm_addr_entry *entry;
+	struct mptcp_addr_info mpc_addr;
+	struct pm_nl_pernet *pernet;
+	unsigned int subflows_max;
+	bool c_flag_case;
+	int i = 0;
+
+	pernet = pm_nl_get_pernet_from_msk(msk);
+	subflows_max = mptcp_pm_get_subflows_max(msk);
+	c_flag_case = remote->id && mptcp_pm_add_addr_c_flag_case(msk);
+
+	mptcp_local_address((struct sock_common *)msk, &mpc_addr);
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
+		if (!(entry->flags & MPTCP_PM_ADDR_FLAG_FULLMESH))
+			continue;
+
+		if (!mptcp_pm_addr_families_match(sk, &entry->addr, remote))
+			continue;
+
+		if (msk->pm.subflows < subflows_max) {
+			bool is_id0;
+
+			locals[i].addr = entry->addr;
+			locals[i].flags = entry->flags;
+			locals[i].ifindex = entry->ifindex;
+
+			is_id0 = mptcp_addresses_equal(&locals[i].addr,
+						       &mpc_addr,
+						       locals[i].addr.port);
+
+			if (c_flag_case &&
+			    (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)) {
+				__clear_bit(locals[i].addr.id,
+					    msk->pm.id_avail_bitmap);
+
+				if (!is_id0)
+					msk->pm.local_addr_used++;
+			}
+
+			/* Special case for ID0: set the correct ID */
+			if (is_id0)
+				locals[i].addr.id = 0;
+
+			msk->pm.subflows++;
+			i++;
+		}
+	}
+	rcu_read_unlock();
+
+	/* Special case: peer sets the C flag, accept one ADD_ADDR if default
+	 * limits are used -- accepting no ADD_ADDR -- and use subflow endpoints
+	 */
+	if (!i && c_flag_case) {
+		unsigned int local_addr_max = mptcp_pm_get_local_addr_max(msk);
+
+		while (msk->pm.local_addr_used < local_addr_max &&
+		       msk->pm.subflows < subflows_max) {
+			struct mptcp_pm_local *local = &locals[i];
+
+			if (!select_local_address(pernet, msk, local))
+				break;
+
+			__clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
+
+			if (!mptcp_pm_addr_families_match(sk, &local->addr,
+							  remote))
+				continue;
+
+			if (mptcp_addresses_equal(&local->addr, &mpc_addr,
+						  local->addr.port))
+				continue;
+
+			msk->pm.local_addr_used++;
+			msk->pm.subflows++;
+			i++;
+		}
+
+		return i;
+	}
+
+	/* If the array is empty, fill in the single
+	 * 'IPADDRANY' local address
+	 */
+	if (!i) {
+		memset(&locals[i], 0, sizeof(locals[i]));
+		locals[i].addr.family =
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+			       remote->family == AF_INET6 &&
+			       ipv6_addr_v4mapped(&remote->addr6) ? AF_INET :
+#endif
+			       remote->family;
+
+		if (!mptcp_pm_addr_families_match(sk, &locals[i].addr, remote))
+			return 0;
+
+		msk->pm.subflows++;
+		i++;
+	}
+
+	return i;
+}
+
+static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
+{
+	struct mptcp_pm_local locals[MPTCP_PM_ADDR_MAX];
+	struct sock *sk = (struct sock *)msk;
+	unsigned int add_addr_accept_max;
+	struct mptcp_addr_info remote;
+	unsigned int subflows_max;
+	bool sf_created = false;
+	int i, nr;
+
+	add_addr_accept_max = mptcp_pm_get_add_addr_accept_max(msk);
+	subflows_max = mptcp_pm_get_subflows_max(msk);
+
+	pr_debug("accepted %d:%d remote family %d\n",
+		 msk->pm.add_addr_accepted, add_addr_accept_max,
+		 msk->pm.remote.family);
+
+	remote = msk->pm.remote;
+	mptcp_pm_announce_addr(msk, &remote, true);
+	mptcp_pm_nl_addr_send_ack(msk);
+
+	if (has_subflow_daddr(msk, &remote))
+		return;
+
+	/* pick id 0 port, if none is provided the remote address */
+	if (!remote.port)
+		remote.port = sk->sk_dport;
+
+	/* connect to the specified remote address, using whatever
+	 * local address the routing configuration will pick.
+	 */
+	nr = fill_local_addresses_vec(msk, &remote, locals);
+	if (nr == 0)
+		return;
+
+	spin_unlock_bh(&msk->pm.lock);
+	for (i = 0; i < nr; i++)
+		if (__mptcp_subflow_connect(sk, &locals[i], &remote) == 0)
+			sf_created = true;
+	spin_lock_bh(&msk->pm.lock);
+
+	if (sf_created) {
+		/* add_addr_accepted is not decr for ID 0 */
+		if (remote.id)
+			msk->pm.add_addr_accepted++;
+		if (msk->pm.add_addr_accepted >= add_addr_accept_max ||
+		    msk->pm.subflows >= subflows_max)
+			WRITE_ONCE(msk->pm.accept_addr, false);
+	}
+}
+
+bool mptcp_pm_nl_is_init_remote_addr(struct mptcp_sock *msk,
+				     const struct mptcp_addr_info *remote)
+{
+	struct mptcp_addr_info mpc_remote;
+
+	remote_address((struct sock_common *)msk, &mpc_remote);
+	return mptcp_addresses_equal(&mpc_remote, remote, remote->port);
+}
+
+static bool subflow_in_rm_list(const struct mptcp_subflow_context *subflow,
+			       const struct mptcp_rm_list *rm_list)
+{
+	u8 i, id = subflow_get_local_id(subflow);
+
+	for (i = 0; i < rm_list->nr; i++) {
+		if (rm_list->ids[i] == id)
+			return true;
+	}
+
+	return false;
+}
+
+void mptcp_pm_nl_addr_send_ack_avoid_list(struct mptcp_sock *msk,
+					  const struct mptcp_rm_list *rm_list)
+{
+	struct mptcp_subflow_context *subflow, *same_id = NULL;
+
+	msk_owned_by_me(msk);
+	lockdep_assert_held(&msk->pm.lock);
+
+	if (!mptcp_pm_should_add_signal(msk) &&
+	    !mptcp_pm_should_rm_signal(msk))
+		return;
+
+	mptcp_for_each_subflow(msk, subflow) {
+		if (!__mptcp_subflow_active(subflow))
+			continue;
+
+		if (unlikely(rm_list &&
+			     subflow_in_rm_list(subflow, rm_list))) {
+			if (!same_id)
+				same_id = subflow;
+		} else {
+			goto send_ack;
+		}
+	}
+
+	if (same_id)
+		subflow = same_id;
+	else
+		return;
+
+send_ack:
+	mptcp_pm_send_ack(msk, subflow, false, false);
+}
+
+void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
+{
+	mptcp_pm_nl_addr_send_ack_avoid_list(msk, NULL);
+}
+
+int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
+				 struct mptcp_addr_info *addr,
+				 struct mptcp_addr_info *rem,
+				 u8 bkup)
+{
+	struct mptcp_subflow_context *subflow;
+
+	pr_debug("bkup=%d\n", bkup);
+
+	mptcp_for_each_subflow(msk, subflow) {
+		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+		struct mptcp_addr_info local, remote;
+
+		if (!__mptcp_subflow_active(subflow))
+			continue;
+
+		mptcp_local_address((struct sock_common *)ssk, &local);
+		if (!mptcp_addresses_equal(&local, addr, addr->port))
+			continue;
+
+		if (rem && rem->family != AF_UNSPEC) {
+			remote_address((struct sock_common *)ssk, &remote);
+			if (!mptcp_addresses_equal(&remote, rem, rem->port))
+				continue;
+		}
+
+		__mptcp_pm_send_ack(msk, subflow, true, bkup);
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
+					   const struct mptcp_rm_list *rm_list,
+					   enum linux_mptcp_mib_field rm_type)
+{
+	struct mptcp_subflow_context *subflow, *tmp;
+	struct sock *sk = (struct sock *)msk;
+	u8 i;
+
+	pr_debug("%s rm_list_nr %d\n",
+		 rm_type == MPTCP_MIB_RMADDR ? "address" : "subflow", rm_list->nr);
+
+	msk_owned_by_me(msk);
+
+	if (sk->sk_state == TCP_LISTEN)
+		return;
+
+	if (!rm_list->nr)
+		return;
+
+	if (list_empty(&msk->conn_list))
+		return;
+
+	for (i = 0; i < rm_list->nr; i++) {
+		u8 rm_id = rm_list->ids[i];
+		bool removed = false;
+
+		mptcp_for_each_subflow_safe(msk, subflow, tmp) {
+			struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+			u8 remote_id = READ_ONCE(subflow->remote_id);
+			int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
+			u8 id = subflow_get_local_id(subflow);
+
+			if ((1 << inet_sk_state_load(ssk)) &
+			    (TCPF_FIN_WAIT1 | TCPF_FIN_WAIT2 | TCPF_CLOSING | TCPF_CLOSE))
+				continue;
+			if (rm_type == MPTCP_MIB_RMADDR && remote_id != rm_id)
+				continue;
+			if (rm_type == MPTCP_MIB_RMSUBFLOW && id != rm_id)
+				continue;
+
+			pr_debug(" -> %s rm_list_ids[%d]=%u local_id=%u remote_id=%u mpc_id=%u\n",
+				 rm_type == MPTCP_MIB_RMADDR ? "address" : "subflow",
+				 i, rm_id, id, remote_id, msk->mpc_endpoint_id);
+			spin_unlock_bh(&msk->pm.lock);
+			mptcp_subflow_shutdown(sk, ssk, how);
+			removed |= subflow->request_join;
+
+			/* the following takes care of updating the subflows counter */
+			mptcp_close_ssk(sk, ssk, subflow);
+			spin_lock_bh(&msk->pm.lock);
+
+			if (rm_type == MPTCP_MIB_RMSUBFLOW)
+				__MPTCP_INC_STATS(sock_net(sk), rm_type);
+		}
+
+		if (rm_type == MPTCP_MIB_RMADDR)
+			__MPTCP_INC_STATS(sock_net(sk), rm_type);
+
+		if (!removed)
+			continue;
+
+		if (!mptcp_pm_is_kernel(msk))
+			continue;
+
+		if (rm_type == MPTCP_MIB_RMADDR && rm_id &&
+		    !WARN_ON_ONCE(msk->pm.add_addr_accepted == 0)) {
+			/* Note: if the subflow has been closed before, this
+			 * add_addr_accepted counter will not be decremented.
+			 */
+			if (--msk->pm.add_addr_accepted < mptcp_pm_get_add_addr_accept_max(msk))
+				WRITE_ONCE(msk->pm.accept_addr, true);
+		}
+	}
+}
+
+static void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk)
+{
+	mptcp_pm_nl_rm_addr_or_subflow(msk, &msk->pm.rm_list_rx, MPTCP_MIB_RMADDR);
+}
+
+static void mptcp_pm_rm_subflow(struct mptcp_sock *msk,
+				const struct mptcp_rm_list *rm_list)
+{
+	mptcp_pm_nl_rm_addr_or_subflow(msk, rm_list, MPTCP_MIB_RMSUBFLOW);
+}
+
+void mptcp_pm_nl_work(struct mptcp_sock *msk)
+{
+	struct mptcp_pm_data *pm = &msk->pm;
+
+	msk_owned_by_me(msk);
+
+	if (!(pm->status & MPTCP_PM_WORK_MASK))
+		return;
+
+	spin_lock_bh(&msk->pm.lock);
+
+	pr_debug("msk=%p status=%x\n", msk, pm->status);
+	if (pm->status & BIT(MPTCP_PM_ADD_ADDR_RECEIVED)) {
+		pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED);
+		mptcp_pm_nl_add_addr_received(msk);
+	}
+	if (pm->status & BIT(MPTCP_PM_ADD_ADDR_SEND_ACK)) {
+		pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_SEND_ACK);
+		mptcp_pm_nl_addr_send_ack(msk);
+	}
+	if (pm->status & BIT(MPTCP_PM_RM_ADDR_RECEIVED)) {
+		pm->status &= ~BIT(MPTCP_PM_RM_ADDR_RECEIVED);
+		mptcp_pm_nl_rm_addr_received(msk);
+	}
+	if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) {
+		pm->status &= ~BIT(MPTCP_PM_ESTABLISHED);
+		mptcp_pm_nl_fully_established(msk);
+	}
+	if (pm->status & BIT(MPTCP_PM_SUBFLOW_ESTABLISHED)) {
+		pm->status &= ~BIT(MPTCP_PM_SUBFLOW_ESTABLISHED);
+		mptcp_pm_nl_subflow_established(msk);
+	}
+
+	spin_unlock_bh(&msk->pm.lock);
+}
+
+static bool address_use_port(struct mptcp_pm_addr_entry *entry)
+{
+	return (entry->flags &
+		(MPTCP_PM_ADDR_FLAG_SIGNAL | MPTCP_PM_ADDR_FLAG_SUBFLOW)) ==
+		MPTCP_PM_ADDR_FLAG_SIGNAL;
+}
+
+/* caller must ensure the RCU grace period is already elapsed */
+static void __mptcp_pm_release_addr_entry(struct mptcp_pm_addr_entry *entry)
+{
+	if (entry->lsk)
+		sock_release(entry->lsk);
+	kfree(entry);
+}
+
+static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
+					     struct mptcp_pm_addr_entry *entry,
+					     bool replace)
+{
+	struct mptcp_pm_addr_entry *cur, *del_entry = NULL;
+	unsigned int addr_max;
+	int ret = -EINVAL;
+
+	spin_lock_bh(&pernet->lock);
+	/* to keep the code simple, don't do IDR-like allocation for address ID,
+	 * just bail when we exceed limits
+	 */
+	if (pernet->next_id == MPTCP_PM_MAX_ADDR_ID)
+		pernet->next_id = 1;
+	if (pernet->addrs >= MPTCP_PM_ADDR_MAX) {
+		ret = -ERANGE;
+		goto out;
+	}
+	if (test_bit(entry->addr.id, pernet->id_bitmap)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	/* do not insert duplicate address, differentiate on port only
+	 * singled addresses
+	 */
+	if (!address_use_port(entry))
+		entry->addr.port = 0;
+	list_for_each_entry(cur, &pernet->local_addr_list, list) {
+		if (mptcp_addresses_equal(&cur->addr, &entry->addr,
+					  cur->addr.port || entry->addr.port)) {
+			/* allow replacing the exiting endpoint only if such
+			 * endpoint is an implicit one and the user-space
+			 * did not provide an endpoint id
+			 */
+			if (!(cur->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT)) {
+				ret = -EEXIST;
+				goto out;
+			}
+			if (entry->addr.id)
+				goto out;
+
+			/* allow callers that only need to look up the local
+			 * addr's id to skip replacement. This allows them to
+			 * avoid calling synchronize_rcu in the packet recv
+			 * path.
+			 */
+			if (!replace) {
+				kfree(entry);
+				ret = cur->addr.id;
+				goto out;
+			}
+
+			pernet->addrs--;
+			entry->addr.id = cur->addr.id;
+			list_del_rcu(&cur->list);
+			del_entry = cur;
+			break;
+		}
+	}
+
+	if (!entry->addr.id) {
+find_next:
+		entry->addr.id = find_next_zero_bit(pernet->id_bitmap,
+						    MPTCP_PM_MAX_ADDR_ID + 1,
+						    pernet->next_id);
+		if (!entry->addr.id && pernet->next_id != 1) {
+			pernet->next_id = 1;
+			goto find_next;
+		}
+	}
+
+	if (!entry->addr.id)
+		goto out;
+
+	__set_bit(entry->addr.id, pernet->id_bitmap);
+	if (entry->addr.id > pernet->next_id)
+		pernet->next_id = entry->addr.id;
+
+	if (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL) {
+		addr_max = pernet->add_addr_signal_max;
+		WRITE_ONCE(pernet->add_addr_signal_max, addr_max + 1);
+	}
+	if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
+		addr_max = pernet->local_addr_max;
+		WRITE_ONCE(pernet->local_addr_max, addr_max + 1);
+	}
+
+	pernet->addrs++;
+	if (!entry->addr.port)
+		list_add_tail_rcu(&entry->list, &pernet->local_addr_list);
+	else
+		list_add_rcu(&entry->list, &pernet->local_addr_list);
+	ret = entry->addr.id;
+
+out:
+	spin_unlock_bh(&pernet->lock);
+
+	/* just replaced an existing entry, free it */
+	if (del_entry) {
+		synchronize_rcu();
+		__mptcp_pm_release_addr_entry(del_entry);
+	}
+	return ret;
+}
+
+static struct lock_class_key mptcp_slock_keys[2];
+static struct lock_class_key mptcp_keys[2];
+
+static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
+					    struct mptcp_pm_addr_entry *entry)
+{
+	bool is_ipv6 = entry->addr.family == AF_INET6;
+	int addrlen = sizeof(struct sockaddr_in);
+	struct sockaddr_storage addr;
+	struct sock *newsk, *ssk;
+	int backlog = 1024;
+	int err;
+
+	err = sock_create_kern(sock_net(sk), entry->addr.family,
+			       SOCK_STREAM, IPPROTO_MPTCP, &entry->lsk);
+	if (err)
+		return err;
+
+	newsk = entry->lsk->sk;
+	if (!newsk)
+		return -EINVAL;
+
+	/* The subflow socket lock is acquired in a nested to the msk one
+	 * in several places, even by the TCP stack, and this msk is a kernel
+	 * socket: lockdep complains. Instead of propagating the _nested
+	 * modifiers in several places, re-init the lock class for the msk
+	 * socket to an mptcp specific one.
+	 */
+	sock_lock_init_class_and_name(newsk,
+				      is_ipv6 ? "mlock-AF_INET6" : "mlock-AF_INET",
+				      &mptcp_slock_keys[is_ipv6],
+				      is_ipv6 ? "msk_lock-AF_INET6" : "msk_lock-AF_INET",
+				      &mptcp_keys[is_ipv6]);
+
+	lock_sock(newsk);
+	ssk = __mptcp_nmpc_sk(mptcp_sk(newsk));
+	release_sock(newsk);
+	if (IS_ERR(ssk))
+		return PTR_ERR(ssk);
+
+	mptcp_info2sockaddr(&entry->addr, &addr, entry->addr.family);
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	if (entry->addr.family == AF_INET6)
+		addrlen = sizeof(struct sockaddr_in6);
+#endif
+	if (ssk->sk_family == AF_INET)
+		err = inet_bind_sk(ssk, (struct sockaddr *)&addr, addrlen);
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	else if (ssk->sk_family == AF_INET6)
+		err = inet6_bind_sk(ssk, (struct sockaddr *)&addr, addrlen);
+#endif
+	if (err)
+		return err;
+
+	/* We don't use mptcp_set_state() here because it needs to be called
+	 * under the msk socket lock. For the moment, that will not bring
+	 * anything more than only calling inet_sk_state_store(), because the
+	 * old status is known (TCP_CLOSE).
+	 */
+	inet_sk_state_store(newsk, TCP_LISTEN);
+	lock_sock(ssk);
+	WRITE_ONCE(mptcp_subflow_ctx(ssk)->pm_listener, true);
+	err = __inet_listen_sk(ssk, backlog);
+	if (!err)
+		mptcp_event_pm_listener(ssk, MPTCP_EVENT_LISTENER_CREATED);
+	release_sock(ssk);
+	return err;
+}
+
+int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk,
+			     struct mptcp_pm_addr_entry *skc)
+{
+	struct mptcp_pm_addr_entry *entry;
+	struct pm_nl_pernet *pernet;
+	int ret;
+
+	pernet = pm_nl_get_pernet_from_msk(msk);
+
+	rcu_read_lock();
+	entry = __lookup_addr(pernet, &skc->addr);
+	ret = entry ? entry->addr.id : -1;
+	rcu_read_unlock();
+	if (ret >= 0)
+		return ret;
+
+	/* address not found, add to local list */
+	entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+	if (!entry)
+		return -ENOMEM;
+
+	*entry = *skc;
+	entry->addr.port = 0;
+	ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, false);
+	if (ret < 0)
+		kfree(entry);
+
+	return ret;
+}
+
+bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc)
+{
+	struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
+	struct mptcp_pm_addr_entry *entry;
+	bool backup;
+
+	rcu_read_lock();
+	entry = __lookup_addr(pernet, skc);
+	backup = entry && !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
+	rcu_read_unlock();
+
+	return backup;
+}
+
+#define MPTCP_PM_CMD_GRP_OFFSET       0
+#define MPTCP_PM_EV_GRP_OFFSET        1
+
+static const struct genl_multicast_group mptcp_pm_mcgrps[] = {
+	[MPTCP_PM_CMD_GRP_OFFSET]	= { .name = MPTCP_PM_CMD_GRP_NAME, },
+	[MPTCP_PM_EV_GRP_OFFSET]        = { .name = MPTCP_PM_EV_GRP_NAME,
+					    .flags = GENL_MCAST_CAP_NET_ADMIN,
+					  },
+};
+
+void mptcp_pm_nl_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk)
+{
+	struct mptcp_subflow_context *iter, *subflow = mptcp_subflow_ctx(ssk);
+	struct sock *sk = (struct sock *)msk;
+	unsigned int active_max_loss_cnt;
+	struct net *net = sock_net(sk);
+	unsigned int stale_loss_cnt;
+	bool slow;
+
+	stale_loss_cnt = mptcp_stale_loss_cnt(net);
+	if (subflow->stale || !stale_loss_cnt || subflow->stale_count <= stale_loss_cnt)
+		return;
+
+	/* look for another available subflow not in loss state */
+	active_max_loss_cnt = max_t(int, stale_loss_cnt - 1, 1);
+	mptcp_for_each_subflow(msk, iter) {
+		if (iter != subflow && mptcp_subflow_active(iter) &&
+		    iter->stale_count < active_max_loss_cnt) {
+			/* we have some alternatives, try to mark this subflow as idle ...*/
+			slow = lock_sock_fast(ssk);
+			if (!tcp_rtx_and_write_queues_empty(ssk)) {
+				subflow->stale = 1;
+				__mptcp_retransmit_pending_data(sk);
+				MPTCP_INC_STATS(net, MPTCP_MIB_SUBFLOWSTALE);
+			}
+			unlock_sock_fast(ssk, slow);
+
+			/* always try to push the pending data regardless of re-injections:
+			 * we can possibly use backup subflows now, and subflow selection
+			 * is cheap under the msk socket lock
+			 */
+			__mptcp_push_pending(sk, 0);
+			return;
+		}
+	}
+}
+
+static int mptcp_pm_family_to_addr(int family)
+{
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	if (family == AF_INET6)
+		return MPTCP_PM_ADDR_ATTR_ADDR6;
+#endif
+	return MPTCP_PM_ADDR_ATTR_ADDR4;
+}
+
+static int mptcp_pm_parse_pm_addr_attr(struct nlattr *tb[],
+				       const struct nlattr *attr,
+				       struct genl_info *info,
+				       struct mptcp_addr_info *addr,
+				       bool require_family)
+{
+	int err, addr_addr;
+
+	if (!attr) {
+		GENL_SET_ERR_MSG(info, "missing address info");
+		return -EINVAL;
+	}
+
+	/* no validation needed - was already done via nested policy */
+	err = nla_parse_nested_deprecated(tb, MPTCP_PM_ADDR_ATTR_MAX, attr,
+					  mptcp_pm_address_nl_policy, info->extack);
+	if (err)
+		return err;
+
+	if (tb[MPTCP_PM_ADDR_ATTR_ID])
+		addr->id = nla_get_u8(tb[MPTCP_PM_ADDR_ATTR_ID]);
+
+	if (!tb[MPTCP_PM_ADDR_ATTR_FAMILY]) {
+		if (!require_family)
+			return 0;
+
+		NL_SET_ERR_MSG_ATTR(info->extack, attr,
+				    "missing family");
+		return -EINVAL;
+	}
+
+	addr->family = nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_FAMILY]);
+	if (addr->family != AF_INET
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	    && addr->family != AF_INET6
+#endif
+	    ) {
+		NL_SET_ERR_MSG_ATTR(info->extack, attr,
+				    "unknown address family");
+		return -EINVAL;
+	}
+	addr_addr = mptcp_pm_family_to_addr(addr->family);
+	if (!tb[addr_addr]) {
+		NL_SET_ERR_MSG_ATTR(info->extack, attr,
+				    "missing address data");
+		return -EINVAL;
+	}
+
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	if (addr->family == AF_INET6)
+		addr->addr6 = nla_get_in6_addr(tb[addr_addr]);
+	else
+#endif
+		addr->addr.s_addr = nla_get_in_addr(tb[addr_addr]);
+
+	if (tb[MPTCP_PM_ADDR_ATTR_PORT])
+		addr->port = htons(nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_PORT]));
+
+	return 0;
+}
+
+int mptcp_pm_parse_addr(struct nlattr *attr, struct genl_info *info,
+			struct mptcp_addr_info *addr)
+{
+	struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1];
+
+	memset(addr, 0, sizeof(*addr));
+
+	return mptcp_pm_parse_pm_addr_attr(tb, attr, info, addr, true);
+}
+
+int mptcp_pm_parse_entry(struct nlattr *attr, struct genl_info *info,
+			 bool require_family,
+			 struct mptcp_pm_addr_entry *entry)
+{
+	struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1];
+	int err;
+
+	memset(entry, 0, sizeof(*entry));
+
+	err = mptcp_pm_parse_pm_addr_attr(tb, attr, info, &entry->addr, require_family);
+	if (err)
+		return err;
+
+	if (tb[MPTCP_PM_ADDR_ATTR_IF_IDX]) {
+		u32 val = nla_get_s32(tb[MPTCP_PM_ADDR_ATTR_IF_IDX]);
+
+		entry->ifindex = val;
+	}
+
+	if (tb[MPTCP_PM_ADDR_ATTR_FLAGS])
+		entry->flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]) &
+			       MPTCP_PM_ADDR_FLAGS_MASK;
+
+	if (tb[MPTCP_PM_ADDR_ATTR_PORT])
+		entry->addr.port = htons(nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_PORT]));
+
+	return 0;
+}
+
+static struct pm_nl_pernet *genl_info_pm_nl(struct genl_info *info)
+{
+	return pm_nl_get_pernet(genl_info_net(info));
+}
+
+static int mptcp_nl_add_subflow_or_signal_addr(struct net *net,
+					       struct mptcp_addr_info *addr)
+{
+	struct mptcp_sock *msk;
+	long s_slot = 0, s_num = 0;
+
+	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
+		struct sock *sk = (struct sock *)msk;
+		struct mptcp_addr_info mpc_addr;
+
+		if (!READ_ONCE(msk->fully_established) ||
+		    mptcp_pm_is_userspace(msk))
+			goto next;
+
+		/* if the endp linked to the init sf is re-added with a != ID */
+		mptcp_local_address((struct sock_common *)msk, &mpc_addr);
+
+		lock_sock(sk);
+		spin_lock_bh(&msk->pm.lock);
+		if (mptcp_addresses_equal(addr, &mpc_addr, addr->port))
+			msk->mpc_endpoint_id = addr->id;
+		mptcp_pm_create_subflow_or_signal_addr(msk);
+		spin_unlock_bh(&msk->pm.lock);
+		release_sock(sk);
+
+next:
+		sock_put(sk);
+		cond_resched();
+	}
+
+	return 0;
+}
+
+int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
+	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
+	struct mptcp_pm_addr_entry addr, *entry;
+	int ret;
+
+	ret = mptcp_pm_parse_entry(attr, info, true, &addr);
+	if (ret < 0)
+		return ret;
+
+	if (addr.addr.port && !address_use_port(&addr)) {
+		GENL_SET_ERR_MSG(info, "flags must have signal and not subflow when using port");
+		return -EINVAL;
+	}
+
+	if (addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL &&
+	    addr.flags & MPTCP_PM_ADDR_FLAG_FULLMESH) {
+		GENL_SET_ERR_MSG(info, "flags mustn't have both signal and fullmesh");
+		return -EINVAL;
+	}
+
+	if (addr.flags & MPTCP_PM_ADDR_FLAG_IMPLICIT) {
+		GENL_SET_ERR_MSG(info, "can't create IMPLICIT endpoint");
+		return -EINVAL;
+	}
+
+	entry = kzalloc(sizeof(*entry), GFP_KERNEL_ACCOUNT);
+	if (!entry) {
+		GENL_SET_ERR_MSG(info, "can't allocate addr");
+		return -ENOMEM;
+	}
+
+	*entry = addr;
+	if (entry->addr.port) {
+		ret = mptcp_pm_nl_create_listen_socket(skb->sk, entry);
+		if (ret) {
+			GENL_SET_ERR_MSG_FMT(info, "create listen socket error: %d", ret);
+			goto out_free;
+		}
+	}
+	ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true);
+	if (ret < 0) {
+		GENL_SET_ERR_MSG_FMT(info, "too many addresses or duplicate one: %d", ret);
+		goto out_free;
+	}
+
+	mptcp_nl_add_subflow_or_signal_addr(sock_net(skb->sk), &entry->addr);
+	return 0;
+
+out_free:
+	__mptcp_pm_release_addr_entry(entry);
+	return ret;
+}
+
+static bool mptcp_pm_announced_remove(struct mptcp_sock *msk,
+				      const struct mptcp_addr_info *addr)
+{
+	struct mptcp_pm_add_entry *entry;
+
+	entry = mptcp_pm_del_add_timer(msk, addr, false);
+	if (entry) {
+		kfree_rcu(entry, rcu);
+		return true;
+	}
+
+	return false;
+}
+
+static u8 mptcp_endp_get_local_id(struct mptcp_sock *msk,
+				  const struct mptcp_addr_info *addr)
+{
+	return msk->mpc_endpoint_id == addr->id ? 0 : addr->id;
+}
+
+static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk,
+				      const struct mptcp_addr_info *addr,
+				      bool force)
+{
+	struct mptcp_rm_list list = { .nr = 0 };
+	bool ret;
+
+	list.ids[list.nr++] = mptcp_endp_get_local_id(msk, addr);
+
+	ret = mptcp_pm_announced_remove(msk, addr);
+	if (ret || force) {
+		spin_lock_bh(&msk->pm.lock);
+		if (ret)
+			msk->pm.add_addr_signaled--;
+		mptcp_pm_remove_addr(msk, &list);
+		spin_unlock_bh(&msk->pm.lock);
+	}
+	return ret;
+}
+
+static void __mark_subflow_endp_available(struct mptcp_sock *msk, u8 id)
+{
+	/* If it was marked as used, and not ID 0, decrement local_addr_used */
+	if (!__test_and_set_bit(id ? : msk->mpc_endpoint_id, msk->pm.id_avail_bitmap) &&
+	    id && !WARN_ON_ONCE(msk->pm.local_addr_used == 0))
+		msk->pm.local_addr_used--;
+}
+
+static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
+						   const struct mptcp_pm_addr_entry *entry)
+{
+	const struct mptcp_addr_info *addr = &entry->addr;
+	struct mptcp_rm_list list = { .nr = 1 };
+	long s_slot = 0, s_num = 0;
+	struct mptcp_sock *msk;
+
+	pr_debug("remove_id=%d\n", addr->id);
+
+	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
+		struct sock *sk = (struct sock *)msk;
+		bool remove_subflow;
+
+		if (mptcp_pm_is_userspace(msk))
+			goto next;
+
+		lock_sock(sk);
+		remove_subflow = has_subflow_saddr(msk, addr);
+		mptcp_pm_remove_anno_addr(msk, addr, remove_subflow &&
+					  !(entry->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT));
+
+		list.ids[0] = mptcp_endp_get_local_id(msk, addr);
+
+		spin_lock_bh(&msk->pm.lock);
+		if (remove_subflow)
+			mptcp_pm_rm_subflow(msk, &list);
+		if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
+			__mark_subflow_endp_available(msk, list.ids[0]);
+		else /* mark endp ID as available, e.g. Signal or MPC endp */
+			__set_bit(addr->id, msk->pm.id_avail_bitmap);
+		spin_unlock_bh(&msk->pm.lock);
+
+		if (msk->mpc_endpoint_id == entry->addr.id)
+			msk->mpc_endpoint_id = 0;
+		release_sock(sk);
+
+next:
+		sock_put(sk);
+		cond_resched();
+	}
+
+	return 0;
+}
+
+static int mptcp_nl_remove_id_zero_address(struct net *net,
+					   struct mptcp_addr_info *addr)
+{
+	struct mptcp_rm_list list = { .nr = 0 };
+	long s_slot = 0, s_num = 0;
+	struct mptcp_sock *msk;
+
+	list.ids[list.nr++] = 0;
+
+	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
+		struct sock *sk = (struct sock *)msk;
+		struct mptcp_addr_info msk_local;
+
+		if (list_empty(&msk->conn_list) || mptcp_pm_is_userspace(msk))
+			goto next;
+
+		mptcp_local_address((struct sock_common *)msk, &msk_local);
+		if (!mptcp_addresses_equal(&msk_local, addr, addr->port))
+			goto next;
+
+		lock_sock(sk);
+		spin_lock_bh(&msk->pm.lock);
+		mptcp_pm_remove_addr(msk, &list);
+		mptcp_pm_rm_subflow(msk, &list);
+		__mark_subflow_endp_available(msk, 0);
+		spin_unlock_bh(&msk->pm.lock);
+		release_sock(sk);
+
+next:
+		sock_put(sk);
+		cond_resched();
+	}
+
+	return 0;
+}
+
+int mptcp_pm_nl_del_addr_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
+	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
+	struct mptcp_pm_addr_entry addr, *entry;
+	unsigned int addr_max;
+	int ret;
+
+	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
+	if (ret < 0)
+		return ret;
+
+	/* the zero id address is special: the first address used by the msk
+	 * always gets such an id, so different subflows can have different zero
+	 * id addresses. Additionally zero id is not accounted for in id_bitmap.
+	 * Let's use an 'mptcp_rm_list' instead of the common remove code.
+	 */
+	if (addr.addr.id == 0)
+		return mptcp_nl_remove_id_zero_address(sock_net(skb->sk), &addr.addr);
+
+	spin_lock_bh(&pernet->lock);
+	entry = __lookup_addr_by_id(pernet, addr.addr.id);
+	if (!entry) {
+		GENL_SET_ERR_MSG(info, "address not found");
+		spin_unlock_bh(&pernet->lock);
+		return -EINVAL;
+	}
+	if (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL) {
+		addr_max = pernet->add_addr_signal_max;
+		WRITE_ONCE(pernet->add_addr_signal_max, addr_max - 1);
+	}
+	if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
+		addr_max = pernet->local_addr_max;
+		WRITE_ONCE(pernet->local_addr_max, addr_max - 1);
+	}
+
+	pernet->addrs--;
+	list_del_rcu(&entry->list);
+	__clear_bit(entry->addr.id, pernet->id_bitmap);
+	spin_unlock_bh(&pernet->lock);
+
+	mptcp_nl_remove_subflow_and_signal_addr(sock_net(skb->sk), entry);
+	synchronize_rcu();
+	__mptcp_pm_release_addr_entry(entry);
+
+	return ret;
+}
+
+/* Called from the userspace PM only */
+void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list)
+{
+	struct mptcp_rm_list alist = { .nr = 0 };
+	struct mptcp_pm_addr_entry *entry;
+	int anno_nr = 0;
+
+	list_for_each_entry(entry, rm_list, list) {
+		if (alist.nr >= MPTCP_RM_IDS_MAX)
+			break;
+
+		/* only delete if either announced or matching a subflow */
+		if (mptcp_pm_announced_remove(msk, &entry->addr))
+			anno_nr++;
+		else if (!has_subflow_saddr(msk, &entry->addr))
+			continue;
+
+		alist.ids[alist.nr++] = entry->addr.id;
+	}
+
+	if (alist.nr) {
+		spin_lock_bh(&msk->pm.lock);
+		msk->pm.add_addr_signaled -= anno_nr;
+		mptcp_pm_remove_addr(msk, &alist);
+		spin_unlock_bh(&msk->pm.lock);
+	}
+}
+
+/* Called from the in-kernel PM only */
+static void mptcp_pm_flush_addrs_and_subflows(struct mptcp_sock *msk,
+					      struct list_head *rm_list)
+{
+	struct mptcp_rm_list alist = { .nr = 0 }, slist = { .nr = 0 };
+	struct mptcp_pm_addr_entry *entry;
+
+	list_for_each_entry(entry, rm_list, list) {
+		if (slist.nr < MPTCP_RM_IDS_MAX &&
+		    has_subflow_saddr(msk, &entry->addr))
+			slist.ids[slist.nr++] = mptcp_endp_get_local_id(msk, &entry->addr);
+
+		if (alist.nr < MPTCP_RM_IDS_MAX &&
+		    mptcp_pm_announced_remove(msk, &entry->addr))
+			alist.ids[alist.nr++] = mptcp_endp_get_local_id(msk, &entry->addr);
+	}
+
+	spin_lock_bh(&msk->pm.lock);
+	if (alist.nr) {
+		msk->pm.add_addr_signaled -= alist.nr;
+		mptcp_pm_remove_addr(msk, &alist);
+	}
+	if (slist.nr)
+		mptcp_pm_rm_subflow(msk, &slist);
+	/* Reset counters: maybe some subflows have been removed before */
+	bitmap_fill(msk->pm.id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
+	msk->pm.local_addr_used = 0;
+	spin_unlock_bh(&msk->pm.lock);
+}
+
+static void mptcp_nl_flush_addrs_list(struct net *net,
+				      struct list_head *rm_list)
+{
+	long s_slot = 0, s_num = 0;
+	struct mptcp_sock *msk;
+
+	if (list_empty(rm_list))
+		return;
+
+	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
+		struct sock *sk = (struct sock *)msk;
+
+		if (!mptcp_pm_is_userspace(msk)) {
+			lock_sock(sk);
+			mptcp_pm_flush_addrs_and_subflows(msk, rm_list);
+			release_sock(sk);
+		}
+
+		sock_put(sk);
+		cond_resched();
+	}
+}
+
+/* caller must ensure the RCU grace period is already elapsed */
+static void __flush_addrs(struct list_head *list)
+{
+	while (!list_empty(list)) {
+		struct mptcp_pm_addr_entry *cur;
+
+		cur = list_entry(list->next,
+				 struct mptcp_pm_addr_entry, list);
+		list_del_rcu(&cur->list);
+		__mptcp_pm_release_addr_entry(cur);
+	}
+}
+
+static void __reset_counters(struct pm_nl_pernet *pernet)
+{
+	WRITE_ONCE(pernet->add_addr_signal_max, 0);
+	WRITE_ONCE(pernet->local_addr_max, 0);
+	pernet->addrs = 0;
+}
+
+int mptcp_pm_nl_flush_addrs_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
+	struct list_head free_list;
+
+	spin_lock_bh(&pernet->lock);
+	free_list = pernet->local_addr_list;
+	INIT_LIST_HEAD_RCU(&pernet->local_addr_list);
+	__reset_counters(pernet);
+	pernet->next_id = 1;
+	bitmap_zero(pernet->id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
+	spin_unlock_bh(&pernet->lock);
+
+	if (free_list.next == &pernet->local_addr_list)
+		return 0;
+
+	synchronize_rcu();
+
+	/* Adjust the pointers to free_list instead of pernet->local_addr_list */
+	free_list.prev->next = &free_list;
+	free_list.next->prev = &free_list;
+
+	mptcp_nl_flush_addrs_list(sock_net(skb->sk), &free_list);
+	__flush_addrs(&free_list);
+	return 0;
+}
+
+int mptcp_nl_fill_addr(struct sk_buff *skb,
+		       struct mptcp_pm_addr_entry *entry)
+{
+	struct mptcp_addr_info *addr = &entry->addr;
+	struct nlattr *attr;
+
+	attr = nla_nest_start(skb, MPTCP_PM_ATTR_ADDR);
+	if (!attr)
+		return -EMSGSIZE;
+
+	if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_FAMILY, addr->family))
+		goto nla_put_failure;
+	if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_PORT, ntohs(addr->port)))
+		goto nla_put_failure;
+	if (nla_put_u8(skb, MPTCP_PM_ADDR_ATTR_ID, addr->id))
+		goto nla_put_failure;
+	if (nla_put_u32(skb, MPTCP_PM_ADDR_ATTR_FLAGS, entry->flags))
+		goto nla_put_failure;
+	if (entry->ifindex &&
+	    nla_put_s32(skb, MPTCP_PM_ADDR_ATTR_IF_IDX, entry->ifindex))
+		goto nla_put_failure;
+
+	if (addr->family == AF_INET &&
+	    nla_put_in_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR4,
+			    addr->addr.s_addr))
+		goto nla_put_failure;
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	else if (addr->family == AF_INET6 &&
+		 nla_put_in6_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR6, &addr->addr6))
+		goto nla_put_failure;
+#endif
+	nla_nest_end(skb, attr);
+	return 0;
+
+nla_put_failure:
+	nla_nest_cancel(skb, attr);
+	return -EMSGSIZE;
+}
+
+int mptcp_pm_nl_get_addr(struct sk_buff *skb, struct genl_info *info)
+{
+	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
+	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
+	struct mptcp_pm_addr_entry addr, *entry;
+	struct sk_buff *msg;
+	void *reply;
+	int ret;
+
+	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
+	if (ret < 0)
+		return ret;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
+				  info->genlhdr->cmd);
+	if (!reply) {
+		GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
+		ret = -EMSGSIZE;
+		goto fail;
+	}
+
+	spin_lock_bh(&pernet->lock);
+	entry = __lookup_addr_by_id(pernet, addr.addr.id);
+	if (!entry) {
+		GENL_SET_ERR_MSG(info, "address not found");
+		ret = -EINVAL;
+		goto unlock_fail;
+	}
+
+	ret = mptcp_nl_fill_addr(msg, entry);
+	if (ret)
+		goto unlock_fail;
+
+	genlmsg_end(msg, reply);
+	ret = genlmsg_reply(msg, info);
+	spin_unlock_bh(&pernet->lock);
+	return ret;
+
+unlock_fail:
+	spin_unlock_bh(&pernet->lock);
+
+fail:
+	nlmsg_free(msg);
+	return ret;
+}
+
+int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	return mptcp_pm_get_addr(skb, info);
+}
+
+int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
+			  struct netlink_callback *cb)
+{
+	struct net *net = sock_net(msg->sk);
+	struct mptcp_pm_addr_entry *entry;
+	struct pm_nl_pernet *pernet;
+	int id = cb->args[0];
+	void *hdr;
+	int i;
+
+	pernet = pm_nl_get_pernet(net);
+
+	spin_lock_bh(&pernet->lock);
+	for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
+		if (test_bit(i, pernet->id_bitmap)) {
+			entry = __lookup_addr_by_id(pernet, i);
+			if (!entry)
+				break;
+
+			if (entry->addr.id <= id)
+				continue;
+
+			hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
+					  cb->nlh->nlmsg_seq, &mptcp_genl_family,
+					  NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR);
+			if (!hdr)
+				break;
+
+			if (mptcp_nl_fill_addr(msg, entry) < 0) {
+				genlmsg_cancel(msg, hdr);
+				break;
+			}
+
+			id = entry->addr.id;
+			genlmsg_end(msg, hdr);
+		}
+	}
+	spin_unlock_bh(&pernet->lock);
+
+	cb->args[0] = id;
+	return msg->len;
+}
+
+int mptcp_pm_nl_get_addr_dumpit(struct sk_buff *msg,
+				struct netlink_callback *cb)
+{
+	return mptcp_pm_dump_addr(msg, cb);
+}
+
+static int parse_limit(struct genl_info *info, int id, unsigned int *limit)
+{
+	struct nlattr *attr = info->attrs[id];
+
+	if (!attr)
+		return 0;
+
+	*limit = nla_get_u32(attr);
+	if (*limit > MPTCP_PM_ADDR_MAX) {
+		GENL_SET_ERR_MSG(info, "limit greater than maximum");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+int mptcp_pm_nl_set_limits_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
+	unsigned int rcv_addrs, subflows;
+	int ret;
+
+	spin_lock_bh(&pernet->lock);
+	rcv_addrs = pernet->add_addr_accept_max;
+	ret = parse_limit(info, MPTCP_PM_ATTR_RCV_ADD_ADDRS, &rcv_addrs);
+	if (ret)
+		goto unlock;
+
+	subflows = pernet->subflows_max;
+	ret = parse_limit(info, MPTCP_PM_ATTR_SUBFLOWS, &subflows);
+	if (ret)
+		goto unlock;
+
+	WRITE_ONCE(pernet->add_addr_accept_max, rcv_addrs);
+	WRITE_ONCE(pernet->subflows_max, subflows);
+
+unlock:
+	spin_unlock_bh(&pernet->lock);
+	return ret;
+}
+
+int mptcp_pm_nl_get_limits_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
+	struct sk_buff *msg;
+	void *reply;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
+				  MPTCP_PM_CMD_GET_LIMITS);
+	if (!reply)
+		goto fail;
+
+	if (nla_put_u32(msg, MPTCP_PM_ATTR_RCV_ADD_ADDRS,
+			READ_ONCE(pernet->add_addr_accept_max)))
+		goto fail;
+
+	if (nla_put_u32(msg, MPTCP_PM_ATTR_SUBFLOWS,
+			READ_ONCE(pernet->subflows_max)))
+		goto fail;
+
+	genlmsg_end(msg, reply);
+	return genlmsg_reply(msg, info);
+
+fail:
+	GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
+	nlmsg_free(msg);
+	return -EMSGSIZE;
+}
+
+static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk,
+				 struct mptcp_addr_info *addr)
+{
+	struct mptcp_rm_list list = { .nr = 0 };
+
+	list.ids[list.nr++] = mptcp_endp_get_local_id(msk, addr);
+
+	spin_lock_bh(&msk->pm.lock);
+	mptcp_pm_rm_subflow(msk, &list);
+	__mark_subflow_endp_available(msk, list.ids[0]);
+	mptcp_pm_create_subflow_or_signal_addr(msk);
+	spin_unlock_bh(&msk->pm.lock);
+}
+
+static int mptcp_nl_set_flags(struct net *net,
+			      struct mptcp_addr_info *addr,
+			      u8 bkup, u8 changed)
+{
+	long s_slot = 0, s_num = 0;
+	struct mptcp_sock *msk;
+	int ret = -EINVAL;
+
+	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
+		struct sock *sk = (struct sock *)msk;
+
+		if (list_empty(&msk->conn_list) || mptcp_pm_is_userspace(msk))
+			goto next;
+
+		lock_sock(sk);
+		if (changed & MPTCP_PM_ADDR_FLAG_BACKUP)
+			ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, NULL, bkup);
+		if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH)
+			mptcp_pm_nl_fullmesh(msk, addr);
+		release_sock(sk);
+
+next:
+		sock_put(sk);
+		cond_resched();
+	}
+
+	return ret;
+}
+
+int mptcp_pm_nl_set_flags(struct sk_buff *skb, struct genl_info *info)
+{
+	struct mptcp_pm_addr_entry addr = { .addr = { .family = AF_UNSPEC }, };
+	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
+	u8 changed, mask = MPTCP_PM_ADDR_FLAG_BACKUP |
+			   MPTCP_PM_ADDR_FLAG_FULLMESH;
+	struct net *net = sock_net(skb->sk);
+	struct mptcp_pm_addr_entry *entry;
+	struct pm_nl_pernet *pernet;
+	u8 lookup_by_id = 0;
+	u8 bkup = 0;
+	int ret;
+
+	pernet = pm_nl_get_pernet(net);
+
+	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
+	if (ret < 0)
+		return ret;
+
+	if (addr.addr.family == AF_UNSPEC) {
+		lookup_by_id = 1;
+		if (!addr.addr.id) {
+			GENL_SET_ERR_MSG(info, "missing required inputs");
+			return -EOPNOTSUPP;
+		}
+	}
+
+	if (addr.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
+		bkup = 1;
+
+	spin_lock_bh(&pernet->lock);
+	entry = lookup_by_id ? __lookup_addr_by_id(pernet, addr.addr.id) :
+			       __lookup_addr(pernet, &addr.addr);
+	if (!entry) {
+		spin_unlock_bh(&pernet->lock);
+		GENL_SET_ERR_MSG(info, "address not found");
+		return -EINVAL;
+	}
+	if ((addr.flags & MPTCP_PM_ADDR_FLAG_FULLMESH) &&
+	    (entry->flags & (MPTCP_PM_ADDR_FLAG_SIGNAL |
+			     MPTCP_PM_ADDR_FLAG_IMPLICIT))) {
+		spin_unlock_bh(&pernet->lock);
+		GENL_SET_ERR_MSG(info, "invalid addr flags");
+		return -EINVAL;
+	}
+
+	changed = (addr.flags ^ entry->flags) & mask;
+	entry->flags = (entry->flags & ~mask) | (addr.flags & mask);
+	addr = *entry;
+	spin_unlock_bh(&pernet->lock);
+
+	mptcp_nl_set_flags(net, &addr.addr, bkup, changed);
+	return 0;
+}
+
+int mptcp_pm_nl_set_flags_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	return mptcp_pm_set_flags(skb, info);
+}
+
+static void mptcp_nl_mcast_send(struct net *net, struct sk_buff *nlskb, gfp_t gfp)
+{
+	genlmsg_multicast_netns(&mptcp_genl_family, net,
+				nlskb, 0, MPTCP_PM_EV_GRP_OFFSET, gfp);
+}
+
+bool mptcp_userspace_pm_active(const struct mptcp_sock *msk)
+{
+	return genl_has_listeners(&mptcp_genl_family,
+				  sock_net((const struct sock *)msk),
+				  MPTCP_PM_EV_GRP_OFFSET);
+}
+
+static int mptcp_event_add_subflow(struct sk_buff *skb, const struct sock *ssk)
+{
+	const struct inet_sock *issk = inet_sk(ssk);
+	const struct mptcp_subflow_context *sf;
+
+	if (nla_put_u16(skb, MPTCP_ATTR_FAMILY, ssk->sk_family))
+		return -EMSGSIZE;
+
+	switch (ssk->sk_family) {
+	case AF_INET:
+		if (nla_put_in_addr(skb, MPTCP_ATTR_SADDR4, issk->inet_saddr))
+			return -EMSGSIZE;
+		if (nla_put_in_addr(skb, MPTCP_ATTR_DADDR4, issk->inet_daddr))
+			return -EMSGSIZE;
+		break;
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	case AF_INET6: {
+		const struct ipv6_pinfo *np = inet6_sk(ssk);
+
+		if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &np->saddr))
+			return -EMSGSIZE;
+		if (nla_put_in6_addr(skb, MPTCP_ATTR_DADDR6, &ssk->sk_v6_daddr))
+			return -EMSGSIZE;
+		break;
+	}
+#endif
+	default:
+		WARN_ON_ONCE(1);
+		return -EMSGSIZE;
+	}
+
+	if (nla_put_be16(skb, MPTCP_ATTR_SPORT, issk->inet_sport))
+		return -EMSGSIZE;
+	if (nla_put_be16(skb, MPTCP_ATTR_DPORT, issk->inet_dport))
+		return -EMSGSIZE;
+
+	sf = mptcp_subflow_ctx(ssk);
+	if (WARN_ON_ONCE(!sf))
+		return -EINVAL;
+
+	if (nla_put_u8(skb, MPTCP_ATTR_LOC_ID, subflow_get_local_id(sf)))
+		return -EMSGSIZE;
+
+	if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, sf->remote_id))
+		return -EMSGSIZE;
+
+	return 0;
+}
+
+static int mptcp_event_put_token_and_ssk(struct sk_buff *skb,
+					 const struct mptcp_sock *msk,
+					 const struct sock *ssk)
+{
+	const struct sock *sk = (const struct sock *)msk;
+	const struct mptcp_subflow_context *sf;
+	u8 sk_err;
+
+	if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
+		return -EMSGSIZE;
+
+	if (mptcp_event_add_subflow(skb, ssk))
+		return -EMSGSIZE;
+
+	sf = mptcp_subflow_ctx(ssk);
+	if (WARN_ON_ONCE(!sf))
+		return -EINVAL;
+
+	if (nla_put_u8(skb, MPTCP_ATTR_BACKUP, sf->backup))
+		return -EMSGSIZE;
+
+	if (ssk->sk_bound_dev_if &&
+	    nla_put_s32(skb, MPTCP_ATTR_IF_IDX, ssk->sk_bound_dev_if))
+		return -EMSGSIZE;
+
+	sk_err = READ_ONCE(ssk->sk_err);
+	if (sk_err && sk->sk_state == TCP_ESTABLISHED &&
+	    nla_put_u8(skb, MPTCP_ATTR_ERROR, sk_err))
+		return -EMSGSIZE;
+
+	return 0;
+}
+
+static int mptcp_event_sub_established(struct sk_buff *skb,
+				       const struct mptcp_sock *msk,
+				       const struct sock *ssk)
+{
+	return mptcp_event_put_token_and_ssk(skb, msk, ssk);
+}
+
+static int mptcp_event_sub_closed(struct sk_buff *skb,
+				  const struct mptcp_sock *msk,
+				  const struct sock *ssk)
+{
+	const struct mptcp_subflow_context *sf;
+
+	if (mptcp_event_put_token_and_ssk(skb, msk, ssk))
+		return -EMSGSIZE;
+
+	sf = mptcp_subflow_ctx(ssk);
+	if (!sf->reset_seen)
+		return 0;
+
+	if (nla_put_u32(skb, MPTCP_ATTR_RESET_REASON, sf->reset_reason))
+		return -EMSGSIZE;
+
+	if (nla_put_u32(skb, MPTCP_ATTR_RESET_FLAGS, sf->reset_transient))
+		return -EMSGSIZE;
+
+	return 0;
+}
+
+static int mptcp_event_created(struct sk_buff *skb,
+			       const struct mptcp_sock *msk,
+			       const struct sock *ssk)
+{
+	int err = nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token));
+	u16 flags = 0;
+
+	if (err)
+		return err;
+
+	if (nla_put_u8(skb, MPTCP_ATTR_SERVER_SIDE, READ_ONCE(msk->pm.server_side)))
+		return -EMSGSIZE;
+
+	if (READ_ONCE(msk->pm.remote_deny_join_id0))
+		flags |= MPTCP_PM_EV_FLAG_DENY_JOIN_ID0;
+
+	if (flags && nla_put_u16(skb, MPTCP_ATTR_FLAGS, flags))
+		return -EMSGSIZE;
+
+	return mptcp_event_add_subflow(skb, ssk);
+}
+
+void mptcp_event_addr_removed(const struct mptcp_sock *msk, uint8_t id)
+{
+	struct net *net = sock_net((const struct sock *)msk);
+	struct nlmsghdr *nlh;
+	struct sk_buff *skb;
+
+	if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
+		return;
+
+	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+	if (!skb)
+		return;
+
+	nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, MPTCP_EVENT_REMOVED);
+	if (!nlh)
+		goto nla_put_failure;
+
+	if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
+		goto nla_put_failure;
+
+	if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, id))
+		goto nla_put_failure;
+
+	genlmsg_end(skb, nlh);
+	mptcp_nl_mcast_send(net, skb, GFP_ATOMIC);
+	return;
+
+nla_put_failure:
+	nlmsg_free(skb);
+}
+
+void mptcp_event_addr_announced(const struct sock *ssk,
+				const struct mptcp_addr_info *info)
+{
+	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
+	struct mptcp_sock *msk = mptcp_sk(subflow->conn);
+	struct net *net = sock_net(ssk);
+	struct nlmsghdr *nlh;
+	struct sk_buff *skb;
+
+	if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
+		return;
+
+	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+	if (!skb)
+		return;
+
+	nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0,
+			  MPTCP_EVENT_ANNOUNCED);
+	if (!nlh)
+		goto nla_put_failure;
+
+	if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
+		goto nla_put_failure;
+
+	if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, info->id))
+		goto nla_put_failure;
+
+	if (nla_put_be16(skb, MPTCP_ATTR_DPORT,
+			 info->port == 0 ?
+			 inet_sk(ssk)->inet_dport :
+			 info->port))
+		goto nla_put_failure;
+
+	switch (info->family) {
+	case AF_INET:
+		if (nla_put_in_addr(skb, MPTCP_ATTR_DADDR4, info->addr.s_addr))
+			goto nla_put_failure;
+		break;
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	case AF_INET6:
+		if (nla_put_in6_addr(skb, MPTCP_ATTR_DADDR6, &info->addr6))
+			goto nla_put_failure;
+		break;
+#endif
+	default:
+		WARN_ON_ONCE(1);
+		goto nla_put_failure;
+	}
+
+	genlmsg_end(skb, nlh);
+	mptcp_nl_mcast_send(net, skb, GFP_ATOMIC);
+	return;
+
+nla_put_failure:
+	nlmsg_free(skb);
+}
+
+void mptcp_event_pm_listener(const struct sock *ssk,
+			     enum mptcp_event_type event)
+{
+	const struct inet_sock *issk = inet_sk(ssk);
+	struct net *net = sock_net(ssk);
+	struct nlmsghdr *nlh;
+	struct sk_buff *skb;
+
+	if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
+		return;
+
+	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!skb)
+		return;
+
+	nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, event);
+	if (!nlh)
+		goto nla_put_failure;
+
+	if (nla_put_u16(skb, MPTCP_ATTR_FAMILY, ssk->sk_family))
+		goto nla_put_failure;
+
+	if (nla_put_be16(skb, MPTCP_ATTR_SPORT, issk->inet_sport))
+		goto nla_put_failure;
+
+	switch (ssk->sk_family) {
+	case AF_INET:
+		if (nla_put_in_addr(skb, MPTCP_ATTR_SADDR4, issk->inet_saddr))
+			goto nla_put_failure;
+		break;
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+	case AF_INET6: {
+		const struct ipv6_pinfo *np = inet6_sk(ssk);
+
+		if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &np->saddr))
+			goto nla_put_failure;
+		break;
+	}
+#endif
+	default:
+		WARN_ON_ONCE(1);
+		goto nla_put_failure;
+	}
+
+	genlmsg_end(skb, nlh);
+	mptcp_nl_mcast_send(net, skb, GFP_KERNEL);
+	return;
+
+nla_put_failure:
+	nlmsg_free(skb);
+}
+
+void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
+		 const struct sock *ssk, gfp_t gfp)
+{
+	struct net *net = sock_net((const struct sock *)msk);
+	struct nlmsghdr *nlh;
+	struct sk_buff *skb;
+
+	if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
+		return;
+
+	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+	if (!skb)
+		return;
+
+	nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, type);
+	if (!nlh)
+		goto nla_put_failure;
+
+	switch (type) {
+	case MPTCP_EVENT_UNSPEC:
+		WARN_ON_ONCE(1);
+		break;
+	case MPTCP_EVENT_CREATED:
+	case MPTCP_EVENT_ESTABLISHED:
+		if (mptcp_event_created(skb, msk, ssk) < 0)
+			goto nla_put_failure;
+		break;
+	case MPTCP_EVENT_CLOSED:
+		if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)) < 0)
+			goto nla_put_failure;
+		break;
+	case MPTCP_EVENT_ANNOUNCED:
+	case MPTCP_EVENT_REMOVED:
+		/* call mptcp_event_addr_announced()/removed instead */
+		WARN_ON_ONCE(1);
+		break;
+	case MPTCP_EVENT_SUB_ESTABLISHED:
+	case MPTCP_EVENT_SUB_PRIORITY:
+		if (mptcp_event_sub_established(skb, msk, ssk) < 0)
+			goto nla_put_failure;
+		break;
+	case MPTCP_EVENT_SUB_CLOSED:
+		if (mptcp_event_sub_closed(skb, msk, ssk) < 0)
+			goto nla_put_failure;
+		break;
+	case MPTCP_EVENT_LISTENER_CREATED:
+	case MPTCP_EVENT_LISTENER_CLOSED:
+		break;
+	}
+
+	genlmsg_end(skb, nlh);
+	mptcp_nl_mcast_send(net, skb, gfp);
+	return;
+
+nla_put_failure:
+	nlmsg_free(skb);
+}
+
+struct genl_family mptcp_genl_family __ro_after_init = {
+	.name		= MPTCP_PM_NAME,
+	.version	= MPTCP_PM_VER,
+	.netnsok	= true,
+	.module		= THIS_MODULE,
+	.ops		= mptcp_pm_nl_ops,
+	.n_ops		= ARRAY_SIZE(mptcp_pm_nl_ops),
+	.resv_start_op	= MPTCP_PM_CMD_SUBFLOW_DESTROY + 1,
+	.mcgrps		= mptcp_pm_mcgrps,
+	.n_mcgrps	= ARRAY_SIZE(mptcp_pm_mcgrps),
+};
+
+static int __net_init pm_nl_init_net(struct net *net)
+{
+	struct pm_nl_pernet *pernet = pm_nl_get_pernet(net);
+
+	INIT_LIST_HEAD_RCU(&pernet->local_addr_list);
+
+	/* Cit. 2 subflows ought to be enough for anybody. */
+	pernet->subflows_max = 2;
+	pernet->next_id = 1;
+	pernet->stale_loss_cnt = 4;
+	spin_lock_init(&pernet->lock);
+
+	/* No need to initialize other pernet fields, the struct is zeroed at
+	 * allocation time.
+	 */
+
+	return 0;
+}
+
+static void __net_exit pm_nl_exit_net(struct list_head *net_list)
+{
+	struct net *net;
+
+	list_for_each_entry(net, net_list, exit_list) {
+		struct pm_nl_pernet *pernet = pm_nl_get_pernet(net);
+
+		/* net is removed from namespace list, can't race with
+		 * other modifiers, also netns core already waited for a
+		 * RCU grace period.
+		 */
+		__flush_addrs(&pernet->local_addr_list);
+	}
+}
+
+static struct pernet_operations mptcp_pm_pernet_ops = {
+	.init = pm_nl_init_net,
+	.exit_batch = pm_nl_exit_net,
+	.id = &pm_nl_pernet_id,
+	.size = sizeof(struct pm_nl_pernet),
+};
+
+void __init mptcp_pm_nl_init(void)
+{
+	if (register_pernet_subsys(&mptcp_pm_pernet_ops) < 0)
+		panic("Failed to register MPTCP PM pernet subsystem.\n");
+
+	if (genl_register_family(&mptcp_genl_family))
+		panic("Failed to register MPTCP PM netlink family\n");
+}
--- a/net/mptcp/pm_netlink.c
+++ /dev/null
@@ -1,2603 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Multipath TCP
- *
- * Copyright (c) 2020, Red Hat, Inc.
- */
-
-#define pr_fmt(fmt) "MPTCP: " fmt
-
-#include <linux/inet.h>
-#include <linux/kernel.h>
-#include <net/inet_common.h>
-#include <net/netns/generic.h>
-#include <net/mptcp.h>
-
-#include "protocol.h"
-#include "mib.h"
-#include "mptcp_pm_gen.h"
-
-static int pm_nl_pernet_id;
-
-struct mptcp_pm_add_entry {
-	struct list_head	list;
-	struct mptcp_addr_info	addr;
-	u8			retrans_times;
-	bool			timer_done;
-	struct timer_list	add_timer;
-	struct mptcp_sock	*sock;
-	struct rcu_head		rcu;
-};
-
-struct pm_nl_pernet {
-	/* protects pernet updates */
-	spinlock_t		lock;
-	struct list_head	local_addr_list;
-	unsigned int		addrs;
-	unsigned int		stale_loss_cnt;
-	unsigned int		add_addr_signal_max;
-	unsigned int		add_addr_accept_max;
-	unsigned int		local_addr_max;
-	unsigned int		subflows_max;
-	unsigned int		next_id;
-	DECLARE_BITMAP(id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
-};
-
-#define MPTCP_PM_ADDR_MAX	8
-#define ADD_ADDR_RETRANS_MAX	3
-
-static struct pm_nl_pernet *pm_nl_get_pernet(const struct net *net)
-{
-	return net_generic(net, pm_nl_pernet_id);
-}
-
-static struct pm_nl_pernet *
-pm_nl_get_pernet_from_msk(const struct mptcp_sock *msk)
-{
-	return pm_nl_get_pernet(sock_net((struct sock *)msk));
-}
-
-bool mptcp_addresses_equal(const struct mptcp_addr_info *a,
-			   const struct mptcp_addr_info *b, bool use_port)
-{
-	bool addr_equals = false;
-
-	if (a->family == b->family) {
-		if (a->family == AF_INET)
-			addr_equals = a->addr.s_addr == b->addr.s_addr;
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-		else
-			addr_equals = !ipv6_addr_cmp(&a->addr6, &b->addr6);
-	} else if (a->family == AF_INET) {
-		if (ipv6_addr_v4mapped(&b->addr6))
-			addr_equals = a->addr.s_addr == b->addr6.s6_addr32[3];
-	} else if (b->family == AF_INET) {
-		if (ipv6_addr_v4mapped(&a->addr6))
-			addr_equals = a->addr6.s6_addr32[3] == b->addr.s_addr;
-#endif
-	}
-
-	if (!addr_equals)
-		return false;
-	if (!use_port)
-		return true;
-
-	return a->port == b->port;
-}
-
-void mptcp_local_address(const struct sock_common *skc, struct mptcp_addr_info *addr)
-{
-	addr->family = skc->skc_family;
-	addr->port = htons(skc->skc_num);
-	if (addr->family == AF_INET)
-		addr->addr.s_addr = skc->skc_rcv_saddr;
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-	else if (addr->family == AF_INET6)
-		addr->addr6 = skc->skc_v6_rcv_saddr;
-#endif
-}
-
-static void remote_address(const struct sock_common *skc,
-			   struct mptcp_addr_info *addr)
-{
-	addr->family = skc->skc_family;
-	addr->port = skc->skc_dport;
-	if (addr->family == AF_INET)
-		addr->addr.s_addr = skc->skc_daddr;
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-	else if (addr->family == AF_INET6)
-		addr->addr6 = skc->skc_v6_daddr;
-#endif
-}
-
-static bool lookup_subflow_by_saddr(const struct list_head *list,
-				    const struct mptcp_addr_info *saddr)
-{
-	struct mptcp_subflow_context *subflow;
-	struct mptcp_addr_info cur;
-	struct sock_common *skc;
-
-	list_for_each_entry(subflow, list, node) {
-		skc = (struct sock_common *)mptcp_subflow_tcp_sock(subflow);
-
-		mptcp_local_address(skc, &cur);
-		if (mptcp_addresses_equal(&cur, saddr, saddr->port))
-			return true;
-	}
-
-	return false;
-}
-
-static bool lookup_subflow_by_daddr(const struct list_head *list,
-				    const struct mptcp_addr_info *daddr)
-{
-	struct mptcp_subflow_context *subflow;
-	struct mptcp_addr_info cur;
-
-	list_for_each_entry(subflow, list, node) {
-		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
-
-		if (!((1 << inet_sk_state_load(ssk)) &
-		      (TCPF_ESTABLISHED | TCPF_SYN_SENT | TCPF_SYN_RECV)))
-			continue;
-
-		remote_address((struct sock_common *)ssk, &cur);
-		if (mptcp_addresses_equal(&cur, daddr, daddr->port))
-			return true;
-	}
-
-	return false;
-}
-
-static bool
-select_local_address(const struct pm_nl_pernet *pernet,
-		     const struct mptcp_sock *msk,
-		     struct mptcp_pm_local *new_local)
-{
-	struct mptcp_pm_addr_entry *entry;
-	bool found = false;
-
-	msk_owned_by_me(msk);
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
-		if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW))
-			continue;
-
-		if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
-			continue;
-
-		new_local->addr = entry->addr;
-		new_local->flags = entry->flags;
-		new_local->ifindex = entry->ifindex;
-		found = true;
-		break;
-	}
-	rcu_read_unlock();
-
-	return found;
-}
-
-static bool
-select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk,
-		     struct mptcp_pm_local *new_local)
-{
-	struct mptcp_pm_addr_entry *entry;
-	bool found = false;
-
-	rcu_read_lock();
-	/* do not keep any additional per socket state, just signal
-	 * the address list in order.
-	 * Note: removal from the local address list during the msk life-cycle
-	 * can lead to additional addresses not being announced.
-	 */
-	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
-		if (!test_bit(entry->addr.id, msk->pm.id_avail_bitmap))
-			continue;
-
-		if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL))
-			continue;
-
-		new_local->addr = entry->addr;
-		new_local->flags = entry->flags;
-		new_local->ifindex = entry->ifindex;
-		found = true;
-		break;
-	}
-	rcu_read_unlock();
-
-	return found;
-}
-
-unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk)
-{
-	const struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
-
-	return READ_ONCE(pernet->add_addr_signal_max);
-}
-EXPORT_SYMBOL_GPL(mptcp_pm_get_add_addr_signal_max);
-
-unsigned int mptcp_pm_get_add_addr_accept_max(const struct mptcp_sock *msk)
-{
-	struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
-
-	return READ_ONCE(pernet->add_addr_accept_max);
-}
-EXPORT_SYMBOL_GPL(mptcp_pm_get_add_addr_accept_max);
-
-unsigned int mptcp_pm_get_subflows_max(const struct mptcp_sock *msk)
-{
-	struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
-
-	return READ_ONCE(pernet->subflows_max);
-}
-EXPORT_SYMBOL_GPL(mptcp_pm_get_subflows_max);
-
-unsigned int mptcp_pm_get_local_addr_max(const struct mptcp_sock *msk)
-{
-	struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
-
-	return READ_ONCE(pernet->local_addr_max);
-}
-EXPORT_SYMBOL_GPL(mptcp_pm_get_local_addr_max);
-
-bool mptcp_pm_nl_check_work_pending(struct mptcp_sock *msk)
-{
-	struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
-
-	if (msk->pm.subflows == mptcp_pm_get_subflows_max(msk) ||
-	    (find_next_and_bit(pernet->id_bitmap, msk->pm.id_avail_bitmap,
-			       MPTCP_PM_MAX_ADDR_ID + 1, 0) == MPTCP_PM_MAX_ADDR_ID + 1)) {
-		WRITE_ONCE(msk->pm.work_pending, false);
-		return false;
-	}
-	return true;
-}
-
-struct mptcp_pm_add_entry *
-mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
-				const struct mptcp_addr_info *addr)
-{
-	struct mptcp_pm_add_entry *entry;
-
-	lockdep_assert_held(&msk->pm.lock);
-
-	list_for_each_entry(entry, &msk->pm.anno_list, list) {
-		if (mptcp_addresses_equal(&entry->addr, addr, true))
-			return entry;
-	}
-
-	return NULL;
-}
-
-bool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk)
-{
-	struct mptcp_pm_add_entry *entry;
-	struct mptcp_addr_info saddr;
-	bool ret = false;
-
-	mptcp_local_address((struct sock_common *)sk, &saddr);
-
-	spin_lock_bh(&msk->pm.lock);
-	list_for_each_entry(entry, &msk->pm.anno_list, list) {
-		if (mptcp_addresses_equal(&entry->addr, &saddr, true)) {
-			ret = true;
-			goto out;
-		}
-	}
-
-out:
-	spin_unlock_bh(&msk->pm.lock);
-	return ret;
-}
-
-static void mptcp_pm_add_timer(struct timer_list *timer)
-{
-	struct mptcp_pm_add_entry *entry = from_timer(entry, timer, add_timer);
-	struct mptcp_sock *msk = entry->sock;
-	struct sock *sk = (struct sock *)msk;
-	unsigned int timeout = 0;
-	bool retransmit;
-
-	pr_debug("msk=%p\n", msk);
-
-	bh_lock_sock(sk);
-	if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE))
-		goto out;
-
-	if (sock_owned_by_user(sk)) {
-		/* Try again later. */
-		timeout = HZ / 20;
-		goto out;
-	}
-
-	if (mptcp_pm_should_add_signal_addr(msk)) {
-		timeout = HZ;
-		goto out;
-	}
-
-	timeout = mptcp_get_add_addr_timeout(sock_net(sk));
-	if (!timeout)
-		goto out;
-
-	spin_lock_bh(&msk->pm.lock);
-
-	/* The cancel path (mptcp_pm_del_add_timer()) can race with this
-	 * callback. Once cancel updates retrans_times to MAX, suppress further
-	 * retransmissions here. If this callback acquires pm.lock first, one
-	 * final transmit attempt is still possible.
-	 */
-	if (entry->retrans_times < ADD_ADDR_RETRANS_MAX &&
-	    !mptcp_pm_should_add_signal_addr(msk)) {
-		pr_debug("retransmit ADD_ADDR id=%d\n", entry->addr.id);
-		mptcp_pm_announce_addr(msk, &entry->addr, false);
-		mptcp_pm_add_addr_send_ack(msk);
-		entry->retrans_times++;
-	}
-
-	retransmit = entry->retrans_times < ADD_ADDR_RETRANS_MAX;
-	if (!retransmit)
-		timeout = 0;
-
-	spin_unlock_bh(&msk->pm.lock);
-
-	if (!retransmit)
-		mptcp_pm_subflow_established(msk);
-
-out:
-	if (timeout)
-		sk_reset_timer(sk, timer, jiffies + timeout);
-	else
-		/* if sock_put calls sk_free: avoid waiting for this timer */
-		entry->timer_done = true;
-	bh_unlock_sock(sk);
-	sock_put(sk);
-}
-
-struct mptcp_pm_add_entry *
-mptcp_pm_del_add_timer(struct mptcp_sock *msk,
-		       const struct mptcp_addr_info *addr, bool check_id)
-{
-	struct mptcp_pm_add_entry *entry;
-	struct sock *sk = (struct sock *)msk;
-	bool stop_timer = false;
-
-	rcu_read_lock();
-
-	spin_lock_bh(&msk->pm.lock);
-	entry = mptcp_lookup_anno_list_by_saddr(msk, addr);
-	if (entry && (!check_id || entry->addr.id == addr->id)) {
-		entry->retrans_times = ADD_ADDR_RETRANS_MAX;
-		stop_timer = true;
-	}
-	if (!check_id && entry)
-		list_del(&entry->list);
-	spin_unlock_bh(&msk->pm.lock);
-
-	/* Note: entry might have been removed by another thread.
-	 * We hold rcu_read_lock() to ensure it is not freed under us.
-	 */
-	if (stop_timer) {
-		if (check_id)
-			sk_stop_timer(sk, &entry->add_timer);
-		else
-			sk_stop_timer_sync(sk, &entry->add_timer);
-	}
-
-	rcu_read_unlock();
-	return entry;
-}
-
-bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
-			      const struct mptcp_addr_info *addr)
-{
-	struct mptcp_pm_add_entry *add_entry = NULL;
-	struct sock *sk = (struct sock *)msk;
-	struct net *net = sock_net(sk);
-	unsigned int timeout;
-
-	lockdep_assert_held(&msk->pm.lock);
-
-	if (msk->pm.status & BIT(MPTCP_PM_DESTROYING))
-		return false;
-
-	add_entry = mptcp_lookup_anno_list_by_saddr(msk, addr);
-
-	if (add_entry) {
-		if (WARN_ON_ONCE(mptcp_pm_is_kernel(msk)))
-			return false;
-
-		goto reset_timer;
-	}
-
-	add_entry = kmalloc(sizeof(*add_entry), GFP_ATOMIC);
-	if (!add_entry)
-		return false;
-
-	list_add(&add_entry->list, &msk->pm.anno_list);
-
-	add_entry->addr = *addr;
-	add_entry->sock = msk;
-
-	timer_setup(&add_entry->add_timer, mptcp_pm_add_timer, 0);
-reset_timer:
-	add_entry->retrans_times = 0;
-	add_entry->timer_done = false;
-	timeout = mptcp_get_add_addr_timeout(net);
-	if (timeout)
-		sk_reset_timer(sk, &add_entry->add_timer, jiffies + timeout);
-
-	return true;
-}
-
-void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
-{
-	struct mptcp_pm_add_entry *entry, *tmp;
-	struct sock *sk = (struct sock *)msk;
-	LIST_HEAD(free_list);
-
-	pr_debug("msk=%p\n", msk);
-
-	spin_lock_bh(&msk->pm.lock);
-	list_splice_init(&msk->pm.anno_list, &free_list);
-	spin_unlock_bh(&msk->pm.lock);
-
-	list_for_each_entry_safe(entry, tmp, &free_list, list) {
-		if (!entry->timer_done)
-			sk_stop_timer_sync(sk, &entry->add_timer);
-		kfree_rcu(entry, rcu);
-	}
-}
-
-/* Fill all the remote addresses into the array addrs[],
- * and return the array size.
- */
-static unsigned int fill_remote_addresses_vec(struct mptcp_sock *msk,
-					      struct mptcp_addr_info *local,
-					      bool fullmesh,
-					      struct mptcp_addr_info *addrs)
-{
-	bool deny_id0 = READ_ONCE(msk->pm.remote_deny_join_id0);
-	struct sock *sk = (struct sock *)msk, *ssk;
-	struct mptcp_subflow_context *subflow;
-	struct mptcp_addr_info remote = { 0 };
-	unsigned int subflows_max;
-	int i = 0;
-
-	subflows_max = mptcp_pm_get_subflows_max(msk);
-	remote_address((struct sock_common *)sk, &remote);
-
-	/* Non-fullmesh endpoint, fill in the single entry
-	 * corresponding to the primary MPC subflow remote address
-	 */
-	if (!fullmesh) {
-		if (deny_id0)
-			return 0;
-
-		if (!mptcp_pm_addr_families_match(sk, local, &remote))
-			return 0;
-
-		msk->pm.subflows++;
-		addrs[i++] = remote;
-	} else {
-		DECLARE_BITMAP(unavail_id, MPTCP_PM_MAX_ADDR_ID + 1);
-
-		/* Forbid creation of new subflows matching existing
-		 * ones, possibly already created by incoming ADD_ADDR
-		 */
-		bitmap_zero(unavail_id, MPTCP_PM_MAX_ADDR_ID + 1);
-		mptcp_for_each_subflow(msk, subflow)
-			if (READ_ONCE(subflow->local_id) == local->id)
-				__set_bit(subflow->remote_id, unavail_id);
-
-		mptcp_for_each_subflow(msk, subflow) {
-			ssk = mptcp_subflow_tcp_sock(subflow);
-			remote_address((struct sock_common *)ssk, &addrs[i]);
-			addrs[i].id = READ_ONCE(subflow->remote_id);
-			if (deny_id0 && !addrs[i].id)
-				continue;
-
-			if (test_bit(addrs[i].id, unavail_id))
-				continue;
-
-			if (!mptcp_pm_addr_families_match(sk, local, &addrs[i]))
-				continue;
-
-			if (msk->pm.subflows < subflows_max) {
-				/* forbid creating multiple address towards
-				 * this id
-				 */
-				__set_bit(addrs[i].id, unavail_id);
-				msk->pm.subflows++;
-				i++;
-			}
-		}
-	}
-
-	return i;
-}
-
-static void __mptcp_pm_send_ack(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
-				bool prio, bool backup)
-{
-	struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
-	bool slow;
-
-	pr_debug("send ack for %s\n",
-		 prio ? "mp_prio" : (mptcp_pm_should_add_signal(msk) ? "add_addr" : "rm_addr"));
-
-	slow = lock_sock_fast(ssk);
-	if (prio) {
-		subflow->send_mp_prio = 1;
-		subflow->request_bkup = backup;
-	}
-
-	__mptcp_subflow_send_ack(ssk);
-	unlock_sock_fast(ssk, slow);
-}
-
-static void mptcp_pm_send_ack(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow,
-			      bool prio, bool backup)
-{
-	spin_unlock_bh(&msk->pm.lock);
-	__mptcp_pm_send_ack(msk, subflow, prio, backup);
-	spin_lock_bh(&msk->pm.lock);
-}
-
-static struct mptcp_pm_addr_entry *
-__lookup_addr_by_id(struct pm_nl_pernet *pernet, unsigned int id)
-{
-	struct mptcp_pm_addr_entry *entry;
-
-	list_for_each_entry(entry, &pernet->local_addr_list, list) {
-		if (entry->addr.id == id)
-			return entry;
-	}
-	return NULL;
-}
-
-static struct mptcp_pm_addr_entry *
-__lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info)
-{
-	struct mptcp_pm_addr_entry *entry;
-
-	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list,
-				lockdep_is_held(&pernet->lock)) {
-		if (mptcp_addresses_equal(&entry->addr, info, entry->addr.port))
-			return entry;
-	}
-	return NULL;
-}
-
-static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
-{
-	struct sock *sk = (struct sock *)msk;
-	unsigned int add_addr_signal_max;
-	bool signal_and_subflow = false;
-	unsigned int local_addr_max;
-	struct pm_nl_pernet *pernet;
-	struct mptcp_pm_local local;
-	unsigned int subflows_max;
-
-	pernet = pm_nl_get_pernet(sock_net(sk));
-
-	add_addr_signal_max = mptcp_pm_get_add_addr_signal_max(msk);
-	local_addr_max = mptcp_pm_get_local_addr_max(msk);
-	subflows_max = mptcp_pm_get_subflows_max(msk);
-
-	/* do lazy endpoint usage accounting for the MPC subflows */
-	if (unlikely(!(msk->pm.status & BIT(MPTCP_PM_MPC_ENDPOINT_ACCOUNTED))) && msk->first) {
-		struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(msk->first);
-		struct mptcp_pm_addr_entry *entry;
-		struct mptcp_addr_info mpc_addr;
-		bool backup = false;
-
-		mptcp_local_address((struct sock_common *)msk->first, &mpc_addr);
-		rcu_read_lock();
-		entry = __lookup_addr(pernet, &mpc_addr);
-		if (entry) {
-			__clear_bit(entry->addr.id, msk->pm.id_avail_bitmap);
-			msk->mpc_endpoint_id = entry->addr.id;
-			backup = !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
-		}
-		rcu_read_unlock();
-
-		if (backup)
-			mptcp_pm_send_ack(msk, subflow, true, backup);
-
-		msk->pm.status |= BIT(MPTCP_PM_MPC_ENDPOINT_ACCOUNTED);
-	}
-
-	pr_debug("local %d:%d signal %d:%d subflows %d:%d\n",
-		 msk->pm.local_addr_used, local_addr_max,
-		 msk->pm.add_addr_signaled, add_addr_signal_max,
-		 msk->pm.subflows, subflows_max);
-
-	/* check first for announce */
-	if (msk->pm.add_addr_signaled < add_addr_signal_max) {
-		u8 endp_id;
-
-		/* due to racing events on both ends we can reach here while
-		 * previous add address is still running: if we invoke now
-		 * mptcp_pm_announce_addr(), that will fail and the
-		 * corresponding id will be marked as used.
-		 * Instead let the PM machinery reschedule us when the
-		 * current address announce will be completed.
-		 */
-		if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL))
-			return;
-
-		if (!select_signal_address(pernet, msk, &local))
-			goto subflow;
-
-		/* Special case for ID0: set the correct ID */
-		endp_id = local.addr.id;
-		if (endp_id == msk->mpc_endpoint_id)
-			local.addr.id = 0;
-
-		/* If the alloc fails, we are on memory pressure, not worth
-		 * continuing, and trying to create subflows.
-		 */
-		if (!mptcp_pm_alloc_anno_list(msk, &local.addr))
-			return;
-
-		__clear_bit(endp_id, msk->pm.id_avail_bitmap);
-		msk->pm.add_addr_signaled++;
-
-		mptcp_pm_announce_addr(msk, &local.addr, false);
-		mptcp_pm_nl_addr_send_ack(msk);
-
-		if (local.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
-			signal_and_subflow = true;
-	}
-
-subflow:
-	/* No need to try establishing subflows to remote id0 if not allowed */
-	if (mptcp_pm_add_addr_c_flag_case(msk))
-		goto exit;
-
-	/* check if should create a new subflow */
-	while (msk->pm.local_addr_used < local_addr_max &&
-	       msk->pm.subflows < subflows_max) {
-		struct mptcp_addr_info addrs[MPTCP_PM_ADDR_MAX];
-		bool fullmesh;
-		int i, nr;
-
-		if (signal_and_subflow)
-			signal_and_subflow = false;
-		else if (!select_local_address(pernet, msk, &local))
-			break;
-
-		fullmesh = !!(local.flags & MPTCP_PM_ADDR_FLAG_FULLMESH);
-
-		__clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
-
-		/* Special case for ID0: set the correct ID */
-		if (local.addr.id == msk->mpc_endpoint_id)
-			local.addr.id = 0;
-		else /* local_addr_used is not decr for ID 0 */
-			msk->pm.local_addr_used++;
-
-		nr = fill_remote_addresses_vec(msk, &local.addr, fullmesh, addrs);
-		if (nr == 0)
-			continue;
-
-		spin_unlock_bh(&msk->pm.lock);
-		for (i = 0; i < nr; i++)
-			__mptcp_subflow_connect(sk, &local, &addrs[i]);
-		spin_lock_bh(&msk->pm.lock);
-	}
-
-exit:
-	/* If an endpoint has both the signal and subflow flags, but it is not
-	 * possible to create subflows -- the 'while' loop body above never
-	 * executed --  then still mark the endp as used, which is somehow the
-	 * case. This avoids issues later when removing the endpoint and calling
-	 * __mark_subflow_endp_available(), which expects the increment here.
-	 */
-	if (signal_and_subflow && local.addr.id != msk->mpc_endpoint_id)
-		msk->pm.local_addr_used++;
-
-	mptcp_pm_nl_check_work_pending(msk);
-}
-
-static void mptcp_pm_nl_fully_established(struct mptcp_sock *msk)
-{
-	mptcp_pm_create_subflow_or_signal_addr(msk);
-}
-
-static void mptcp_pm_nl_subflow_established(struct mptcp_sock *msk)
-{
-	mptcp_pm_create_subflow_or_signal_addr(msk);
-}
-
-/* Fill all the local addresses into the array addrs[],
- * and return the array size.
- */
-static unsigned int fill_local_addresses_vec(struct mptcp_sock *msk,
-					     struct mptcp_addr_info *remote,
-					     struct mptcp_pm_local *locals)
-{
-	struct sock *sk = (struct sock *)msk;
-	struct mptcp_pm_addr_entry *entry;
-	struct mptcp_addr_info mpc_addr;
-	struct pm_nl_pernet *pernet;
-	unsigned int subflows_max;
-	bool c_flag_case;
-	int i = 0;
-
-	pernet = pm_nl_get_pernet_from_msk(msk);
-	subflows_max = mptcp_pm_get_subflows_max(msk);
-	c_flag_case = remote->id && mptcp_pm_add_addr_c_flag_case(msk);
-
-	mptcp_local_address((struct sock_common *)msk, &mpc_addr);
-
-	rcu_read_lock();
-	list_for_each_entry_rcu(entry, &pernet->local_addr_list, list) {
-		if (!(entry->flags & MPTCP_PM_ADDR_FLAG_FULLMESH))
-			continue;
-
-		if (!mptcp_pm_addr_families_match(sk, &entry->addr, remote))
-			continue;
-
-		if (msk->pm.subflows < subflows_max) {
-			bool is_id0;
-
-			locals[i].addr = entry->addr;
-			locals[i].flags = entry->flags;
-			locals[i].ifindex = entry->ifindex;
-
-			is_id0 = mptcp_addresses_equal(&locals[i].addr,
-						       &mpc_addr,
-						       locals[i].addr.port);
-
-			if (c_flag_case &&
-			    (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)) {
-				__clear_bit(locals[i].addr.id,
-					    msk->pm.id_avail_bitmap);
-
-				if (!is_id0)
-					msk->pm.local_addr_used++;
-			}
-
-			/* Special case for ID0: set the correct ID */
-			if (is_id0)
-				locals[i].addr.id = 0;
-
-			msk->pm.subflows++;
-			i++;
-		}
-	}
-	rcu_read_unlock();
-
-	/* Special case: peer sets the C flag, accept one ADD_ADDR if default
-	 * limits are used -- accepting no ADD_ADDR -- and use subflow endpoints
-	 */
-	if (!i && c_flag_case) {
-		unsigned int local_addr_max = mptcp_pm_get_local_addr_max(msk);
-
-		while (msk->pm.local_addr_used < local_addr_max &&
-		       msk->pm.subflows < subflows_max) {
-			struct mptcp_pm_local *local = &locals[i];
-
-			if (!select_local_address(pernet, msk, local))
-				break;
-
-			__clear_bit(local->addr.id, msk->pm.id_avail_bitmap);
-
-			if (!mptcp_pm_addr_families_match(sk, &local->addr,
-							  remote))
-				continue;
-
-			if (mptcp_addresses_equal(&local->addr, &mpc_addr,
-						  local->addr.port))
-				continue;
-
-			msk->pm.local_addr_used++;
-			msk->pm.subflows++;
-			i++;
-		}
-
-		return i;
-	}
-
-	/* If the array is empty, fill in the single
-	 * 'IPADDRANY' local address
-	 */
-	if (!i) {
-		memset(&locals[i], 0, sizeof(locals[i]));
-		locals[i].addr.family =
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-			       remote->family == AF_INET6 &&
-			       ipv6_addr_v4mapped(&remote->addr6) ? AF_INET :
-#endif
-			       remote->family;
-
-		if (!mptcp_pm_addr_families_match(sk, &locals[i].addr, remote))
-			return 0;
-
-		msk->pm.subflows++;
-		i++;
-	}
-
-	return i;
-}
-
-static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk)
-{
-	struct mptcp_pm_local locals[MPTCP_PM_ADDR_MAX];
-	struct sock *sk = (struct sock *)msk;
-	unsigned int add_addr_accept_max;
-	struct mptcp_addr_info remote;
-	unsigned int subflows_max;
-	bool sf_created = false;
-	int i, nr;
-
-	add_addr_accept_max = mptcp_pm_get_add_addr_accept_max(msk);
-	subflows_max = mptcp_pm_get_subflows_max(msk);
-
-	pr_debug("accepted %d:%d remote family %d\n",
-		 msk->pm.add_addr_accepted, add_addr_accept_max,
-		 msk->pm.remote.family);
-
-	remote = msk->pm.remote;
-	mptcp_pm_announce_addr(msk, &remote, true);
-	mptcp_pm_nl_addr_send_ack(msk);
-
-	if (lookup_subflow_by_daddr(&msk->conn_list, &remote))
-		return;
-
-	/* pick id 0 port, if none is provided the remote address */
-	if (!remote.port)
-		remote.port = sk->sk_dport;
-
-	/* connect to the specified remote address, using whatever
-	 * local address the routing configuration will pick.
-	 */
-	nr = fill_local_addresses_vec(msk, &remote, locals);
-	if (nr == 0)
-		return;
-
-	spin_unlock_bh(&msk->pm.lock);
-	for (i = 0; i < nr; i++)
-		if (__mptcp_subflow_connect(sk, &locals[i], &remote) == 0)
-			sf_created = true;
-	spin_lock_bh(&msk->pm.lock);
-
-	if (sf_created) {
-		/* add_addr_accepted is not decr for ID 0 */
-		if (remote.id)
-			msk->pm.add_addr_accepted++;
-		if (msk->pm.add_addr_accepted >= add_addr_accept_max ||
-		    msk->pm.subflows >= subflows_max)
-			WRITE_ONCE(msk->pm.accept_addr, false);
-	}
-}
-
-bool mptcp_pm_nl_is_init_remote_addr(struct mptcp_sock *msk,
-				     const struct mptcp_addr_info *remote)
-{
-	struct mptcp_addr_info mpc_remote;
-
-	remote_address((struct sock_common *)msk, &mpc_remote);
-	return mptcp_addresses_equal(&mpc_remote, remote, remote->port);
-}
-
-static bool subflow_in_rm_list(const struct mptcp_subflow_context *subflow,
-			       const struct mptcp_rm_list *rm_list)
-{
-	u8 i, id = subflow_get_local_id(subflow);
-
-	for (i = 0; i < rm_list->nr; i++) {
-		if (rm_list->ids[i] == id)
-			return true;
-	}
-
-	return false;
-}
-
-void mptcp_pm_nl_addr_send_ack_avoid_list(struct mptcp_sock *msk,
-					  const struct mptcp_rm_list *rm_list)
-{
-	struct mptcp_subflow_context *subflow, *same_id = NULL;
-
-	msk_owned_by_me(msk);
-	lockdep_assert_held(&msk->pm.lock);
-
-	if (!mptcp_pm_should_add_signal(msk) &&
-	    !mptcp_pm_should_rm_signal(msk))
-		return;
-
-	mptcp_for_each_subflow(msk, subflow) {
-		if (!__mptcp_subflow_active(subflow))
-			continue;
-
-		if (unlikely(rm_list &&
-			     subflow_in_rm_list(subflow, rm_list))) {
-			if (!same_id)
-				same_id = subflow;
-		} else {
-			goto send_ack;
-		}
-	}
-
-	if (same_id)
-		subflow = same_id;
-	else
-		return;
-
-send_ack:
-	mptcp_pm_send_ack(msk, subflow, false, false);
-}
-
-void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk)
-{
-	mptcp_pm_nl_addr_send_ack_avoid_list(msk, NULL);
-}
-
-int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk,
-				 struct mptcp_addr_info *addr,
-				 struct mptcp_addr_info *rem,
-				 u8 bkup)
-{
-	struct mptcp_subflow_context *subflow;
-
-	pr_debug("bkup=%d\n", bkup);
-
-	mptcp_for_each_subflow(msk, subflow) {
-		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
-		struct mptcp_addr_info local, remote;
-
-		if (!__mptcp_subflow_active(subflow))
-			continue;
-
-		mptcp_local_address((struct sock_common *)ssk, &local);
-		if (!mptcp_addresses_equal(&local, addr, addr->port))
-			continue;
-
-		if (rem && rem->family != AF_UNSPEC) {
-			remote_address((struct sock_common *)ssk, &remote);
-			if (!mptcp_addresses_equal(&remote, rem, rem->port))
-				continue;
-		}
-
-		__mptcp_pm_send_ack(msk, subflow, true, bkup);
-		return 0;
-	}
-
-	return -EINVAL;
-}
-
-static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk,
-					   const struct mptcp_rm_list *rm_list,
-					   enum linux_mptcp_mib_field rm_type)
-{
-	struct mptcp_subflow_context *subflow, *tmp;
-	struct sock *sk = (struct sock *)msk;
-	u8 i;
-
-	pr_debug("%s rm_list_nr %d\n",
-		 rm_type == MPTCP_MIB_RMADDR ? "address" : "subflow", rm_list->nr);
-
-	msk_owned_by_me(msk);
-
-	if (sk->sk_state == TCP_LISTEN)
-		return;
-
-	if (!rm_list->nr)
-		return;
-
-	if (list_empty(&msk->conn_list))
-		return;
-
-	for (i = 0; i < rm_list->nr; i++) {
-		u8 rm_id = rm_list->ids[i];
-		bool removed = false;
-
-		mptcp_for_each_subflow_safe(msk, subflow, tmp) {
-			struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
-			u8 remote_id = READ_ONCE(subflow->remote_id);
-			int how = RCV_SHUTDOWN | SEND_SHUTDOWN;
-			u8 id = subflow_get_local_id(subflow);
-
-			if ((1 << inet_sk_state_load(ssk)) &
-			    (TCPF_FIN_WAIT1 | TCPF_FIN_WAIT2 | TCPF_CLOSING | TCPF_CLOSE))
-				continue;
-			if (rm_type == MPTCP_MIB_RMADDR && remote_id != rm_id)
-				continue;
-			if (rm_type == MPTCP_MIB_RMSUBFLOW && id != rm_id)
-				continue;
-
-			pr_debug(" -> %s rm_list_ids[%d]=%u local_id=%u remote_id=%u mpc_id=%u\n",
-				 rm_type == MPTCP_MIB_RMADDR ? "address" : "subflow",
-				 i, rm_id, id, remote_id, msk->mpc_endpoint_id);
-			spin_unlock_bh(&msk->pm.lock);
-			mptcp_subflow_shutdown(sk, ssk, how);
-			removed |= subflow->request_join;
-
-			/* the following takes care of updating the subflows counter */
-			mptcp_close_ssk(sk, ssk, subflow);
-			spin_lock_bh(&msk->pm.lock);
-
-			if (rm_type == MPTCP_MIB_RMSUBFLOW)
-				__MPTCP_INC_STATS(sock_net(sk), rm_type);
-		}
-
-		if (rm_type == MPTCP_MIB_RMADDR)
-			__MPTCP_INC_STATS(sock_net(sk), rm_type);
-
-		if (!removed)
-			continue;
-
-		if (!mptcp_pm_is_kernel(msk))
-			continue;
-
-		if (rm_type == MPTCP_MIB_RMADDR && rm_id &&
-		    !WARN_ON_ONCE(msk->pm.add_addr_accepted == 0)) {
-			/* Note: if the subflow has been closed before, this
-			 * add_addr_accepted counter will not be decremented.
-			 */
-			if (--msk->pm.add_addr_accepted < mptcp_pm_get_add_addr_accept_max(msk))
-				WRITE_ONCE(msk->pm.accept_addr, true);
-		}
-	}
-}
-
-static void mptcp_pm_nl_rm_addr_received(struct mptcp_sock *msk)
-{
-	mptcp_pm_nl_rm_addr_or_subflow(msk, &msk->pm.rm_list_rx, MPTCP_MIB_RMADDR);
-}
-
-static void mptcp_pm_nl_rm_subflow_received(struct mptcp_sock *msk,
-					    const struct mptcp_rm_list *rm_list)
-{
-	mptcp_pm_nl_rm_addr_or_subflow(msk, rm_list, MPTCP_MIB_RMSUBFLOW);
-}
-
-void mptcp_pm_nl_work(struct mptcp_sock *msk)
-{
-	struct mptcp_pm_data *pm = &msk->pm;
-
-	msk_owned_by_me(msk);
-
-	if (!(pm->status & MPTCP_PM_WORK_MASK))
-		return;
-
-	spin_lock_bh(&msk->pm.lock);
-
-	pr_debug("msk=%p status=%x\n", msk, pm->status);
-	if (pm->status & BIT(MPTCP_PM_ADD_ADDR_RECEIVED)) {
-		pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_RECEIVED);
-		mptcp_pm_nl_add_addr_received(msk);
-	}
-	if (pm->status & BIT(MPTCP_PM_ADD_ADDR_SEND_ACK)) {
-		pm->status &= ~BIT(MPTCP_PM_ADD_ADDR_SEND_ACK);
-		mptcp_pm_nl_addr_send_ack(msk);
-	}
-	if (pm->status & BIT(MPTCP_PM_RM_ADDR_RECEIVED)) {
-		pm->status &= ~BIT(MPTCP_PM_RM_ADDR_RECEIVED);
-		mptcp_pm_nl_rm_addr_received(msk);
-	}
-	if (pm->status & BIT(MPTCP_PM_ESTABLISHED)) {
-		pm->status &= ~BIT(MPTCP_PM_ESTABLISHED);
-		mptcp_pm_nl_fully_established(msk);
-	}
-	if (pm->status & BIT(MPTCP_PM_SUBFLOW_ESTABLISHED)) {
-		pm->status &= ~BIT(MPTCP_PM_SUBFLOW_ESTABLISHED);
-		mptcp_pm_nl_subflow_established(msk);
-	}
-
-	spin_unlock_bh(&msk->pm.lock);
-}
-
-static bool address_use_port(struct mptcp_pm_addr_entry *entry)
-{
-	return (entry->flags &
-		(MPTCP_PM_ADDR_FLAG_SIGNAL | MPTCP_PM_ADDR_FLAG_SUBFLOW)) ==
-		MPTCP_PM_ADDR_FLAG_SIGNAL;
-}
-
-/* caller must ensure the RCU grace period is already elapsed */
-static void __mptcp_pm_release_addr_entry(struct mptcp_pm_addr_entry *entry)
-{
-	if (entry->lsk)
-		sock_release(entry->lsk);
-	kfree(entry);
-}
-
-static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
-					     struct mptcp_pm_addr_entry *entry,
-					     bool replace)
-{
-	struct mptcp_pm_addr_entry *cur, *del_entry = NULL;
-	unsigned int addr_max;
-	int ret = -EINVAL;
-
-	spin_lock_bh(&pernet->lock);
-	/* to keep the code simple, don't do IDR-like allocation for address ID,
-	 * just bail when we exceed limits
-	 */
-	if (pernet->next_id == MPTCP_PM_MAX_ADDR_ID)
-		pernet->next_id = 1;
-	if (pernet->addrs >= MPTCP_PM_ADDR_MAX) {
-		ret = -ERANGE;
-		goto out;
-	}
-	if (test_bit(entry->addr.id, pernet->id_bitmap)) {
-		ret = -EBUSY;
-		goto out;
-	}
-
-	/* do not insert duplicate address, differentiate on port only
-	 * singled addresses
-	 */
-	if (!address_use_port(entry))
-		entry->addr.port = 0;
-	list_for_each_entry(cur, &pernet->local_addr_list, list) {
-		if (mptcp_addresses_equal(&cur->addr, &entry->addr,
-					  cur->addr.port || entry->addr.port)) {
-			/* allow replacing the exiting endpoint only if such
-			 * endpoint is an implicit one and the user-space
-			 * did not provide an endpoint id
-			 */
-			if (!(cur->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT)) {
-				ret = -EEXIST;
-				goto out;
-			}
-			if (entry->addr.id)
-				goto out;
-
-			/* allow callers that only need to look up the local
-			 * addr's id to skip replacement. This allows them to
-			 * avoid calling synchronize_rcu in the packet recv
-			 * path.
-			 */
-			if (!replace) {
-				kfree(entry);
-				ret = cur->addr.id;
-				goto out;
-			}
-
-			pernet->addrs--;
-			entry->addr.id = cur->addr.id;
-			list_del_rcu(&cur->list);
-			del_entry = cur;
-			break;
-		}
-	}
-
-	if (!entry->addr.id) {
-find_next:
-		entry->addr.id = find_next_zero_bit(pernet->id_bitmap,
-						    MPTCP_PM_MAX_ADDR_ID + 1,
-						    pernet->next_id);
-		if (!entry->addr.id && pernet->next_id != 1) {
-			pernet->next_id = 1;
-			goto find_next;
-		}
-	}
-
-	if (!entry->addr.id)
-		goto out;
-
-	__set_bit(entry->addr.id, pernet->id_bitmap);
-	if (entry->addr.id > pernet->next_id)
-		pernet->next_id = entry->addr.id;
-
-	if (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL) {
-		addr_max = pernet->add_addr_signal_max;
-		WRITE_ONCE(pernet->add_addr_signal_max, addr_max + 1);
-	}
-	if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
-		addr_max = pernet->local_addr_max;
-		WRITE_ONCE(pernet->local_addr_max, addr_max + 1);
-	}
-
-	pernet->addrs++;
-	if (!entry->addr.port)
-		list_add_tail_rcu(&entry->list, &pernet->local_addr_list);
-	else
-		list_add_rcu(&entry->list, &pernet->local_addr_list);
-	ret = entry->addr.id;
-
-out:
-	spin_unlock_bh(&pernet->lock);
-
-	/* just replaced an existing entry, free it */
-	if (del_entry) {
-		synchronize_rcu();
-		__mptcp_pm_release_addr_entry(del_entry);
-	}
-	return ret;
-}
-
-static struct lock_class_key mptcp_slock_keys[2];
-static struct lock_class_key mptcp_keys[2];
-
-static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
-					    struct mptcp_pm_addr_entry *entry)
-{
-	bool is_ipv6 = entry->addr.family == AF_INET6;
-	int addrlen = sizeof(struct sockaddr_in);
-	struct sockaddr_storage addr;
-	struct sock *newsk, *ssk;
-	int backlog = 1024;
-	int err;
-
-	err = sock_create_kern(sock_net(sk), entry->addr.family,
-			       SOCK_STREAM, IPPROTO_MPTCP, &entry->lsk);
-	if (err)
-		return err;
-
-	newsk = entry->lsk->sk;
-	if (!newsk)
-		return -EINVAL;
-
-	/* The subflow socket lock is acquired in a nested to the msk one
-	 * in several places, even by the TCP stack, and this msk is a kernel
-	 * socket: lockdep complains. Instead of propagating the _nested
-	 * modifiers in several places, re-init the lock class for the msk
-	 * socket to an mptcp specific one.
-	 */
-	sock_lock_init_class_and_name(newsk,
-				      is_ipv6 ? "mlock-AF_INET6" : "mlock-AF_INET",
-				      &mptcp_slock_keys[is_ipv6],
-				      is_ipv6 ? "msk_lock-AF_INET6" : "msk_lock-AF_INET",
-				      &mptcp_keys[is_ipv6]);
-
-	lock_sock(newsk);
-	ssk = __mptcp_nmpc_sk(mptcp_sk(newsk));
-	release_sock(newsk);
-	if (IS_ERR(ssk))
-		return PTR_ERR(ssk);
-
-	mptcp_info2sockaddr(&entry->addr, &addr, entry->addr.family);
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-	if (entry->addr.family == AF_INET6)
-		addrlen = sizeof(struct sockaddr_in6);
-#endif
-	if (ssk->sk_family == AF_INET)
-		err = inet_bind_sk(ssk, (struct sockaddr *)&addr, addrlen);
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-	else if (ssk->sk_family == AF_INET6)
-		err = inet6_bind_sk(ssk, (struct sockaddr *)&addr, addrlen);
-#endif
-	if (err)
-		return err;
-
-	/* We don't use mptcp_set_state() here because it needs to be called
-	 * under the msk socket lock. For the moment, that will not bring
-	 * anything more than only calling inet_sk_state_store(), because the
-	 * old status is known (TCP_CLOSE).
-	 */
-	inet_sk_state_store(newsk, TCP_LISTEN);
-	lock_sock(ssk);
-	WRITE_ONCE(mptcp_subflow_ctx(ssk)->pm_listener, true);
-	err = __inet_listen_sk(ssk, backlog);
-	if (!err)
-		mptcp_event_pm_listener(ssk, MPTCP_EVENT_LISTENER_CREATED);
-	release_sock(ssk);
-	return err;
-}
-
-int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk,
-			     struct mptcp_pm_addr_entry *skc)
-{
-	struct mptcp_pm_addr_entry *entry;
-	struct pm_nl_pernet *pernet;
-	int ret;
-
-	pernet = pm_nl_get_pernet_from_msk(msk);
-
-	rcu_read_lock();
-	entry = __lookup_addr(pernet, &skc->addr);
-	ret = entry ? entry->addr.id : -1;
-	rcu_read_unlock();
-	if (ret >= 0)
-		return ret;
-
-	/* address not found, add to local list */
-	entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
-	if (!entry)
-		return -ENOMEM;
-
-	*entry = *skc;
-	entry->addr.port = 0;
-	ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, false);
-	if (ret < 0)
-		kfree(entry);
-
-	return ret;
-}
-
-bool mptcp_pm_nl_is_backup(struct mptcp_sock *msk, struct mptcp_addr_info *skc)
-{
-	struct pm_nl_pernet *pernet = pm_nl_get_pernet_from_msk(msk);
-	struct mptcp_pm_addr_entry *entry;
-	bool backup;
-
-	rcu_read_lock();
-	entry = __lookup_addr(pernet, skc);
-	backup = entry && !!(entry->flags & MPTCP_PM_ADDR_FLAG_BACKUP);
-	rcu_read_unlock();
-
-	return backup;
-}
-
-#define MPTCP_PM_CMD_GRP_OFFSET       0
-#define MPTCP_PM_EV_GRP_OFFSET        1
-
-static const struct genl_multicast_group mptcp_pm_mcgrps[] = {
-	[MPTCP_PM_CMD_GRP_OFFSET]	= { .name = MPTCP_PM_CMD_GRP_NAME, },
-	[MPTCP_PM_EV_GRP_OFFSET]        = { .name = MPTCP_PM_EV_GRP_NAME,
-					    .flags = GENL_MCAST_CAP_NET_ADMIN,
-					  },
-};
-
-void mptcp_pm_nl_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk)
-{
-	struct mptcp_subflow_context *iter, *subflow = mptcp_subflow_ctx(ssk);
-	struct sock *sk = (struct sock *)msk;
-	unsigned int active_max_loss_cnt;
-	struct net *net = sock_net(sk);
-	unsigned int stale_loss_cnt;
-	bool slow;
-
-	stale_loss_cnt = mptcp_stale_loss_cnt(net);
-	if (subflow->stale || !stale_loss_cnt || subflow->stale_count <= stale_loss_cnt)
-		return;
-
-	/* look for another available subflow not in loss state */
-	active_max_loss_cnt = max_t(int, stale_loss_cnt - 1, 1);
-	mptcp_for_each_subflow(msk, iter) {
-		if (iter != subflow && mptcp_subflow_active(iter) &&
-		    iter->stale_count < active_max_loss_cnt) {
-			/* we have some alternatives, try to mark this subflow as idle ...*/
-			slow = lock_sock_fast(ssk);
-			if (!tcp_rtx_and_write_queues_empty(ssk)) {
-				subflow->stale = 1;
-				__mptcp_retransmit_pending_data(sk);
-				MPTCP_INC_STATS(net, MPTCP_MIB_SUBFLOWSTALE);
-			}
-			unlock_sock_fast(ssk, slow);
-
-			/* always try to push the pending data regardless of re-injections:
-			 * we can possibly use backup subflows now, and subflow selection
-			 * is cheap under the msk socket lock
-			 */
-			__mptcp_push_pending(sk, 0);
-			return;
-		}
-	}
-}
-
-static int mptcp_pm_family_to_addr(int family)
-{
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-	if (family == AF_INET6)
-		return MPTCP_PM_ADDR_ATTR_ADDR6;
-#endif
-	return MPTCP_PM_ADDR_ATTR_ADDR4;
-}
-
-static int mptcp_pm_parse_pm_addr_attr(struct nlattr *tb[],
-				       const struct nlattr *attr,
-				       struct genl_info *info,
-				       struct mptcp_addr_info *addr,
-				       bool require_family)
-{
-	int err, addr_addr;
-
-	if (!attr) {
-		GENL_SET_ERR_MSG(info, "missing address info");
-		return -EINVAL;
-	}
-
-	/* no validation needed - was already done via nested policy */
-	err = nla_parse_nested_deprecated(tb, MPTCP_PM_ADDR_ATTR_MAX, attr,
-					  mptcp_pm_address_nl_policy, info->extack);
-	if (err)
-		return err;
-
-	if (tb[MPTCP_PM_ADDR_ATTR_ID])
-		addr->id = nla_get_u8(tb[MPTCP_PM_ADDR_ATTR_ID]);
-
-	if (!tb[MPTCP_PM_ADDR_ATTR_FAMILY]) {
-		if (!require_family)
-			return 0;
-
-		NL_SET_ERR_MSG_ATTR(info->extack, attr,
-				    "missing family");
-		return -EINVAL;
-	}
-
-	addr->family = nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_FAMILY]);
-	if (addr->family != AF_INET
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-	    && addr->family != AF_INET6
-#endif
-	    ) {
-		NL_SET_ERR_MSG_ATTR(info->extack, attr,
-				    "unknown address family");
-		return -EINVAL;
-	}
-	addr_addr = mptcp_pm_family_to_addr(addr->family);
-	if (!tb[addr_addr]) {
-		NL_SET_ERR_MSG_ATTR(info->extack, attr,
-				    "missing address data");
-		return -EINVAL;
-	}
-
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-	if (addr->family == AF_INET6)
-		addr->addr6 = nla_get_in6_addr(tb[addr_addr]);
-	else
-#endif
-		addr->addr.s_addr = nla_get_in_addr(tb[addr_addr]);
-
-	if (tb[MPTCP_PM_ADDR_ATTR_PORT])
-		addr->port = htons(nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_PORT]));
-
-	return 0;
-}
-
-int mptcp_pm_parse_addr(struct nlattr *attr, struct genl_info *info,
-			struct mptcp_addr_info *addr)
-{
-	struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1];
-
-	memset(addr, 0, sizeof(*addr));
-
-	return mptcp_pm_parse_pm_addr_attr(tb, attr, info, addr, true);
-}
-
-int mptcp_pm_parse_entry(struct nlattr *attr, struct genl_info *info,
-			 bool require_family,
-			 struct mptcp_pm_addr_entry *entry)
-{
-	struct nlattr *tb[MPTCP_PM_ADDR_ATTR_MAX + 1];
-	int err;
-
-	memset(entry, 0, sizeof(*entry));
-
-	err = mptcp_pm_parse_pm_addr_attr(tb, attr, info, &entry->addr, require_family);
-	if (err)
-		return err;
-
-	if (tb[MPTCP_PM_ADDR_ATTR_IF_IDX]) {
-		u32 val = nla_get_s32(tb[MPTCP_PM_ADDR_ATTR_IF_IDX]);
-
-		entry->ifindex = val;
-	}
-
-	if (tb[MPTCP_PM_ADDR_ATTR_FLAGS])
-		entry->flags = nla_get_u32(tb[MPTCP_PM_ADDR_ATTR_FLAGS]) &
-			       MPTCP_PM_ADDR_FLAGS_MASK;
-
-	if (tb[MPTCP_PM_ADDR_ATTR_PORT])
-		entry->addr.port = htons(nla_get_u16(tb[MPTCP_PM_ADDR_ATTR_PORT]));
-
-	return 0;
-}
-
-static struct pm_nl_pernet *genl_info_pm_nl(struct genl_info *info)
-{
-	return pm_nl_get_pernet(genl_info_net(info));
-}
-
-static int mptcp_nl_add_subflow_or_signal_addr(struct net *net,
-					       struct mptcp_addr_info *addr)
-{
-	struct mptcp_sock *msk;
-	long s_slot = 0, s_num = 0;
-
-	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
-		struct sock *sk = (struct sock *)msk;
-		struct mptcp_addr_info mpc_addr;
-
-		if (!READ_ONCE(msk->fully_established) ||
-		    mptcp_pm_is_userspace(msk))
-			goto next;
-
-		/* if the endp linked to the init sf is re-added with a != ID */
-		mptcp_local_address((struct sock_common *)msk, &mpc_addr);
-
-		lock_sock(sk);
-		spin_lock_bh(&msk->pm.lock);
-		if (mptcp_addresses_equal(addr, &mpc_addr, addr->port))
-			msk->mpc_endpoint_id = addr->id;
-		mptcp_pm_create_subflow_or_signal_addr(msk);
-		spin_unlock_bh(&msk->pm.lock);
-		release_sock(sk);
-
-next:
-		sock_put(sk);
-		cond_resched();
-	}
-
-	return 0;
-}
-
-int mptcp_pm_nl_add_addr_doit(struct sk_buff *skb, struct genl_info *info)
-{
-	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
-	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
-	struct mptcp_pm_addr_entry addr, *entry;
-	int ret;
-
-	ret = mptcp_pm_parse_entry(attr, info, true, &addr);
-	if (ret < 0)
-		return ret;
-
-	if (addr.addr.port && !address_use_port(&addr)) {
-		GENL_SET_ERR_MSG(info, "flags must have signal and not subflow when using port");
-		return -EINVAL;
-	}
-
-	if (addr.flags & MPTCP_PM_ADDR_FLAG_SIGNAL &&
-	    addr.flags & MPTCP_PM_ADDR_FLAG_FULLMESH) {
-		GENL_SET_ERR_MSG(info, "flags mustn't have both signal and fullmesh");
-		return -EINVAL;
-	}
-
-	if (addr.flags & MPTCP_PM_ADDR_FLAG_IMPLICIT) {
-		GENL_SET_ERR_MSG(info, "can't create IMPLICIT endpoint");
-		return -EINVAL;
-	}
-
-	entry = kzalloc(sizeof(*entry), GFP_KERNEL_ACCOUNT);
-	if (!entry) {
-		GENL_SET_ERR_MSG(info, "can't allocate addr");
-		return -ENOMEM;
-	}
-
-	*entry = addr;
-	if (entry->addr.port) {
-		ret = mptcp_pm_nl_create_listen_socket(skb->sk, entry);
-		if (ret) {
-			GENL_SET_ERR_MSG_FMT(info, "create listen socket error: %d", ret);
-			goto out_free;
-		}
-	}
-	ret = mptcp_pm_nl_append_new_local_addr(pernet, entry, true);
-	if (ret < 0) {
-		GENL_SET_ERR_MSG_FMT(info, "too many addresses or duplicate one: %d", ret);
-		goto out_free;
-	}
-
-	mptcp_nl_add_subflow_or_signal_addr(sock_net(skb->sk), &entry->addr);
-	return 0;
-
-out_free:
-	__mptcp_pm_release_addr_entry(entry);
-	return ret;
-}
-
-static bool remove_anno_list_by_saddr(struct mptcp_sock *msk,
-				      const struct mptcp_addr_info *addr)
-{
-	struct mptcp_pm_add_entry *entry;
-
-	entry = mptcp_pm_del_add_timer(msk, addr, false);
-	if (entry) {
-		kfree_rcu(entry, rcu);
-		return true;
-	}
-
-	return false;
-}
-
-static u8 mptcp_endp_get_local_id(struct mptcp_sock *msk,
-				  const struct mptcp_addr_info *addr)
-{
-	return msk->mpc_endpoint_id == addr->id ? 0 : addr->id;
-}
-
-static bool mptcp_pm_remove_anno_addr(struct mptcp_sock *msk,
-				      const struct mptcp_addr_info *addr,
-				      bool force)
-{
-	struct mptcp_rm_list list = { .nr = 0 };
-	bool ret;
-
-	list.ids[list.nr++] = mptcp_endp_get_local_id(msk, addr);
-
-	ret = remove_anno_list_by_saddr(msk, addr);
-	if (ret || force) {
-		spin_lock_bh(&msk->pm.lock);
-		if (ret)
-			msk->pm.add_addr_signaled--;
-		mptcp_pm_remove_addr(msk, &list);
-		spin_unlock_bh(&msk->pm.lock);
-	}
-	return ret;
-}
-
-static void __mark_subflow_endp_available(struct mptcp_sock *msk, u8 id)
-{
-	/* If it was marked as used, and not ID 0, decrement local_addr_used */
-	if (!__test_and_set_bit(id ? : msk->mpc_endpoint_id, msk->pm.id_avail_bitmap) &&
-	    id && !WARN_ON_ONCE(msk->pm.local_addr_used == 0))
-		msk->pm.local_addr_used--;
-}
-
-static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
-						   const struct mptcp_pm_addr_entry *entry)
-{
-	const struct mptcp_addr_info *addr = &entry->addr;
-	struct mptcp_rm_list list = { .nr = 1 };
-	long s_slot = 0, s_num = 0;
-	struct mptcp_sock *msk;
-
-	pr_debug("remove_id=%d\n", addr->id);
-
-	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
-		struct sock *sk = (struct sock *)msk;
-		bool remove_subflow;
-
-		if (mptcp_pm_is_userspace(msk))
-			goto next;
-
-		lock_sock(sk);
-		remove_subflow = lookup_subflow_by_saddr(&msk->conn_list, addr);
-		mptcp_pm_remove_anno_addr(msk, addr, remove_subflow &&
-					  !(entry->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT));
-
-		list.ids[0] = mptcp_endp_get_local_id(msk, addr);
-
-		spin_lock_bh(&msk->pm.lock);
-		if (remove_subflow)
-			mptcp_pm_nl_rm_subflow_received(msk, &list);
-		if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW)
-			__mark_subflow_endp_available(msk, list.ids[0]);
-		else /* mark endp ID as available, e.g. Signal or MPC endp */
-			__set_bit(addr->id, msk->pm.id_avail_bitmap);
-		spin_unlock_bh(&msk->pm.lock);
-
-		if (msk->mpc_endpoint_id == entry->addr.id)
-			msk->mpc_endpoint_id = 0;
-		release_sock(sk);
-
-next:
-		sock_put(sk);
-		cond_resched();
-	}
-
-	return 0;
-}
-
-static int mptcp_nl_remove_id_zero_address(struct net *net,
-					   struct mptcp_addr_info *addr)
-{
-	struct mptcp_rm_list list = { .nr = 0 };
-	long s_slot = 0, s_num = 0;
-	struct mptcp_sock *msk;
-
-	list.ids[list.nr++] = 0;
-
-	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
-		struct sock *sk = (struct sock *)msk;
-		struct mptcp_addr_info msk_local;
-
-		if (list_empty(&msk->conn_list) || mptcp_pm_is_userspace(msk))
-			goto next;
-
-		mptcp_local_address((struct sock_common *)msk, &msk_local);
-		if (!mptcp_addresses_equal(&msk_local, addr, addr->port))
-			goto next;
-
-		lock_sock(sk);
-		spin_lock_bh(&msk->pm.lock);
-		mptcp_pm_remove_addr(msk, &list);
-		mptcp_pm_nl_rm_subflow_received(msk, &list);
-		__mark_subflow_endp_available(msk, 0);
-		spin_unlock_bh(&msk->pm.lock);
-		release_sock(sk);
-
-next:
-		sock_put(sk);
-		cond_resched();
-	}
-
-	return 0;
-}
-
-int mptcp_pm_nl_del_addr_doit(struct sk_buff *skb, struct genl_info *info)
-{
-	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
-	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
-	struct mptcp_pm_addr_entry addr, *entry;
-	unsigned int addr_max;
-	int ret;
-
-	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
-	if (ret < 0)
-		return ret;
-
-	/* the zero id address is special: the first address used by the msk
-	 * always gets such an id, so different subflows can have different zero
-	 * id addresses. Additionally zero id is not accounted for in id_bitmap.
-	 * Let's use an 'mptcp_rm_list' instead of the common remove code.
-	 */
-	if (addr.addr.id == 0)
-		return mptcp_nl_remove_id_zero_address(sock_net(skb->sk), &addr.addr);
-
-	spin_lock_bh(&pernet->lock);
-	entry = __lookup_addr_by_id(pernet, addr.addr.id);
-	if (!entry) {
-		GENL_SET_ERR_MSG(info, "address not found");
-		spin_unlock_bh(&pernet->lock);
-		return -EINVAL;
-	}
-	if (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL) {
-		addr_max = pernet->add_addr_signal_max;
-		WRITE_ONCE(pernet->add_addr_signal_max, addr_max - 1);
-	}
-	if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
-		addr_max = pernet->local_addr_max;
-		WRITE_ONCE(pernet->local_addr_max, addr_max - 1);
-	}
-
-	pernet->addrs--;
-	list_del_rcu(&entry->list);
-	__clear_bit(entry->addr.id, pernet->id_bitmap);
-	spin_unlock_bh(&pernet->lock);
-
-	mptcp_nl_remove_subflow_and_signal_addr(sock_net(skb->sk), entry);
-	synchronize_rcu();
-	__mptcp_pm_release_addr_entry(entry);
-
-	return ret;
-}
-
-/* Called from the userspace PM only */
-void mptcp_pm_remove_addrs(struct mptcp_sock *msk, struct list_head *rm_list)
-{
-	struct mptcp_rm_list alist = { .nr = 0 };
-	struct mptcp_pm_addr_entry *entry;
-	int anno_nr = 0;
-
-	list_for_each_entry(entry, rm_list, list) {
-		if (alist.nr >= MPTCP_RM_IDS_MAX)
-			break;
-
-		/* only delete if either announced or matching a subflow */
-		if (remove_anno_list_by_saddr(msk, &entry->addr))
-			anno_nr++;
-		else if (!lookup_subflow_by_saddr(&msk->conn_list,
-						  &entry->addr))
-			continue;
-
-		alist.ids[alist.nr++] = entry->addr.id;
-	}
-
-	if (alist.nr) {
-		spin_lock_bh(&msk->pm.lock);
-		msk->pm.add_addr_signaled -= anno_nr;
-		mptcp_pm_remove_addr(msk, &alist);
-		spin_unlock_bh(&msk->pm.lock);
-	}
-}
-
-/* Called from the in-kernel PM only */
-static void mptcp_pm_flush_addrs_and_subflows(struct mptcp_sock *msk,
-					      struct list_head *rm_list)
-{
-	struct mptcp_rm_list alist = { .nr = 0 }, slist = { .nr = 0 };
-	struct mptcp_pm_addr_entry *entry;
-
-	list_for_each_entry(entry, rm_list, list) {
-		if (slist.nr < MPTCP_RM_IDS_MAX &&
-		    lookup_subflow_by_saddr(&msk->conn_list, &entry->addr))
-			slist.ids[slist.nr++] = mptcp_endp_get_local_id(msk, &entry->addr);
-
-		if (alist.nr < MPTCP_RM_IDS_MAX &&
-		    remove_anno_list_by_saddr(msk, &entry->addr))
-			alist.ids[alist.nr++] = mptcp_endp_get_local_id(msk, &entry->addr);
-	}
-
-	spin_lock_bh(&msk->pm.lock);
-	if (alist.nr) {
-		msk->pm.add_addr_signaled -= alist.nr;
-		mptcp_pm_remove_addr(msk, &alist);
-	}
-	if (slist.nr)
-		mptcp_pm_nl_rm_subflow_received(msk, &slist);
-	/* Reset counters: maybe some subflows have been removed before */
-	bitmap_fill(msk->pm.id_avail_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
-	msk->pm.local_addr_used = 0;
-	spin_unlock_bh(&msk->pm.lock);
-}
-
-static void mptcp_nl_flush_addrs_list(struct net *net,
-				      struct list_head *rm_list)
-{
-	long s_slot = 0, s_num = 0;
-	struct mptcp_sock *msk;
-
-	if (list_empty(rm_list))
-		return;
-
-	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
-		struct sock *sk = (struct sock *)msk;
-
-		if (!mptcp_pm_is_userspace(msk)) {
-			lock_sock(sk);
-			mptcp_pm_flush_addrs_and_subflows(msk, rm_list);
-			release_sock(sk);
-		}
-
-		sock_put(sk);
-		cond_resched();
-	}
-}
-
-/* caller must ensure the RCU grace period is already elapsed */
-static void __flush_addrs(struct list_head *list)
-{
-	while (!list_empty(list)) {
-		struct mptcp_pm_addr_entry *cur;
-
-		cur = list_entry(list->next,
-				 struct mptcp_pm_addr_entry, list);
-		list_del_rcu(&cur->list);
-		__mptcp_pm_release_addr_entry(cur);
-	}
-}
-
-static void __reset_counters(struct pm_nl_pernet *pernet)
-{
-	WRITE_ONCE(pernet->add_addr_signal_max, 0);
-	WRITE_ONCE(pernet->local_addr_max, 0);
-	pernet->addrs = 0;
-}
-
-int mptcp_pm_nl_flush_addrs_doit(struct sk_buff *skb, struct genl_info *info)
-{
-	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
-	struct list_head free_list;
-
-	spin_lock_bh(&pernet->lock);
-	free_list = pernet->local_addr_list;
-	INIT_LIST_HEAD_RCU(&pernet->local_addr_list);
-	__reset_counters(pernet);
-	pernet->next_id = 1;
-	bitmap_zero(pernet->id_bitmap, MPTCP_PM_MAX_ADDR_ID + 1);
-	spin_unlock_bh(&pernet->lock);
-
-	if (free_list.next == &pernet->local_addr_list)
-		return 0;
-
-	synchronize_rcu();
-
-	/* Adjust the pointers to free_list instead of pernet->local_addr_list */
-	free_list.prev->next = &free_list;
-	free_list.next->prev = &free_list;
-
-	mptcp_nl_flush_addrs_list(sock_net(skb->sk), &free_list);
-	__flush_addrs(&free_list);
-	return 0;
-}
-
-int mptcp_nl_fill_addr(struct sk_buff *skb,
-		       struct mptcp_pm_addr_entry *entry)
-{
-	struct mptcp_addr_info *addr = &entry->addr;
-	struct nlattr *attr;
-
-	attr = nla_nest_start(skb, MPTCP_PM_ATTR_ADDR);
-	if (!attr)
-		return -EMSGSIZE;
-
-	if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_FAMILY, addr->family))
-		goto nla_put_failure;
-	if (nla_put_u16(skb, MPTCP_PM_ADDR_ATTR_PORT, ntohs(addr->port)))
-		goto nla_put_failure;
-	if (nla_put_u8(skb, MPTCP_PM_ADDR_ATTR_ID, addr->id))
-		goto nla_put_failure;
-	if (nla_put_u32(skb, MPTCP_PM_ADDR_ATTR_FLAGS, entry->flags))
-		goto nla_put_failure;
-	if (entry->ifindex &&
-	    nla_put_s32(skb, MPTCP_PM_ADDR_ATTR_IF_IDX, entry->ifindex))
-		goto nla_put_failure;
-
-	if (addr->family == AF_INET &&
-	    nla_put_in_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR4,
-			    addr->addr.s_addr))
-		goto nla_put_failure;
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-	else if (addr->family == AF_INET6 &&
-		 nla_put_in6_addr(skb, MPTCP_PM_ADDR_ATTR_ADDR6, &addr->addr6))
-		goto nla_put_failure;
-#endif
-	nla_nest_end(skb, attr);
-	return 0;
-
-nla_put_failure:
-	nla_nest_cancel(skb, attr);
-	return -EMSGSIZE;
-}
-
-int mptcp_pm_nl_get_addr(struct sk_buff *skb, struct genl_info *info)
-{
-	struct nlattr *attr = info->attrs[MPTCP_PM_ENDPOINT_ADDR];
-	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
-	struct mptcp_pm_addr_entry addr, *entry;
-	struct sk_buff *msg;
-	void *reply;
-	int ret;
-
-	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
-	if (ret < 0)
-		return ret;
-
-	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-	if (!msg)
-		return -ENOMEM;
-
-	reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
-				  info->genlhdr->cmd);
-	if (!reply) {
-		GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
-		ret = -EMSGSIZE;
-		goto fail;
-	}
-
-	spin_lock_bh(&pernet->lock);
-	entry = __lookup_addr_by_id(pernet, addr.addr.id);
-	if (!entry) {
-		GENL_SET_ERR_MSG(info, "address not found");
-		ret = -EINVAL;
-		goto unlock_fail;
-	}
-
-	ret = mptcp_nl_fill_addr(msg, entry);
-	if (ret)
-		goto unlock_fail;
-
-	genlmsg_end(msg, reply);
-	ret = genlmsg_reply(msg, info);
-	spin_unlock_bh(&pernet->lock);
-	return ret;
-
-unlock_fail:
-	spin_unlock_bh(&pernet->lock);
-
-fail:
-	nlmsg_free(msg);
-	return ret;
-}
-
-int mptcp_pm_nl_get_addr_doit(struct sk_buff *skb, struct genl_info *info)
-{
-	return mptcp_pm_get_addr(skb, info);
-}
-
-int mptcp_pm_nl_dump_addr(struct sk_buff *msg,
-			  struct netlink_callback *cb)
-{
-	struct net *net = sock_net(msg->sk);
-	struct mptcp_pm_addr_entry *entry;
-	struct pm_nl_pernet *pernet;
-	int id = cb->args[0];
-	void *hdr;
-	int i;
-
-	pernet = pm_nl_get_pernet(net);
-
-	spin_lock_bh(&pernet->lock);
-	for (i = id; i < MPTCP_PM_MAX_ADDR_ID + 1; i++) {
-		if (test_bit(i, pernet->id_bitmap)) {
-			entry = __lookup_addr_by_id(pernet, i);
-			if (!entry)
-				break;
-
-			if (entry->addr.id <= id)
-				continue;
-
-			hdr = genlmsg_put(msg, NETLINK_CB(cb->skb).portid,
-					  cb->nlh->nlmsg_seq, &mptcp_genl_family,
-					  NLM_F_MULTI, MPTCP_PM_CMD_GET_ADDR);
-			if (!hdr)
-				break;
-
-			if (mptcp_nl_fill_addr(msg, entry) < 0) {
-				genlmsg_cancel(msg, hdr);
-				break;
-			}
-
-			id = entry->addr.id;
-			genlmsg_end(msg, hdr);
-		}
-	}
-	spin_unlock_bh(&pernet->lock);
-
-	cb->args[0] = id;
-	return msg->len;
-}
-
-int mptcp_pm_nl_get_addr_dumpit(struct sk_buff *msg,
-				struct netlink_callback *cb)
-{
-	return mptcp_pm_dump_addr(msg, cb);
-}
-
-static int parse_limit(struct genl_info *info, int id, unsigned int *limit)
-{
-	struct nlattr *attr = info->attrs[id];
-
-	if (!attr)
-		return 0;
-
-	*limit = nla_get_u32(attr);
-	if (*limit > MPTCP_PM_ADDR_MAX) {
-		GENL_SET_ERR_MSG(info, "limit greater than maximum");
-		return -EINVAL;
-	}
-	return 0;
-}
-
-int mptcp_pm_nl_set_limits_doit(struct sk_buff *skb, struct genl_info *info)
-{
-	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
-	unsigned int rcv_addrs, subflows;
-	int ret;
-
-	spin_lock_bh(&pernet->lock);
-	rcv_addrs = pernet->add_addr_accept_max;
-	ret = parse_limit(info, MPTCP_PM_ATTR_RCV_ADD_ADDRS, &rcv_addrs);
-	if (ret)
-		goto unlock;
-
-	subflows = pernet->subflows_max;
-	ret = parse_limit(info, MPTCP_PM_ATTR_SUBFLOWS, &subflows);
-	if (ret)
-		goto unlock;
-
-	WRITE_ONCE(pernet->add_addr_accept_max, rcv_addrs);
-	WRITE_ONCE(pernet->subflows_max, subflows);
-
-unlock:
-	spin_unlock_bh(&pernet->lock);
-	return ret;
-}
-
-int mptcp_pm_nl_get_limits_doit(struct sk_buff *skb, struct genl_info *info)
-{
-	struct pm_nl_pernet *pernet = genl_info_pm_nl(info);
-	struct sk_buff *msg;
-	void *reply;
-
-	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-	if (!msg)
-		return -ENOMEM;
-
-	reply = genlmsg_put_reply(msg, info, &mptcp_genl_family, 0,
-				  MPTCP_PM_CMD_GET_LIMITS);
-	if (!reply)
-		goto fail;
-
-	if (nla_put_u32(msg, MPTCP_PM_ATTR_RCV_ADD_ADDRS,
-			READ_ONCE(pernet->add_addr_accept_max)))
-		goto fail;
-
-	if (nla_put_u32(msg, MPTCP_PM_ATTR_SUBFLOWS,
-			READ_ONCE(pernet->subflows_max)))
-		goto fail;
-
-	genlmsg_end(msg, reply);
-	return genlmsg_reply(msg, info);
-
-fail:
-	GENL_SET_ERR_MSG(info, "not enough space in Netlink message");
-	nlmsg_free(msg);
-	return -EMSGSIZE;
-}
-
-static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk,
-				 struct mptcp_addr_info *addr)
-{
-	struct mptcp_rm_list list = { .nr = 0 };
-
-	list.ids[list.nr++] = mptcp_endp_get_local_id(msk, addr);
-
-	spin_lock_bh(&msk->pm.lock);
-	mptcp_pm_nl_rm_subflow_received(msk, &list);
-	__mark_subflow_endp_available(msk, list.ids[0]);
-	mptcp_pm_create_subflow_or_signal_addr(msk);
-	spin_unlock_bh(&msk->pm.lock);
-}
-
-static int mptcp_nl_set_flags(struct net *net,
-			      struct mptcp_addr_info *addr,
-			      u8 bkup, u8 changed)
-{
-	long s_slot = 0, s_num = 0;
-	struct mptcp_sock *msk;
-	int ret = -EINVAL;
-
-	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
-		struct sock *sk = (struct sock *)msk;
-
-		if (list_empty(&msk->conn_list) || mptcp_pm_is_userspace(msk))
-			goto next;
-
-		lock_sock(sk);
-		if (changed & MPTCP_PM_ADDR_FLAG_BACKUP)
-			ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, NULL, bkup);
-		if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH)
-			mptcp_pm_nl_fullmesh(msk, addr);
-		release_sock(sk);
-
-next:
-		sock_put(sk);
-		cond_resched();
-	}
-
-	return ret;
-}
-
-int mptcp_pm_nl_set_flags(struct sk_buff *skb, struct genl_info *info)
-{
-	struct mptcp_pm_addr_entry addr = { .addr = { .family = AF_UNSPEC }, };
-	struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR];
-	u8 changed, mask = MPTCP_PM_ADDR_FLAG_BACKUP |
-			   MPTCP_PM_ADDR_FLAG_FULLMESH;
-	struct net *net = sock_net(skb->sk);
-	struct mptcp_pm_addr_entry *entry;
-	struct pm_nl_pernet *pernet;
-	u8 lookup_by_id = 0;
-	u8 bkup = 0;
-	int ret;
-
-	pernet = pm_nl_get_pernet(net);
-
-	ret = mptcp_pm_parse_entry(attr, info, false, &addr);
-	if (ret < 0)
-		return ret;
-
-	if (addr.addr.family == AF_UNSPEC) {
-		lookup_by_id = 1;
-		if (!addr.addr.id) {
-			GENL_SET_ERR_MSG(info, "missing required inputs");
-			return -EOPNOTSUPP;
-		}
-	}
-
-	if (addr.flags & MPTCP_PM_ADDR_FLAG_BACKUP)
-		bkup = 1;
-
-	spin_lock_bh(&pernet->lock);
-	entry = lookup_by_id ? __lookup_addr_by_id(pernet, addr.addr.id) :
-			       __lookup_addr(pernet, &addr.addr);
-	if (!entry) {
-		spin_unlock_bh(&pernet->lock);
-		GENL_SET_ERR_MSG(info, "address not found");
-		return -EINVAL;
-	}
-	if ((addr.flags & MPTCP_PM_ADDR_FLAG_FULLMESH) &&
-	    (entry->flags & (MPTCP_PM_ADDR_FLAG_SIGNAL |
-			     MPTCP_PM_ADDR_FLAG_IMPLICIT))) {
-		spin_unlock_bh(&pernet->lock);
-		GENL_SET_ERR_MSG(info, "invalid addr flags");
-		return -EINVAL;
-	}
-
-	changed = (addr.flags ^ entry->flags) & mask;
-	entry->flags = (entry->flags & ~mask) | (addr.flags & mask);
-	addr = *entry;
-	spin_unlock_bh(&pernet->lock);
-
-	mptcp_nl_set_flags(net, &addr.addr, bkup, changed);
-	return 0;
-}
-
-int mptcp_pm_nl_set_flags_doit(struct sk_buff *skb, struct genl_info *info)
-{
-	return mptcp_pm_set_flags(skb, info);
-}
-
-static void mptcp_nl_mcast_send(struct net *net, struct sk_buff *nlskb, gfp_t gfp)
-{
-	genlmsg_multicast_netns(&mptcp_genl_family, net,
-				nlskb, 0, MPTCP_PM_EV_GRP_OFFSET, gfp);
-}
-
-bool mptcp_userspace_pm_active(const struct mptcp_sock *msk)
-{
-	return genl_has_listeners(&mptcp_genl_family,
-				  sock_net((const struct sock *)msk),
-				  MPTCP_PM_EV_GRP_OFFSET);
-}
-
-static int mptcp_event_add_subflow(struct sk_buff *skb, const struct sock *ssk)
-{
-	const struct inet_sock *issk = inet_sk(ssk);
-	const struct mptcp_subflow_context *sf;
-
-	if (nla_put_u16(skb, MPTCP_ATTR_FAMILY, ssk->sk_family))
-		return -EMSGSIZE;
-
-	switch (ssk->sk_family) {
-	case AF_INET:
-		if (nla_put_in_addr(skb, MPTCP_ATTR_SADDR4, issk->inet_saddr))
-			return -EMSGSIZE;
-		if (nla_put_in_addr(skb, MPTCP_ATTR_DADDR4, issk->inet_daddr))
-			return -EMSGSIZE;
-		break;
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-	case AF_INET6: {
-		const struct ipv6_pinfo *np = inet6_sk(ssk);
-
-		if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &np->saddr))
-			return -EMSGSIZE;
-		if (nla_put_in6_addr(skb, MPTCP_ATTR_DADDR6, &ssk->sk_v6_daddr))
-			return -EMSGSIZE;
-		break;
-	}
-#endif
-	default:
-		WARN_ON_ONCE(1);
-		return -EMSGSIZE;
-	}
-
-	if (nla_put_be16(skb, MPTCP_ATTR_SPORT, issk->inet_sport))
-		return -EMSGSIZE;
-	if (nla_put_be16(skb, MPTCP_ATTR_DPORT, issk->inet_dport))
-		return -EMSGSIZE;
-
-	sf = mptcp_subflow_ctx(ssk);
-	if (WARN_ON_ONCE(!sf))
-		return -EINVAL;
-
-	if (nla_put_u8(skb, MPTCP_ATTR_LOC_ID, subflow_get_local_id(sf)))
-		return -EMSGSIZE;
-
-	if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, sf->remote_id))
-		return -EMSGSIZE;
-
-	return 0;
-}
-
-static int mptcp_event_put_token_and_ssk(struct sk_buff *skb,
-					 const struct mptcp_sock *msk,
-					 const struct sock *ssk)
-{
-	const struct sock *sk = (const struct sock *)msk;
-	const struct mptcp_subflow_context *sf;
-	u8 sk_err;
-
-	if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
-		return -EMSGSIZE;
-
-	if (mptcp_event_add_subflow(skb, ssk))
-		return -EMSGSIZE;
-
-	sf = mptcp_subflow_ctx(ssk);
-	if (WARN_ON_ONCE(!sf))
-		return -EINVAL;
-
-	if (nla_put_u8(skb, MPTCP_ATTR_BACKUP, sf->backup))
-		return -EMSGSIZE;
-
-	if (ssk->sk_bound_dev_if &&
-	    nla_put_s32(skb, MPTCP_ATTR_IF_IDX, ssk->sk_bound_dev_if))
-		return -EMSGSIZE;
-
-	sk_err = READ_ONCE(ssk->sk_err);
-	if (sk_err && sk->sk_state == TCP_ESTABLISHED &&
-	    nla_put_u8(skb, MPTCP_ATTR_ERROR, sk_err))
-		return -EMSGSIZE;
-
-	return 0;
-}
-
-static int mptcp_event_sub_established(struct sk_buff *skb,
-				       const struct mptcp_sock *msk,
-				       const struct sock *ssk)
-{
-	return mptcp_event_put_token_and_ssk(skb, msk, ssk);
-}
-
-static int mptcp_event_sub_closed(struct sk_buff *skb,
-				  const struct mptcp_sock *msk,
-				  const struct sock *ssk)
-{
-	const struct mptcp_subflow_context *sf;
-
-	if (mptcp_event_put_token_and_ssk(skb, msk, ssk))
-		return -EMSGSIZE;
-
-	sf = mptcp_subflow_ctx(ssk);
-	if (!sf->reset_seen)
-		return 0;
-
-	if (nla_put_u32(skb, MPTCP_ATTR_RESET_REASON, sf->reset_reason))
-		return -EMSGSIZE;
-
-	if (nla_put_u32(skb, MPTCP_ATTR_RESET_FLAGS, sf->reset_transient))
-		return -EMSGSIZE;
-
-	return 0;
-}
-
-static int mptcp_event_created(struct sk_buff *skb,
-			       const struct mptcp_sock *msk,
-			       const struct sock *ssk)
-{
-	int err = nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token));
-	u16 flags = 0;
-
-	if (err)
-		return err;
-
-	if (nla_put_u8(skb, MPTCP_ATTR_SERVER_SIDE, READ_ONCE(msk->pm.server_side)))
-		return -EMSGSIZE;
-
-	if (READ_ONCE(msk->pm.remote_deny_join_id0))
-		flags |= MPTCP_PM_EV_FLAG_DENY_JOIN_ID0;
-
-	if (flags && nla_put_u16(skb, MPTCP_ATTR_FLAGS, flags))
-		return -EMSGSIZE;
-
-	return mptcp_event_add_subflow(skb, ssk);
-}
-
-void mptcp_event_addr_removed(const struct mptcp_sock *msk, uint8_t id)
-{
-	struct net *net = sock_net((const struct sock *)msk);
-	struct nlmsghdr *nlh;
-	struct sk_buff *skb;
-
-	if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
-		return;
-
-	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
-	if (!skb)
-		return;
-
-	nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, MPTCP_EVENT_REMOVED);
-	if (!nlh)
-		goto nla_put_failure;
-
-	if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
-		goto nla_put_failure;
-
-	if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, id))
-		goto nla_put_failure;
-
-	genlmsg_end(skb, nlh);
-	mptcp_nl_mcast_send(net, skb, GFP_ATOMIC);
-	return;
-
-nla_put_failure:
-	nlmsg_free(skb);
-}
-
-void mptcp_event_addr_announced(const struct sock *ssk,
-				const struct mptcp_addr_info *info)
-{
-	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
-	struct mptcp_sock *msk = mptcp_sk(subflow->conn);
-	struct net *net = sock_net(ssk);
-	struct nlmsghdr *nlh;
-	struct sk_buff *skb;
-
-	if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
-		return;
-
-	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
-	if (!skb)
-		return;
-
-	nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0,
-			  MPTCP_EVENT_ANNOUNCED);
-	if (!nlh)
-		goto nla_put_failure;
-
-	if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)))
-		goto nla_put_failure;
-
-	if (nla_put_u8(skb, MPTCP_ATTR_REM_ID, info->id))
-		goto nla_put_failure;
-
-	if (nla_put_be16(skb, MPTCP_ATTR_DPORT,
-			 info->port == 0 ?
-			 inet_sk(ssk)->inet_dport :
-			 info->port))
-		goto nla_put_failure;
-
-	switch (info->family) {
-	case AF_INET:
-		if (nla_put_in_addr(skb, MPTCP_ATTR_DADDR4, info->addr.s_addr))
-			goto nla_put_failure;
-		break;
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-	case AF_INET6:
-		if (nla_put_in6_addr(skb, MPTCP_ATTR_DADDR6, &info->addr6))
-			goto nla_put_failure;
-		break;
-#endif
-	default:
-		WARN_ON_ONCE(1);
-		goto nla_put_failure;
-	}
-
-	genlmsg_end(skb, nlh);
-	mptcp_nl_mcast_send(net, skb, GFP_ATOMIC);
-	return;
-
-nla_put_failure:
-	nlmsg_free(skb);
-}
-
-void mptcp_event_pm_listener(const struct sock *ssk,
-			     enum mptcp_event_type event)
-{
-	const struct inet_sock *issk = inet_sk(ssk);
-	struct net *net = sock_net(ssk);
-	struct nlmsghdr *nlh;
-	struct sk_buff *skb;
-
-	if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
-		return;
-
-	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-	if (!skb)
-		return;
-
-	nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, event);
-	if (!nlh)
-		goto nla_put_failure;
-
-	if (nla_put_u16(skb, MPTCP_ATTR_FAMILY, ssk->sk_family))
-		goto nla_put_failure;
-
-	if (nla_put_be16(skb, MPTCP_ATTR_SPORT, issk->inet_sport))
-		goto nla_put_failure;
-
-	switch (ssk->sk_family) {
-	case AF_INET:
-		if (nla_put_in_addr(skb, MPTCP_ATTR_SADDR4, issk->inet_saddr))
-			goto nla_put_failure;
-		break;
-#if IS_ENABLED(CONFIG_MPTCP_IPV6)
-	case AF_INET6: {
-		const struct ipv6_pinfo *np = inet6_sk(ssk);
-
-		if (nla_put_in6_addr(skb, MPTCP_ATTR_SADDR6, &np->saddr))
-			goto nla_put_failure;
-		break;
-	}
-#endif
-	default:
-		WARN_ON_ONCE(1);
-		goto nla_put_failure;
-	}
-
-	genlmsg_end(skb, nlh);
-	mptcp_nl_mcast_send(net, skb, GFP_KERNEL);
-	return;
-
-nla_put_failure:
-	nlmsg_free(skb);
-}
-
-void mptcp_event(enum mptcp_event_type type, const struct mptcp_sock *msk,
-		 const struct sock *ssk, gfp_t gfp)
-{
-	struct net *net = sock_net((const struct sock *)msk);
-	struct nlmsghdr *nlh;
-	struct sk_buff *skb;
-
-	if (!genl_has_listeners(&mptcp_genl_family, net, MPTCP_PM_EV_GRP_OFFSET))
-		return;
-
-	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
-	if (!skb)
-		return;
-
-	nlh = genlmsg_put(skb, 0, 0, &mptcp_genl_family, 0, type);
-	if (!nlh)
-		goto nla_put_failure;
-
-	switch (type) {
-	case MPTCP_EVENT_UNSPEC:
-		WARN_ON_ONCE(1);
-		break;
-	case MPTCP_EVENT_CREATED:
-	case MPTCP_EVENT_ESTABLISHED:
-		if (mptcp_event_created(skb, msk, ssk) < 0)
-			goto nla_put_failure;
-		break;
-	case MPTCP_EVENT_CLOSED:
-		if (nla_put_u32(skb, MPTCP_ATTR_TOKEN, READ_ONCE(msk->token)) < 0)
-			goto nla_put_failure;
-		break;
-	case MPTCP_EVENT_ANNOUNCED:
-	case MPTCP_EVENT_REMOVED:
-		/* call mptcp_event_addr_announced()/removed instead */
-		WARN_ON_ONCE(1);
-		break;
-	case MPTCP_EVENT_SUB_ESTABLISHED:
-	case MPTCP_EVENT_SUB_PRIORITY:
-		if (mptcp_event_sub_established(skb, msk, ssk) < 0)
-			goto nla_put_failure;
-		break;
-	case MPTCP_EVENT_SUB_CLOSED:
-		if (mptcp_event_sub_closed(skb, msk, ssk) < 0)
-			goto nla_put_failure;
-		break;
-	case MPTCP_EVENT_LISTENER_CREATED:
-	case MPTCP_EVENT_LISTENER_CLOSED:
-		break;
-	}
-
-	genlmsg_end(skb, nlh);
-	mptcp_nl_mcast_send(net, skb, gfp);
-	return;
-
-nla_put_failure:
-	nlmsg_free(skb);
-}
-
-struct genl_family mptcp_genl_family __ro_after_init = {
-	.name		= MPTCP_PM_NAME,
-	.version	= MPTCP_PM_VER,
-	.netnsok	= true,
-	.module		= THIS_MODULE,
-	.ops		= mptcp_pm_nl_ops,
-	.n_ops		= ARRAY_SIZE(mptcp_pm_nl_ops),
-	.resv_start_op	= MPTCP_PM_CMD_SUBFLOW_DESTROY + 1,
-	.mcgrps		= mptcp_pm_mcgrps,
-	.n_mcgrps	= ARRAY_SIZE(mptcp_pm_mcgrps),
-};
-
-static int __net_init pm_nl_init_net(struct net *net)
-{
-	struct pm_nl_pernet *pernet = pm_nl_get_pernet(net);
-
-	INIT_LIST_HEAD_RCU(&pernet->local_addr_list);
-
-	/* Cit. 2 subflows ought to be enough for anybody. */
-	pernet->subflows_max = 2;
-	pernet->next_id = 1;
-	pernet->stale_loss_cnt = 4;
-	spin_lock_init(&pernet->lock);
-
-	/* No need to initialize other pernet fields, the struct is zeroed at
-	 * allocation time.
-	 */
-
-	return 0;
-}
-
-static void __net_exit pm_nl_exit_net(struct list_head *net_list)
-{
-	struct net *net;
-
-	list_for_each_entry(net, net_list, exit_list) {
-		struct pm_nl_pernet *pernet = pm_nl_get_pernet(net);
-
-		/* net is removed from namespace list, can't race with
-		 * other modifiers, also netns core already waited for a
-		 * RCU grace period.
-		 */
-		__flush_addrs(&pernet->local_addr_list);
-	}
-}
-
-static struct pernet_operations mptcp_pm_pernet_ops = {
-	.init = pm_nl_init_net,
-	.exit_batch = pm_nl_exit_net,
-	.id = &pm_nl_pernet_id,
-	.size = sizeof(struct pm_nl_pernet),
-};
-
-void __init mptcp_pm_nl_init(void)
-{
-	if (register_pernet_subsys(&mptcp_pm_pernet_ops) < 0)
-		panic("Failed to register MPTCP PM pernet subsystem.\n");
-
-	if (genl_register_family(&mptcp_genl_family))
-		panic("Failed to register MPTCP PM netlink family\n");
-}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 769/877] mptcp: pm: rename add_entry structure to add_addr
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (767 preceding siblings ...)
  2026-09-30 15:27 ` [PATCH 6.12 768/877] mptcp: pm: use for_each_subflow helper Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 770/877] mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0 Greg Kroah-Hartman
                   ` (115 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mat Martineau,
	Matthieu Baerts (NGI0), Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>

[ Upstream commit 350d76dd6e79468ac85767f2d236299a135572df ]

Using only the 'add' prefix is confusing: does it refer to a generic
added entry or address, or specifically to ADD_ADDRs. Using add_addr
removes this confusion.

Reviewed-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260605-net-next-mptcp-add-addr6-port-ts-v2-10-758e7ca73f4d@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Stable backport adaptation for 2ac7d6e620764f1fc79eb4edd3610a7a661981ca:

The stable tree retains the ADD_ADDR announcement structure and helpers
in pm_kernel.c, renamed from pm_netlink.c by the preceding dependency.
Apply the structure-tag rename to those existing definitions and users
instead of importing the upstream helper block into pm.c.

Update both return-type declarations in protocol.h: the announcement
lookup is still externally visible on this branch. Preserve the stable
function bodies, timer APIs, allocation APIs and linkage; no functions
are added. The target's ID0 removal hunks apply unchanged to pm_kernel.c.

[ sashal: Reduced backport -- upstream 350d76dd6e794 touches 2 file(s), this
  backport carries 2. Not backported here:
  net/mptcp/pm.c
  This note is generated from the file lists only; see the resolution record
  for the reasoning. ]

Stable-dep-of: 2ac7d6e62076 ("mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mptcp/pm_kernel.c |   20 ++++++++++----------
 net/mptcp/protocol.h  |    4 ++--
 2 files changed, 12 insertions(+), 12 deletions(-)

--- a/net/mptcp/pm_kernel.c
+++ b/net/mptcp/pm_kernel.c
@@ -18,7 +18,7 @@
 
 static int pm_nl_pernet_id;
 
-struct mptcp_pm_add_entry {
+struct mptcp_pm_add_addr {
 	struct list_head	list;
 	struct mptcp_addr_info	addr;
 	u8			retrans_times;
@@ -253,11 +253,11 @@ bool mptcp_pm_nl_check_work_pending(stru
 	return true;
 }
 
-struct mptcp_pm_add_entry *
+struct mptcp_pm_add_addr *
 mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
 				const struct mptcp_addr_info *addr)
 {
-	struct mptcp_pm_add_entry *entry;
+	struct mptcp_pm_add_addr *entry;
 
 	lockdep_assert_held(&msk->pm.lock);
 
@@ -271,7 +271,7 @@ mptcp_lookup_anno_list_by_saddr(const st
 
 bool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk)
 {
-	struct mptcp_pm_add_entry *entry;
+	struct mptcp_pm_add_addr *entry;
 	struct mptcp_addr_info saddr;
 	bool ret = false;
 
@@ -292,7 +292,7 @@ out:
 
 static void mptcp_pm_add_timer(struct timer_list *timer)
 {
-	struct mptcp_pm_add_entry *entry = from_timer(entry, timer, add_timer);
+	struct mptcp_pm_add_addr *entry = from_timer(entry, timer, add_timer);
 	struct mptcp_sock *msk = entry->sock;
 	struct sock *sk = (struct sock *)msk;
 	unsigned int timeout = 0;
@@ -353,11 +353,11 @@ out:
 	sock_put(sk);
 }
 
-struct mptcp_pm_add_entry *
+struct mptcp_pm_add_addr *
 mptcp_pm_del_add_timer(struct mptcp_sock *msk,
 		       const struct mptcp_addr_info *addr, bool check_id)
 {
-	struct mptcp_pm_add_entry *entry;
+	struct mptcp_pm_add_addr *entry;
 	struct sock *sk = (struct sock *)msk;
 	bool stop_timer = false;
 
@@ -390,7 +390,7 @@ mptcp_pm_del_add_timer(struct mptcp_sock
 bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
 			      const struct mptcp_addr_info *addr)
 {
-	struct mptcp_pm_add_entry *add_entry = NULL;
+	struct mptcp_pm_add_addr *add_entry = NULL;
 	struct sock *sk = (struct sock *)msk;
 	struct net *net = sock_net(sk);
 	unsigned int timeout;
@@ -431,7 +431,7 @@ reset_timer:
 
 void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
 {
-	struct mptcp_pm_add_entry *entry, *tmp;
+	struct mptcp_pm_add_addr *entry, *tmp;
 	struct sock *sk = (struct sock *)msk;
 	LIST_HEAD(free_list);
 
@@ -1575,7 +1575,7 @@ out_free:
 static bool mptcp_pm_announced_remove(struct mptcp_sock *msk,
 				      const struct mptcp_addr_info *addr)
 {
-	struct mptcp_pm_add_entry *entry;
+	struct mptcp_pm_add_addr *entry;
 
 	entry = mptcp_pm_del_add_timer(msk, addr, false);
 	if (entry) {
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1049,10 +1049,10 @@ bool mptcp_pm_alloc_anno_list(struct mpt
 			      const struct mptcp_addr_info *addr);
 void mptcp_pm_free_anno_list(struct mptcp_sock *msk);
 bool mptcp_pm_sport_in_anno_list(struct mptcp_sock *msk, const struct sock *sk);
-struct mptcp_pm_add_entry *
+struct mptcp_pm_add_addr *
 mptcp_pm_del_add_timer(struct mptcp_sock *msk,
 		       const struct mptcp_addr_info *addr, bool check_id);
-struct mptcp_pm_add_entry *
+struct mptcp_pm_add_addr *
 mptcp_lookup_anno_list_by_saddr(const struct mptcp_sock *msk,
 				const struct mptcp_addr_info *addr);
 int mptcp_pm_set_flags(struct sk_buff *skb, struct genl_info *info);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 770/877] mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (768 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 769/877] mptcp: pm: rename add_entry structure to add_addr Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 771/877] tcp: introduce icsk->icsk_keepalive_timer Greg Kroah-Hartman
                   ` (114 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+55c2a5c871441261ed14, Tao Cui,
	Kalpan Jani, Matthieu Baerts (NGI0), Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Kalpan Jani <kalpan.jani@mpiricsoftware.com>

[ Upstream commit 2ac7d6e620764f1fc79eb4edd3610a7a661981ca ]

The in-kernel MPTCP path manager can leave a stale ADD_ADDR announcement
entry alive when removing the id 0 endpoint. This happens because the id 0
removal path does not tear down pending announcements, unlike the non-zero
id path.

When the PM later reselects id 0 after adding another signal endpoint, it
finds the stale anno_list entry and hits WARN_ON_ONCE(mptcp_pm_is_kernel())
in mptcp_pm_announced_alloc().

Root cause: asymmetry between removal paths.
- Non-zero id path: mptcp_nl_remove_subflow_and_signal_addr() calls
  mptcp_pm_remove_announced() to clean up.
- Id 0 path: mptcp_nl_remove_id_zero_address() skips cleanup entirely.

Fix by making the id 0 path symmetric: call mptcp_pm_announced_remove()
and decrement add_addr_signaled before queuing the RM_ADDR.

Subtle detail: signal endpoints are stored in anno_list with port 0, but
msk_local carries the connection's local port. In other words, entries
linked to ID0 paths should have port == 0. A follow-up patch will ensure
that. mptcp_pm_announced_remove() uses use_port=true for comparison. So
clear the port before the lookup.

Fixes: 740d798e8767 ("mptcp: remove id 0 address")
Cc: stable@vger.kernel.org
Reported-by: syzbot+55c2a5c871441261ed14@syzkaller.appspotmail.com
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/620
Suggested-by: Tao Cui <cuitao@kylinos.cn>
Signed-off-by: Kalpan Jani <kalpan.jani@mpiricsoftware.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-4-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mptcp/pm_kernel.c |    8 ++++++++
 1 file changed, 8 insertions(+)

--- a/net/mptcp/pm_kernel.c
+++ b/net/mptcp/pm_kernel.c
@@ -1677,6 +1677,8 @@ static int mptcp_nl_remove_id_zero_addre
 	while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
 		struct sock *sk = (struct sock *)msk;
 		struct mptcp_addr_info msk_local;
+		struct mptcp_addr_info anno_addr;
+		bool announced;
 
 		if (list_empty(&msk->conn_list) || mptcp_pm_is_userspace(msk))
 			goto next;
@@ -1686,7 +1688,13 @@ static int mptcp_nl_remove_id_zero_addre
 			goto next;
 
 		lock_sock(sk);
+		/* Drop a possibly pending ADD_ADDR for this address. */
+		anno_addr = msk_local;
+		anno_addr.port = 0;
+		announced = mptcp_pm_announced_remove(msk, &anno_addr);
 		spin_lock_bh(&msk->pm.lock);
+		if (announced)
+			msk->pm.add_addr_signaled--;
 		mptcp_pm_remove_addr(msk, &list);
 		mptcp_pm_rm_subflow(msk, &list);
 		__mark_subflow_endp_available(msk, 0);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 771/877] tcp: introduce icsk->icsk_keepalive_timer
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (769 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 770/877] mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0 Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 772/877] mptcp: do not reschedule the RTX timer for fallback sockets Greg Kroah-Hartman
                   ` (113 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Kuniyuki Iwashima,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <edumazet@google.com>

[ Upstream commit 08dfe370239e53494453cee1e2ded2cdaa1efd12 ]

sk->sk_timer has been used for TCP keepalives.

Keepalive timers are not in fast path, we want to use sk->sk_timer
storage for retransmit timers, for better cache locality.

Create icsk->icsk_keepalive_timer and change keepalive
code to no longer use sk->sk_timer.

Added space is reclaimed in the following patch.

This includes changes to MPTCP, which was also using sk_timer.

Alias icsk->mptcp_tout_timer and icsk->icsk_keepalive_timer
for inet_sk_diag_fill() sake.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20251124175013.1473655-4-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Stable dependency adaptation for e2ab913f68c7d11e2561b8a8ad0b87ffefcad667:

Retain the 6.12 from_timer() API, icsk_timeout fields, documentation
format and existing inet_csk_{reset,delete}_keepalive_timer() helpers.
Convert the DCCP keepalive callback as well, since DCCP still shares the
inet_csk timer initialization on this branch. Do not add TCP-only timer
helper functions from newer kernels.

Include the MPTCP portion of 9a5e5334adc03: alias sk_timer storage as
mptcp_retransmit_timer and migrate every MPTCP retransmit timer user.
TCP and DCCP retain their existing icsk_retransmit_timer storage.

Adapt the fallback accounting preparation from c65c2e3bae69, authored by
Paolo Abeni. Move the existing __mptcp_try_fallback() from protocol.h to
protocol.c, pass its fallback MIB through the existing callers, and add
the matching counters. Preserve the mptcp_subflow_early_fallback() name
and use the stable simultaneous-connect and blackhole fallback paths.
This supplies the fallback-helper context expected by the target.

No new functions are introduced. The target's RTX enable-bit fix remains
in the target commit; this dependency only prepares its application.

Stable-dep-of: e2ab913f68c7 ("mptcp: do not reschedule the RTX timer for fallback sockets")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/networking/net_cachelines/inet_connection_sock.rst |    1 
 include/net/inet_connection_sock.h                               |   11 +
 include/net/sock.h                                               |    6 
 net/dccp/timer.c                                                 |    4 
 net/ipv4/inet_connection_sock.c                                  |   10 -
 net/ipv4/inet_diag.c                                             |    4 
 net/ipv4/tcp_ipv4.c                                              |    4 
 net/ipv4/tcp_timer.c                                             |    5 
 net/ipv6/tcp_ipv6.c                                              |    4 
 net/mptcp/ctrl.c                                                 |    4 
 net/mptcp/mib.c                                                  |    5 
 net/mptcp/mib.h                                                  |    5 
 net/mptcp/options.c                                              |    6 
 net/mptcp/protocol.c                                             |   70 +++++-----
 net/mptcp/protocol.h                                             |   31 +---
 net/mptcp/subflow.c                                              |   10 -
 tools/testing/selftests/bpf/progs/bpf_iter_tcp4.c                |    4 
 tools/testing/selftests/bpf/progs/bpf_iter_tcp6.c                |    4 
 18 files changed, 107 insertions(+), 81 deletions(-)

--- a/Documentation/networking/net_cachelines/inet_connection_sock.rst
+++ b/Documentation/networking/net_cachelines/inet_connection_sock.rst
@@ -14,6 +14,7 @@ struct_inet_bind2_bucket            icsk
 unsigned_long                       icsk_timeout           read_mostly         -                   inet_csk_reset_xmit_timer,tcp_connect
 struct_timer_list                   icsk_retransmit_timer  read_mostly         -                   inet_csk_reset_xmit_timer,tcp_connect
 struct_timer_list                   icsk_delack_timer      read_mostly         -                   inet_csk_reset_xmit_timer,tcp_connect
+struct_timer_list                   icsk_keepalive_timer  -                   -
 u32                                 icsk_rto               read_write          -                   tcp_cwnd_validate,tcp_schedule_loss_probe,tcp_connect_init,tcp_connect,tcp_write_xmit,tcp_push_one
 u32                                 icsk_rto_min           -                   -                   
 u32                                 icsk_delack_max        -                   -                   
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -62,6 +62,9 @@ struct inet_connection_sock_af_ops {
  * @icsk_bind2_hash:	   Bind node in the bhash2 table
  * @icsk_timeout:	   Timeout
  * @icsk_retransmit_timer: Resend (no ack)
+ * @icsk_delack_timer:     Delayed ACK timer
+ * @icsk_keepalive_timer:  Keepalive timer
+ * @mptcp_tout_timer: MPTCP timeout timer
  * @icsk_rto:		   Retransmit timeout
  * @icsk_pmtu_cookie	   Last pmtu seen by socket
  * @icsk_ca_ops		   Pluggable congestion control hook
@@ -88,8 +91,12 @@ struct inet_connection_sock {
 	struct inet_bind_bucket	  *icsk_bind_hash;
 	struct inet_bind2_bucket  *icsk_bind2_hash;
 	unsigned long		  icsk_timeout;
- 	struct timer_list	  icsk_retransmit_timer;
- 	struct timer_list	  icsk_delack_timer;
+	struct timer_list	  icsk_retransmit_timer;
+	struct timer_list	  icsk_delack_timer;
+	union {
+		struct timer_list icsk_keepalive_timer;
+		struct timer_list mptcp_tout_timer;
+	};
 	__u32			  icsk_rto;
 	__u32                     icsk_rto_min;
 	__u32                     icsk_delack_max;
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -300,6 +300,7 @@ struct sk_filter;
   *	@sk_txrehash: enable TX hash rethink
   *	@sk_filter: socket filtering instructions
   *	@sk_timer: sock cleanup timer
+  *	@mptcp_retransmit_timer: MPTCP retransmit timer
   *	@sk_stamp: time stamp of last packet received
   *	@sk_stamp_seq: lock for accessing sk_stamp on 32 bit architectures only
   *	@sk_tsflags: SO_TIMESTAMPING flags
@@ -465,7 +466,10 @@ struct sock {
 	u32			sk_dst_pending_confirm;
 	u32			sk_pacing_status; /* see enum sk_pacing */
 	struct page_frag	sk_frag;
-	struct timer_list	sk_timer;
+	union {
+		struct timer_list sk_timer;
+		struct timer_list mptcp_retransmit_timer;
+	};
 
 	unsigned long		sk_pacing_rate; /* bytes per second */
 	atomic_t		sk_zckey;
--- a/net/dccp/timer.c
+++ b/net/dccp/timer.c
@@ -160,7 +160,9 @@ out:
 
 static void dccp_keepalive_timer(struct timer_list *t)
 {
-	struct sock *sk = from_timer(sk, t, sk_timer);
+	struct inet_connection_sock *icsk =
+		from_timer(icsk, t, icsk_keepalive_timer);
+	struct sock *sk = &icsk->icsk_inet.sk;
 
 	pr_err("dccp should not use a keepalive timer !\n");
 	sock_put(sk);
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -750,7 +750,7 @@ void inet_csk_init_xmit_timers(struct so
 
 	timer_setup(&icsk->icsk_retransmit_timer, retransmit_handler, 0);
 	timer_setup(&icsk->icsk_delack_timer, delack_handler, 0);
-	timer_setup(&sk->sk_timer, keepalive_handler, 0);
+	timer_setup(&icsk->icsk_keepalive_timer, keepalive_handler, 0);
 	icsk->icsk_pending = icsk->icsk_ack.pending = 0;
 }
 EXPORT_SYMBOL(inet_csk_init_xmit_timers);
@@ -763,7 +763,7 @@ void inet_csk_clear_xmit_timers(struct s
 
 	sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
 	sk_stop_timer(sk, &icsk->icsk_delack_timer);
-	sk_stop_timer(sk, &sk->sk_timer);
+	sk_stop_timer(sk, &icsk->icsk_keepalive_timer);
 }
 EXPORT_SYMBOL(inet_csk_clear_xmit_timers);
 
@@ -778,18 +778,18 @@ void inet_csk_clear_xmit_timers_sync(str
 
 	sk_stop_timer_sync(sk, &icsk->icsk_retransmit_timer);
 	sk_stop_timer_sync(sk, &icsk->icsk_delack_timer);
-	sk_stop_timer_sync(sk, &sk->sk_timer);
+	sk_stop_timer_sync(sk, &icsk->icsk_keepalive_timer);
 }
 
 void inet_csk_delete_keepalive_timer(struct sock *sk)
 {
-	sk_stop_timer(sk, &sk->sk_timer);
+	sk_stop_timer(sk, &inet_csk(sk)->icsk_keepalive_timer);
 }
 EXPORT_SYMBOL(inet_csk_delete_keepalive_timer);
 
 void inet_csk_reset_keepalive_timer(struct sock *sk, unsigned long len)
 {
-	sk_reset_timer(sk, &sk->sk_timer, jiffies + len);
+	sk_reset_timer(sk, &inet_csk(sk)->icsk_keepalive_timer, jiffies + len);
 }
 EXPORT_SYMBOL(inet_csk_reset_keepalive_timer);
 
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -319,11 +319,11 @@ int inet_sk_diag_fill(struct sock *sk, s
 		r->idiag_retrans = icsk->icsk_probes_out;
 		r->idiag_expires =
 			jiffies_delta_to_msecs(icsk->icsk_timeout - jiffies);
-	} else if (timer_pending(&sk->sk_timer)) {
+	} else if (timer_pending(&icsk->icsk_keepalive_timer)) {
 		r->idiag_timer = 2;
 		r->idiag_retrans = icsk->icsk_probes_out;
 		r->idiag_expires =
-			jiffies_delta_to_msecs(sk->sk_timer.expires - jiffies);
+			jiffies_delta_to_msecs(icsk->icsk_keepalive_timer.expires - jiffies);
 	}
 
 	if ((ext & (1 << (INET_DIAG_INFO - 1))) && handler->idiag_info_size) {
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -2918,9 +2918,9 @@ static void get_tcp4_sock(struct sock *s
 	} else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
 		timer_active	= 4;
 		timer_expires	= icsk->icsk_timeout;
-	} else if (timer_pending(&sk->sk_timer)) {
+	} else if (timer_pending(&icsk->icsk_keepalive_timer)) {
 		timer_active	= 2;
-		timer_expires	= sk->sk_timer.expires;
+		timer_expires	= icsk->icsk_keepalive_timer.expires;
 	} else {
 		timer_active	= 0;
 		timer_expires = jiffies;
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -755,8 +755,9 @@ EXPORT_IPV6_MOD_GPL(tcp_set_keepalive);
 
 static void tcp_keepalive_timer (struct timer_list *t)
 {
-	struct sock *sk = from_timer(sk, t, sk_timer);
-	struct inet_connection_sock *icsk = inet_csk(sk);
+	struct inet_connection_sock *icsk =
+		from_timer(icsk, t, icsk_keepalive_timer);
+	struct sock *sk = &icsk->icsk_inet.sk;
 	struct tcp_sock *tp = tcp_sk(sk);
 	u32 elapsed;
 
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -2179,9 +2179,9 @@ static void get_tcp6_sock(struct seq_fil
 	} else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
 		timer_active	= 4;
 		timer_expires	= icsk->icsk_timeout;
-	} else if (timer_pending(&sp->sk_timer)) {
+	} else if (timer_pending(&icsk->icsk_keepalive_timer)) {
 		timer_active	= 2;
-		timer_expires	= sp->sk_timer.expires;
+		timer_expires	= icsk->icsk_keepalive_timer.expires;
 	} else {
 		timer_active	= 0;
 		timer_expires = jiffies;
--- a/net/mptcp/ctrl.c
+++ b/net/mptcp/ctrl.c
@@ -407,9 +407,9 @@ void mptcp_active_detect_blackhole(struc
 
 	if (subflow->request_mptcp && ssk->sk_state == TCP_SYN_SENT) {
 		if (timeouts == 2 || (timeouts < 2 && expired)) {
-			MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_MPCAPABLEACTIVEDROP);
 			subflow->mpc_drop = 1;
-			mptcp_subflow_early_fallback(mptcp_sk(subflow->conn), subflow);
+			mptcp_subflow_early_fallback(mptcp_sk(subflow->conn), subflow,
+						     MPTCP_MIB_MPCAPABLEACTIVEDROP);
 		}
 	} else if (ssk->sk_state == TCP_SYN_SENT) {
 		subflow->mpc_drop = 0;
--- a/net/mptcp/mib.c
+++ b/net/mptcp/mib.c
@@ -79,6 +79,11 @@ static const struct snmp_mib mptcp_snmp_
 	SNMP_MIB_ITEM("RcvWndConflict", MPTCP_MIB_RCVWNDCONFLICT),
 	SNMP_MIB_ITEM("MPCurrEstab", MPTCP_MIB_CURRESTAB),
 	SNMP_MIB_ITEM("Blackhole", MPTCP_MIB_BLACKHOLE),
+	SNMP_MIB_ITEM("MPCapableDataFallback", MPTCP_MIB_MPCAPABLEDATAFALLBACK),
+	SNMP_MIB_ITEM("MD5SigFallback", MPTCP_MIB_MD5SIGFALLBACK),
+	SNMP_MIB_ITEM("DssFallback", MPTCP_MIB_DSSFALLBACK),
+	SNMP_MIB_ITEM("SimultConnectFallback", MPTCP_MIB_SIMULTCONNFALLBACK),
+	SNMP_MIB_ITEM("FallbackFailed", MPTCP_MIB_FALLBACKFAILED),
 	SNMP_MIB_SENTINEL
 };
 
--- a/net/mptcp/mib.h
+++ b/net/mptcp/mib.h
@@ -80,6 +80,11 @@ enum linux_mptcp_mib_field {
 	MPTCP_MIB_RCVWNDCONFLICT,	/* Conflict with while updating msk rcv wnd */
 	MPTCP_MIB_CURRESTAB,		/* Current established MPTCP connections */
 	MPTCP_MIB_BLACKHOLE,		/* A blackhole has been detected */
+	MPTCP_MIB_MPCAPABLEDATAFALLBACK,	/* No DSS/MPC+data on first established packet */
+	MPTCP_MIB_MD5SIGFALLBACK,	/* Conflicting TCP option enabled */
+	MPTCP_MIB_DSSFALLBACK,		/* Bad or missing DSS */
+	MPTCP_MIB_SIMULTCONNFALLBACK,	/* Simultaneous connect */
+	MPTCP_MIB_FALLBACKFAILED,	/* Can't fallback due to msk status */
 	__MPTCP_MIB_MAX
 };
 
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -473,7 +473,7 @@ bool mptcp_syn_options(struct sock *sk,
 	subflow->snd_isn = TCP_SKB_CB(skb)->end_seq;
 	if (subflow->request_mptcp) {
 		if (unlikely(subflow_simultaneous_connect(sk))) {
-			WARN_ON_ONCE(!mptcp_try_fallback(sk));
+			WARN_ON_ONCE(!mptcp_try_fallback(sk, MPTCP_MIB_SIMULTCONNFALLBACK));
 
 			/* Ensure mptcp_finish_connect() will not process the
 			 * MPC handshake.
@@ -1043,8 +1043,10 @@ static bool check_fully_established(stru
 		if (subflow->mp_join)
 			goto reset;
 		subflow->mp_capable = 0;
-		if (!mptcp_try_fallback(ssk))
+		if (!mptcp_try_fallback(ssk, MPTCP_MIB_MPCAPABLEDATAFALLBACK)) {
+			MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_FALLBACKFAILED);
 			goto reset;
+		}
 		pr_fallback(msk);
 		return false;
 	}
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -67,6 +67,26 @@ static const struct proto_ops *mptcp_fal
 	return &inet_stream_ops;
 }
 
+bool __mptcp_try_fallback(struct mptcp_sock *msk, int fb_mib)
+{
+	struct net *net = sock_net((struct sock *)msk);
+
+	if (__mptcp_check_fallback(msk))
+		return true;
+
+	spin_lock_bh(&msk->fallback_lock);
+	if (!msk->allow_infinite_fallback) {
+		spin_unlock_bh(&msk->fallback_lock);
+		return false;
+	}
+
+	msk->allow_subflows = false;
+	set_bit(MPTCP_FALLBACK_DONE, &msk->flags);
+	__MPTCP_INC_STATS(net, fb_mib);
+	spin_unlock_bh(&msk->fallback_lock);
+	return true;
+}
+
 static int __mptcp_socket_create(struct mptcp_sock *msk)
 {
 	struct mptcp_subflow_context *subflow;
@@ -414,9 +434,7 @@ static bool __mptcp_move_skb(struct sock
 
 static void mptcp_stop_rtx_timer(struct sock *sk)
 {
-	struct inet_connection_sock *icsk = inet_csk(sk);
-
-	sk_stop_timer(sk, &icsk->icsk_retransmit_timer);
+	sk_stop_timer(sk, &sk->mptcp_retransmit_timer);
 	mptcp_sk(sk)->timer_ival = 0;
 }
 
@@ -659,10 +677,7 @@ static bool mptcp_check_data_fin(struct
 
 static void mptcp_dss_corruption(struct mptcp_sock *msk, struct sock *ssk)
 {
-	if (mptcp_try_fallback(ssk)) {
-		MPTCP_INC_STATS(sock_net(ssk),
-				MPTCP_MIB_DSSCORRUPTIONFALLBACK);
-	} else {
+	if (!mptcp_try_fallback(ssk, MPTCP_MIB_DSSCORRUPTIONFALLBACK)) {
 		MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DSSCORRUPTIONRESET);
 		mptcp_subflow_reset(ssk);
 	}
@@ -973,12 +988,11 @@ static void __mptcp_flush_join_list(stru
 
 static bool mptcp_rtx_timer_pending(struct sock *sk)
 {
-	return timer_pending(&inet_csk(sk)->icsk_retransmit_timer);
+	return timer_pending(&sk->mptcp_retransmit_timer);
 }
 
 static void mptcp_reset_rtx_timer(struct sock *sk)
 {
-	struct inet_connection_sock *icsk = inet_csk(sk);
 	unsigned long tout;
 
 	/* prevent rescheduling on close */
@@ -986,7 +1000,7 @@ static void mptcp_reset_rtx_timer(struct
 		return;
 
 	tout = mptcp_sk(sk)->timer_ival;
-	sk_reset_timer(sk, &icsk->icsk_retransmit_timer, jiffies + tout);
+	sk_reset_timer(sk, &sk->mptcp_retransmit_timer, jiffies + tout);
 }
 
 bool mptcp_schedule_work(struct sock *sk)
@@ -1293,12 +1307,12 @@ static void mptcp_update_infinite_map(st
 	mpext->infinite_map = 1;
 	mpext->data_len = 0;
 
-	if (!mptcp_try_fallback(ssk)) {
+	if (!mptcp_try_fallback(ssk, MPTCP_MIB_INFINITEMAPTX)) {
+		MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_FALLBACKFAILED);
 		mptcp_subflow_reset(ssk);
 		return;
 	}
 
-	MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPTX);
 	mptcp_subflow_ctx(ssk)->send_infinite_map = 0;
 	pr_fallback(msk);
 }
@@ -2393,9 +2407,7 @@ out_err:
 
 static void mptcp_retransmit_timer(struct timer_list *t)
 {
-	struct inet_connection_sock *icsk = from_timer(icsk, t,
-						       icsk_retransmit_timer);
-	struct sock *sk = &icsk->icsk_inet.sk;
+	struct sock *sk = from_timer(sk, t, mptcp_retransmit_timer);
 	struct mptcp_sock *msk = mptcp_sk(sk);
 
 	bh_lock_sock(sk);
@@ -2413,7 +2425,9 @@ static void mptcp_retransmit_timer(struc
 
 static void mptcp_tout_timer(struct timer_list *t)
 {
-	struct sock *sk = from_timer(sk, t, sk_timer);
+	struct inet_connection_sock *icsk =
+		from_timer(icsk, t, mptcp_tout_timer);
+	struct sock *sk = &icsk->icsk_inet.sk;
 
 	mptcp_schedule_work(sk);
 	sock_put(sk);
@@ -2856,7 +2870,7 @@ void mptcp_reset_tout_timer(struct mptcp
 	 */
 	timeout = inet_csk(sk)->icsk_mtup.probe_timestamp ? close_timeout : fail_tout;
 
-	sk_reset_timer(sk, &sk->sk_timer, timeout);
+	sk_reset_timer(sk, &inet_csk(sk)->mptcp_tout_timer, timeout);
 }
 
 static void mptcp_mp_fail_no_response(struct mptcp_sock *msk)
@@ -2988,9 +3002,8 @@ static void __mptcp_init_sock(struct soc
 	mptcp_pm_data_init(msk);
 	spin_lock_init(&msk->fallback_lock);
 
-	/* re-use the csk retrans timer for MPTCP-level retrans */
-	timer_setup(&msk->sk.icsk_retransmit_timer, mptcp_retransmit_timer, 0);
-	timer_setup(&sk->sk_timer, mptcp_tout_timer, 0);
+	timer_setup(&sk->mptcp_retransmit_timer, mptcp_retransmit_timer, 0);
+	timer_setup(&msk->sk.mptcp_tout_timer, mptcp_tout_timer, 0);
 }
 
 static void mptcp_ca_reset(struct sock *sk)
@@ -3192,7 +3205,7 @@ static void __mptcp_destroy_sock(struct
 	might_sleep();
 
 	mptcp_stop_rtx_timer(sk);
-	sk_stop_timer(sk, &sk->sk_timer);
+	sk_stop_timer(sk, &inet_csk(sk)->mptcp_tout_timer);
 	msk->pm.status = 0;
 	mptcp_release_sched(msk);
 
@@ -3938,16 +3951,15 @@ static int mptcp_connect(struct sock *sk
 	 * TCP option space.
 	 */
 	if (rcu_access_pointer(tcp_sk(ssk)->md5sig_info))
-		mptcp_subflow_early_fallback(msk, subflow);
+		mptcp_subflow_early_fallback(msk, subflow, MPTCP_MIB_MD5SIGFALLBACK);
 #endif
 	if (subflow->request_mptcp) {
-		if (mptcp_active_should_disable(sk)) {
-			MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_MPCAPABLEACTIVEDISABLED);
-			mptcp_subflow_early_fallback(msk, subflow);
-		} else if (mptcp_token_new_connect(ssk) < 0) {
-			MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_TOKENFALLBACKINIT);
-			mptcp_subflow_early_fallback(msk, subflow);
-		}
+		if (mptcp_active_should_disable(sk))
+			mptcp_subflow_early_fallback(msk, subflow,
+						     MPTCP_MIB_MPCAPABLEACTIVEDISABLED);
+		else if (mptcp_token_new_connect(ssk) < 0)
+			mptcp_subflow_early_fallback(msk, subflow,
+						     MPTCP_MIB_TOKENFALLBACKINIT);
 	}
 
 	WRITE_ONCE(msk->write_seq, subflow->idsn);
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -845,7 +845,7 @@ static inline void mptcp_stop_tout_timer
 	if (!inet_csk(sk)->icsk_mtup.probe_timestamp)
 		return;
 
-	sk_stop_timer(sk, &sk->sk_timer);
+	sk_stop_timer(sk, &inet_csk(sk)->mptcp_tout_timer);
 	inet_csk(sk)->icsk_mtup.probe_timestamp = 0;
 }
 
@@ -1216,24 +1216,6 @@ static inline bool mptcp_check_fallback(
 	return __mptcp_check_fallback(msk);
 }
 
-static inline bool __mptcp_try_fallback(struct mptcp_sock *msk)
-{
-	if (__mptcp_check_fallback(msk)) {
-		pr_debug("TCP fallback already done (msk=%p)\n", msk);
-		return true;
-	}
-	spin_lock_bh(&msk->fallback_lock);
-	if (!msk->allow_infinite_fallback) {
-		spin_unlock_bh(&msk->fallback_lock);
-		return false;
-	}
-
-	msk->allow_subflows = false;
-	set_bit(MPTCP_FALLBACK_DONE, &msk->flags);
-	spin_unlock_bh(&msk->fallback_lock);
-	return true;
-}
-
 static inline bool __mptcp_has_initial_subflow(const struct mptcp_sock *msk)
 {
 	struct sock *ssk = READ_ONCE(msk->first);
@@ -1243,14 +1225,16 @@ static inline bool __mptcp_has_initial_s
 			TCPF_SYN_RECV | TCPF_LISTEN));
 }
 
-static inline bool mptcp_try_fallback(struct sock *ssk)
+bool __mptcp_try_fallback(struct mptcp_sock *msk, int fb_mib);
+
+static inline bool mptcp_try_fallback(struct sock *ssk, int fb_mib)
 {
 	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
 	struct sock *sk = subflow->conn;
 	struct mptcp_sock *msk;
 
 	msk = mptcp_sk(sk);
-	if (!__mptcp_try_fallback(msk))
+	if (!__mptcp_try_fallback(msk, fb_mib))
 		return false;
 	if (READ_ONCE(msk->snd_data_fin_enable) && !(ssk->sk_shutdown & SEND_SHUTDOWN)) {
 		gfp_t saved_allocation = ssk->sk_allocation;
@@ -1269,11 +1253,12 @@ static inline bool mptcp_try_fallback(st
 #define pr_fallback(a) pr_debug("%s:fallback to TCP (msk=%p)\n", __func__, a)
 
 static inline void mptcp_subflow_early_fallback(struct mptcp_sock *msk,
-						struct mptcp_subflow_context *subflow)
+						struct mptcp_subflow_context *subflow,
+						int fb_mib)
 {
 	pr_fallback(msk);
 	subflow->request_mptcp = 0;
-	WARN_ON_ONCE(!__mptcp_try_fallback(msk));
+	WARN_ON_ONCE(!__mptcp_try_fallback(msk, fb_mib));
 }
 
 static inline bool mptcp_check_infinite_map(struct sk_buff *skb)
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -550,11 +550,13 @@ static void subflow_finish_connect(struc
 	mptcp_get_options(skb, &mp_opt);
 	if (subflow->request_mptcp) {
 		if (!(mp_opt.suboptions & OPTION_MPTCP_MPC_SYNACK)) {
-			if (!mptcp_try_fallback(sk))
+			if (!mptcp_try_fallback(sk,
+						MPTCP_MIB_MPCAPABLEACTIVEFALLBACK)) {
+				MPTCP_INC_STATS(sock_net(sk),
+						MPTCP_MIB_FALLBACKFAILED);
 				goto do_reset;
+			}
 
-			MPTCP_INC_STATS(sock_net(sk),
-					MPTCP_MIB_MPCAPABLEACTIVEFALLBACK);
 			pr_fallback(msk);
 			goto fallback;
 		}
@@ -1404,7 +1406,7 @@ fallback:
 			return true;
 		}
 
-		if (!mptcp_try_fallback(ssk)) {
+		if (!mptcp_try_fallback(ssk, MPTCP_MIB_DSSFALLBACK)) {
 			/* fatal protocol error, close the socket.
 			 * subflow_error_report() will introduce the appropriate barriers
 			 */
--- a/tools/testing/selftests/bpf/progs/bpf_iter_tcp4.c
+++ b/tools/testing/selftests/bpf/progs/bpf_iter_tcp4.c
@@ -103,9 +103,9 @@ static int dump_tcp_sock(struct seq_file
 	} else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
 		timer_active = 4;
 		timer_expires = icsk->icsk_timeout;
-	} else if (timer_pending(&sp->sk_timer)) {
+	} else if (timer_pending(&icsk->icsk_keepalive_timer)) {
 		timer_active = 2;
-		timer_expires = sp->sk_timer.expires;
+		timer_expires = icsk->icsk_keepalive_timer.expires;
 	} else {
 		timer_active = 0;
 		timer_expires = bpf_jiffies64();
--- a/tools/testing/selftests/bpf/progs/bpf_iter_tcp6.c
+++ b/tools/testing/selftests/bpf/progs/bpf_iter_tcp6.c
@@ -103,9 +103,9 @@ static int dump_tcp6_sock(struct seq_fil
 	} else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
 		timer_active = 4;
 		timer_expires = icsk->icsk_timeout;
-	} else if (timer_pending(&sp->sk_timer)) {
+	} else if (timer_pending(&icsk->icsk_keepalive_timer)) {
 		timer_active = 2;
-		timer_expires = sp->sk_timer.expires;
+		timer_expires = icsk->icsk_keepalive_timer.expires;
 	} else {
 		timer_active = 0;
 		timer_expires = bpf_jiffies64();



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 772/877] mptcp: do not reschedule the RTX timer for fallback sockets
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (770 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 771/877] tcp: introduce icsk->icsk_keepalive_timer Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 773/877] mptcp: prevent race between disconnect() and rtx Greg Kroah-Hartman
                   ` (112 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Paolo Abeni, Matthieu Baerts (NGI0),
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Paolo Abeni <pabeni@redhat.com>

[ Upstream commit e2ab913f68c7d11e2561b8a8ad0b87ffefcad667 ]

On fallback socket the retrans timer is a quite convoluted no-op, but
currently nothing prevents the MPTCP core to keep rescheduling it.

Additionally gate RTX timer reset to the msk not being fallen back to
TCP yet. To avoid adding multiple tests in fast-path, use a new flags
bit for such condition.

The RTX enable bit is clear at close time and set before the msk could
start retransmitting, with a couple of caveats:

- passive sockets inherit the bit from the listener msk; set the bit on
  such socket to avoid flipping it in the fast-path, even if the
  listener will obviously never retransmit.

- while fastopening (MPTFO), mptcp_sendmsg_fastopen still ends-up
  calling mptcp_connect via tcp_sendmsg_fastopen ->
  __inet_stream_connect(ssk->sk_socket), and the first subflow's
  sk_socket points to the msk one.

Fixes: b51f9b80c032 ("mptcp: introduce MPTCP retransmission timer")
Cc: stable@vger.kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-1-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mptcp/protocol.c |   13 ++++++++++---
 net/mptcp/protocol.h |    1 +
 2 files changed, 11 insertions(+), 3 deletions(-)

--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -82,6 +82,7 @@ bool __mptcp_try_fallback(struct mptcp_s
 
 	msk->allow_subflows = false;
 	set_bit(MPTCP_FALLBACK_DONE, &msk->flags);
+	clear_bit(MPTCP_RTX_ENABLED, &msk->flags);
 	__MPTCP_INC_STATS(net, fb_mib);
 	spin_unlock_bh(&msk->fallback_lock);
 	return true;
@@ -993,13 +994,14 @@ static bool mptcp_rtx_timer_pending(stru
 
 static void mptcp_reset_rtx_timer(struct sock *sk)
 {
+	struct mptcp_sock *msk = mptcp_sk(sk);
 	unsigned long tout;
 
-	/* prevent rescheduling on close */
-	if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE))
+	/* Prevent rescheduling on close and in case of fallback. */
+	if (!test_bit(MPTCP_RTX_ENABLED, &msk->flags))
 		return;
 
-	tout = mptcp_sk(sk)->timer_ival;
+	tout = msk->timer_ival;
 	sk_reset_timer(sk, &sk->mptcp_retransmit_timer, jiffies + tout);
 }
 
@@ -3121,6 +3123,9 @@ void mptcp_set_state(struct sock *sk, in
 		 * transition from TCP_SYN_RECV to TCP_CLOSE_WAIT.
 		 */
 		break;
+	case TCP_CLOSE:
+		clear_bit(MPTCP_RTX_ENABLED, &mptcp_sk(sk)->flags);
+		fallthrough;
 	default:
 		if (oldstate == TCP_ESTABLISHED || oldstate == TCP_CLOSE_WAIT)
 			MPTCP_DEC_STATS(sock_net(sk), MPTCP_MIB_CURRESTAB);
@@ -3944,6 +3949,7 @@ static int mptcp_connect(struct sock *sk
 	if (IS_ERR(ssk))
 		return PTR_ERR(ssk);
 
+	set_bit(MPTCP_RTX_ENABLED, &msk->flags);
 	mptcp_set_state(sk, TCP_SYN_SENT);
 	subflow = mptcp_subflow_ctx(ssk);
 #ifdef CONFIG_TCP_MD5SIG
@@ -4092,6 +4098,7 @@ static int mptcp_listen(struct socket *s
 		goto unlock;
 	}
 
+	set_bit(MPTCP_RTX_ENABLED, &msk->flags);
 	mptcp_set_state(sk, TCP_LISTEN);
 	sock_set_flag(sk, SOCK_RCU_FREE);
 
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -116,6 +116,7 @@
 #define MPTCP_WORK_RTX		1
 #define MPTCP_FALLBACK_DONE	2
 #define MPTCP_WORK_CLOSE_SUBFLOW 3
+#define MPTCP_RTX_ENABLED	4
 
 /* MPTCP socket release cb flags */
 #define MPTCP_PUSH_PENDING	1



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 773/877] mptcp: prevent race between disconnect() and rtx
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (771 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 772/877] mptcp: do not reschedule the RTX timer for fallback sockets Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-10-01 20:30   ` Harshit Mogalapalli
  2026-09-30 15:28 ` [PATCH 6.12 774/877] smb: client: refactor ACL setting control flow in id_mode_to_cifs_acl() Greg Kroah-Hartman
                   ` (111 subsequent siblings)
  884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Paolo Abeni, Matthieu Baerts (NGI0),
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Paolo Abeni <pabeni@redhat.com>

[ Upstream commit 85c580b0d8590520ae00a15c29e9fb9c99427a3e ]

Sashiko noted that the two event can race, leading to inconsistent
status. Prevent the race using the synchronous timer stop operation.

Cc: stable@vger.kernel.org
Fixes: b29fcfb54cd7 ("mptcp: full disconnect implementation")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-6-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mptcp/protocol.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3367,6 +3367,7 @@ static void mptcp_copy_inaddrs(struct so
 
 static int mptcp_disconnect(struct sock *sk, int flags)
 {
+	struct inet_connection_sock *icsk = inet_csk(sk);
 	struct mptcp_sock *msk = mptcp_sk(sk);
 
 	/* We are on the fastopen error path. We can't call straight into the
@@ -3379,8 +3380,13 @@ static int mptcp_disconnect(struct sock
 	mptcp_check_listen_stop(sk);
 	mptcp_set_state(sk, TCP_CLOSE);
 
-	mptcp_stop_rtx_timer(sk);
-	mptcp_stop_tout_timer(sk);
+	/* The later subflow close can not kick again the tout timer,
+	 * as the msk is already in closed status.
+	 */
+	msk->timer_ival = icsk->icsk_rto_min;
+	sk_stop_timer_sync(sk, &sk->mptcp_retransmit_timer);
+	icsk->icsk_mtup.probe_timestamp = 0;
+	sk_stop_timer_sync(sk, &icsk->mptcp_tout_timer);
 
 	if (msk->token)
 		mptcp_event(MPTCP_EVENT_CLOSED, msk, NULL, GFP_KERNEL);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 774/877] smb: client: refactor ACL setting control flow in id_mode_to_cifs_acl()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (772 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 773/877] mptcp: prevent race between disconnect() and rtx Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 775/877] smb/client: fix security flag calculation when setting security descriptors Greg Kroah-Hartman
                   ` (110 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Ralph Boehme, Steve French,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ralph Boehme <slow@samba.org>

[ Upstream commit a540a64c4801fe02e452ee37e961018106418260 ]

Refactor the control flow in id_mode_to_cifs_acl() to reduce nesting and
prevent error code overwriting.

Instead of wrapping the call to ops->set_acl() in a conditional block,
introduce early exits (goto id_mode_to_cifs_acl_exit) when build_sec_desc()
fails or ops->set_acl is NULL. This ensures that any actual error returned
by build_sec_desc() is not overwritten with -EOPNOTSUPP.

Signed-off-by: Ralph Boehme <slow@samba.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: d05045177a85 ("smb: client: fail DACL rewrite when the new DACL exceeds 64K")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/cifsacl.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

--- a/fs/smb/client/cifsacl.c
+++ b/fs/smb/client/cifsacl.c
@@ -1798,14 +1798,18 @@ id_mode_to_cifs_acl(struct inode *inode,
 
 	cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc);
 
-	if (ops->set_acl == NULL)
-		rc = -EOPNOTSUPP;
+	if (rc != 0)
+		goto id_mode_to_cifs_acl_exit;
 
-	if (!rc) {
-		/* Set the security descriptor */
-		rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
-		cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
+	if (ops->set_acl == NULL) {
+		rc = -EOPNOTSUPP;
+		goto id_mode_to_cifs_acl_exit;
 	}
+
+	/* Set the security descriptor */
+	rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
+	cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
+
 id_mode_to_cifs_acl_exit:
 	cifs_put_tlink(tlink);
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 775/877] smb/client: fix security flag calculation when setting security descriptors
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (773 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 774/877] smb: client: refactor ACL setting control flow in id_mode_to_cifs_acl() Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 776/877] smb: client: fail DACL rewrite when the new DACL exceeds 64K Greg Kroah-Hartman
                   ` (109 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Ralph Boehme, Steve French,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ralph Boehme <slow@samba.org>

[ Upstream commit 4939889c985da68936090cc013e58c28b7bff34f ]

In id_mode_to_cifs_acl(), aclflag was initialized to CIFS_ACL_DACL by default.
This forced the client to request setting the DACL even when only an ownership
(chown) or group (chgrp) change was being performed.

Let build_sec_desc() do the proper flag calculation by initializing aclflag
to 0. build_sec_desc() sets the appropriate bits (CIFS_ACL_OWNER, CIFS_ACL_GROUP,
or CIFS_ACL_DACL) depending on what actually changed. During ownership transfer,
CIFS_ACL_DACL is only set if replace_sids_and_copy_aces() actually replaces the
SIDs inside any of the DACL's ACEs.

If build_sec_desc() results in aclflag being 0 (meaning no changes were mapped),
exit early to avoid sending an empty security descriptor update to the server.

Signed-off-by: Ralph Boehme <slow@samba.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: d05045177a85 ("smb: client: fail DACL rewrite when the new DACL exceeds 64K")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/cifsacl.c |   22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

--- a/fs/smb/client/cifsacl.c
+++ b/fs/smb/client/cifsacl.c
@@ -1131,7 +1131,8 @@ set_size:
 
 static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *pndacl,
 		struct smb_sid *pownersid, struct smb_sid *pgrpsid,
-		struct smb_sid *pnownersid, struct smb_sid *pngrpsid)
+		struct smb_sid *pnownersid, struct smb_sid *pngrpsid,
+		int *aclflag)
 {
 	int i;
 	u16 size = 0;
@@ -1155,12 +1156,15 @@ static __u16 replace_sids_and_copy_aces(
 		pntace = (struct smb_ace *) (acl_base + size);
 		pnntace = (struct smb_ace *) (nacl_base + nsize);
 
-		if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0)
+		if (pnownersid && compare_sids(&pntace->sid, pownersid) == 0) {
 			ace_size = cifs_copy_ace(pnntace, pntace, pnownersid);
-		else if (pngrpsid && compare_sids(&pntace->sid, pgrpsid) == 0)
+			*aclflag |= CIFS_ACL_DACL;
+		} else if (pngrpsid && compare_sids(&pntace->sid, pgrpsid) == 0) {
 			ace_size = cifs_copy_ace(pnntace, pntace, pngrpsid);
-		else
+			*aclflag |= CIFS_ACL_DACL;
+		} else {
 			ace_size = cifs_copy_ace(pnntace, pntace, NULL);
+		}
 
 		size += le16_to_cpu(pntace->size);
 		nsize += ace_size;
@@ -1482,7 +1486,8 @@ static int build_sec_desc(struct smb_nts
 			/* Replace ACEs for old owner with new one */
 			size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
 					owner_sid_ptr, group_sid_ptr,
-					nowner_sid_ptr, ngroup_sid_ptr);
+					nowner_sid_ptr, ngroup_sid_ptr,
+					aclflag);
 			ndacl_ptr->size = cpu_to_le16(size);
 		}
 
@@ -1697,7 +1702,7 @@ id_mode_to_cifs_acl(struct inode *inode,
 			kuid_t uid, kgid_t gid)
 {
 	int rc = 0;
-	int aclflag = CIFS_ACL_DACL; /* default flag to set */
+	int aclflag = 0;
 	__u32 secdesclen = 0;
 	__u32 nsecdesclen = 0;
 	__u32 dacloffset = 0;
@@ -1801,6 +1806,11 @@ id_mode_to_cifs_acl(struct inode *inode,
 	if (rc != 0)
 		goto id_mode_to_cifs_acl_exit;
 
+	if (aclflag == 0) {
+		cifs_dbg(FYI, "set_cifs_acl aclflag=0, no change mapped\n");
+		goto id_mode_to_cifs_acl_exit;
+	}
+
 	if (ops->set_acl == NULL) {
 		rc = -EOPNOTSUPP;
 		goto id_mode_to_cifs_acl_exit;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 776/877] smb: client: fail DACL rewrite when the new DACL exceeds 64K
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (774 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 775/877] smb/client: fix security flag calculation when setting security descriptors Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 777/877] xfs: report healthy filesystem events in scrub stats Greg Kroah-Hartman
                   ` (108 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Bjoern Doebel,
	Paulo Alcantara, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bjoern Doebel <doebel@amazon.de>

[ Upstream commit d05045177a855386bca5e1909e08d06290e6e3b3 ]

replace_sids_and_copy_aces() and set_chmod_dacl() accumulate the size of
the DACL they build in a u16. That accumulator can wrap.

validate_dacl() caps num_aces at (dacl_size - sizeof(struct smb_acl)) /
20, i.e. 3276 for a maximally sized DACL, while each rewritten ACE can
grow to sizeof(struct smb_ace) (76 bytes) once its SID is replaced with
one carrying SID_MAX_SUB_AUTHORITIES sub-authorities. The worst case is
therefore sizeof(struct smb_acl) + 3276 * 76 = 248984 bytes, far beyond
what a u16 can hold. A wraparound is reached with 863 ACEs.

After the wraparound, ndacl_ptr->size becomes meaningless and the offset
will point anywhere in the ACE array. As a result, we will see
corruption of the DACL, which then gets sent to the server. This is not
an out-of-bounds write as the allocation now covers the worst-case
expansion, so writes will always go into the buffer.

Adjust the code to use a u32 internally and return -EOVERFLOW in the
overflow case. The operation must be refused, because a DACL can only
hold 2^16-1 bytes on the wire and larger DACLs cannot be represented.

set_chmod_dacl() carries the same pattern and is fixed the same way. It
only wraps once the source DACL comes within roughly 380 bytes of the
64K ceiling, but the failure mode is identical.

Suggested-by: Namjae Jeon <linkinjeon@kernel.org>
Cc: stable@vger.kernel.org
Fixes: f5065508897a ("cifs: Retain old ACEs when converting between mode bits and ACL.")
Assisted-by: Kiro:claude-opus-5
Signed-off-by: Bjoern Doebel <doebel@amazon.de>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/cifsacl.c |   39 ++++++++++++++++++++++++++-------------
 1 file changed, 26 insertions(+), 13 deletions(-)

--- a/fs/smb/client/cifsacl.c
+++ b/fs/smb/client/cifsacl.c
@@ -1024,13 +1024,13 @@ unsigned int setup_special_user_owner_AC
 static void populate_new_aces(char *nacl_base,
 		struct smb_sid *pownersid,
 		struct smb_sid *pgrpsid,
-		__u64 *pnmode, u16 *pnum_aces, u16 *pnsize,
+		__u64 *pnmode, u16 *pnum_aces, u32 *pnsize,
 		bool modefromsid,
 		bool posix)
 {
 	__u64 nmode;
 	u16 num_aces = 0;
-	u16 nsize = 0;
+	u32 nsize = 0;
 	__u64 user_mode;
 	__u64 group_mode;
 	__u64 other_mode;
@@ -1129,17 +1129,17 @@ set_size:
 	*pnsize = nsize;
 }
 
-static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *pndacl,
-		struct smb_sid *pownersid, struct smb_sid *pgrpsid,
-		struct smb_sid *pnownersid, struct smb_sid *pngrpsid,
-		int *aclflag)
+static int replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *pndacl,
+				      struct smb_sid *pownersid, struct smb_sid *pgrpsid,
+				      struct smb_sid *pnownersid, struct smb_sid *pngrpsid,
+				      int *aclflag, u16 *pnsize)
 {
 	int i;
 	u16 size = 0;
 	struct smb_ace *pntace = NULL;
 	char *acl_base = NULL;
 	u16 src_num_aces = 0;
-	u16 nsize = 0;
+	u32 nsize = 0;
 	struct smb_ace *pnntace = NULL;
 	char *nacl_base = NULL;
 	u16 ace_size = 0;
@@ -1168,9 +1168,12 @@ static __u16 replace_sids_and_copy_aces(
 
 		size += le16_to_cpu(pntace->size);
 		nsize += ace_size;
+		if (nsize > U16_MAX)
+			return -EOVERFLOW;
 	}
 
-	return nsize;
+	*pnsize = nsize;
+	return 0;
 }
 
 static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
@@ -1182,7 +1185,7 @@ static int set_chmod_dacl(struct smb_acl
 	struct smb_ace *pntace = NULL;
 	char *acl_base = NULL;
 	u16 src_num_aces = 0;
-	u16 nsize = 0;
+	u32 nsize = 0;
 	struct smb_ace *pnntace = NULL;
 	char *nacl_base = NULL;
 	u16 num_aces = 0;
@@ -1233,6 +1236,8 @@ static int set_chmod_dacl(struct smb_acl
 
 		nsize += cifs_copy_ace(pnntace, pntace, NULL);
 		num_aces++;
+		if (nsize > U16_MAX)
+			return -EOVERFLOW;
 
 next_ace:
 		size += le16_to_cpu(pntace->size);
@@ -1249,6 +1254,10 @@ next_ace:
 	}
 
 finalize_dacl:
+	/* The DACL size field is 16-bit on the wire, see MS-DTYP 2.4.5 */
+	if (nsize > U16_MAX)
+		return -EOVERFLOW;
+
 	pndacl->num_aces = cpu_to_le16(num_aces);
 	pndacl->size = cpu_to_le16(nsize);
 
@@ -1409,6 +1418,8 @@ static int build_sec_desc(struct smb_nts
 
 		rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
 				    pnmode, mode_from_sid, posix);
+		if (rc)
+			return rc;
 
 		sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
 		/* copy the non-dacl portion of secdesc */
@@ -1484,10 +1495,12 @@ static int build_sec_desc(struct smb_nts
 
 		if (dacloffset) {
 			/* Replace ACEs for old owner with new one */
-			size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
-					owner_sid_ptr, group_sid_ptr,
-					nowner_sid_ptr, ngroup_sid_ptr,
-					aclflag);
+			rc = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
+							owner_sid_ptr, group_sid_ptr,
+							nowner_sid_ptr, ngroup_sid_ptr,
+							aclflag, &size);
+			if (rc)
+				goto chown_chgrp_exit;
 			ndacl_ptr->size = cpu_to_le16(size);
 		}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 777/877] xfs: report healthy filesystem events in scrub stats
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (775 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 776/877] smb: client: fail DACL rewrite when the new DACL exceeds 64K Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 778/877] xfs: fix short ifork reaping computation in xreap_bmapi_binval Greg Kroah-Hartman
                   ` (107 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Carlos Maiolino,
	Christoph Hellwig, Carlos Maiolino, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Darrick J. Wong" <djwong@kernel.org>

[ Upstream commit 0ae61c331ec552ad0c278c5c48a1c4ccb90b4bab ]

LOLLM also notices that I forgot to expose the "clean bill of health"
scrub stats.  Fix that.

Cc: stable@vger.kernel.org # v6.9
Fixes: a1f3e0cca41036 ("xfs: update health status if we get a clean bill of health")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
[ adjusted table insertion context for missing METAPATH, RGSUPER, RTRMAPBT, and RTREFCBT entries. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/scrub/stats.c |    1 +
 1 file changed, 1 insertion(+)

--- a/fs/xfs/scrub/stats.c
+++ b/fs/xfs/scrub/stats.c
@@ -80,6 +80,7 @@ static const char *name_map[XFS_SCRUB_TY
 	[XFS_SCRUB_TYPE_QUOTACHECK]	= "quotacheck",
 	[XFS_SCRUB_TYPE_NLINKS]		= "nlinks",
 	[XFS_SCRUB_TYPE_DIRTREE]	= "dirtree",
+	[XFS_SCRUB_TYPE_HEALTHY]	= "healthy",
 };
 
 /* Format the scrub stats into a text buffer, similar to pcp style. */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 778/877] xfs: fix short ifork reaping computation in xreap_bmapi_binval
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (776 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 777/877] xfs: report healthy filesystem events in scrub stats Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 779/877] xfs: strengthen the "is cow staging" helpers in scrub Greg Kroah-Hartman
                   ` (106 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Darrick J. Wong" <djwong@kernel.org>

[ Upstream commit eacb8479507756c3305994e87fb2fb1183827e98 ]

LOLLM got really confused about the update to imap->br_blockcount in
xreap_bmapi_binval if xreap_inc_binval returns false.  The intent of
this code is that we shorten the imap to whatever length of space we
invalidated so that the next iteration through the loop will start
wherever we left off.  Unfortunately, the calculation sets br_blockcount
to the amount of *unfinished* work, which means that we pointlessly
re-scan blocks that we already reaped.  This is benign, but we should
fix the computation anyway.

Cc: stable@vger.kernel.org # v6.10
Fixes: 5befb047b9f4de ("xfs: add the ability to reap entire inode forks")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
[ Adjusted context to retain `invalidated > XREAP_MAX_BINVAL` instead of `xreap_inc_binval(rs)`. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/scrub/reap.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/xfs/scrub/reap.c
+++ b/fs/xfs/scrub/reap.c
@@ -861,7 +861,7 @@ xreap_bmapi_binval(
 			 * much of the mapping we've seen so far.
 			 */
 			if (invalidated > XREAP_MAX_BINVAL) {
-				imap->br_blockcount = agbno_next - bno;
+				imap->br_blockcount = bno - agbno;
 				goto out;
 			}
 		}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 779/877] xfs: strengthen the "is cow staging" helpers in scrub
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (777 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 778/877] xfs: fix short ifork reaping computation in xreap_bmapi_binval Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 780/877] xfs: remove the i_ino field in struct xfs_inode Greg Kroah-Hartman
                   ` (105 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Darrick J. Wong" <djwong@kernel.org>

[ Upstream commit 0d43368844a75ad13561a1198a3b027940730756 ]

LOLLM pointed out a bug in both of the refcount scrub predicates that
determine if a range of blocks is marked as CoW staging in the btree.
While it compares blockcount < len, this isn't enough to determine that
the CoW staging record is at least as large as the range passed into the
helper.  Fix both of them.

Cc: stable@vger.kernel.org # v4.16
Fixes: f6d5fc21fdc713 ("xfs: cross-reference refcount btree during scrub")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
[ Omitted the rtrefcount.c hunk because Linux 6.12 lacks realtime refcount scrub support. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/scrub/refcount.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

--- a/fs/xfs/scrub/refcount.c
+++ b/fs/xfs/scrub/refcount.c
@@ -581,8 +581,12 @@ xchk_xref_is_cow_staging(
 	if (rc.rc_domain != XFS_REFC_DOMAIN_COW)
 		xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0);
 
+	/* Can't start after bno */
+	if (rc.rc_startblock > agbno)
+		xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0);
+
 	/* Must be at least as long as what was passed in */
-	if (rc.rc_blockcount < len)
+	if (rc.rc_startblock + rc.rc_blockcount < agbno + len)
 		xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0);
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 780/877] xfs: remove the i_ino field in struct xfs_inode
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (778 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 779/877] xfs: strengthen the "is cow staging" helpers in scrub Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 781/877] xfs: fix under-reservation of blocks when repairing sf directories Greg Kroah-Hartman
                   ` (104 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Carlos Maiolino,
	Darrick J. Wong, Carlos Maiolino, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Christoph Hellwig <hch@lst.de>

[ Upstream commit 1113a6d6d5d1336f4415fa1367aac0f853f0892d ]

Now that the VFS inode has a u64 i_ino field, there is no need to store
a copy of the inode number in the xfs_inode structure.

Introduce an I_INO() wrapper as a shortcut to the inode number so that
we don't have to propagate the VFS inode everywhere.

The only non-obvious part is the clearing of i_ino to 0 for RCU freeing
the inode.  None of this calls into VFS paths, which makes clearing the
VFS inode field here just as safe as clearing the old field in the
xfs_inode.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>

[6.12 dependency adaptation]

Keep only the inode-number accessor spelling needed for the attr and
directory repair hunks of 4d3c07591534517c633945c8d8e6526f10e3fabc to
apply cleanly.  Define I_INO as a macro over xfs_inode.i_ino and convert
only the two xfs_da_args.owner initializers in xrep_xattr_swap_prep and
xrep_dir_swap_prep.  No functions are added.

Unlike upstream, this stable tree still has an unsigned long VFS i_ino.
Retain the separate 64-bit XFS inode number and all existing allocation,
reinitialization, reclaim, and VFS setup behavior to avoid truncation on
32-bit systems.  Drop the remaining tree-wide conversions, including
changes to metadata-directory, realtime, and health-monitor files that
do not exist in this tree.  The accessor and the two substitutions are
behavior preserving; the reservation fix remains in the target commit.

Original upstream rationale follows:

Now that the VFS inode has a u64 i_ino field, there is no need to store
a copy of the inode number in the xfs_inode structure.

Introduce an I_INO() wrapper as a shortcut to the inode number so that
we don't have to propagate the VFS inode everywhere.

The only non-obvious part is the clearing of i_ino to 0 for RCU freeing
the inode.  None of this calls into VFS paths, which makes clearing the
VFS inode field here just as safe as clearing the old field in the
xfs_inode.

[ sashal: Reduced backport -- upstream 1113a6d6d5d13 touches 91 file(s), this
  backport carries 3. Not backported here:
  fs/xfs/libxfs/xfs_attr.c
  fs/xfs/libxfs/xfs_attr_leaf.c
  fs/xfs/libxfs/xfs_bmap_btree.c
  fs/xfs/libxfs/xfs_bmap.c
  fs/xfs/libxfs/xfs_btree.c
  fs/xfs/libxfs/xfs_btree_staging.c
  fs/xfs/libxfs/xfs_da_btree.c
  fs/xfs/libxfs/xfs_dir2.c
  ... and 80 more
  This note is generated from the file lists only; see the resolution record
  for the reasoning. ]

Stable-dep-of: 4d3c07591534 ("xfs: fix under-reservation of blocks when repairing sf directories")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/scrub/attr_repair.c |    2 +-
 fs/xfs/scrub/dir_repair.c  |    2 +-
 fs/xfs/xfs_inode.h         |    3 +++
 3 files changed, 5 insertions(+), 2 deletions(-)

--- a/fs/xfs/scrub/attr_repair.c
+++ b/fs/xfs/scrub/attr_repair.c
@@ -1295,7 +1295,7 @@ xrep_xattr_swap_prep(
 			.whichfork	= XFS_ATTR_FORK,
 			.trans		= sc->tp,
 			.total		= 1,
-			.owner		= sc->ip->i_ino,
+			.owner		= I_INO(sc->ip),
 		};
 
 		error = xfs_attr_shortform_to_leaf(&args);
--- a/fs/xfs/scrub/dir_repair.c
+++ b/fs/xfs/scrub/dir_repair.c
@@ -1487,7 +1487,7 @@ xrep_dir_swap_prep(
 			.whichfork	= XFS_DATA_FORK,
 			.trans		= sc->tp,
 			.total		= 1,
-			.owner		= sc->ip->i_ino,
+			.owner		= I_INO(sc->ip),
 		};
 
 		error = xfs_dir2_sf_to_block(&args);
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -178,6 +178,9 @@ static inline const struct inode *VFS_IC
 	return &ip->i_vnode;
 }
 
+/* Keep the full inode number on systems with a 32-bit VFS i_ino. */
+#define I_INO(ip)	((ip)->i_ino)
+
 /*
  * For regular files we only update the on-disk filesize when actually
  * writing data back to disk.  Until then only the copy in the VFS inode



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 781/877] xfs: fix under-reservation of blocks when repairing sf directories
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (779 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 780/877] xfs: remove the i_ino field in struct xfs_inode Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 782/877] xfs: fix backwards mergeability logic in refcount scrubber Greg Kroah-Hartman
                   ` (103 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, floss, dgc, Darrick J. Wong,
	Christoph Hellwig, Carlos Maiolino, Carlos Maiolino, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Darrick J. Wong" <djwong@kernel.org>

[ Upstream commit 4d3c07591534517c633945c8d8e6526f10e3fabc ]

Whilst running QA on XFS for-next as of 7.3-rc2 with MKFS_OPTIONS="-n
size=8192", I observed the following (trimmed) dmesg splat:

 XFS: Assertion failed: args->total >= dp->i_nblocks - nblks, file: fs/xfs/libxfs/xfs_da_btree.c, line: 2387
 WARNING: fs/xfs/xfs_message.c:104 at assfail+0x46/0x4a [xfs], CPU#0: xfs_scrub/1426511
 CPU: 0 UID: 0 PID: 1426511 Comm: xfs_scrub Tainted: G        W           7.3.0-rc2-djwx #rc2 PREEMPT(lazy)  6e418570b606a39783b0e7e7b30dc407b965f9e8
 Tainted: [W]=WARN
 RIP: 0010:assfail+0x46/0x4a [xfs]
 RSP: 0018:ffffc900010d7890 EFLAGS: 00010246
 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00000000ffffffd1
 RDX: 0000000000000000 RSI: 0000000000000021 RDI: ffffffffa059fd38
 RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000
 R10: 000000000000000a R11: 000000007fffffff R12: ffffc900010d7940
 R13: ffff888368d8f980 R14: ffffc900010d7a48 R15: ffffc900010d78d0
 FS:  00007f445c5ce680(0000) GS:ffff8884a97ea000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: 00007f443803b9a8 CR3: 0000000107a4b000 CR4: 00000000003506f0
 Call Trace:
  <TASK>
  xfs_da_grow_inode_int+0x2e0/0x300 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
  xfs_dir2_grow_inode+0x6e/0x150 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
  xfs_dir2_sf_to_block+0x149/0x870 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
  xrep_dir_swap_prep+0xe2/0x110 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
  xrep_dir_swap+0xfb/0x2f0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
  xrep_dir_rebuild_tree+0x99/0x100 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
  xrep_directory+0x83/0x1c0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
  xrep_attempt+0x4f/0x1e0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
  xfs_scrub_metadata+0x393/0x5b0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
  xfs_ioc_scrubv_metadata+0x306/0x570 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
  xfs_file_ioctl+0xa4f/0x1150 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
  __x64_sys_ioctl+0x76/0xc0
  do_syscall_64+0x7a/0x3b0
  entry_SYSCALL_64_after_hwframe+0x4b/0x53

This is a consequence of commit 0fe77e57588b98, which added the
following assertion to xfs_da_grow_inode_int:

 ASSERT(args->total >= dp->i_nblocks - nblks);

Tracing this back to xrep_dir_swap_prep, I noticed that the xfs_da_args
object that's passed to xfs_dir2_sf_to_block sets args->total to 1.
This is incorrect because mkfs set the directory block size to 8k and
the filesystem block size to 4k.  In other words, args->total should be
2 here, not 1.

Dave Chinner tripped over the same problem with the same branch through
a different channel -- his test setup set the fs block size to 1k, in
which case the directory block size is still set to 4k.  Here,
args->total should be 4.

Changing the assignment of args->total to sc->mp->m_dir_geo->fsbcount
makes the assertion go away, but that isn't a complete fix.  In
xrep_tempexch_estimate, we also incorrectly assume that a shortform
conversion requires 1 fsblock when it should be m_dir_geo->fsbcount.
Without that, we can under-reserve space in the transaction and cause a
filesystem shutdown.

Note that the xfs_dabuf_nfsb helper will compute the correct value for
directories and xattr, so we use that instead of open-coding the logic.
Also fix xrep_xattr_swap_prep to assign args->total via xfs_dabuf_nfsb
to avoid one logic bomb if we ever support multi-fsblock attrs.

Cc: stable@vger.kernel.org # v6.10
Cc: floss@jetm.me
Reported-by: dgc@kernel.org
Fixes: 629fdaf5f5b1b7 ("xfs: use atomic extent swapping to fix user file fork data")
Tripped-by: 0fe77e57588b98 ("xfs: assert the reservation covers each da fork growth")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/libxfs/xfs_da_btree.c |    2 +-
 fs/xfs/libxfs/xfs_da_btree.h |    2 ++
 fs/xfs/scrub/attr_repair.c   |    2 +-
 fs/xfs/scrub/dir_repair.c    |    2 +-
 fs/xfs/scrub/tempfile.c      |   29 ++++++++++++++++++++++-------
 5 files changed, 27 insertions(+), 10 deletions(-)

--- a/fs/xfs/libxfs/xfs_da_btree.c
+++ b/fs/xfs/libxfs/xfs_da_btree.c
@@ -130,7 +130,7 @@ xfs_da_state_reset(
 	state->mp = state->args->dp->i_mount;
 }
 
-static inline int xfs_dabuf_nfsb(struct xfs_mount *mp, int whichfork)
+inline int xfs_dabuf_nfsb(struct xfs_mount *mp, int whichfork)
 {
 	if (whichfork == XFS_DATA_FORK)
 		return mp->m_dir_geo->fsbcount;
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -242,4 +242,6 @@ xfs_failaddr_t xfs_da3_node_header_check
 
 extern struct kmem_cache	*xfs_da_state_cache;
 
+int xfs_dabuf_nfsb(struct xfs_mount *mp, int whichfork);
+
 #endif	/* __XFS_DA_BTREE_H__ */
--- a/fs/xfs/scrub/attr_repair.c
+++ b/fs/xfs/scrub/attr_repair.c
@@ -1294,7 +1294,7 @@ xrep_xattr_swap_prep(
 			.geo		= sc->mp->m_attr_geo,
 			.whichfork	= XFS_ATTR_FORK,
 			.trans		= sc->tp,
-			.total		= 1,
+			.total		= xfs_dabuf_nfsb(sc->mp, XFS_ATTR_FORK),
 			.owner		= I_INO(sc->ip),
 		};
 
--- a/fs/xfs/scrub/dir_repair.c
+++ b/fs/xfs/scrub/dir_repair.c
@@ -1486,7 +1486,7 @@ xrep_dir_swap_prep(
 			.geo		= sc->mp->m_dir_geo,
 			.whichfork	= XFS_DATA_FORK,
 			.trans		= sc->tp,
-			.total		= 1,
+			.total		= xfs_dabuf_nfsb(sc->mp, XFS_DATA_FORK),
 			.owner		= I_INO(sc->ip),
 		};
 
--- a/fs/xfs/scrub/tempfile.c
+++ b/fs/xfs/scrub/tempfile.c
@@ -536,6 +536,19 @@ xrep_tempexch_prep_request(
 	return 0;
 }
 
+static inline unsigned int
+xrep_tempexch_estimate_sf_resblks(
+	struct xfs_scrub	*sc,
+	int			whichfork)
+{
+	/* repairing a symlink target */
+	if (S_ISLNK(VFS_I(sc->ip)->i_mode) && whichfork == XFS_DATA_FORK)
+		return 1;
+
+	/* everything else is a directory or an xattr structure */
+	return xfs_dabuf_nfsb(sc->mp, whichfork);
+}
+
 /*
  * Fill out the mapping exchange resource estimation structures in preparation
  * for exchanging the contents of a metadata file that we've rebuilt in the
@@ -550,6 +563,8 @@ xrep_tempexch_estimate(
 	struct xfs_ifork	*ifp;
 	struct xfs_ifork	*tifp;
 	int			whichfork = xfs_exchmaps_reqfork(req);
+	unsigned int		sf_resblks =
+		xrep_tempexch_estimate_sf_resblks(sc, whichfork);
 	int			state = 0;
 
 	/*
@@ -580,9 +595,9 @@ xrep_tempexch_estimate(
 		 * plus the block we converted.
 		 */
 		req->ip1_bcount = sc->tempip->i_nblocks;
-		req->ip2_bcount = 1;
+		req->ip2_bcount = sf_resblks;
 		req->nr_exchanges = 1 + tifp->if_nextents;
-		req->resblks = 1;
+		req->resblks = sf_resblks;
 		break;
 	case 2:
 		/*
@@ -594,10 +609,10 @@ xrep_tempexch_estimate(
 		 * is (worst case) the extent count of the file being repaired
 		 * plus the block we converted.
 		 */
-		req->ip1_bcount = 1;
+		req->ip1_bcount = sf_resblks;
 		req->ip2_bcount = sc->ip->i_nblocks;
 		req->nr_exchanges = 1 + ifp->if_nextents;
-		req->resblks = 1;
+		req->resblks = sf_resblks;
 		break;
 	case 3:
 		/*
@@ -609,10 +624,10 @@ xrep_tempexch_estimate(
 		 * fileoff 0.  Presumably, the caller could not exchange the
 		 * two inode fork areas directly.
 		 */
-		req->ip1_bcount = 1;
-		req->ip2_bcount = 1;
+		req->ip1_bcount = sf_resblks;
+		req->ip2_bcount = sf_resblks;
 		req->nr_exchanges = 1;
-		req->resblks = 2;
+		req->resblks = 2 * sf_resblks;
 		break;
 	}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 782/877] xfs: fix backwards mergeability logic in refcount scrubber
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (780 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 781/877] xfs: fix under-reservation of blocks when repairing sf directories Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 783/877] cifs: Fix specification of function pointers Greg Kroah-Hartman
                   ` (102 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Darrick J. Wong" <djwong@kernel.org>

[ Upstream commit e8b01aaafffe6b852325debdf1ef4b13ccea1cd7 ]

When we start the refcount or rtrefcount btree scanners, prev_rec is
initialized to all zeroes.  This is done so that the record mergeability
checks skip the first record because you must have two records to
compare.  Unfortunately, I got the logic backwards, so scrub has never
complained about mergeable refcountbt records.  Fix this bug that LOLLM
noticed.

Cc: stable@vger.kernel.org # v6.4
Fixes: db0502b39c21d1 ("xfs: flag refcount btree records that could be merged")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
[ omitted the rtrefcount.c hunk because the file does not exist in Linux 6.12. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/xfs/scrub/refcount.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/xfs/scrub/refcount.c
+++ b/fs/xfs/scrub/refcount.c
@@ -411,7 +411,7 @@ xchk_refcount_mergeable(
 	const struct xfs_refcount_irec	*r1 = &rrc->prev_rec;
 
 	/* Ignore if prev_rec is not yet initialized. */
-	if (r1->rc_blockcount > 0)
+	if (r1->rc_blockcount == 0)
 		return false;
 
 	if (r1->rc_domain != r2->rc_domain)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 783/877] cifs: Fix specification of function pointers
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (781 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 782/877] xfs: fix backwards mergeability logic in refcount scrubber Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 784/877] 9p: Fix v9fs_issue_write() to update i_size and remote_i_size Greg Kroah-Hartman
                   ` (101 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, David Howells,
	Paulo Alcantara (Red Hat), linux-cifs, Steve French, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: David Howells <dhowells@redhat.com>

[ Upstream commit 6a86a4cc281a5cfceda7af60ea6fa506b3db7430 ]

Change the mid_receive_t, mid_callback_t and mid_handle_t function pointers
to have the pointer marker in the typedef.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
cc: linux-cifs@vger.kernel.org
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: c60ae98c5aa6 ("9p: Fix v9fs_issue_write() to update i_size and remote_i_size")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/cifsglob.h  |   12 ++++++------
 fs/smb/client/cifsproto.h |    8 ++++----
 fs/smb/client/transport.c |    4 ++--
 3 files changed, 12 insertions(+), 12 deletions(-)

--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -1619,7 +1619,7 @@ static inline void cifs_stats_bytes_read
  * Returns zero on a successful receive, or an error. The receive state in
  * the TCP_Server_Info will also be updated.
  */
-typedef int (mid_receive_t)(struct TCP_Server_Info *server,
+typedef int (*mid_receive_t)(struct TCP_Server_Info *server,
 			    struct mid_q_entry *mid);
 
 /*
@@ -1630,13 +1630,13 @@ typedef int (mid_receive_t)(struct TCP_S
  * - it will be called by cifsd, with no locks held
  * - the mid will be removed from any lists
  */
-typedef void (mid_callback_t)(struct mid_q_entry *mid);
+typedef void (*mid_callback_t)(struct mid_q_entry *mid);
 
 /*
  * This is the protopyte for mid handle function. This is called once the mid
  * has been recognized after decryption of the message.
  */
-typedef int (mid_handle_t)(struct TCP_Server_Info *server,
+typedef int (*mid_handle_t)(struct TCP_Server_Info *server,
 			    struct mid_q_entry *mid);
 
 /* one of these for every pending CIFS request to the server */
@@ -1654,9 +1654,9 @@ struct mid_q_entry {
 	unsigned long when_sent; /* time when smb send finished */
 	unsigned long when_received; /* when demux complete (taken off wire) */
 #endif
-	mid_receive_t *receive; /* call receive callback */
-	mid_callback_t *callback; /* call completion callback */
-	mid_handle_t *handle; /* call handle mid callback */
+	mid_receive_t receive;	/* call receive callback */
+	mid_callback_t callback; /* call completion callback */
+	mid_handle_t handle;	/* call handle mid callback */
 	void *callback_data;	  /* general purpose pointer for callback */
 	struct task_struct *creator;
 	void *resp_buf;		/* pointer to received SMB header */
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -96,10 +96,10 @@ extern int cifs_ipaddr_cmp(struct sockad
 extern bool cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs);
 extern int cifs_discard_remaining_data(struct TCP_Server_Info *server);
 extern int cifs_call_async(struct TCP_Server_Info *server,
-			struct smb_rqst *rqst,
-			mid_receive_t *receive, mid_callback_t *callback,
-			mid_handle_t *handle, void *cbdata, const int flags,
-			const struct cifs_credits *exist_credits);
+			   struct smb_rqst *rqst,
+			   mid_receive_t receive, mid_callback_t callback,
+			   mid_handle_t handle, void *cbdata, const int flags,
+			   const struct cifs_credits *exist_credits);
 extern struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses);
 extern int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
 			  struct TCP_Server_Info *server,
--- a/fs/smb/client/transport.c
+++ b/fs/smb/client/transport.c
@@ -792,8 +792,8 @@ cifs_setup_async_request(struct TCP_Serv
  */
 int
 cifs_call_async(struct TCP_Server_Info *server, struct smb_rqst *rqst,
-		mid_receive_t *receive, mid_callback_t *callback,
-		mid_handle_t *handle, void *cbdata, const int flags,
+		mid_receive_t receive, mid_callback_t callback,
+		mid_handle_t handle, void *cbdata, const int flags,
 		const struct cifs_credits *exist_credits)
 {
 	int rc;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 784/877] 9p: Fix v9fs_issue_write() to update i_size and remote_i_size
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (782 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 783/877] cifs: Fix specification of function pointers Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 785/877] phy: renesas: rcar-gen3-usb2: Avoid long delay in atomic context Greg Kroah-Hartman
                   ` (100 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Michael Mulqueen, David Howells,
	Dominique Martinet, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: David Howells <dhowells@redhat.com>

[ Upstream commit c60ae98c5aa64021751b38ab1313b19d620bf640 ]

Fix v9fs_issue_write() to update i_size and remote_i_size to the new size
of the server file if we made it larger, using the start fpos and the count
returned by p9_client_write() to calculate the new minimum file size.

This assumes that if the 9P server makes a short write (say it hits
ENOSPC), a reduced count is returned.

Fixes: 5fb70e7275a6 ("netfs, 9p: Implement helpers for new write code")
Reported-by: Michael Mulqueen <mike@method-b.uk>
Closes: https://lore.kernel.org/r/fbb9e395-1e07-4212-8f70-23f3cd498074@method-b.uk/
Cc: stable@vger.kernel.org
Signed-off-by: David Howells <dhowells@redhat.com>
Message-ID: <2226525.1789118704@warthog.procyon.org.uk>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
[ replaced unavailable netfs_write_sizes() with i_size_write() and direct remote_i_size updates under inode->i_lock. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/9p/vfs_addr.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)

--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -54,9 +54,21 @@ static void v9fs_begin_writeback(struct
 static void v9fs_issue_write(struct netfs_io_subrequest *subreq)
 {
 	struct p9_fid *fid = subreq->rreq->netfs_priv;
+	struct inode *inode = subreq->rreq->inode;
+	struct netfs_inode *ictx = netfs_inode(inode);
 	int err, len;
 
 	len = p9_client_write(fid, subreq->start, &subreq->io_iter, &err);
+	if (len > 0) {
+		unsigned long long end = subreq->start + len;
+
+		spin_lock(&inode->i_lock);
+		if (end > i_size_read(inode))
+			i_size_write(inode, end);
+		if (end > ictx->remote_i_size)
+			ictx->remote_i_size = end;
+		spin_unlock(&inode->i_lock);
+	}
 	netfs_write_subrequest_terminated(subreq, len ?: err, false);
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 785/877] phy: renesas: rcar-gen3-usb2: Avoid long delay in atomic context
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (783 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 784/877] 9p: Fix v9fs_issue_write() to update i_size and remote_i_size Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 786/877] ALSA: usb-audio: Optimize the copy of packet sizes for implicit fb handling Greg Kroah-Hartman
                   ` (99 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Pavel Machek, Nobuhiro Iwamatsu,
	Claudiu Beznea, Manivannan Sadhasivam, Vinod Koul, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>

[ Upstream commit 48e97c59a49c9e90270f5e3d221db253b76de5da ]

The OTG PHY initialization sequence needs to wait for 20 ms at a specific
step, as described in commit 72c0339c115b ("phy: renesas:
rcar-gen3-usb2: follow the hardware manual procedure").

Commit 55a387ebb921 ("phy: renesas: rcar-gen3-usb2: Lock around hardware
registers and driver data") tried to address various problems in the
rcar-gen3-usb2 driver and converted the mutex protecting HW register
accesses to a spin lock, leaving, however, a long delay in the critical
section protected by the spin lock. This may become a problem,
especially on RT kernels.

To address this, release the spin lock before sleeping for 20 ms as
required by the HW manual and reacquire it afterwards. To avoid other
threads entering the critical section and configuring the HW while the
software is waiting for the OTG initialization to complete, introduce the
otg_initializing variable alongside the otg_init_done wait queue. Any
other thread trying to configure the HW while the OTG PHY initialization
is in progress waits for the wait queue instead of immediately returning
errors to PHY users. The IRQs were also disabled while waiting for the OTG
PHY initialization to complete, as the interrupt handler may also apply HW
settings.

The OTG can only be initialized once. It is initialized by the first PHY
that calls struct phy_ops::rcar_gen3_phy_usb2_init().

To avoid failures when multiple PHYs call struct
phy_ops::rcar_gen3_phy_usb2_init() simultaneously, and the PHY responsible
for initializing the OTG either fails or deinit quiqly and another PHY
takes over the PHY init role), the code waiting for the
channel->otg_init_done wait queue retries up to NUM_OF_PHYS times.

Fixes: 55a387ebb921 ("phy: renesas: rcar-gen3-usb2: Lock around hardware registers and driver data")
Cc: stable@vger.kernel.org
Reported-by: Pavel Machek <pavel@nabladev.com>
Closes: https://lore.kernel.org/all/afhkX2Ys2BG1gnqy@duo.ucw.cz
Reported-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
Closes: https://lore.kernel.org/all/afhkX2Ys2BG1gnqy@duo.ucw.cz
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Link: https://lore.kernel.org/all/afhkX2Ys2BG1gnqy@duo.ucw.cz
Link: https://patch.msgid.link/20260716183246.3183877-1-claudiu.beznea+renesas@tuxon.dev
Signed-off-by: Vinod Koul <vkoul@kernel.org>
[ adapted newer SoC configuration references to Linux 6.12’s existing channel structure. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/phy/renesas/phy-rcar-gen3-usb2.c |  302 ++++++++++++++++++++++++++-----
 1 file changed, 261 insertions(+), 41 deletions(-)

--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -23,6 +23,7 @@
 #include <linux/reset.h>
 #include <linux/string.h>
 #include <linux/usb/of.h>
+#include <linux/wait.h>
 #include <linux/workqueue.h>
 
 /******* USB2.0 Host registers (original offset is +0x200) *******/
@@ -88,6 +89,13 @@
 #define USB2_OBINT_IDCHG_EN		BIT(0)
 #define USB2_LINECTRL1_USB2_IDMON	BIT(0)
 
+/*
+ * The OTG initialization is expected to finish in 20ms. Choose a large enough
+ * timeout to avoid waiters exit prematurely the waiting section under heavy
+ * CPU load.
+ */
+#define USB2_OTG_INIT_TIMEOUT		msecs_to_jiffies(120)
+
 #define NUM_OF_PHYS			4
 enum rcar_gen3_phy_index {
 	PHY_INDEX_BOTH_HC,
@@ -118,6 +126,7 @@ struct rcar_gen3_chan {
 	struct rcar_gen3_phy rphys[NUM_OF_PHYS];
 	struct regulator *vbus;
 	struct work_struct work;
+	wait_queue_head_t otg_init_done;
 	spinlock_t lock;	/* protects access to hardware and driver data structure. */
 	enum usb_dr_mode dr_mode;
 	u32 obint_enable_bits;
@@ -125,6 +134,13 @@ struct rcar_gen3_chan {
 	bool is_otg_channel;
 	bool uses_otg_pins;
 	bool soc_no_adp_ctrl;
+	/*
+	 * The OTG can be initialized only once and needs to release the spinlock
+	 * and wait for 20 ms due to hardware constraints. If a thread executes
+	 * PHY configuration code while the OTG PHY is waiting for the 20 ms, the
+	 * thread will have to wait for the OTG PHY initialization to complete.
+	 */
+	bool otg_initializing;
 };
 
 struct rcar_gen3_phy_drv_data {
@@ -347,26 +363,58 @@ static ssize_t role_store(struct device
 	struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
 	bool is_b_device;
 	enum phy_mode cur_mode, new_mode;
+	int retries = NUM_OF_PHYS;
+	unsigned long flags;
+	int ret = -EIO;
 
-	guard(spinlock_irqsave)(&ch->lock);
+	spin_lock_irqsave(&ch->lock, flags);
 
-	if (!ch->is_otg_channel || !rcar_gen3_is_any_otg_rphy_initialized(ch))
-		return -EIO;
+	if (!ch->is_otg_channel)
+		goto unlock;
 
-	if (sysfs_streq(buf, "host"))
+	while (retries-- && ch->otg_initializing) {
+		spin_unlock_irqrestore(&ch->lock, flags);
+
+		ret = wait_event_timeout(ch->otg_init_done, !ch->otg_initializing,
+					 USB2_OTG_INIT_TIMEOUT);
+		ret = ret ? 0 : -ETIMEDOUT;
+		if (ret && !retries)
+			goto exit;
+
+		spin_lock_irqsave(&ch->lock, flags);
+	}
+
+	/* If another thread started a new initialization just return -EBUSY. */
+	if (ch->otg_initializing) {
+		ret = -EBUSY;
+		goto unlock;
+	} else {
+		ret = 0;
+	}
+
+	if (!rcar_gen3_is_any_otg_rphy_initialized(ch)) {
+		ret = -EIO;
+		goto unlock;
+	}
+
+	if (sysfs_streq(buf, "host")) {
 		new_mode = PHY_MODE_USB_HOST;
-	else if (sysfs_streq(buf, "peripheral"))
+	} else if (sysfs_streq(buf, "peripheral")) {
 		new_mode = PHY_MODE_USB_DEVICE;
-	else
-		return -EINVAL;
+	} else {
+		ret = -EINVAL;
+		goto unlock;
+	}
 
 	/* is_b_device: true is B-Device. false is A-Device. */
 	is_b_device = rcar_gen3_check_id(ch);
 	cur_mode = rcar_gen3_get_phy_mode(ch);
 
 	/* If current and new mode is the same, this returns the error */
-	if (cur_mode == new_mode)
-		return -EINVAL;
+	if (cur_mode == new_mode) {
+		ret = -EINVAL;
+		goto unlock;
+	}
 
 	if (new_mode == PHY_MODE_USB_HOST) { /* And is_host must be false */
 		if (!is_b_device)	/* A-Peripheral */
@@ -380,7 +428,10 @@ static ssize_t role_store(struct device
 			rcar_gen3_init_for_peri(ch);
 	}
 
-	return count;
+unlock:
+	spin_unlock_irqrestore(&ch->lock, flags);
+exit:
+	return ret ?: count;
 }
 
 static ssize_t role_show(struct device *dev, struct device_attribute *attr,
@@ -396,14 +447,11 @@ static ssize_t role_show(struct device *
 }
 static DEVICE_ATTR_RW(role);
 
-static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
+static void rcar_gen3_init_otg_phase0(struct rcar_gen3_chan *ch)
 {
 	void __iomem *usb2_base = ch->base;
 	u32 val;
 
-	if (!ch->is_otg_channel || rcar_gen3_is_any_otg_rphy_initialized(ch))
-		return;
-
 	/* Should not use functions of read-modify-write a register */
 	val = readl(usb2_base + USB2_LINECTRL1);
 	val = (val & ~USB2_LINECTRL1_DP_RPD) | USB2_LINECTRL1_DPRPD_EN |
@@ -417,7 +465,11 @@ static void rcar_gen3_init_otg(struct rc
 		val = readl(usb2_base + USB2_ADPCTRL);
 		writel(val | USB2_ADPCTRL_IDPULLUP, usb2_base + USB2_ADPCTRL);
 	}
-	mdelay(20);
+}
+
+static void rcar_gen3_init_otg_phase1(struct rcar_gen3_chan *ch)
+{
+	void __iomem *usb2_base = ch->base;
 
 	writel(0xffffffff, usb2_base + USB2_OBINTSTA);
 	writel(ch->obint_enable_bits, usb2_base + USB2_OBINTEN);
@@ -431,6 +483,7 @@ static irqreturn_t rcar_gen3_phy_usb2_ir
 	void __iomem *usb2_base = ch->base;
 	struct device *dev = ch->dev;
 	irqreturn_t ret = IRQ_NONE;
+	unsigned long flags;
 	u32 status;
 
 	pm_runtime_get_noresume(dev);
@@ -438,29 +491,98 @@ static irqreturn_t rcar_gen3_phy_usb2_ir
 	if (pm_runtime_suspended(dev))
 		goto rpm_put;
 
-	scoped_guard(spinlock, &ch->lock) {
-		status = readl(usb2_base + USB2_OBINTSTA);
-		if (status & ch->obint_enable_bits) {
-			dev_vdbg(dev, "%s: %08x\n", __func__, status);
-			writel(ch->obint_enable_bits, usb2_base + USB2_OBINTSTA);
-			rcar_gen3_device_recognition(ch);
-			ret = IRQ_HANDLED;
-		}
+	spin_lock_irqsave(&ch->lock, flags);
+
+	status = readl(usb2_base + USB2_OBINTSTA);
+	if (status & ch->obint_enable_bits) {
+		dev_vdbg(dev, "%s: %08x\n", __func__, status);
+		writel(ch->obint_enable_bits, usb2_base + USB2_OBINTSTA);
+
+		ret = IRQ_HANDLED;
+
+		/* This should not happen! */
+		if (ch->otg_initializing)
+			goto unlock;
+
+		rcar_gen3_device_recognition(ch);
 	}
 
+unlock:
+	spin_unlock_irqrestore(&ch->lock, flags);
 rpm_put:
 	pm_runtime_put_noidle(dev);
 	return ret;
 }
 
+static void rcar_gen3_phy_usb2_irqs_mask_all(struct rcar_gen3_chan *channel,
+					     u32 *masked_irqs_bits)
+{
+	u32 val, bitmask = USB2_INT_ENABLE_UCOM_INTEN;
+	void __iomem *usb2_base = channel->base;
+
+	for (unsigned int i = 0; i < NUM_OF_PHYS; i++)
+		bitmask |= channel->rphys[i].int_enable_bits;
+
+	val = readl(usb2_base + USB2_INT_ENABLE);
+	*masked_irqs_bits = val & bitmask;
+	val &= ~bitmask;
+	writel(val, usb2_base + USB2_INT_ENABLE);
+
+	/*
+	 * Don't report channel->obint_enable_bits IRQs. These are
+	 * unmasked anyway in rcar_gen3_init_otg_phase1().
+	 */
+	val = readl(usb2_base + USB2_OBINTEN);
+	val &= ~channel->obint_enable_bits;
+	writel(val, usb2_base + USB2_OBINTEN);
+}
+
+static void rcar_gen3_phy_usb2_irqs_unmask(struct rcar_gen3_chan *channel,
+					   u32 irqs_bits)
+{
+	u32 val, bitmask = USB2_INT_ENABLE_UCOM_INTEN;
+	void __iomem *usb2_base = channel->base;
+
+	for (unsigned int i = 0; i < NUM_OF_PHYS; i++)
+		bitmask |= channel->rphys[i].int_enable_bits;
+
+	val = readl(usb2_base + USB2_INT_ENABLE);
+	val &= ~bitmask;
+	val |= irqs_bits;
+	writel(val, usb2_base + USB2_INT_ENABLE);
+}
+
 static int rcar_gen3_phy_usb2_init(struct phy *p)
 {
 	struct rcar_gen3_phy *rphy = phy_get_drvdata(p);
 	struct rcar_gen3_chan *channel = rphy->ch;
 	void __iomem *usb2_base = channel->base;
+	int retries = NUM_OF_PHYS;
+	unsigned long flags;
 	u32 val;
+	int ret;
+
+	spin_lock_irqsave(&channel->lock, flags);
+
+	while (retries-- && channel->otg_initializing) {
+		spin_unlock_irqrestore(&channel->lock, flags);
 
-	guard(spinlock_irqsave)(&channel->lock);
+		ret = wait_event_timeout(channel->otg_init_done, !channel->otg_initializing,
+					 USB2_OTG_INIT_TIMEOUT);
+		ret = ret ? 0 : -ETIMEDOUT;
+		if (ret && !retries)
+			return ret;
+
+		spin_lock_irqsave(&channel->lock, flags);
+	}
+
+	/* If another thread started a new initialization just return -EBUSY. */
+	if (channel->otg_initializing) {
+		ret = -EBUSY;
+		goto unlock;
+	} else {
+		ret = 0;
+	}
 
 	/* Initialize USB2 part */
 	val = readl(usb2_base + USB2_INT_ENABLE);
@@ -473,12 +595,30 @@ static int rcar_gen3_phy_usb2_init(struc
 	}
 
 	/* Initialize otg part (only if we initialize a PHY with IRQs). */
-	if (rphy->int_enable_bits)
-		rcar_gen3_init_otg(channel);
+	if (rphy->int_enable_bits && channel->is_otg_channel &&
+	    !rcar_gen3_is_any_otg_rphy_initialized(channel)) {
+		u32 masked_irq_bits = 0;
+
+		rcar_gen3_init_otg_phase0(channel);
+		rcar_gen3_phy_usb2_irqs_mask_all(channel, &masked_irq_bits);
+		channel->otg_initializing = true;
+		spin_unlock_irqrestore(&channel->lock, flags);
+
+		fsleep(20000);
+
+		spin_lock_irqsave(&channel->lock, flags);
+		rcar_gen3_phy_usb2_irqs_unmask(channel, masked_irq_bits);
+		rcar_gen3_init_otg_phase1(channel);
+		channel->otg_initializing = false;
+		wake_up_all(&channel->otg_init_done);
+	}
 
 	rphy->initialized = true;
 
-	return 0;
+unlock:
+	spin_unlock_irqrestore(&channel->lock, flags);
+
+	return ret;
 }
 
 static int rcar_gen3_phy_usb2_exit(struct phy *p)
@@ -486,9 +626,32 @@ static int rcar_gen3_phy_usb2_exit(struc
 	struct rcar_gen3_phy *rphy = phy_get_drvdata(p);
 	struct rcar_gen3_chan *channel = rphy->ch;
 	void __iomem *usb2_base = channel->base;
+	int retries = NUM_OF_PHYS;
+	unsigned long flags;
 	u32 val;
+	int ret;
+
+	spin_lock_irqsave(&channel->lock, flags);
+
+	while (retries-- && channel->otg_initializing) {
+		spin_unlock_irqrestore(&channel->lock, flags);
 
-	guard(spinlock_irqsave)(&channel->lock);
+		ret = wait_event_timeout(channel->otg_init_done, !channel->otg_initializing,
+					 USB2_OTG_INIT_TIMEOUT);
+		ret = ret ? 0 : -ETIMEDOUT;
+		if (ret && !retries)
+			return ret;
+
+		spin_lock_irqsave(&channel->lock, flags);
+	}
+
+	/* If another thread started a new initialization just return -EBUSY. */
+	if (channel->otg_initializing) {
+		ret = -EBUSY;
+		goto unlock;
+	} else {
+		ret = 0;
+	}
 
 	rphy->initialized = false;
 
@@ -498,7 +661,9 @@ static int rcar_gen3_phy_usb2_exit(struc
 		val &= ~USB2_INT_ENABLE_UCOM_INTEN;
 	writel(val, usb2_base + USB2_INT_ENABLE);
 
-	return 0;
+unlock:
+	spin_unlock_irqrestore(&channel->lock, flags);
+	return ret;
 }
 
 static int rcar_gen3_phy_usb2_power_on(struct phy *p)
@@ -506,8 +671,10 @@ static int rcar_gen3_phy_usb2_power_on(s
 	struct rcar_gen3_phy *rphy = phy_get_drvdata(p);
 	struct rcar_gen3_chan *channel = rphy->ch;
 	void __iomem *usb2_base = channel->base;
+	int retries = NUM_OF_PHYS;
+	unsigned long flags;
 	u32 val;
-	int ret = 0;
+	int ret;
 
 	if (channel->vbus) {
 		ret = regulator_enable(channel->vbus);
@@ -515,7 +682,27 @@ static int rcar_gen3_phy_usb2_power_on(s
 			return ret;
 	}
 
-	guard(spinlock_irqsave)(&channel->lock);
+	spin_lock_irqsave(&channel->lock, flags);
+
+	while (retries-- && channel->otg_initializing) {
+		spin_unlock_irqrestore(&channel->lock, flags);
+
+		ret = wait_event_timeout(channel->otg_init_done, !channel->otg_initializing,
+					 USB2_OTG_INIT_TIMEOUT);
+		ret = ret ? 0 : -ETIMEDOUT;
+		if (ret && !retries)
+			goto disable_regulator;
+
+		spin_lock_irqsave(&channel->lock, flags);
+	}
+
+	/* If another thread started a new initialization just return -EBUSY. */
+	if (channel->otg_initializing) {
+		ret = -EBUSY;
+		goto unlock;
+	} else {
+		ret = 0;
+	}
 
 	if (!rcar_gen3_are_all_rphys_power_off(channel))
 		goto out;
@@ -530,27 +717,59 @@ out:
 	/* The powered flag should be set for any other phys anyway */
 	rphy->powered = true;
 
-	return 0;
+unlock:
+	spin_unlock_irqrestore(&channel->lock, flags);
+
+disable_regulator:
+	if (ret && channel->vbus)
+		regulator_disable(channel->vbus);
+
+	return ret;
 }
 
 static int rcar_gen3_phy_usb2_power_off(struct phy *p)
 {
 	struct rcar_gen3_phy *rphy = phy_get_drvdata(p);
 	struct rcar_gen3_chan *channel = rphy->ch;
-	int ret = 0;
+	int retries = NUM_OF_PHYS;
+	unsigned long flags;
+	int ret;
 
-	scoped_guard(spinlock_irqsave, &channel->lock) {
-		rphy->powered = false;
+	spin_lock_irqsave(&channel->lock, flags);
 
-		if (rcar_gen3_are_all_rphys_power_off(channel)) {
-			u32 val = readl(channel->base + USB2_USBCTR);
+	while (retries-- && channel->otg_initializing) {
+		spin_unlock_irqrestore(&channel->lock, flags);
 
-			val |= USB2_USBCTR_PLL_RST;
-			writel(val, channel->base + USB2_USBCTR);
-		}
+		ret = wait_event_timeout(channel->otg_init_done, !channel->otg_initializing,
+					 USB2_OTG_INIT_TIMEOUT);
+		ret = ret ? 0 : -ETIMEDOUT;
+		if (ret && !retries)
+			return ret;
+
+		spin_lock_irqsave(&channel->lock, flags);
+	}
+
+	/* If another thread started a new initialization just return -EBUSY. */
+	if (channel->otg_initializing) {
+		ret = -EBUSY;
+		goto unlock;
+	} else {
+		ret = 0;
+	}
+
+	rphy->powered = false;
+
+	if (rcar_gen3_are_all_rphys_power_off(channel)) {
+		u32 val = readl(channel->base + USB2_USBCTR);
+
+		val |= USB2_USBCTR_PLL_RST;
+		writel(val, channel->base + USB2_USBCTR);
 	}
 
-	if (channel->vbus)
+unlock:
+	spin_unlock_irqrestore(&channel->lock, flags);
+
+	if (!ret && channel->vbus)
 		ret = regulator_disable(channel->vbus);
 
 	return ret;
@@ -774,6 +993,7 @@ static int rcar_gen3_phy_usb2_probe(stru
 		channel->obint_enable_bits = USB2_OBINT_IDCHG_EN;
 
 	spin_lock_init(&channel->lock);
+	init_waitqueue_head(&channel->otg_init_done);
 	for (i = 0; i < NUM_OF_PHYS; i++) {
 		channel->rphys[i].phy = devm_phy_create(dev, NULL,
 							phy_data->phy_usb2_ops);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 786/877] ALSA: usb-audio: Optimize the copy of packet sizes for implicit fb handling
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (784 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 785/877] phy: renesas: rcar-gen3-usb2: Avoid long delay in atomic context Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 787/877] ALSA: usb-audio: Clamp implicit feedback packet count to URB capacity Greg Kroah-Hartman
                   ` (98 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Takashi Iwai, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <tiwai@suse.de>

[ Upstream commit 36adb51ac0b19edb32ffeea3fe66b174bad25ead ]

We did manual copies over loop for the packet data update of the
implicit feedback, but this can be optimized with a simple memcpy().

Along with it, change the data type of snd_usb_packet_info struct to
align with other (from uint32_t to int).

No functional changes but only code optimizations.

Link: https://patch.msgid.link/20260216141209.1849200-3-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Stable-dep-of: 76a986c980bb ("ALSA: usb-audio: Clamp implicit feedback packet count to URB capacity")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 sound/usb/card.h     |    2 +-
 sound/usb/endpoint.c |    6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -89,7 +89,7 @@ struct snd_usb_endpoint {
 	struct snd_urb_ctx urb[MAX_URBS];
 
 	struct snd_usb_packet_info {
-		uint32_t packet_size[MAX_PACKS_HS];
+		int packet_size[MAX_PACKS_HS];
 		int packets;
 	} next_packet[MAX_URBS];
 	unsigned int next_packet_head;	/* ring buffer offset to read */
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -478,7 +478,7 @@ int snd_usb_queue_pending_output_urbs(st
 		unsigned long flags;
 		struct snd_usb_packet_info *packet;
 		struct snd_urb_ctx *ctx = NULL;
-		int err, i;
+		int err;
 
 		spin_lock_irqsave(&ep->lock, flags);
 		if ((!implicit_fb || ep->next_packet_queued > 0) &&
@@ -498,8 +498,8 @@ int snd_usb_queue_pending_output_urbs(st
 		/* copy over the length information */
 		if (implicit_fb) {
 			ctx->packets = packet->packets;
-			for (i = 0; i < packet->packets; i++)
-				ctx->packet_size[i] = packet->packet_size[i];
+			memcpy(ctx->packet_size, packet->packet_size,
+			       packet->packets * sizeof(packet->packet_size[0]));
 		}
 
 		/* call the data handler to fill in playback data */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 787/877] ALSA: usb-audio: Clamp implicit feedback packet count to URB capacity
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (785 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 786/877] ALSA: usb-audio: Optimize the copy of packet sizes for implicit fb handling Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 788/877] swiotlb: use the adjusted address for the highmem page lookup Greg Kroah-Hartman
                   ` (97 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, co+8eacd4fa193b1b28, Xiang Mei,
	Takashi Iwai, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Xiang Mei <xmei5@asu.edu>

[ Upstream commit 76a986c980bb502c7688d605ac7a67fd257a9a1b ]

data_ep_set_params() allocates each data URB for exactly u->packets
isochronous frames, so urb->iso_frame_desc[] has u->packets slots and
ctx->packets is the driver's only record of that limit. For an implicit
feedback sink, snd_usb_queue_pending_output_urbs() overwrites it with the
sync source's packet count, which is calculated independently from the
capture endpoint's parameters. When that count is larger,
prepare_playback_urb() and prepare_silent_urb() can write
iso_frame_desc[] past the allocation; their existing bounds limit payload
bytes, not the descriptor index.

The reproducer uses a high-speed UAC2 device declaring bInterval 1 for
implicit feedback capture (8 packets) and bInterval 4 for playback
(1 packet). On the first capture completion after the stream starts, it
accesses seven descriptors spanning 112 bytes beyond the one-packet URB:

  BUG: KASAN: slab-out-of-bounds in prepare_playback_urb (sound/usb/pcm.c:1560)
  Write of size 4 at addr ffff88801e696ad0 by task vhci_rx/178
   prepare_playback_urb (sound/usb/pcm.c:1560)
   prepare_outbound_urb (sound/usb/endpoint.c:340)
   snd_usb_queue_pending_output_urbs (sound/usb/endpoint.c:501)
   snd_complete_urb (sound/usb/endpoint.c:1834)
   __usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1657)
   usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1741)
   vhci_rx_loop (drivers/usb/usbip/vhci_rx.c:107)
   kthread (kernel/kthread.c:436)
  The buggy address belongs to the object at ffff88801e696a00
   which belongs to the cache kmalloc-256 of size 256
  The buggy address is located 0 bytes to the right of
   allocated 208-byte region [ffff88801e696a00, ffff88801e696ad0)

Record the allocated packet count per endpoint and clamp both the adopted
count and the packet-size copy to it. Fold the Format Type II delimiter
into urb_packs before the allocation loop so the recorded limit matches
every URB.

Fixes: cf044e441902 ("ALSA: usb-audio: Update the number of packets properly at receiving")
Reported-by: co+8eacd4fa193b1b28@bugs.sh
Closes: https://lore.kernel.org/all/22xPn8drvIUtYgVeQnBiNqXuevOTpBAjepLz%40bugs.sh/
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Xiang Mei <xmei5@asu.edu>
Link: https://patch.msgid.link/20260912200530.1955491-1-xmei5@asu.edu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 sound/usb/card.h     |    1 +
 sound/usb/endpoint.c |   12 +++++++-----
 2 files changed, 8 insertions(+), 5 deletions(-)

--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -115,6 +115,7 @@ struct snd_usb_endpoint {
 	unsigned int phase;		/* phase accumulator */
 	unsigned int maxpacksize;	/* max packet size in bytes */
 	unsigned int maxframesize;      /* max packet size in frames */
+	unsigned int max_urb_packs;	/* packets allocated per data URB */
 	unsigned int max_urb_frames;	/* max URB size in frames */
 	unsigned int curpacksize;	/* current packet size in bytes (for capture) */
 	unsigned int curframesize;      /* current packet size in frames (for capture) */
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -497,9 +497,10 @@ int snd_usb_queue_pending_output_urbs(st
 
 		/* copy over the length information */
 		if (implicit_fb) {
-			ctx->packets = packet->packets;
+			ctx->packets = min_t(int, packet->packets,
+					     ep->max_urb_packs);
 			memcpy(ctx->packet_size, packet->packet_size,
-			       packet->packets * sizeof(packet->packet_size[0]));
+			       ctx->packets * sizeof(packet->packet_size[0]));
 		}
 
 		/* call the data handler to fill in playback data */
@@ -1259,15 +1260,16 @@ static int data_ep_set_params(struct snd
 		ep->nurbs = min(max_urbs, urbs_per_period * ep->cur_buffer_periods);
 	}
 
+	if (fmt->fmt_type == UAC_FORMAT_TYPE_II)
+		urb_packs++; /* for transfer delimiter */
+	ep->max_urb_packs = urb_packs;
+
 	/* allocate and initialize data urbs */
 	for (i = 0; i < ep->nurbs; i++) {
 		struct snd_urb_ctx *u = &ep->urb[i];
 		u->index = i;
 		u->ep = ep;
 		u->packets = urb_packs;
-
-		if (fmt->fmt_type == UAC_FORMAT_TYPE_II)
-			u->packets++; /* for transfer delimiter */
 		u->buffer_size = maxsize * u->packets;
 		u->urb = usb_alloc_urb(u->packets, GFP_KERNEL);
 		if (!u->urb)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 788/877] swiotlb: use the adjusted address for the highmem page lookup
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (786 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 787/877] ALSA: usb-audio: Clamp implicit feedback packet count to URB capacity Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 789/877] net: phy: mediatek: do not report link and per-speed LED rules together Greg Kroah-Hartman
                   ` (96 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Michael Kelley,
	Marek Szyprowski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>

[ Upstream commit b7d7914a9ae3097e63d113007e4fb44d33d515b1 ]

swiotlb_bounce() reads the page frame number from the slot's recorded
orig_addr, then advances orig_addr by tlb_offset to reach the address
the caller asked about. The highmem branch mixes the two: the offset
within the page comes from the adjusted address, the page from the value
before it.

Once the adjustment crosses a page boundary the pair no longer describes
one location, and the whole copy lands one page below the intended one
for a positive tlb_offset, one above for a negative one. DMA_FROM_DEVICE
writes the device data over the wrong page and leaves the intended one
stale, DMA_TO_DEVICE feeds the device from a page the mapping may not
cover. Partial syncs through dma_sync_single_range_for_*() are what make
tlb_offset non-zero.

The branch test is picked the same way, so a slot recorded in lowmem can
be adjusted into highmem and the lowmem path then hands a highmem
address to phys_to_virt().

Take both from orig_addr once it is final and keep pfn in the branch
that uses it. PhysHighMem() asks the question straight from the address,
as dma-debug already does.

Fixes: 5f89468e2f06 ("swiotlb: manipulate orig_addr when tlb_addr has offset")
Cc: stable@vger.kernel.org
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Link: https://lore.kernel.org/r/20260905084210.148255-1-donggeunyoo.kernel@gmail.com
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
[ replaced unavailable PhysHighMem(orig_addr) with PageHighMem(pfn_to_page(PFN_DOWN(orig_addr))). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/dma/swiotlb.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -869,7 +869,6 @@ static void swiotlb_bounce(struct device
 	int index = (tlb_addr - mem->start) >> IO_TLB_SHIFT;
 	phys_addr_t orig_addr = mem->slots[index].orig_addr;
 	size_t alloc_size = mem->slots[index].alloc_size;
-	unsigned long pfn = PFN_DOWN(orig_addr);
 	unsigned char *vaddr = mem->vaddr + tlb_addr - mem->start;
 	int tlb_offset;
 
@@ -899,7 +898,8 @@ static void swiotlb_bounce(struct device
 		size = alloc_size;
 	}
 
-	if (PageHighMem(pfn_to_page(pfn))) {
+	if (PageHighMem(pfn_to_page(PFN_DOWN(orig_addr)))) {
+		unsigned long pfn = PFN_DOWN(orig_addr);
 		unsigned int offset = orig_addr & ~PAGE_MASK;
 		struct page *page;
 		unsigned int sz = 0;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 789/877] net: phy: mediatek: do not report link and per-speed LED rules together
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (787 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 788/877] swiotlb: use the adjusted address for the highmem page lookup Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 790/877] btrfs: take commit root semaphore when iterating in mark_block_group_to_copy() Greg Kroah-Hartman
                   ` (95 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ahmed Naseef, Andrew Lunn,
	Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ahmed Naseef <naseefkm@gmail.com>

[ Upstream commit bde5212360bd44506edec073ebbd6d0c72f75820 ]

mtk_phy_led_hw_ctrl_get() reports TRIGGER_NETDEV_LINK whenever any of the
speed bits in on_set is on, and in addition reports every individual
TRIGGER_NETDEV_LINK_* bit that is set. The netdev trigger refuses that
combination: netdev_led_attr_store() rejects TRIGGER_NETDEV_LINK together
with any per-speed rule, and it validates the whole resulting mode rather
than just the bit being written. Once the hardware has any link bit
programmed, every write to the trigger attributes of that LED therefore
fails with -EINVAL and the LED can no longer be configured.

The rules are also fed back into the hardware: the trigger stores what is
read back, and a later write of device_name programs it again, expanding
TRIGGER_NETDEV_LINK to every speed in on_set. An LED configured for a
single speed is thereby silently widened to "on at any link speed".

Both are easy to see on the EcoNet EN7528, whose four PHYs share one LED
block. The first LED programs the block correctly, the second reads those
rules back and rewrites them widened, and the remaining two then read the
widened value, so an LED configured for "link_10 link_100" ends up lit on a
1000 Mbps link.

on_set holds every speed the LED can indicate and is exactly what
mtk_phy_led_hw_ctrl_set() programs for TRIGGER_NETDEV_LINK, so report the
speed independent rule only when all of them are on, and the individual
speeds otherwise. The mapping is then the inverse of the one used when
programming the LED and round trips without changing the register.

Fixes: c66937b0f8db ("net: phy: mediatek-ge-soc: support PHY LEDs")
Cc: stable@vger.kernel.org
Signed-off-by: Ahmed Naseef <naseefkm@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/20260912134306.3544329-1-naseefkm@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ adapted the LED helper changes to the existing gigabit-only implementation in mtk-ge-soc.c. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/phy/mediatek/mtk-ge-soc.c |   23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

--- a/drivers/net/phy/mediatek/mtk-ge-soc.c
+++ b/drivers/net/phy/mediatek/mtk-ge-soc.c
@@ -1276,17 +1276,24 @@ static int mt798x_phy_led_hw_control_get
 	if (!rules)
 		return 0;
 
-	if (on & MTK_PHY_LED_ON_LINK)
+	/* TRIGGER_NETDEV_LINK must not be reported together with any of the
+	 * per-speed rules, the netdev trigger rejects that combination.
+	 * MTK_PHY_LED_ON_LINK holds every speed this LED can indicate and is what
+	 * mt798x_phy_led_hw_control_set() programs for TRIGGER_NETDEV_LINK, so
+	 * report the speed independent rule only when they are all on.
+	 */
+	if ((on & MTK_PHY_LED_ON_LINK) == MTK_PHY_LED_ON_LINK) {
 		*rules |= BIT(TRIGGER_NETDEV_LINK);
+	} else {
+		if (on & MTK_PHY_LED_ON_LINK10)
+			*rules |= BIT(TRIGGER_NETDEV_LINK_10);
 
-	if (on & MTK_PHY_LED_ON_LINK10)
-		*rules |= BIT(TRIGGER_NETDEV_LINK_10);
+		if (on & MTK_PHY_LED_ON_LINK100)
+			*rules |= BIT(TRIGGER_NETDEV_LINK_100);
 
-	if (on & MTK_PHY_LED_ON_LINK100)
-		*rules |= BIT(TRIGGER_NETDEV_LINK_100);
-
-	if (on & MTK_PHY_LED_ON_LINK1000)
-		*rules |= BIT(TRIGGER_NETDEV_LINK_1000);
+		if (on & MTK_PHY_LED_ON_LINK1000)
+			*rules |= BIT(TRIGGER_NETDEV_LINK_1000);
+	}
 
 	if (on & MTK_PHY_LED_ON_FDX)
 		*rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 790/877] btrfs: take commit root semaphore when iterating in mark_block_group_to_copy()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (788 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 789/877] net: phy: mediatek: do not report link and per-speed LED rules together Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 791/877] arm64: Use load LSE atomics for the non-return per-CPU atomic operations Greg Kroah-Hartman
                   ` (94 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Johannes Thumshirn, Hongling Zeng,
	David Sterba, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Hongling Zeng <zenghongling@kylinos.cn>

[ Upstream commit 0594e3423f4ba3137c734371169491f9a98e9af4 ]

mark_block_group_to_copy() iterates over the commit root with
skip_locking=true. A concurrent transaction commit can swap and free
the commit root during iteration, causing use-after-free when
accessing extent buffers.

Fix it by using path->need_commit_sem to protect the commit root search.

Fixes: 78ce9fc269af ("btrfs: zoned: mark block groups to copy for device-replace")
CC: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.5
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
[ changed path->need_commit_sem assignment from true to 1 to match the older unsigned bitfield representation. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/btrfs/dev-replace.c |    1 +
 1 file changed, 1 insertion(+)

--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -505,6 +505,7 @@ static int mark_block_group_to_copy(stru
 	path->reada = READA_FORWARD;
 	path->search_commit_root = 1;
 	path->skip_locking = 1;
+	path->need_commit_sem = 1;
 
 	key.objectid = src_dev->devid;
 	key.type = BTRFS_DEV_EXTENT_KEY;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 791/877] arm64: Use load LSE atomics for the non-return per-CPU atomic operations
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (789 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 790/877] btrfs: take commit root semaphore when iterating in mark_block_group_to_copy() Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 792/877] arm64: percpu: Fix LSE operations on {8,16}-bit types Greg Kroah-Hartman
                   ` (93 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Catalin Marinas, Paul E. McKenney,
	Will Deacon, Palmer Dabbelt, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Catalin Marinas <catalin.marinas@arm.com>

[ Upstream commit 535fdfc5a228524552ee8810c9175e877e127c27 ]

The non-return per-CPU this_cpu_*() atomic operations are implemented as
STADD/STCLR/STSET when FEAT_LSE is available. On many microarchitecture
implementations, these instructions tend to be executed "far" in the
interconnect or memory subsystem (unless the data is already in the L1
cache). This is in general more efficient when there is contention as it
avoids bouncing cache lines between CPUs. The load atomics (e.g. LDADD
without XZR as destination), OTOH, tend to be executed "near" with the
data loaded into the L1 cache.

STADD executed back to back as in srcu_read_{lock,unlock}*() incur an
additional overhead due to the default posting behaviour on several CPU
implementations. Since the per-CPU atomics are unlikely to be used
concurrently on the same memory location, encourage the hardware to to
execute them "near" by issuing load atomics - LDADD/LDCLR/LDSET - with
the destination register unused (but not XZR).

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/e7d539ed-ced0-4b96-8ecd-048a5b803b85@paulmck-laptop
Reported-by: Paul E. McKenney <paulmck@kernel.org>
Tested-by: Paul E. McKenney <paulmck@kernel.org>
Cc: Will Deacon <will@kernel.org>
Reviewed-by: Palmer Dabbelt <palmer@dabbelt.com>
[will: Add comment and link to the discussion thread]
Signed-off-by: Will Deacon <will@kernel.org>
Stable-dep-of: 8cf2093f5372 ("arm64: percpu: Fix LSE operations on {8,16}-bit types")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/arm64/include/asm/percpu.h |   15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

--- a/arch/arm64/include/asm/percpu.h
+++ b/arch/arm64/include/asm/percpu.h
@@ -77,7 +77,7 @@ __percpu_##name##_case_##sz(void *ptr, u
 	"	stxr" #sfx "\t%w[loop], %" #w "[tmp], %[ptr]\n"		\
 	"	cbnz	%w[loop], 1b",					\
 	/* LSE atomics */						\
-		#op_lse "\t%" #w "[val], %[ptr]\n"			\
+		#op_lse "\t%" #w "[val], %" #w "[tmp], %[ptr]\n"	\
 		__nops(3))						\
 	: [loop] "=&r" (loop), [tmp] "=&r" (tmp),			\
 	  [ptr] "+Q"(*(u##sz *)ptr)					\
@@ -124,9 +124,16 @@ PERCPU_RW_OPS(8)
 PERCPU_RW_OPS(16)
 PERCPU_RW_OPS(32)
 PERCPU_RW_OPS(64)
-PERCPU_OP(add, add, stadd)
-PERCPU_OP(andnot, bic, stclr)
-PERCPU_OP(or, orr, stset)
+
+/*
+ * Use value-returning atomics for CPU-local ops as they are more likely
+ * to execute "near" to the CPU (e.g. in L1$).
+ *
+ * https://lore.kernel.org/r/e7d539ed-ced0-4b96-8ecd-048a5b803b85@paulmck-laptop
+ */
+PERCPU_OP(add, add, ldadd)
+PERCPU_OP(andnot, bic, ldclr)
+PERCPU_OP(or, orr, ldset)
 PERCPU_RET_OP(add, add, ldadd)
 
 #undef PERCPU_RW_OPS



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 792/877] arm64: percpu: Fix LSE operations on {8,16}-bit types
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (790 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 791/877] arm64: Use load LSE atomics for the non-return per-CPU atomic operations Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 793/877] i2c: qcom-cci: Stop complaining about DT set clock rate Greg Kroah-Hartman
                   ` (92 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Mark Rutland, Jinjie Ruan,
	Ada Couprie Diaz, Ard Biesheuvel, Catalin Marinas, James Morse,
	Marc Zyngier, Peter Zijlstra, Vladimir Murzin, Will Deacon,
	Yang Shi, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mark Rutland <mark.rutland@arm.com>

[ Upstream commit 8cf2093f5372952a9ebc805c418d45df7112cd14 ]

The assembly for __percpu_##name##_case_##sz() and
__percpu_##name##_return_case_##sz() doesn't use the 'sfx' macro
argument to form the LSE instruction. Without 'sfx', a W register
argument will imply a 32-bit memory location, and consequently
{8,16}-bit ops will erroneously read and write 32 bits of memory when
the LSE instruction is used.

Fix this by appending 'sfx' to 'op_lse' to LSE instruction. It is not
necessary (and not valid) to append 'sfx' to 'op_llsc', as 'op_llsc' is
a register-register operation which does not access memory (and does not
take a size suffix).

Fixes: 959bf2fd03b5 ("arm64: percpu: Rewrite per-cpu ops to allow use of LSE atomics")
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Reviewed-by: Jinjie Ruan <ruanjinjie@huawei.com>
Cc: Ada Couprie Diaz <ada.coupriediaz@arm.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Vladimir Murzin <vladimir.murzin@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Yang Shi <yang@os.amperecomputing.com>
Cc: stable@vger.kernel.org
Reviewed-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/arm64/include/asm/percpu.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/arch/arm64/include/asm/percpu.h
+++ b/arch/arm64/include/asm/percpu.h
@@ -77,7 +77,7 @@ __percpu_##name##_case_##sz(void *ptr, u
 	"	stxr" #sfx "\t%w[loop], %" #w "[tmp], %[ptr]\n"		\
 	"	cbnz	%w[loop], 1b",					\
 	/* LSE atomics */						\
-		#op_lse "\t%" #w "[val], %" #w "[tmp], %[ptr]\n"	\
+		#op_lse #sfx "\t%" #w "[val], %" #w "[tmp], %[ptr]\n"	\
 		__nops(3))						\
 	: [loop] "=&r" (loop), [tmp] "=&r" (tmp),			\
 	  [ptr] "+Q"(*(u##sz *)ptr)					\
@@ -98,7 +98,7 @@ __percpu_##name##_return_case_##sz(void
 	"	stxr" #sfx "\t%w[loop], %" #w "[ret], %[ptr]\n"		\
 	"	cbnz	%w[loop], 1b",					\
 	/* LSE atomics */						\
-		#op_lse "\t%" #w "[val], %" #w "[ret], %[ptr]\n"	\
+		#op_lse #sfx "\t%" #w "[val], %" #w "[ret], %[ptr]\n"	\
 		#op_llsc "\t%" #w "[ret], %" #w "[ret], %" #w "[val]\n"	\
 		__nops(2))						\
 	: [loop] "=&r" (loop), [ret] "=&r" (ret),			\



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 793/877] i2c: qcom-cci: Stop complaining about DT set clock rate
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (791 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 792/877] arm64: percpu: Fix LSE operations on {8,16}-bit types Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 794/877] i2c: qcom-cci: Remove the unused variable cci_clk_rate Greg Kroah-Hartman
                   ` (91 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bryan ODonoghue, Vladimir Zapolskiy,
	Richard Acayan, Andi Shyti, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bryan O'Donoghue <bryan.odonoghue@linaro.org>

[ Upstream commit 8284750a182937bf805f703311501730f02eb40e ]

It is common practice in the downstream and upstream CCI dt to set CCI
clock rates to 19.2 MHz. It appears to be fairly common for initial code to
set the CCI clock rate to 37.5 MHz.

Applying the widely used CCI clock rates from downstream ought not to cause
warning messages in the upstream kernel where our general policy is to
usually copy downstream hardware clock rates across the range of Qualcomm
drivers.

Drop the warning it is pervasive across CAMSS users but doesn't add any
information or warrant any changes to the DT to align the DT clock rate to
the bootloader clock rate.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Link: https://lore.kernel.org/linux-arm-msm/20240824115900.40702-1-bryan.odonoghue@linaro.org
Signed-off-by: Richard Acayan <mailingradian@gmail.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Stable-dep-of: 7362a1553eb0 ("i2c: qcom-cci: fix device_node refcount leak in cci_probe()/cci_remove()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/i2c/busses/i2c-qcom-cci.c |    8 --------
 1 file changed, 8 deletions(-)

--- a/drivers/i2c/busses/i2c-qcom-cci.c
+++ b/drivers/i2c/busses/i2c-qcom-cci.c
@@ -602,14 +602,6 @@ static int cci_probe(struct platform_dev
 		}
 	}
 
-	if (cci_clk_rate != cci->data->cci_clk_rate) {
-		/* cci clock set by the bootloader or via assigned clock rate
-		 * in DT.
-		 */
-		dev_warn(dev, "Found %lu cci clk rate while %lu was expected\n",
-			 cci_clk_rate, cci->data->cci_clk_rate);
-	}
-
 	ret = cci_enable_clocks(cci);
 	if (ret < 0)
 		return ret;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 794/877] i2c: qcom-cci: Remove the unused variable cci_clk_rate
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (792 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 793/877] i2c: qcom-cci: Stop complaining about DT set clock rate Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 795/877] i2c: qcom-cci: fix device_node refcount leak in cci_probe()/cci_remove() Greg Kroah-Hartman
                   ` (90 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Abaci Robot, Jiapeng Chong,
	Dmitry Baryshkov, Vladimir Zapolskiy, Andi Shyti, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>

[ Upstream commit b88c79699d72caa947ecaae85839b3563662ccce ]

Variable cci_clk_rate is not effectively used, so delete it.

drivers/i2c/busses/i2c-qcom-cci.c:526:16: warning: variable ‘cci_clk_rate’ set but not used.

Reported-by: Abaci Robot <abaci@linux.alibaba.com>
Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=11532
Fixes: 8284750a1829 ("i2c: qcom-cci: Stop complaining about DT set clock rate")
Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Stable-dep-of: 7362a1553eb0 ("i2c: qcom-cci: fix device_node refcount leak in cci_probe()/cci_remove()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/i2c/busses/i2c-qcom-cci.c |    9 ---------
 1 file changed, 9 deletions(-)

--- a/drivers/i2c/busses/i2c-qcom-cci.c
+++ b/drivers/i2c/busses/i2c-qcom-cci.c
@@ -523,7 +523,6 @@ static const struct dev_pm_ops qcom_cci_
 static int cci_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	unsigned long cci_clk_rate = 0;
 	struct device_node *child;
 	struct resource *r;
 	struct cci *cci;
@@ -594,14 +593,6 @@ static int cci_probe(struct platform_dev
 		return dev_err_probe(dev, -EINVAL, "not enough clocks in DT\n");
 	cci->nclocks = ret;
 
-	/* Retrieve CCI clock rate */
-	for (i = 0; i < cci->nclocks; i++) {
-		if (!strcmp(cci->clocks[i].id, "cci")) {
-			cci_clk_rate = clk_get_rate(cci->clocks[i].clk);
-			break;
-		}
-	}
-
 	ret = cci_enable_clocks(cci);
 	if (ret < 0)
 		return ret;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 795/877] i2c: qcom-cci: fix device_node refcount leak in cci_probe()/cci_remove()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (793 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 794/877] i2c: qcom-cci: Remove the unused variable cci_clk_rate Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 796/877] scsi: fnic: Fix missed link-up when critical IRQ targets offline CPU Greg Kroah-Hartman
                   ` (89 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Konrad Dybcio, Liu Zhenlong,
	Vladimir Zapolskiy, Andi Shyti, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Liu Zhenlong <dragonliu2018@gmail.com>

[ Upstream commit 7362a1553eb09a8cdf8be7e509bd5309a8342486 ]

The of_node_put() matching of_node_get() runs after i2c_del_adapter(),
whose trailing memset() zeroes adap->dev and thus adap->dev.of_node,
making the put a no-op and leaking the node on every adapter removal
and error cleanup.

Use a devm action: the pointer is captured at registration, out of
reach of that memset(), and devres runs the put once on probe failure
and detach, replacing the three manual of_node_put() calls.  The
setup loop uses the scoped iterator form so the child node is released
automatically if devm_add_action_or_reset() fails mid-loop.

Suggested-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Fixes: 02a4a69667a2 ("i2c: qcom-cci: don't put a device tree node before i2c_add_adapter()")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Liu Zhenlong <dragonliu2018@gmail.com>
Cc: <stable@vger.kernel.org> # v5.17+
Reviewed-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260818175750.4205-1-dragonliu2018@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/i2c/busses/i2c-qcom-cci.c |   20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

--- a/drivers/i2c/busses/i2c-qcom-cci.c
+++ b/drivers/i2c/busses/i2c-qcom-cci.c
@@ -520,10 +520,14 @@ static const struct dev_pm_ops qcom_cci_
 	SET_RUNTIME_PM_OPS(cci_suspend_runtime, cci_resume_runtime, NULL)
 };
 
+static void cci_put_of_node(void *data)
+{
+	of_node_put(data);
+}
+
 static int cci_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct device_node *child;
 	struct resource *r;
 	struct cci *cci;
 	int ret, i;
@@ -539,7 +543,7 @@ static int cci_probe(struct platform_dev
 	if (!cci->data)
 		return -ENOENT;
 
-	for_each_available_child_of_node(dev->of_node, child) {
+	for_each_available_child_of_node_scoped(dev->of_node, child) {
 		struct cci_master *master;
 		u32 idx;
 
@@ -560,6 +564,9 @@ static int cci_probe(struct platform_dev
 		master->adap.algo = &cci_algo;
 		master->adap.dev.parent = dev;
 		master->adap.dev.of_node = of_node_get(child);
+		ret = devm_add_action_or_reset(dev, cci_put_of_node, child);
+		if (ret)
+			return ret;
 		master->master = idx;
 		master->cci = cci;
 
@@ -631,10 +638,8 @@ static int cci_probe(struct platform_dev
 			continue;
 
 		ret = i2c_add_adapter(&cci->master[i].adap);
-		if (ret < 0) {
-			of_node_put(cci->master[i].adap.dev.of_node);
+		if (ret < 0)
 			goto error_i2c;
-		}
 	}
 
 	return 0;
@@ -644,10 +649,8 @@ error_i2c:
 	pm_runtime_dont_use_autosuspend(dev);
 
 	for (--i ; i >= 0; i--) {
-		if (cci->master[i].cci) {
+		if (cci->master[i].cci)
 			i2c_del_adapter(&cci->master[i].adap);
-			of_node_put(cci->master[i].adap.dev.of_node);
-		}
 	}
 error:
 	disable_irq(cci->irq);
@@ -665,7 +668,6 @@ static void cci_remove(struct platform_d
 	for (i = 0; i < cci->data->num_masters; i++) {
 		if (cci->master[i].cci) {
 			i2c_del_adapter(&cci->master[i].adap);
-			of_node_put(cci->master[i].adap.dev.of_node);
 			cci_halt(cci, i);
 		}
 	}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 796/877] scsi: fnic: Fix missed link-up when critical IRQ targets offline CPU
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (794 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 795/877] i2c: qcom-cci: fix device_node refcount leak in cci_probe()/cci_remove() Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 797/877] Input: hp_sdc - shut down kicker timer on module exit Greg Kroah-Hartman
                   ` (88 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sesidhar Baddela,
	Arulprabhu Ponnusamy, Gian Carlo Boffa, Karan Tilak Kumar,
	Arun Easi, Laurence Oberman, Martin K. Petersen (Oracle),
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Arun Easi <aeasi@cisco.com>

[ Upstream commit 0cb1fd924126f1f581621a5e804df98a02be9dff ]

When CPU Hyper Threading is disabled, sibling CPUs remain present but
are reported offline. Managed MSI-X IRQs can still receive affinity
masks that include those offline CPUs. If a driver-critical vector is
managed, it can be parked on an offline CPU and the driver may miss
critical events such as link-up.

Keep driver-critical vectors unmanaged so they can be migrated by the
IRQ core when their target CPU is offlined.

Since HWQ-0 is unmanaged now, in some queue combinations there can be no
mappings to it in mq_map. So without the blk-mq fix mentioned below,
system may crash during cpu offline/online tests.

Fixes: 8a8449ca5e33 ("scsi: fnic: Modify ISRs to support multiqueue (MQ)")
Cc: stable@vger.kernel.org
Depends-on: commit 10845a105bbc ("blk-mq: skip CPU offline notify on unmapped hctx")
Reviewed-by: Sesidhar Baddela <sebaddel@cisco.com>
Reviewed-by: Arulprabhu Ponnusamy <arulponn@cisco.com>
Reviewed-by: Gian Carlo Boffa <gcboffa@cisco.com>
Reviewed-by: Karan Tilak Kumar <kartilak@cisco.com>
Signed-off-by: Arun Easi <aeasi@cisco.com>
Reviewed-by: Laurence Oberman <loberman@redhat.com>
Link: https://patch.msgid.link/20260903175547.57971-1-aeasi@cisco.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ inlined upstream’s queue-mapping initialization helper into the existing fnic mapping function. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/scsi/fnic/fnic.h      |    2 +-
 drivers/scsi/fnic/fnic_isr.c  |   13 ++++++++++---
 drivers/scsi/fnic/fnic_main.c |   33 ++++++++++++++++++++++++++++++++-
 3 files changed, 43 insertions(+), 5 deletions(-)

--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -27,7 +27,7 @@
 
 #define DRV_NAME		"fnic"
 #define DRV_DESCRIPTION		"Cisco FCoE HBA Driver"
-#define DRV_VERSION		"1.7.0.0"
+#define DRV_VERSION		"1.7.0.1"
 #define PFX			DRV_NAME ": "
 #define DFX                     DRV_NAME "%d: "
 
--- a/drivers/scsi/fnic/fnic_isr.c
+++ b/drivers/scsi/fnic/fnic_isr.c
@@ -245,7 +245,14 @@ int fnic_set_intr_mode_msix(struct fnic
 	unsigned int m = ARRAY_SIZE(fnic->wq);
 	unsigned int o = ARRAY_SIZE(fnic->hw_copy_wq);
 	unsigned int min_irqs = n + m + 1 + 1; /*rq, raw wq, wq, err*/
-
+	/*
+	 * Make driver critical vectors unmanaged, or else it can get tied
+	 * to an offline CPU. This can happen when hyper-threading is off.
+	 */
+	struct irq_affinity affd = {
+		.pre_vectors = n + m + 1, /* rq, raw wq, 1 ioq */
+		.post_vectors = 1, /* err */
+	};
 	/*
 	 * We need n RQs, m WQs, o Copy WQs, n+m+o CQs, and n+m+o+1 INTRs
 	 * (last INTR is used for WQ/RQ errors and notification area)
@@ -263,8 +270,8 @@ int fnic_set_intr_mode_msix(struct fnic
 		int vec_count = 0;
 		int vecs = fnic->rq_count + fnic->raw_wq_count + fnic->wq_copy_count + 1;
 
-		vec_count = pci_alloc_irq_vectors(fnic->pdev, min_irqs, vecs,
-					PCI_IRQ_MSIX | PCI_IRQ_AFFINITY);
+		vec_count = pci_alloc_irq_vectors_affinity(fnic->pdev, min_irqs,
+			    vecs, PCI_IRQ_MSIX|PCI_IRQ_AFFINITY, &affd);
 		FNIC_ISR_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
 					"allocated %d MSI-X vectors\n",
 					vec_count);
--- a/drivers/scsi/fnic/fnic_main.c
+++ b/drivers/scsi/fnic/fnic_main.c
@@ -579,6 +579,8 @@ static int fnic_scsi_drv_init(struct fni
 
 void fnic_mq_map_queues_cpus(struct Scsi_Host *host)
 {
+	const struct cpumask *mask;
+	unsigned int queue, cpu;
 	struct fc_lport *lp = shost_priv(host);
 	struct fnic *fnic = lport_priv(lp);
 	struct pci_dev *l_pdev = fnic->pdev;
@@ -600,7 +602,36 @@ void fnic_mq_map_queues_cpus(struct Scsi
 		return;
 	}
 
-	blk_mq_map_hw_queues(qmap, &l_pdev->dev, FNIC_PCI_OFFSET);
+	for_each_possible_cpu(cpu)
+		qmap->mq_map[cpu] = 0;
+
+	/*
+	 * Setup CPU to Queue mapping for all managed MSI-X IRQs.
+	 * Q0 is driver critical and non-managed, hence start from Q1.
+	 */
+	for (queue = 1; queue < qmap->nr_queues; queue++) {
+		int irq_num = pci_irq_vector(fnic->pdev,
+					     queue + FNIC_PCI_OFFSET);
+
+		if (irq_num < 0)
+			continue;
+
+		mask = pci_irq_get_affinity(fnic->pdev,
+					    queue + FNIC_PCI_OFFSET);
+		if (!mask) {
+			shost_printk(KERN_ERR, host,
+				"failed to get irq_affinity map for queue:%d\n", irq_num);
+			continue;
+		}
+		FNIC_MAIN_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
+				"got irq_affinity map for %d:\n", irq_num);
+		for_each_cpu(cpu, mask) {
+			qmap->mq_map[cpu] = qmap->queue_offset + queue;
+			FNIC_MAIN_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num,
+				      "[Q%d] cpu:%d <=> irq:%d\n",
+				      queue, cpu, irq_num);
+		}
+	}
 }
 
 static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 797/877] Input: hp_sdc - shut down kicker timer on module exit
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (795 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 796/877] scsi: fnic: Fix missed link-up when critical IRQ targets offline CPU Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 798/877] wifi: wcn36xx: Fix potential use-after-free in TX ack timer teardown Greg Kroah-Hartman
                   ` (87 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Helge Deller,
	Dmitry Torokhov, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Runyu Xiao <runyu.xiao@seu.edu.cn>

[ Upstream commit 309731e95917125bbd13626a7a5600490a5bf44f ]

hp_sdc_kicker() rearms hp_sdc.kicker with mod_timer() after scheduling the
tasklet.  The module exit path uses timer_delete_sync().  That waits for a
callback already running but can still leave the timer rearmed.

A callback can therefore leave the timer pending while hp_sdc_exit() tears
down the driver, allowing timer activity to access dismantled driver state.

Use timer_shutdown_sync() for final teardown.  It waits for a running
callback and prevents rearming after module exit begins.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Acked-by: Helge Deller <deller@gmx.de>
Link: https://patch.msgid.link/20260902154004.3595416-1-runyu.xiao@seu.edu.cn
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
[ adjusted the removal hunk to match del_timer_sync() instead of timer_delete_sync() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/input/serio/hp_sdc.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/input/serio/hp_sdc.c
+++ b/drivers/input/serio/hp_sdc.c
@@ -980,7 +980,7 @@ static void hp_sdc_exit(void)
 	free_irq(hp_sdc.irq, &hp_sdc);
 	write_unlock_irq(&hp_sdc.lock);
 
-	del_timer_sync(&hp_sdc.kicker);
+	timer_shutdown_sync(&hp_sdc.kicker);
 
 	tasklet_kill(&hp_sdc.task);
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 798/877] wifi: wcn36xx: Fix potential use-after-free in TX ack timer teardown
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (796 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 797/877] Input: hp_sdc - shut down kicker timer on module exit Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 799/877] hwmon: (pwm-fan) Stop RPM timer before freeing tach data Greg Kroah-Hartman
                   ` (86 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Song Li, Fan Wu, Loic Poulain,
	Jeff Johnson, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Fan Wu <fanwu01@zju.edu.cn>

[ Upstream commit d9be5e75530772fc31637070d51e5717d6aeaa2a ]

wcn36xx_dxe_deinit() tears down the TX ack timer with timer_delete(),
which only dequeues the timer and does not wait for a callback that is
already executing; the preceding free_irq() calls synchronize the
interrupt handlers only. The callback, wcn36xx_dxe_tx_timer(), can
therefore be running past the teardown and use the wcn freed along
with the ieee80211_hw in wcn36xx_remove(): it takes wcn->dxe_lock,
reads wcn->tx_ack_skb and passes wcn->hw to
ieee80211_tx_status_irqsafe().

Fix this by using timer_shutdown_sync(), which waits for a running
callback and also prevents the timer from being rearmed again. The
timer is set up again by wcn36xx_dxe_init() on the next start, so the
start/stop cycle is unaffected.

This issue was found by an in-house static analysis tool.

Fixes: fdf21cc37149 ("wcn36xx: Add TX ack support")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Co-developed-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Reviewed-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
Link: https://patch.msgid.link/20260910020907.3353-1-fanwu01@zju.edu.cn
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
[ Adapted the patch to replace del_timer() instead of timer_delete(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/wireless/ath/wcn36xx/dxe.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/net/wireless/ath/wcn36xx/dxe.c
+++ b/drivers/net/wireless/ath/wcn36xx/dxe.c
@@ -1055,7 +1055,7 @@ void wcn36xx_dxe_deinit(struct wcn36xx *
 
 	free_irq(wcn->tx_irq, wcn);
 	free_irq(wcn->rx_irq, wcn);
-	del_timer(&wcn->tx_ack_timer);
+	timer_shutdown_sync(&wcn->tx_ack_timer);
 
 	if (wcn->tx_ack_skb) {
 		ieee80211_tx_status_irqsafe(wcn->hw, wcn->tx_ack_skb);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 799/877] hwmon: (pwm-fan) Stop RPM timer before freeing tach data
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (797 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 798/877] wifi: wcn36xx: Fix potential use-after-free in TX ack timer teardown Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 800/877] drm/msm/dpu: clear pending peripheral flush state Greg Kroah-Hartman
                   ` (85 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Yibo Tan, Guenter Roeck, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Yibo Tan <lhfff@tju.edu.cn>

[ Upstream commit 26d5ff79768548efb1e604bb6e8697c101e06269 ]

sample_timer() rearms the RPM timer and accesses the devm-managed
ctx->tachs and ctx->pulses_per_revolution arrays. The cleanup action
which stops the timer is registered before those arrays are allocated.

Since devres releases entries in reverse order, driver detach can free
the arrays before pwm_fan_cleanup() shuts down the timer. A timer expiry
in that window accesses the freed tach data.

With a KASAN kernel, a test-only kprobe delayed entry to
pwm_fan_cleanup() while normal sysfs unbind ran. Each of three runs
reported three four-byte reads and two four-byte writes in sample_timer()
after its backing devm allocations had been freed. The helper did not
invoke the timer callback, cleanup actions or free functions.

With the fix, three matching unbind runs completed without KASAN, BUG,
WARNING, Oops or panic. Instrumentation confirmed that timer retirement
completed before the first timer backing allocation was released.

Split timer retirement from the power cleanup and register its devres
action after the timer backing data and IRQ actions are installed. This
preserves the early power rollback action while ensuring the timer is
retired before its backing data is released. Use timer_shutdown_sync()
because the callback can rearm itself.

Fixes: 01695410d452 ("hwmon: (pwm-fan) Store tach data separately")
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5
Signed-off-by: Yibo Tan <lhfff@tju.edu.cn>
Link: https://patch.msgid.link/20260911071809.130151-1-lhfff@tju.edu.cn
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
[ Adapted cleanup changes to the older pwm_fan_cleanup() using del_timer_sync() without pwm_shutdown handling. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/hwmon/pwm-fan.c |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

--- a/drivers/hwmon/pwm-fan.c
+++ b/drivers/hwmon/pwm-fan.c
@@ -466,12 +466,18 @@ static void pwm_fan_cleanup(void *__ctx)
 {
 	struct pwm_fan_ctx *ctx = __ctx;
 
-	del_timer_sync(&ctx->rpm_timer);
 	/* Switch off everything */
 	ctx->enable_mode = pwm_disable_reg_disable;
 	pwm_fan_power_off(ctx, true);
 }
 
+static void pwm_fan_timer_cleanup(void *__ctx)
+{
+	struct pwm_fan_ctx *ctx = __ctx;
+
+	timer_shutdown_sync(&ctx->rpm_timer);
+}
+
 static int pwm_fan_probe(struct platform_device *pdev)
 {
 	struct thermal_cooling_device *cdev;
@@ -614,6 +620,10 @@ static int pwm_fan_probe(struct platform
 	}
 
 	if (ctx->tach_count > 0) {
+		ret = devm_add_action_or_reset(dev, pwm_fan_timer_cleanup, ctx);
+		if (ret)
+			return ret;
+
 		ctx->sample_start = ktime_get();
 		mod_timer(&ctx->rpm_timer, jiffies + HZ);
 
@@ -655,6 +665,7 @@ static void pwm_fan_shutdown(struct plat
 {
 	struct pwm_fan_ctx *ctx = platform_get_drvdata(pdev);
 
+	pwm_fan_timer_cleanup(ctx);
 	pwm_fan_cleanup(ctx);
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 800/877] drm/msm/dpu: clear pending peripheral flush state
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (798 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 799/877] hwmon: (pwm-fan) Stop RPM timer before freeing tach data Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 801/877] wifi: libipw: reject TKIP frames without a full MIC Greg Kroah-Hartman
                   ` (84 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Saim Shujah, Dmitry Baryshkov,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Saim Shujah <saimzst@gmail.com>

[ Upstream commit a5b5cc909931572aec446e129c035b76b3f0c1fa ]

dpu_hw_ctl_clear_pending_flush() resets the cached per-block state after a
flush transaction, but misses pending_periph_flush_mask.

The peripheral flush updater accumulates interface bits in this mask. A
later transaction which sets the top-level peripheral flush bit can write
stale interface bits to CTL_PERIPH_FLUSH together with the current state.

Peripheral flush support was added after the helper started clearing every
individual pending flush mask. Clear the peripheral mask together with the
other cached child masks.

Fixes: 64f7b81f0358 ("drm/msm/dpu: add support of new peripheral flush mechanism")
Cc: stable@vger.kernel.org
Signed-off-by: Saim Shujah <saimzst@gmail.com>
Patchwork: https://patchwork.freedesktop.org/patch/748968/
Link: https://lore.kernel.org/r/20260828065440.140410-1-saimzst@gmail.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
[ Adjusted context due to the missing pending_cwb_flush_mask field in Linux 6.12. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -110,6 +110,7 @@ static inline void dpu_hw_ctl_clear_pend
 	ctx->pending_flush_mask = 0x0;
 	ctx->pending_intf_flush_mask = 0;
 	ctx->pending_wb_flush_mask = 0;
+	ctx->pending_periph_flush_mask = 0;
 	ctx->pending_merge_3d_flush_mask = 0;
 	ctx->pending_dsc_flush_mask = 0;
 	ctx->pending_cdm_flush_mask = 0;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 801/877] wifi: libipw: reject TKIP frames without a full MIC
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (799 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 800/877] drm/msm/dpu: clear pending peripheral flush state Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 802/877] wifi: mac80211: track MU-MIMO configuration on disabled interfaces Greg Kroah-Hartman
                   ` (83 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Daehyeon Ko, Johannes Berg,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Daehyeon Ko <4ncienth@gmail.com>

[ Upstream commit 06f42accaf3c6aecab1dcc57f68dde6c06c8b380 ]

libipw_michael_mic_verify() assumes that an skb contains an eight-byte
Michael MIC. A short TKIP frame makes the unsigned payload length wrap,
causing michael_mic() to read past the skb.

Check that the MIC is present before verifying it, and use the existing
MICHAEL_MIC_LEN constant for all MIC lengths in the verifier.

Fixes: b453872c35cf ("[NET] ieee80211 subsystem")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Link: https://patch.msgid.link/20260909061124.3802517-1-4ncienth@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[ adapted libipw changes to the older lib80211 implementation and Michael MIC helper interface. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/wireless/lib80211_crypt_tkip.c |   13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

--- a/net/wireless/lib80211_crypt_tkip.c
+++ b/net/wireless/lib80211_crypt_tkip.c
@@ -38,6 +38,7 @@ MODULE_DESCRIPTION("lib80211 crypt: TKIP
 MODULE_LICENSE("GPL");
 
 #define TKIP_HDR_LEN 8
+#define MICHAEL_MIC_LEN 8
 
 struct lib80211_tkip_data {
 #define TKIP_KEY_LEN 32
@@ -585,16 +586,18 @@ static int lib80211_michael_mic_verify(s
 					int hdr_len, void *priv)
 {
 	struct lib80211_tkip_data *tkey = priv;
-	u8 mic[8];
+	u8 mic[MICHAEL_MIC_LEN];
 
-	if (!tkey->key_set)
+	if (!tkey->key_set || skb->len < hdr_len + MICHAEL_MIC_LEN)
 		return -1;
 
 	michael_mic_hdr(skb, tkey->rx_hdr);
 	if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
-			skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
+			skb->data + hdr_len,
+			skb->len - MICHAEL_MIC_LEN - hdr_len, mic))
 		return -1;
-	if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
+	if (memcmp(mic, skb->data + skb->len - MICHAEL_MIC_LEN,
+		   MICHAEL_MIC_LEN) != 0) {
 		struct ieee80211_hdr *hdr;
 		hdr = (struct ieee80211_hdr *)skb->data;
 		printk(KERN_DEBUG "%s: Michael MIC verification failed for "
@@ -612,7 +615,7 @@ static int lib80211_michael_mic_verify(s
 	tkey->rx_iv32 = tkey->rx_iv32_new;
 	tkey->rx_iv16 = tkey->rx_iv16_new;
 
-	skb_trim(skb, skb->len - 8);
+	skb_trim(skb, skb->len - MICHAEL_MIC_LEN);
 
 	return 0;
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 802/877] wifi: mac80211: track MU-MIMO configuration on disabled interfaces
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (800 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 801/877] wifi: libipw: reject TKIP frames without a full MIC Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 803/877] wifi: mac80211: refuse to make a monitor active when it has no queue Greg Kroah-Hartman
                   ` (82 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Benjamin Berg, Johannes Berg,
	Miri Korenblit, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Benjamin Berg <benjamin.berg@intel.com>

[ Upstream commit a5aa46f1ac4f53e03b9b75cbf55634131f2f8cac ]

For monitoring, userspace will try to configure the VIF sdata, while the
driver may see the monitor_sdata that is created when only monitor
interfaces are up. This causes the odd situation that it may not be
possible to store the MU-MIMO configuration on monitor_sdata.

Fix this by storing that information on the VIF sdata and updating the
monitor_sdata when available and the interface is up. Also, adjust the
code that adds monitor_sdata so that it will configure MU-MIMO based on
the newly added interface or one of the existing ones.

This should give a mostly consistent behaviour when configuring MU-MIMO
on sniffer interfaces. Should the user configure MU-MIMO on multiple
sniffer interfaces, then mac80211 will simply select one of the
configurations. This behaviour should be good enough and avoids breaking
user expectations in the common scenarios.

Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20251110141514.677915f8f6bb.If4e04a57052f9ca763562a67248b06fd80d0c2c1@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

[ Backport to 6.12: omit NO_VIRTUAL_MONITOR handling, since this tree
  only exposes WANT_MONITOR_VIF. Keep the existing monitors counter and
  cooked-monitor handling, and traverse mon_list through u.mntr.list.
  Update the existing reconfiguration call at wake_up rather than adding
  the later upstream call site. All three virtual-monitor creation calls
  now pass the configuration source, or NULL to select a running monitor.

  Retain the MU-MIMO configuration changes so target 2b04d6556964
  ("wifi: mac80211: refuse to make a monitor active when it has no queue")
  merges cleanly on top. No new functions are introduced. ]

Stable-dep-of: 2b04d6556964 ("wifi: mac80211: refuse to make a monitor active when it has no queue")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mac80211/cfg.c         |   39 +++++++++++++++++++++++++++++----------
 net/mac80211/ieee80211_i.h |    3 ++-
 net/mac80211/iface.c       |   43 +++++++++++++++++++++++++++++++++++++------
 net/mac80211/util.c        |    3 ++-
 4 files changed, 70 insertions(+), 18 deletions(-)

--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -63,12 +63,14 @@ static void ieee80211_set_mu_mimo_follow
 		memcpy(sdata->vif.bss_conf.mu_group.position,
 		       params->vht_mumimo_groups + WLAN_MEMBERSHIP_LEN,
 		       WLAN_USER_POSITION_LEN);
-		ieee80211_link_info_change_notify(sdata, &sdata->deflink,
-						  BSS_CHANGED_MU_GROUPS);
+
 		/* don't care about endianness - just check for 0 */
 		memcpy(&membership, params->vht_mumimo_groups,
 		       WLAN_MEMBERSHIP_LEN);
 		mu_mimo_groups = membership != 0;
+
+		/* Unset following if configured explicitly */
+		eth_broadcast_addr(sdata->u.mntr.mu_follow_addr);
 	}
 
 	if (params->vht_mumimo_follow_addr) {
@@ -76,16 +78,26 @@ static void ieee80211_set_mu_mimo_follow
 			is_valid_ether_addr(params->vht_mumimo_follow_addr);
 		ether_addr_copy(sdata->u.mntr.mu_follow_addr,
 				params->vht_mumimo_follow_addr);
+
+		/* Unset current membership until a management frame is RXed */
+		memset(sdata->vif.bss_conf.mu_group.membership, 0,
+		       WLAN_MEMBERSHIP_LEN);
 	}
 
 	sdata->vif.bss_conf.mu_mimo_owner = mu_mimo_groups || mu_mimo_follow;
+
+	/* Notify only after setting mu_mimo_owner */
+	if (sdata->vif.bss_conf.mu_mimo_owner &&
+	    sdata->flags & IEEE80211_SDATA_IN_DRIVER)
+		ieee80211_link_info_change_notify(sdata, &sdata->deflink,
+						  BSS_CHANGED_MU_GROUPS);
 }
 
 static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,
 				     struct vif_params *params)
 {
 	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_sub_if_data *monitor_sdata;
+	struct ieee80211_sub_if_data *monitor_sdata = NULL;
 
 	/* check flags first */
 	if (params->flags && ieee80211_sdata_running(sdata)) {
@@ -104,18 +116,25 @@ static int ieee80211_set_mon_options(str
 			return -EBUSY;
 	}
 
-	/* also validate MU-MIMO change */
-	monitor_sdata = wiphy_dereference(local->hw.wiphy,
-					  local->monitor_sdata);
-
-	if (!monitor_sdata &&
+	/* validate whether MU-MIMO can be configured */
+	if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) &&
 	    (params->vht_mumimo_groups || params->vht_mumimo_follow_addr))
 		return -EOPNOTSUPP;
 
+	/* Also update dependent monitor_sdata if required */
+	if (test_bit(SDATA_STATE_RUNNING, &sdata->state))
+		monitor_sdata = wiphy_dereference(local->hw.wiphy,
+						  local->monitor_sdata);
+
 	/* apply all changes now - no failures allowed */
 
-	if (monitor_sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
-		ieee80211_set_mu_mimo_follow(monitor_sdata, params);
+	if (ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) {
+		/* This is copied in when the VIF is activated */
+		ieee80211_set_mu_mimo_follow(sdata, params);
+
+		if (monitor_sdata)
+			ieee80211_set_mu_mimo_follow(monitor_sdata, params);
+	}
 
 	if (params->flags) {
 		if (ieee80211_sdata_running(sdata)) {
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -2045,7 +2045,8 @@ void ieee80211_adjust_monitor_flags(stru
 				    const int offset);
 int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up);
 void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata);
-int ieee80211_add_virtual_monitor(struct ieee80211_local *local);
+int ieee80211_add_virtual_monitor(struct ieee80211_local *local,
+				  struct ieee80211_sub_if_data *creator_sdata);
 void ieee80211_del_virtual_monitor(struct ieee80211_local *local);
 
 bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -763,8 +763,9 @@ static void ieee80211_do_stop(struct iee
 	ieee80211_configure_filter(local);
 	ieee80211_hw_config(local, hw_reconf_flags);
 
+	/* Passing NULL means an interface is picked for configuration */
 	if (local->monitors == local->open_count)
-		ieee80211_add_virtual_monitor(local);
+		ieee80211_add_virtual_monitor(local, NULL);
 }
 
 static void ieee80211_stop_mbssid(struct ieee80211_sub_if_data *sdata)
@@ -1188,7 +1189,8 @@ static void ieee80211_sdata_init(struct
 	ieee80211_link_init(sdata, -1, &sdata->deflink, &sdata->vif.bss_conf);
 }
 
-int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
+int ieee80211_add_virtual_monitor(struct ieee80211_local *local,
+				  struct ieee80211_sub_if_data *creator_sdata)
 {
 	struct ieee80211_sub_if_data *sdata;
 	int ret;
@@ -1196,8 +1198,10 @@ int ieee80211_add_virtual_monitor(struct
 	ASSERT_RTNL();
 	lockdep_assert_wiphy(local->hw.wiphy);
 
-	if (local->monitor_sdata)
-		return 0;
+	/* Already have a monitor set up, configure it */
+	sdata = wiphy_dereference(local->hw.wiphy, local->monitor_sdata);
+	if (sdata)
+		goto configure_monitor;
 
 	sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL);
 	if (!sdata)
@@ -1251,6 +1255,32 @@ int ieee80211_add_virtual_monitor(struct
 	skb_queue_head_init(&sdata->status_queue);
 	wiphy_work_init(&sdata->work, ieee80211_iface_work);
 
+configure_monitor:
+	/* Copy in the MU-MIMO configuration if set */
+	if (!creator_sdata) {
+		struct ieee80211_sub_if_data *other;
+
+		list_for_each_entry(other, &local->mon_list, u.mntr.list) {
+			if (!other->vif.bss_conf.mu_mimo_owner)
+				continue;
+
+			creator_sdata = other;
+			break;
+		}
+	}
+
+	if (creator_sdata && creator_sdata->vif.bss_conf.mu_mimo_owner) {
+		sdata->vif.bss_conf.mu_mimo_owner = true;
+		memcpy(&sdata->vif.bss_conf.mu_group,
+		       &creator_sdata->vif.bss_conf.mu_group,
+		       sizeof(sdata->vif.bss_conf.mu_group));
+		memcpy(&sdata->u.mntr.mu_follow_addr,
+		       creator_sdata->u.mntr.mu_follow_addr, ETH_ALEN);
+
+		ieee80211_link_info_change_notify(sdata, &sdata->deflink,
+						  BSS_CHANGED_MU_GROUPS);
+	}
+
 	return 0;
 }
 
@@ -1405,8 +1435,9 @@ int ieee80211_do_open(struct wireless_de
 			res = drv_add_interface(local, sdata);
 			if (res)
 				goto err_stop;
-		} else if (local->monitors == 0 && local->open_count == 0) {
-			res = ieee80211_add_virtual_monitor(local);
+		} else if (local->monitors == local->open_count) {
+			/* add/configure if there is no non-monitor interface */
+			res = ieee80211_add_virtual_monitor(local, sdata);
 			if (res)
 				goto err_stop;
 		}
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2144,8 +2144,9 @@ int ieee80211_reconfig(struct ieee80211_
 
  wake_up:
 
+	/* Passing NULL means an interface is picked for configuration */
 	if (local->monitors == local->open_count && local->monitors > 0)
-		ieee80211_add_virtual_monitor(local);
+		ieee80211_add_virtual_monitor(local, NULL);
 
 	/*
 	 * Clear the WLAN_STA_BLOCK_BA flag so new aggregation



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 803/877] wifi: mac80211: refuse to make a monitor active when it has no queue
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (801 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 802/877] wifi: mac80211: track MU-MIMO configuration on disabled interfaces Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 804/877] smb: mark the new channel addition log as informational log with cifs_info Greg Kroah-Hartman
                   ` (81 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Devin Wittmayer, Johannes Berg,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Devin Wittmayer <lucid_duck@justthetip.ca>

[ Upstream commit 2b04d6556964ae9f89819b86a0a7801e39c3aae5 ]

A monitor interface only gets a TXQ if it's created active, and one can't
be added later. Setting the flag on a down interface is still allowed, so
the driver is handed a monitor with no queue. ath9k dereferences it:

  BUG: kernel NULL pointer dereference, address: 0000000000000066
  RIP: 0010:ath_tx_node_init+0x49/0x170 [ath9k]
   ath9k_add_interface+0x10c/0x140 [ath9k]
   drv_add_interface+0x54/0x250 [mac80211]
   ieee80211_do_open+0x32f/0x800 [mac80211]

Reached with CAP_NET_ADMIN by "iw dev X set monitor active" followed by
"ip link set X up". RTNL is held, so netlink operations block behind it.

Refuse the flag when there is no queue to give.

Fixes: 79af1f866193 ("mac80211: avoid allocating TXQs that won't be used")
Cc: stable@vger.kernel.org
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260904200338.10829-1-lucid_duck@justthetip.ca
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/mac80211/cfg.c |    4 ++++
 1 file changed, 4 insertions(+)

--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -116,6 +116,10 @@ static int ieee80211_set_mon_options(str
 			return -EBUSY;
 	}
 
+	/* TXQs are reserved in ieee80211_if_add() and cannot be added later */
+	if ((params->flags & MONITOR_FLAG_ACTIVE) && !sdata->vif.txq)
+		return -EOPNOTSUPP;
+
 	/* validate whether MU-MIMO can be configured */
 	if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) &&
 	    (params->vht_mumimo_groups || params->vht_mumimo_follow_addr))



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 804/877] smb: mark the new channel addition log as informational log with cifs_info
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (802 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 803/877] wifi: mac80211: refuse to make a monitor active when it has no queue Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 805/877] smb: client: fix use-after-free of iface in cifs_try_adding_channels() Greg Kroah-Hartman
                   ` (80 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bharath SM,
	Paulo Alcantara (Red Hat), Steve French, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bharath SM <bharathsm@microsoft.com>

[ Upstream commit faf1b64888ff13caa94fa09835fcfdabee18b057 ]

For multichannel mounts, when a new channel is successfully opened
we currently log 'successfully opened new channel on iface: <>' as
cifs_dbg(VFS..)  which is eventually translated into a pr_err log.
Marking these informational logs as error logs may lead to confusion
for users so they will now be logged as info logs instead.

Signed-off-by: Bharath SM <bharathsm@microsoft.com>
Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: d034e836eefd ("smb: client: fix use-after-free of iface in cifs_try_adding_channels()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/sess.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/smb/client/sess.c
+++ b/fs/smb/client/sess.c
@@ -267,7 +267,7 @@ int cifs_try_adding_channels(struct cifs
 
 			iface->num_channels++;
 			iface->weight_fulfilled++;
-			cifs_dbg(VFS, "successfully opened new channel on iface:%pIS\n",
+			cifs_info("successfully opened new channel on iface:%pIS\n",
 				 &iface->sockaddr);
 			break;
 		}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 805/877] smb: client: fix use-after-free of iface in cifs_try_adding_channels()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (803 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 804/877] smb: mark the new channel addition log as informational log with cifs_info Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 806/877] drm/amdgpu: Failed to check various return code Greg Kroah-Hartman
                   ` (79 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Joseph Qi, Shyam Prasad N,
	Paulo Alcantara, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Joseph Qi <joseph.qi@linux.alibaba.com>

[ Upstream commit d034e836eefd7ce75e588f7031cffbeec594f5ac ]

cifs_try_adding_channels() iterates ses->iface_list with
list_for_each_entry_safe_from(), which captures the next entry
(niface) under iface_lock.  The loop body then drops iface_lock for
the whole duration of cifs_ses_add_channel().

A concurrent interface refresh (SMB3_request_interfaces() ->
parse_server_interfaces()) marks all ifaces inactive and removes and
frees any that are not re-advertised via list_del() + kref_put(),
where release_iface() is a bare kfree().  Since niface typically has
no channel holding a reference, the list reference is its last and it
can be freed inside the unlocked window.  On continue, the iterator
advance step then dereferences niface->iface_head.next, and the loop
body reads iface->rdma_capable/is_active, both on freed memory.

Fix this by never keeping an unreferenced list pointer across the
unlocked window.  Each channel attempt now re-scans the list from the
head under iface_lock, takes a kref on the selected candidate, and
passes only that referenced candidate to cifs_ses_add_channel().
weight_fulfilled still tracks selection progress, so restarting the
scan preserves the original weighted distribution and the
weight_fulfilled-before-kref_put ordering on the failure path.

Add a per-pass attempts cap so a flapping interface refresh cannot
keep the inner loop spinning within a single tries increment.

Fixes: aa45dadd34e4 ("cifs: change iface_list from array to sorted linked list")
Cc: stable@vger.kernel.org
Assisted-by: Qoder:Qwen3.8-Max
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Acked-by: Shyam Prasad N <sprasad@microsoft.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/sess.c |  106 ++++++++++++++++++++++++++++++---------------------
 1 file changed, 64 insertions(+), 42 deletions(-)

--- a/fs/smb/client/sess.c
+++ b/fs/smb/client/sess.c
@@ -175,9 +175,9 @@ int cifs_try_adding_channels(struct cifs
 	int old_chan_count, new_chan_count;
 	int left;
 	int rc = 0;
-	int tries = 0;
+	int tries = 0, attempts;
 	size_t iface_weight = 0, iface_min_speed = 0;
-	struct cifs_server_iface *iface = NULL, *niface = NULL;
+	struct cifs_server_iface *iface = NULL, *candidate = NULL;
 	struct cifs_server_iface *last_iface = NULL;
 
 	spin_lock(&ses->chan_lock);
@@ -223,67 +223,89 @@ int cifs_try_adding_channels(struct cifs
 			break;
 		}
 
-		if (!iface)
-			iface = list_first_entry(&ses->iface_list, struct cifs_server_iface,
-						 iface_head);
 		last_iface = list_last_entry(&ses->iface_list, struct cifs_server_iface,
 					     iface_head);
 		iface_min_speed = last_iface->speed;
+		spin_unlock(&ses->iface_lock);
 
-		list_for_each_entry_safe_from(iface, niface, &ses->iface_list,
-				    iface_head) {
-			/* do not mix rdma and non-rdma interfaces */
-			if (iface->rdma_capable != ses->server->rdma)
-				continue;
-
-			/* skip ifaces that are unusable */
-			if (!iface->is_active ||
-			    (is_ses_using_iface(ses, iface) &&
-			     !iface->rss_capable))
-				continue;
+		attempts = 0;
+		while (left > 0) {
+			spin_lock(&ses->iface_lock);
 
-			/* check if we already allocated enough channels */
-			iface_weight = iface->speed / iface_min_speed;
+			/*
+			 * iface_lock must be dropped while opening a channel,
+			 * and a concurrent interface refresh may remove and
+			 * free entries during that window, so no list entry
+			 * may be kept across it without a reference.  Scan
+			 * the list from the beginning each time and only pass
+			 * a referenced candidate to cifs_ses_add_channel();
+			 * weight_fulfilled tracks the progress so that no
+			 * iface is selected beyond its weight.
+			 */
+			candidate = NULL;
+			list_for_each_entry(iface, &ses->iface_list, iface_head) {
+				/* do not mix rdma and non-rdma interfaces */
+				if (iface->rdma_capable != ses->server->rdma)
+					continue;
+
+				/* skip ifaces that are unusable */
+				if (!iface->is_active ||
+				    (is_ses_using_iface(ses, iface) &&
+				     !iface->rss_capable))
+					continue;
+
+				/* check if we already allocated enough channels */
+				iface_weight = iface->speed / iface_min_speed;
+
+				if (iface->weight_fulfilled >= iface_weight)
+					continue;
+
+				/* take ref before unlock */
+				kref_get(&iface->refcount);
+				candidate = iface;
+				break;
+			}
 
-			if (iface->weight_fulfilled >= iface_weight)
-				continue;
+			if (!candidate) {
+				/* no usable iface. reset weight_fulfilled and start over */
+				list_for_each_entry(iface, &ses->iface_list, iface_head)
+					iface->weight_fulfilled = 0;
+				spin_unlock(&ses->iface_lock);
+				break;
+			}
 
-			/* take ref before unlock */
-			kref_get(&iface->refcount);
+			attempts++;
+			if (attempts > 3 * ses->chan_max) {
+				kref_put(&candidate->refcount, release_iface);
+				spin_unlock(&ses->iface_lock);
+				break;
+			}
 
 			spin_unlock(&ses->iface_lock);
-			rc = cifs_ses_add_channel(ses, iface);
+			rc = cifs_ses_add_channel(ses, candidate);
 			spin_lock(&ses->iface_lock);
 
 			if (rc) {
 				cifs_dbg(VFS, "failed to open extra channel on iface:%pIS rc=%d\n",
-					 &iface->sockaddr,
+					 &candidate->sockaddr,
 					 rc);
 				/* failure to add chan should increase weight */
-				iface->weight_fulfilled++;
-				kref_put(&iface->refcount, release_iface);
+				candidate->weight_fulfilled++;
+				kref_put(&candidate->refcount, release_iface);
+				spin_unlock(&ses->iface_lock);
 				continue;
 			}
 
-			iface->num_channels++;
-			iface->weight_fulfilled++;
+			candidate->num_channels++;
+			candidate->weight_fulfilled++;
 			cifs_info("successfully opened new channel on iface:%pIS\n",
-				 &iface->sockaddr);
-			break;
-		}
-
-		/* reached end of list. reset weight_fulfilled and start over */
-		if (list_entry_is_head(iface, &ses->iface_list, iface_head)) {
-			list_for_each_entry(iface, &ses->iface_list, iface_head)
-				iface->weight_fulfilled = 0;
+				 &candidate->sockaddr);
 			spin_unlock(&ses->iface_lock);
-			iface = NULL;
-			continue;
-		}
-		spin_unlock(&ses->iface_lock);
 
-		left--;
-		new_chan_count++;
+			left--;
+			new_chan_count++;
+			break;
+		}
 	}
 
 	return new_chan_count - old_chan_count;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 806/877] drm/amdgpu: Failed to check various return code
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (804 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 805/877] smb: client: fix use-after-free of iface in cifs_try_adding_channels() Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 807/877] drm/amdgpu: set the VM pointer to NULL in amdgpu_job_prepare Greg Kroah-Hartman
                   ` (78 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Andrew Martin,
	Harish Kasiviswanathan, Alex Deucher, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Andrew Martin <Andrew.Martin@amd.com>

[ Upstream commit 357ef5b3b7e98b4d21cb0abc1bde1140332c7eb8 ]

Clean up code to quiet the compiler on us failing to check the return
code.

Signed-off-by: Andrew Martin <Andrew.Martin@amd.com>
Reviewed-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Stable-dep-of: 5155002b03b2 ("drm/amdgpu: fix rmmio iounmap skipped on device removal")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c       |    2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c |   14 +++++++-------
 2 files changed, 8 insertions(+), 8 deletions(-)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
@@ -368,7 +368,7 @@ void amdgpu_amdkfd_free_gtt_mem(struct a
 {
 	struct amdgpu_bo **bo = (struct amdgpu_bo **) mem_obj;
 
-	amdgpu_bo_reserve(*bo, true);
+	(void)amdgpu_bo_reserve(*bo, true);
 	amdgpu_bo_kunmap(*bo);
 	amdgpu_bo_unpin(*bo);
 	amdgpu_bo_unreserve(*bo);
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -722,7 +722,7 @@ kfd_mem_dmaunmap_userptr(struct kgd_mem
 		return;
 
 	amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_CPU);
-	ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
+	(void)ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
 
 	dma_unmap_sgtable(adev->dev, ttm->sg, direction, 0);
 	sg_free_table(ttm->sg);
@@ -771,7 +771,7 @@ kfd_mem_dmaunmap_sg_bo(struct kgd_mem *m
 	}
 
 	amdgpu_bo_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_CPU);
-	ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
+	(void)ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
 
 	dir = mem->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_WRITABLE ?
 				DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
@@ -981,7 +981,7 @@ unwind:
 		if (!attachment[i])
 			continue;
 		if (attachment[i]->bo_va) {
-			amdgpu_bo_reserve(bo[i], true);
+			(void)amdgpu_bo_reserve(bo[i], true);
 			if (--attachment[i]->bo_va->ref_count == 0)
 				amdgpu_vm_bo_del(adev, attachment[i]->bo_va);
 			amdgpu_bo_unreserve(bo[i]);
@@ -1251,11 +1251,11 @@ static int unmap_bo_from_gpuvm(struct kg
 		return -EBUSY;
 	}
 
-	amdgpu_vm_bo_unmap(adev, bo_va, entry->va);
+	(void)amdgpu_vm_bo_unmap(adev, bo_va, entry->va);
 
-	amdgpu_vm_clear_freed(adev, vm, &bo_va->last_pt_update);
+	(void)amdgpu_vm_clear_freed(adev, vm, &bo_va->last_pt_update);
 
-	amdgpu_sync_fence(sync, bo_va->last_pt_update);
+	(void)amdgpu_sync_fence(sync, bo_va->last_pt_update);
 
 	return 0;
 }
@@ -2358,7 +2358,7 @@ void amdgpu_amdkfd_gpuvm_unmap_gtt_bo_fr
 {
 	struct amdgpu_bo *bo = mem->bo;
 
-	amdgpu_bo_reserve(bo, true);
+	(void)amdgpu_bo_reserve(bo, true);
 	amdgpu_bo_kunmap(bo);
 	amdgpu_bo_unpin(bo);
 	amdgpu_bo_unreserve(bo);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 807/877] drm/amdgpu: set the VM pointer to NULL in amdgpu_job_prepare
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (805 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 806/877] drm/amdgpu: Failed to check various return code Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 808/877] drm/amdgpu/umsch: remove vpe test from umsch Greg Kroah-Hartman
                   ` (77 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Christian König, Alex Deucher,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Christian König <christian.koenig@amd.com>

[ Upstream commit 26c95e838e6301b0230430ec2fadeabfcb07aeda ]

As soon as the prepare phase is completed the VM might be released,
better set it to NULL.

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Stable-dep-of: 5155002b03b2 ("drm/amdgpu: fix rmmio iounmap skipped on device removal")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c |    7 +++++++
 1 file changed, 7 insertions(+)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -368,6 +368,13 @@ amdgpu_job_prepare_job(struct drm_sched_
 			dev_err(ring->adev->dev, "Error getting VM ID (%d)\n", r);
 			goto error;
 		}
+		/*
+		 * The VM structure might be released after the VMID is
+		 * assigned, we had multiple problems with people trying to use
+		 * the VM pointer so better set it to NULL.
+		 */
+		if (!fence)
+			job->vm = NULL;
 	}
 
 	return fence;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 808/877] drm/amdgpu/umsch: remove vpe test from umsch
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (806 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 807/877] drm/amdgpu: set the VM pointer to NULL in amdgpu_job_prepare Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 809/877] drm/amdgpu: use GFP_NOWAIT for memory allocations Greg Kroah-Hartman
                   ` (76 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Saleemkhan Jamadar, Christian Koenig,
	Alex Deucher, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Saleemkhan Jamadar <saleemkhan.jamadar@amd.com>

[ Upstream commit b0bebbe4ea2a25937d341fa1f2ab2cd8ce339cad ]

current test is more intrusive for user queue test

Signed-off-by: Saleemkhan Jamadar <saleemkhan.jamadar@amd.com>
Suggested-by: Christian Koenig <christian.koenig@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Stable-dep-of: 5155002b03b2 ("drm/amdgpu: fix rmmio iounmap skipped on device removal")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c |  459 ---------------------------
 1 file changed, 1 insertion(+), 458 deletions(-)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c
@@ -32,463 +32,6 @@
 #include "amdgpu_umsch_mm.h"
 #include "umsch_mm_v4_0.h"
 
-struct umsch_mm_test_ctx_data {
-	uint8_t process_csa[PAGE_SIZE];
-	uint8_t vpe_ctx_csa[PAGE_SIZE];
-	uint8_t vcn_ctx_csa[PAGE_SIZE];
-};
-
-struct umsch_mm_test_mqd_data {
-	uint8_t vpe_mqd[PAGE_SIZE];
-	uint8_t vcn_mqd[PAGE_SIZE];
-};
-
-struct umsch_mm_test_ring_data {
-	uint8_t vpe_ring[PAGE_SIZE];
-	uint8_t vpe_ib[PAGE_SIZE];
-	uint8_t vcn_ring[PAGE_SIZE];
-	uint8_t vcn_ib[PAGE_SIZE];
-};
-
-struct umsch_mm_test_queue_info {
-	uint64_t mqd_addr;
-	uint64_t csa_addr;
-	uint32_t doorbell_offset_0;
-	uint32_t doorbell_offset_1;
-	enum UMSCH_SWIP_ENGINE_TYPE engine;
-};
-
-struct umsch_mm_test {
-	struct amdgpu_bo	*ctx_data_obj;
-	uint64_t		ctx_data_gpu_addr;
-	uint32_t		*ctx_data_cpu_addr;
-
-	struct amdgpu_bo	*mqd_data_obj;
-	uint64_t		mqd_data_gpu_addr;
-	uint32_t		*mqd_data_cpu_addr;
-
-	struct amdgpu_bo	*ring_data_obj;
-	uint64_t		ring_data_gpu_addr;
-	uint32_t		*ring_data_cpu_addr;
-
-
-	struct amdgpu_vm	*vm;
-	struct amdgpu_bo_va	*bo_va;
-	uint32_t		pasid;
-	uint32_t		vm_cntx_cntl;
-	uint32_t		num_queues;
-};
-
-static int map_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm,
-			  struct amdgpu_bo *bo, struct amdgpu_bo_va **bo_va,
-			  uint64_t addr, uint32_t size)
-{
-	struct amdgpu_sync sync;
-	struct drm_exec exec;
-	int r;
-
-	amdgpu_sync_create(&sync);
-
-	drm_exec_init(&exec, 0, 0);
-	drm_exec_until_all_locked(&exec) {
-		r = drm_exec_lock_obj(&exec, &bo->tbo.base);
-		drm_exec_retry_on_contention(&exec);
-		if (unlikely(r))
-			goto error_fini_exec;
-
-		r = amdgpu_vm_lock_pd(vm, &exec, 0);
-		drm_exec_retry_on_contention(&exec);
-		if (unlikely(r))
-			goto error_fini_exec;
-	}
-
-	*bo_va = amdgpu_vm_bo_add(adev, vm, bo);
-	if (!*bo_va) {
-		r = -ENOMEM;
-		goto error_fini_exec;
-	}
-
-	r = amdgpu_vm_bo_map(adev, *bo_va, addr, 0, size,
-			     AMDGPU_PTE_READABLE | AMDGPU_PTE_WRITEABLE |
-			     AMDGPU_PTE_EXECUTABLE);
-
-	if (r)
-		goto error_del_bo_va;
-
-
-	r = amdgpu_vm_bo_update(adev, *bo_va, false);
-	if (r)
-		goto error_del_bo_va;
-
-	amdgpu_sync_fence(&sync, (*bo_va)->last_pt_update);
-
-	r = amdgpu_vm_update_pdes(adev, vm, false);
-	if (r)
-		goto error_del_bo_va;
-
-	amdgpu_sync_fence(&sync, vm->last_update);
-
-	amdgpu_sync_wait(&sync, false);
-	drm_exec_fini(&exec);
-
-	amdgpu_sync_free(&sync);
-
-	return 0;
-
-error_del_bo_va:
-	amdgpu_vm_bo_del(adev, *bo_va);
-	amdgpu_sync_free(&sync);
-
-error_fini_exec:
-	drm_exec_fini(&exec);
-	amdgpu_sync_free(&sync);
-	return r;
-}
-
-static int unmap_ring_data(struct amdgpu_device *adev, struct amdgpu_vm *vm,
-			    struct amdgpu_bo *bo, struct amdgpu_bo_va *bo_va,
-			    uint64_t addr)
-{
-	struct drm_exec exec;
-	long r;
-
-	drm_exec_init(&exec, 0, 0);
-	drm_exec_until_all_locked(&exec) {
-		r = drm_exec_lock_obj(&exec, &bo->tbo.base);
-		drm_exec_retry_on_contention(&exec);
-		if (unlikely(r))
-			goto out_unlock;
-
-		r = amdgpu_vm_lock_pd(vm, &exec, 0);
-		drm_exec_retry_on_contention(&exec);
-		if (unlikely(r))
-			goto out_unlock;
-	}
-
-
-	r = amdgpu_vm_bo_unmap(adev, bo_va, addr);
-	if (r)
-		goto out_unlock;
-
-	amdgpu_vm_bo_del(adev, bo_va);
-
-out_unlock:
-	drm_exec_fini(&exec);
-
-	return r;
-}
-
-static void setup_vpe_queue(struct amdgpu_device *adev,
-			    struct umsch_mm_test *test,
-			    struct umsch_mm_test_queue_info *qinfo)
-{
-	struct MQD_INFO *mqd = (struct MQD_INFO *)test->mqd_data_cpu_addr;
-	uint64_t ring_gpu_addr = test->ring_data_gpu_addr;
-
-	mqd->rb_base_lo = (ring_gpu_addr >> 8);
-	mqd->rb_base_hi = (ring_gpu_addr >> 40);
-	mqd->rb_size = PAGE_SIZE / 4;
-	mqd->wptr_val = 0;
-	mqd->rptr_val = 0;
-	mqd->unmapped = 1;
-
-	if (adev->vpe.collaborate_mode)
-		memcpy(++mqd, test->mqd_data_cpu_addr, sizeof(struct MQD_INFO));
-
-	qinfo->mqd_addr = test->mqd_data_gpu_addr;
-	qinfo->csa_addr = test->ctx_data_gpu_addr +
-		offsetof(struct umsch_mm_test_ctx_data, vpe_ctx_csa);
-	qinfo->doorbell_offset_0 = 0;
-	qinfo->doorbell_offset_1 = 0;
-}
-
-static void setup_vcn_queue(struct amdgpu_device *adev,
-			    struct umsch_mm_test *test,
-			    struct umsch_mm_test_queue_info *qinfo)
-{
-}
-
-static int add_test_queue(struct amdgpu_device *adev,
-			  struct umsch_mm_test *test,
-			  struct umsch_mm_test_queue_info *qinfo)
-{
-	struct umsch_mm_add_queue_input queue_input = {};
-	int r;
-
-	queue_input.process_id = test->pasid;
-	queue_input.page_table_base_addr = amdgpu_gmc_pd_addr(test->vm->root.bo);
-
-	queue_input.process_va_start = 0;
-	queue_input.process_va_end = (adev->vm_manager.max_pfn - 1) << AMDGPU_GPU_PAGE_SHIFT;
-
-	queue_input.process_quantum = 100000; /* 10ms */
-	queue_input.process_csa_addr = test->ctx_data_gpu_addr +
-				       offsetof(struct umsch_mm_test_ctx_data, process_csa);
-
-	queue_input.context_quantum = 10000; /* 1ms */
-	queue_input.context_csa_addr = qinfo->csa_addr;
-
-	queue_input.inprocess_context_priority = CONTEXT_PRIORITY_LEVEL_NORMAL;
-	queue_input.context_global_priority_level = CONTEXT_PRIORITY_LEVEL_NORMAL;
-	queue_input.doorbell_offset_0 = qinfo->doorbell_offset_0;
-	queue_input.doorbell_offset_1 = qinfo->doorbell_offset_1;
-
-	queue_input.engine_type = qinfo->engine;
-	queue_input.mqd_addr = qinfo->mqd_addr;
-	queue_input.vm_context_cntl = test->vm_cntx_cntl;
-
-	amdgpu_umsch_mm_lock(&adev->umsch_mm);
-	r = adev->umsch_mm.funcs->add_queue(&adev->umsch_mm, &queue_input);
-	amdgpu_umsch_mm_unlock(&adev->umsch_mm);
-	if (r)
-		return r;
-
-	return 0;
-}
-
-static int remove_test_queue(struct amdgpu_device *adev,
-			     struct umsch_mm_test *test,
-			     struct umsch_mm_test_queue_info *qinfo)
-{
-	struct umsch_mm_remove_queue_input queue_input = {};
-	int r;
-
-	queue_input.doorbell_offset_0 = qinfo->doorbell_offset_0;
-	queue_input.doorbell_offset_1 = qinfo->doorbell_offset_1;
-	queue_input.context_csa_addr = qinfo->csa_addr;
-
-	amdgpu_umsch_mm_lock(&adev->umsch_mm);
-	r = adev->umsch_mm.funcs->remove_queue(&adev->umsch_mm, &queue_input);
-	amdgpu_umsch_mm_unlock(&adev->umsch_mm);
-	if (r)
-		return r;
-
-	return 0;
-}
-
-static int submit_vpe_queue(struct amdgpu_device *adev, struct umsch_mm_test *test)
-{
-	struct MQD_INFO *mqd = (struct MQD_INFO *)test->mqd_data_cpu_addr;
-	uint32_t *ring = test->ring_data_cpu_addr +
-		offsetof(struct umsch_mm_test_ring_data, vpe_ring) / 4;
-	uint32_t *ib = test->ring_data_cpu_addr +
-		offsetof(struct umsch_mm_test_ring_data, vpe_ib) / 4;
-	uint64_t ib_gpu_addr = test->ring_data_gpu_addr +
-		offsetof(struct umsch_mm_test_ring_data, vpe_ib);
-	uint32_t *fence = ib + 2048 / 4;
-	uint64_t fence_gpu_addr = ib_gpu_addr + 2048;
-	const uint32_t test_pattern = 0xdeadbeef;
-	int i;
-
-	ib[0] = VPE_CMD_HEADER(VPE_CMD_OPCODE_FENCE, 0);
-	ib[1] = lower_32_bits(fence_gpu_addr);
-	ib[2] = upper_32_bits(fence_gpu_addr);
-	ib[3] = test_pattern;
-
-	ring[0] = VPE_CMD_HEADER(VPE_CMD_OPCODE_INDIRECT, 0);
-	ring[1] = (ib_gpu_addr & 0xffffffe0);
-	ring[2] = upper_32_bits(ib_gpu_addr);
-	ring[3] = 4;
-	ring[4] = 0;
-	ring[5] = 0;
-
-	mqd->wptr_val = (6 << 2);
-	if (adev->vpe.collaborate_mode)
-		(++mqd)->wptr_val = (6 << 2);
-
-	WDOORBELL32(adev->umsch_mm.agdb_index[CONTEXT_PRIORITY_LEVEL_NORMAL], mqd->wptr_val);
-
-	for (i = 0; i < adev->usec_timeout; i++) {
-		if (*fence == test_pattern)
-			return 0;
-		udelay(1);
-	}
-
-	dev_err(adev->dev, "vpe queue submission timeout\n");
-
-	return -ETIMEDOUT;
-}
-
-static int submit_vcn_queue(struct amdgpu_device *adev, struct umsch_mm_test *test)
-{
-	return 0;
-}
-
-static int setup_umsch_mm_test(struct amdgpu_device *adev,
-			  struct umsch_mm_test *test)
-{
-	struct amdgpu_vmhub *hub = &adev->vmhub[AMDGPU_MMHUB0(0)];
-	int r;
-
-	test->vm_cntx_cntl = hub->vm_cntx_cntl;
-
-	test->vm = kzalloc(sizeof(*test->vm), GFP_KERNEL);
-	if (!test->vm) {
-		r = -ENOMEM;
-		return r;
-	}
-
-	r = amdgpu_vm_init(adev, test->vm, -1);
-	if (r)
-		goto error_free_vm;
-
-	r = amdgpu_pasid_alloc(16);
-	if (r < 0)
-		goto error_fini_vm;
-	test->pasid = r;
-
-	r = amdgpu_bo_create_kernel(adev, sizeof(struct umsch_mm_test_ctx_data),
-				    PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
-				    &test->ctx_data_obj,
-				    &test->ctx_data_gpu_addr,
-				    (void **)&test->ctx_data_cpu_addr);
-	if (r)
-		goto error_free_pasid;
-
-	memset(test->ctx_data_cpu_addr, 0, sizeof(struct umsch_mm_test_ctx_data));
-
-	r = amdgpu_bo_create_kernel(adev, PAGE_SIZE,
-				    PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
-				    &test->mqd_data_obj,
-				    &test->mqd_data_gpu_addr,
-				    (void **)&test->mqd_data_cpu_addr);
-	if (r)
-		goto error_free_ctx_data_obj;
-
-	memset(test->mqd_data_cpu_addr, 0, PAGE_SIZE);
-
-	r = amdgpu_bo_create_kernel(adev, sizeof(struct umsch_mm_test_ring_data),
-				    PAGE_SIZE, AMDGPU_GEM_DOMAIN_GTT,
-				    &test->ring_data_obj,
-				    NULL,
-				    (void **)&test->ring_data_cpu_addr);
-	if (r)
-		goto error_free_mqd_data_obj;
-
-	memset(test->ring_data_cpu_addr, 0, sizeof(struct umsch_mm_test_ring_data));
-
-	test->ring_data_gpu_addr = AMDGPU_VA_RESERVED_BOTTOM;
-	r = map_ring_data(adev, test->vm, test->ring_data_obj, &test->bo_va,
-			  test->ring_data_gpu_addr, sizeof(struct umsch_mm_test_ring_data));
-	if (r)
-		goto error_free_ring_data_obj;
-
-	return 0;
-
-error_free_ring_data_obj:
-	amdgpu_bo_free_kernel(&test->ring_data_obj, NULL,
-			      (void **)&test->ring_data_cpu_addr);
-error_free_mqd_data_obj:
-	amdgpu_bo_free_kernel(&test->mqd_data_obj, &test->mqd_data_gpu_addr,
-			      (void **)&test->mqd_data_cpu_addr);
-error_free_ctx_data_obj:
-	amdgpu_bo_free_kernel(&test->ctx_data_obj, &test->ctx_data_gpu_addr,
-			      (void **)&test->ctx_data_cpu_addr);
-error_free_pasid:
-	amdgpu_pasid_free(test->pasid);
-error_fini_vm:
-	amdgpu_vm_fini(adev, test->vm);
-error_free_vm:
-	kfree(test->vm);
-
-	return r;
-}
-
-static void cleanup_umsch_mm_test(struct amdgpu_device *adev,
-				  struct umsch_mm_test *test)
-{
-	unmap_ring_data(adev, test->vm, test->ring_data_obj,
-			test->bo_va, test->ring_data_gpu_addr);
-	amdgpu_bo_free_kernel(&test->mqd_data_obj, &test->mqd_data_gpu_addr,
-			      (void **)&test->mqd_data_cpu_addr);
-	amdgpu_bo_free_kernel(&test->ring_data_obj, NULL,
-			      (void **)&test->ring_data_cpu_addr);
-	amdgpu_bo_free_kernel(&test->ctx_data_obj, &test->ctx_data_gpu_addr,
-			       (void **)&test->ctx_data_cpu_addr);
-	amdgpu_pasid_free(test->pasid);
-	amdgpu_vm_fini(adev, test->vm);
-	kfree(test->vm);
-}
-
-static int setup_test_queues(struct amdgpu_device *adev,
-			     struct umsch_mm_test *test,
-			     struct umsch_mm_test_queue_info *qinfo)
-{
-	int i, r;
-
-	for (i = 0; i < test->num_queues; i++) {
-		if (qinfo[i].engine == UMSCH_SWIP_ENGINE_TYPE_VPE)
-			setup_vpe_queue(adev, test, &qinfo[i]);
-		else
-			setup_vcn_queue(adev, test, &qinfo[i]);
-
-		r = add_test_queue(adev, test, &qinfo[i]);
-		if (r)
-			return r;
-	}
-
-	return 0;
-}
-
-static int submit_test_queues(struct amdgpu_device *adev,
-			      struct umsch_mm_test *test,
-			      struct umsch_mm_test_queue_info *qinfo)
-{
-	int i, r;
-
-	for (i = 0; i < test->num_queues; i++) {
-		if (qinfo[i].engine == UMSCH_SWIP_ENGINE_TYPE_VPE)
-			r = submit_vpe_queue(adev, test);
-		else
-			r = submit_vcn_queue(adev, test);
-		if (r)
-			return r;
-	}
-
-	return 0;
-}
-
-static void cleanup_test_queues(struct amdgpu_device *adev,
-			      struct umsch_mm_test *test,
-			      struct umsch_mm_test_queue_info *qinfo)
-{
-	int i;
-
-	for (i = 0; i < test->num_queues; i++)
-		remove_test_queue(adev, test, &qinfo[i]);
-}
-
-static int umsch_mm_test(struct amdgpu_device *adev)
-{
-	struct umsch_mm_test_queue_info qinfo[] = {
-		{ .engine = UMSCH_SWIP_ENGINE_TYPE_VPE },
-	};
-	struct umsch_mm_test test = { .num_queues = ARRAY_SIZE(qinfo) };
-	int r;
-
-	r = setup_umsch_mm_test(adev, &test);
-	if (r)
-		return r;
-
-	r = setup_test_queues(adev, &test, qinfo);
-	if (r)
-		goto cleanup;
-
-	r = submit_test_queues(adev, &test, qinfo);
-	if (r)
-		goto cleanup;
-
-	cleanup_test_queues(adev, &test, qinfo);
-	cleanup_umsch_mm_test(adev, &test);
-
-	return 0;
-
-cleanup:
-	cleanup_test_queues(adev, &test, qinfo);
-	cleanup_umsch_mm_test(adev, &test);
-	return r;
-}
-
 int amdgpu_umsch_mm_submit_pkt(struct amdgpu_umsch_mm *umsch, void *pkt, int ndws)
 {
 	struct amdgpu_ring *ring = &umsch->ring;
@@ -791,7 +334,7 @@ static int umsch_mm_late_init(void *hand
 	if (amdgpu_in_reset(adev) || adev->in_s0ix || adev->in_suspend)
 		return 0;
 
-	return umsch_mm_test(adev);
+	return 0;
 }
 
 static int umsch_mm_sw_init(void *handle)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 809/877] drm/amdgpu: use GFP_NOWAIT for memory allocations
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (807 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 808/877] drm/amdgpu/umsch: remove vpe test from umsch Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 810/877] drm/amdgpu: fix rmmio iounmap skipped on device removal Greg Kroah-Hartman
                   ` (75 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Christian König,
	Srinivasan Shanmugam, Alex Deucher, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Christian König <christian.koenig@amd.com>

[ Upstream commit 16590745b571c07869ef8958e0bbe44ab6f08d1f ]

In the critical submission path memory allocations can't wait for
reclaim since that can potentially wait for submissions to finish.

Finally clean that up and mark most memory allocations in the critical
path with GFP_NOWAIT. The only exception left is the dma_fence_array()
used when no VMID is available, but that will be cleaned up later on.

Signed-off-by: Christian König <christian.koenig@amd.com>
Acked-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Stable-dep-of: 5155002b03b2 ("drm/amdgpu: fix rmmio iounmap skipped on device removal")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c |    8 ++++----
 drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c           |   18 +++++++++++-------
 drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c          |   11 +++++++----
 drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c          |    4 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c         |   11 ++++++-----
 drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h         |    3 ++-
 6 files changed, 32 insertions(+), 23 deletions(-)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -491,7 +491,7 @@ static int vm_update_pds(struct amdgpu_v
 	if (ret)
 		return ret;
 
-	return amdgpu_sync_fence(sync, vm->last_update);
+	return amdgpu_sync_fence(sync, vm->last_update, GFP_KERNEL);
 }
 
 static uint64_t get_pte_flags(struct amdgpu_device *adev, struct kgd_mem *mem)
@@ -1255,7 +1255,7 @@ static int unmap_bo_from_gpuvm(struct kg
 
 	(void)amdgpu_vm_clear_freed(adev, vm, &bo_va->last_pt_update);
 
-	(void)amdgpu_sync_fence(sync, bo_va->last_pt_update);
+	(void)amdgpu_sync_fence(sync, bo_va->last_pt_update, GFP_KERNEL);
 
 	return 0;
 }
@@ -1279,7 +1279,7 @@ static int update_gpuvm_pte(struct kgd_m
 		return ret;
 	}
 
-	return amdgpu_sync_fence(sync, bo_va->last_pt_update);
+	return amdgpu_sync_fence(sync, bo_va->last_pt_update, GFP_KERNEL);
 }
 
 static int map_bo_to_gpuvm(struct kgd_mem *mem,
@@ -2971,7 +2971,7 @@ int amdgpu_amdkfd_gpuvm_restore_process_
 		}
 		dma_resv_for_each_fence(&cursor, bo->tbo.base.resv,
 					DMA_RESV_USAGE_KERNEL, fence) {
-			ret = amdgpu_sync_fence(&sync_obj, fence);
+			ret = amdgpu_sync_fence(&sync_obj, fence, GFP_KERNEL);
 			if (ret) {
 				pr_debug("Memory eviction: Sync BO fence failed. Try again\n");
 				goto validate_map_fail;
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -462,7 +462,7 @@ static int amdgpu_cs_p2_dependencies(str
 			dma_fence_put(old);
 		}
 
-		r = amdgpu_sync_fence(&p->sync, fence);
+		r = amdgpu_sync_fence(&p->sync, fence, GFP_KERNEL);
 		dma_fence_put(fence);
 		if (r)
 			return r;
@@ -484,7 +484,7 @@ static int amdgpu_syncobj_lookup_and_add
 		return r;
 	}
 
-	r = amdgpu_sync_fence(&p->sync, fence);
+	r = amdgpu_sync_fence(&p->sync, fence, GFP_KERNEL);
 	dma_fence_put(fence);
 	return r;
 }
@@ -1157,7 +1157,8 @@ static int amdgpu_cs_vm_handling(struct
 	if (r)
 		return r;
 
-	r = amdgpu_sync_fence(&p->sync, fpriv->prt_va->last_pt_update);
+	r = amdgpu_sync_fence(&p->sync, fpriv->prt_va->last_pt_update,
+			      GFP_KERNEL);
 	if (r)
 		return r;
 
@@ -1168,7 +1169,8 @@ static int amdgpu_cs_vm_handling(struct
 		if (r)
 			return r;
 
-		r = amdgpu_sync_fence(&p->sync, bo_va->last_pt_update);
+		r = amdgpu_sync_fence(&p->sync, bo_va->last_pt_update,
+				      GFP_KERNEL);
 		if (r)
 			return r;
 	}
@@ -1187,7 +1189,8 @@ static int amdgpu_cs_vm_handling(struct
 		if (r)
 			return r;
 
-		r = amdgpu_sync_fence(&p->sync, bo_va->last_pt_update);
+		r = amdgpu_sync_fence(&p->sync, bo_va->last_pt_update,
+				      GFP_KERNEL);
 		if (r)
 			return r;
 	}
@@ -1200,7 +1203,7 @@ static int amdgpu_cs_vm_handling(struct
 	if (r)
 		return r;
 
-	r = amdgpu_sync_fence(&p->sync, vm->last_update);
+	r = amdgpu_sync_fence(&p->sync, vm->last_update, GFP_KERNEL);
 	if (r)
 		return r;
 
@@ -1267,7 +1270,8 @@ static int amdgpu_cs_sync_rings(struct a
 			continue;
 		}
 
-		r = amdgpu_sync_fence(&p->gang_leader->explicit_sync, fence);
+		r = amdgpu_sync_fence(&p->gang_leader->explicit_sync, fence,
+				      GFP_KERNEL);
 		dma_fence_put(fence);
 		if (r)
 			return r;
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c
@@ -220,7 +220,7 @@ static int amdgpu_vmid_grab_idle(struct
 		return 0;
 	}
 
-	fences = kmalloc_array(id_mgr->num_ids, sizeof(void *), GFP_KERNEL);
+	fences = kmalloc_array(id_mgr->num_ids, sizeof(void *), GFP_NOWAIT);
 	if (!fences)
 		return -ENOMEM;
 
@@ -337,7 +337,8 @@ static int amdgpu_vmid_grab_reserved(str
 	/* Good we can use this VMID. Remember this submission as
 	* user of the VMID.
 	*/
-	r = amdgpu_sync_fence(&(*id)->active, &job->base.s_fence->finished);
+	r = amdgpu_sync_fence(&(*id)->active, &job->base.s_fence->finished,
+			      GFP_NOWAIT);
 	if (r)
 		return r;
 
@@ -398,7 +399,8 @@ static int amdgpu_vmid_grab_used(struct
 		 * user of the VMID.
 		 */
 		r = amdgpu_sync_fence(&(*id)->active,
-				      &job->base.s_fence->finished);
+				      &job->base.s_fence->finished,
+				      GFP_NOWAIT);
 		if (r)
 			return r;
 
@@ -450,7 +452,8 @@ int amdgpu_vmid_grab(struct amdgpu_vm *v
 
 			/* Remember this submission as user of the VMID */
 			r = amdgpu_sync_fence(&id->active,
-					      &job->base.s_fence->finished);
+					      &job->base.s_fence->finished,
+					      GFP_NOWAIT);
 			if (r)
 				goto error;
 
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -1354,14 +1354,14 @@ int amdgpu_mes_ctx_map_meta_data(struct
 		DRM_ERROR("failed to do vm_bo_update on meta data\n");
 		goto error_del_bo_va;
 	}
-	amdgpu_sync_fence(&sync, bo_va->last_pt_update);
+	amdgpu_sync_fence(&sync, bo_va->last_pt_update, GFP_KERNEL);
 
 	r = amdgpu_vm_update_pdes(adev, vm, false);
 	if (r) {
 		DRM_ERROR("failed to update pdes on meta data\n");
 		goto error_del_bo_va;
 	}
-	amdgpu_sync_fence(&sync, vm->last_update);
+	amdgpu_sync_fence(&sync, vm->last_update, GFP_KERNEL);
 
 	amdgpu_sync_wait(&sync, false);
 	drm_exec_fini(&exec);
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -152,7 +152,8 @@ static bool amdgpu_sync_add_later(struct
  *
  * Add the fence to the sync object.
  */
-int amdgpu_sync_fence(struct amdgpu_sync *sync, struct dma_fence *f)
+int amdgpu_sync_fence(struct amdgpu_sync *sync, struct dma_fence *f,
+		      gfp_t flags)
 {
 	struct amdgpu_sync_entry *e;
 
@@ -162,7 +163,7 @@ int amdgpu_sync_fence(struct amdgpu_sync
 	if (amdgpu_sync_add_later(sync, f))
 		return 0;
 
-	e = kmem_cache_alloc(amdgpu_sync_slab, GFP_KERNEL);
+	e = kmem_cache_alloc(amdgpu_sync_slab, flags);
 	if (!e)
 		return -ENOMEM;
 
@@ -249,7 +250,7 @@ int amdgpu_sync_resv(struct amdgpu_devic
 			struct dma_fence *tmp = dma_fence_chain_contained(f);
 
 			if (amdgpu_sync_test_fence(adev, mode, owner, tmp)) {
-				r = amdgpu_sync_fence(sync, f);
+				r = amdgpu_sync_fence(sync, f, GFP_KERNEL);
 				dma_fence_put(f);
 				if (r)
 					return r;
@@ -281,7 +282,7 @@ int amdgpu_sync_kfd(struct amdgpu_sync *
 		if (fence_owner != AMDGPU_FENCE_OWNER_KFD)
 			continue;
 
-		r = amdgpu_sync_fence(sync, f);
+		r = amdgpu_sync_fence(sync, f, GFP_KERNEL);
 		if (r)
 			break;
 	}
@@ -388,7 +389,7 @@ int amdgpu_sync_clone(struct amdgpu_sync
 	hash_for_each_safe(source->fences, i, tmp, e, node) {
 		f = e->fence;
 		if (!dma_fence_is_signaled(f)) {
-			r = amdgpu_sync_fence(clone, f);
+			r = amdgpu_sync_fence(clone, f, GFP_KERNEL);
 			if (r)
 				return r;
 		} else {
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.h
@@ -47,7 +47,8 @@ struct amdgpu_sync {
 };
 
 void amdgpu_sync_create(struct amdgpu_sync *sync);
-int amdgpu_sync_fence(struct amdgpu_sync *sync, struct dma_fence *f);
+int amdgpu_sync_fence(struct amdgpu_sync *sync, struct dma_fence *f,
+		      gfp_t flags);
 int amdgpu_sync_resv(struct amdgpu_device *adev, struct amdgpu_sync *sync,
 		     struct dma_resv *resv, enum amdgpu_sync_mode mode,
 		     void *owner);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 810/877] drm/amdgpu: fix rmmio iounmap skipped on device removal
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (808 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 809/877] drm/amdgpu: use GFP_NOWAIT for memory allocations Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 811/877] smb: client: fix OOB struct field reads in move_smb2_ea_to_cifs() Greg Kroah-Hartman
                   ` (74 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Chengjun Yao, Asad Kamal,
	Alex Deucher, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Chengjun Yao <Chengjun.Yao@amd.com>

[ Upstream commit 5155002b03b24ba3ef91c5c313b8cf0171b24904 ]

amdgpu_pci_remove() calls drm_dev_unplug() before fini_sw(), so
drm_dev_enter() is already false there and the iounmap() guarded by it
is skipped. This .remove path runs on both hot-unplug and plain rmmod,
so the register BAR ioremap mapping leaks one instance per unload.

Unmap rmmio unconditionally (guard only on non-NULL) and drop the now
unused idx.

Fixes: 62d5f9f7110a ("drm/amdgpu: Unmap MMIO mappings when device is not unplugged")
Signed-off-by: Chengjun Yao <Chengjun.Yao@amd.com>
Reviewed-by: Asad Kamal <asad.kamal@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit dd6f86a97260e5207d3329ad03aa89fdad61b1e6)
Cc: stable@vger.kernel.org
[ removed `int idx;` entirely because the isolation cleanup loop requiring `i` is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -4776,7 +4776,6 @@ void amdgpu_device_fini_hw(struct amdgpu
 
 void amdgpu_device_fini_sw(struct amdgpu_device *adev)
 {
-	int idx;
 	bool px;
 
 	amdgpu_device_ip_fini(adev);
@@ -4814,11 +4813,9 @@ void amdgpu_device_fini_sw(struct amdgpu
 	if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
 		vga_client_unregister(adev->pdev);
 
-	if (drm_dev_enter(adev_to_drm(adev), &idx)) {
-
+	if (adev->rmmio) {
 		iounmap(adev->rmmio);
 		adev->rmmio = NULL;
-		drm_dev_exit(idx);
 	}
 
 	if (IS_ENABLED(CONFIG_PERF_EVENTS))



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 811/877] smb: client: fix OOB struct field reads in move_smb2_ea_to_cifs()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (809 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 810/877] drm/amdgpu: fix rmmio iounmap skipped on device removal Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 812/877] drm: add drm_memory_stats_is_zero Greg Kroah-Hartman
                   ` (73 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
	Paulo Alcantara, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Frank Sorenson <sorenson@redhat.com>

[ Upstream commit eeb5ef6083e1cefa2ef75041b5597ff228b8d7bb ]

In move_smb2_ea_to_cifs(), the while (src_size > 0) loop condition is
insufficient. It allows iteration to continue even if the remaining
src_size is too small to contain a complete smb2_ea_info structure.
Consequently, reads of ea_name_length and ea_value_length can occur
out-of-bounds.

Fix this by ensuring src_size >= sizeof(*src) before attempting to read
any structure fields. Additionally, reject any next_entry_offset that is
smaller than sizeof(*src) or that would advance the pointer beyond the
available buffer.

Note that for calls where the server returns a malformed EA list, the
error returned to userspace changes from -ENODATA (getxattr) or
-ERANGE (listxattr) to -EIO. This correctly signals a server protocol
error rather than misleadingly indicating "attribute not present" or
"output buffer too small".

Fixes: 95907fea4fd8 ("cifs: Add support for reading attributes on SMB2+")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ Replaced unavailable smb_EIO2() tracing calls with -EIO. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/smb2ops.c |   24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -1057,8 +1057,9 @@ move_smb2_ea_to_cifs(char *dst, size_t d
 	char *name, *value;
 	size_t buf_size = dst_size;
 	size_t name_len, value_len, user_name_len;
+	u32 next_off;
 
-	while (src_size > 0) {
+	while (src_size >= sizeof(*src)) {
 		name_len = (size_t)src->ea_name_length;
 		value_len = (size_t)le16_to_cpu(src->ea_value_length);
 
@@ -1113,14 +1114,21 @@ move_smb2_ea_to_cifs(char *dst, size_t d
 		if (!src->next_entry_offset)
 			break;
 
-		if (src_size < le32_to_cpu(src->next_entry_offset)) {
-			/* stop before overrun buffer */
-			rc = -ERANGE;
-			break;
+		next_off = le32_to_cpu(src->next_entry_offset);
+		if (next_off < sizeof(*src) || src_size < next_off) {
+			cifs_dbg(FYI, "EA next_entry_offset %u out of range [%zu, %zu]\n",
+				 next_off, sizeof(*src), src_size);
+			rc = -EIO;
+			goto out;
+		}
+		src_size -= next_off;
+		src = (void *)((char *)src + next_off);
+		if (src_size > 0 && src_size < sizeof(*src)) {
+			cifs_dbg(FYI, "EA next_entry_offset %u left truncated entry (%zu bytes)\n",
+				 next_off, src_size);
+			rc = -EIO;
+			goto out;
 		}
-		src_size -= le32_to_cpu(src->next_entry_offset);
-		src = (void *)((char *)src +
-			       le32_to_cpu(src->next_entry_offset));
 	}
 
 	/* didn't find the named attribute */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 812/877] drm: add drm_memory_stats_is_zero
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (810 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 811/877] smb: client: fix OOB struct field reads in move_smb2_ea_to_cifs() Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 813/877] drm/amdgpu: hold a runtime PM reference for P2P dma-buf attachments Greg Kroah-Hartman
                   ` (72 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Yunxiang Li, Christian König,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Yunxiang Li <Yunxiang.Li@amd.com>

[ Upstream commit fd265d9e0c3358e6b9fe244d8f5d2824fda1c0dc ]

Add a helper to check if the memory stats is zero, this will be used to
check for memory accounting errors.

Signed-off-by: Yunxiang Li <Yunxiang.Li@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241219151411.1150-2-Yunxiang.Li@amd.com
Signed-off-by: Christian König <christian.koenig@amd.com>
Stable-dep-of: 636139603b99 ("drm/amdgpu: hold a runtime PM reference for P2P dma-buf attachments")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/drm_file.c |   10 ++++++++++
 include/drm/drm_file.h     |    1 +
 2 files changed, 11 insertions(+)

--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -840,6 +840,16 @@ static void print_size(struct drm_printe
 	drm_printf(p, "drm-%s-%s:\t%llu%s\n", stat, region, sz, units[u]);
 }
 
+int drm_memory_stats_is_zero(const struct drm_memory_stats *stats)
+{
+	return (stats->shared == 0 &&
+		stats->private == 0 &&
+		stats->resident == 0 &&
+		stats->purgeable == 0 &&
+		stats->active == 0);
+}
+EXPORT_SYMBOL(drm_memory_stats_is_zero);
+
 /**
  * drm_print_memory_stats - A helper to print memory stats
  * @p: The printer to print output to
--- a/include/drm/drm_file.h
+++ b/include/drm/drm_file.h
@@ -485,6 +485,7 @@ struct drm_memory_stats {
 
 enum drm_gem_object_status;
 
+int drm_memory_stats_is_zero(const struct drm_memory_stats *stats);
 void drm_print_memory_stats(struct drm_printer *p,
 			    const struct drm_memory_stats *stats,
 			    enum drm_gem_object_status supported_status,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 813/877] drm/amdgpu: hold a runtime PM reference for P2P dma-buf attachments
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (811 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 812/877] drm: add drm_memory_stats_is_zero Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 814/877] smb: client: fix reparse buffer bounds in cifs_query_reparse_point() Greg Kroah-Hartman
                   ` (71 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Christian König, Mike Lothian,
	Alex Deucher, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mike Lothian <mike@fireburn.co.uk>

[ Upstream commit 636139603b99d2e3a18a46cf3f8d39313ce8042e ]

amdgpu_dma_buf_map() adds VRAM to the allowed domains for a peer2peer
attachment.  GTT is only a fallback placement when VRAM is preferred, so
ttm_bo_validate() migrates the buffer from GTT into VRAM.  While the
exporting device is runtime suspended its SDMA rings are down and the
move fails:

  amdgpu: Move buffer fallback to memcpy unavailable

An importer on a second GPU reaches this holding no runtime PM
reference on the exporter, e.g. a compositor on the APU submitting a
frame that references a buffer exported by an idle dGPU:

  amdgpu_cs_ioctl -> amdgpu_cs_parser_bos -> amdgpu_cs_bo_validate
    -> ttm_bo_validate -> amdgpu_bo_move -> dma_buf_map_attachment
      -> amdgpu_dma_buf_map -> ttm_bo_validate -> amdgpu_bo_move

Pinning a dma-buf into VRAM has the same requirement, which
commit 030631e97b20 ("drm/amdgpu: revert "take runtime pm reference
when we attach a buffer" v2") called out as the one case that would
need the reference back.

Take it in attach and drop it in detach.  pm_runtime_get_if_active()
never resumes the device, so it cannot deadlock against the reservation
taken during resume, which is why the old pm_runtime_get_sync() had to
go.  If the device is not active, clear peer2peer instead: the buffer
then stays in GTT, which remains accessible while the GPU is powered
down.  If runtime PM is disabled, take a plain reference so the put in
detach stays balanced.

Fixes: 030631e97b20 ("drm/amdgpu: revert "take runtime pm reference when we attach a buffer" v2")
Suggested-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Mike Lothian <mike@fireburn.co.uk>
Assisted-by: Claude:Opus-5 [Claude Code]
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 062ff15e30a48d14fb7d7558eba84f8dc97197f0)
Cc: stable@vger.kernel.org
[ omitted err_pm_put cleanup because this branch lacks the reservation-locking failure path. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c |   36 ++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -41,6 +41,7 @@
 #include <linux/dma-buf.h>
 #include <linux/dma-fence-array.h>
 #include <linux/pci-p2pdma.h>
+#include <linux/pm_runtime.h>
 
 static const struct dma_buf_attach_ops amdgpu_dma_buf_attach_ops;
 
@@ -97,10 +98,44 @@ static int amdgpu_dma_buf_attach(struct
 	    pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0)
 		attach->peer2peer = false;
 
+	/*
+	 * Only allow P2P while the exporter is active, and keep it active
+	 * until detach.  With runtime PM disabled take a plain reference so
+	 * the put in detach stays balanced.
+	 */
+	if (attach->peer2peer) {
+		struct device *dev = adev_to_drm(adev)->dev;
+		int ret = pm_runtime_get_if_active(dev);
+
+		if (!ret)
+			attach->peer2peer = false;
+		else if (ret < 0)
+			pm_runtime_get_noresume(dev);
+	}
+
 	return 0;
 }
 
 /**
+ * amdgpu_dma_buf_detach - &dma_buf_ops.detach implementation
+ *
+ * @dmabuf: DMA-buf where we remove the attachment from
+ * @attach: the attachment to remove
+ *
+ * Drop the runtime PM reference taken in amdgpu_dma_buf_attach().
+ */
+static void amdgpu_dma_buf_detach(struct dma_buf *dmabuf,
+				  struct dma_buf_attachment *attach)
+{
+	struct drm_gem_object *obj = dmabuf->priv;
+	struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
+	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
+
+	if (attach->peer2peer)
+		pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
+}
+
+/**
  * amdgpu_dma_buf_pin - &dma_buf_ops.pin implementation
  *
  * @attach: attachment to pin down
@@ -270,6 +305,7 @@ static int amdgpu_dma_buf_begin_cpu_acce
 
 const struct dma_buf_ops amdgpu_dmabuf_ops = {
 	.attach = amdgpu_dma_buf_attach,
+	.detach = amdgpu_dma_buf_detach,
 	.pin = amdgpu_dma_buf_pin,
 	.unpin = amdgpu_dma_buf_unpin,
 	.map_dma_buf = amdgpu_dma_buf_map,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 814/877] smb: client: fix reparse buffer bounds in cifs_query_reparse_point()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (812 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 813/877] drm/amdgpu: hold a runtime PM reference for P2P dma-buf attachments Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 815/877] smb/client: send lease break ACKs thru correct session for multiuser mounts Greg Kroah-Hartman
                   ` (70 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Frank Sorenson, David Howells,
	Paulo Alcantara, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Frank Sorenson <sorenson@redhat.com>

[ Upstream commit 5f0306e731e2f46e91419eae57eee3a241c055e0 ]

In cifs_query_reparse_point(), the start >= end check before casting to
struct reparse_data_buffer * only ensures the start pointer is within the
response. It fails to verify that there is enough space remaining for the
fixed 8-byte header of the structure.

If a server provides a DataOffset that leaves less than 8 bytes remaining,
the check passes, but subsequent reads of ReparseTag and ReparseDataLength
will occur out-of-bounds.

Fix this by ensuring the remaining space is at least the size of the
reparse_data_buffer structure before accessing its fields.

Fixes: 56e84c64fc25 ("cifs: Fix validation of SMB1 query reparse point response")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ Adjusted context to retain existing `rc = -EIO` error handling instead of upstream `smb_EIO2()`. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/cifssmb.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -2829,7 +2829,7 @@ int cifs_query_reparse_point(const unsig
 
 	end = 2 + get_bcc(&io_rsp->hdr) + (__u8 *)&io_rsp->ByteCount;
 	start = (__u8 *)&io_rsp->hdr.Protocol + data_offset;
-	if (start >= end) {
+	if (start >= end || (size_t)(end - start) < sizeof(*buf)) {
 		rc = -EIO;
 		goto error;
 	}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 815/877] smb/client: send lease break ACKs thru correct session for multiuser mounts
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (813 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 814/877] smb: client: fix reparse buffer bounds in cifs_query_reparse_point() Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 816/877] arm64/boot: Disable trapping of PMZR_EL0 writes to EL2 Greg Kroah-Hartman
                   ` (69 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, April Cardenas, Namjae Jeon,
	Bharath S M, Paulo Alcantara, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: April Cardenas <april.cardenas@canonical.com>

[ Upstream commit ebc5660132ddd244b57f03ed324922013a3d7363 ]

Currently, when cifs_oplock_break handles a break request from the server
it searches for the appropriate tlink to handle the request
but incorrectly uses the current fsuid as the search key, eventually
causing read errors for users with multiuser mounts on NetApp.
Fix this by using the tlink from the cfile struct instead to respond
through the correct session.

As breaks are handled in a worker thread, the current fsuid
isn't guaranteed to match the session that the break is intended for.
This means that cifs_sb_tlink may search the rbtree using the wrong fsuid,
and return a tlink with an incorrect session than
the lease break was intended for. As a result, the breaks
may be ACKed through an incorrect session.

While it seems that Samba/Windows Servers 2016-2025 ignore this as long as
the lease key is correct, we ran into a case where if you're using
NetApp ONTAP or Azure NetApp Files they will reject the ACK
and return `STATUS_LOCK_NOT_GRANTED` errors on any future read requests
a user may initiate through their still held open file handle,
and the server will eventually close the file.

In the dmesg logs, the user may see errors like these:

CIFS: Status code returned 0xc0000128 STATUS_FILE_CLOSED
CIFS: VFS: Send error in read = -9

With a multiuser mount using NetApp, this issue is really easy
for users to hit on a wide variety of kernel versions
by attempting to copy a file from the share
to the local machine through GNOME Files/Nautilus.
This copy will always result in Nautilus throwing
a `Bad File Descriptor` error to the user and fail.
With this fix, you can copy files through Nautilus without issue.

>>From looking at the traces, it seems that glib will
open the file first, and call listxattr before actually attempting
to copy the file data. The listxattr call always triggers a break,
causing the copy to fail.

The proposed fix returns to the way the client grabbed the tlink before
commit e8f5f849ffce2 ("cifs: fix potential oops in cifs_oplock_break").

The bulk of that commit (checking for list empty) remains untouched, and
I think the change to using cifs_sb_tlink was intended to avoid a
NULL/ERR deference on the tlink as well as update the reference count.

I believe this fix should preserve those safety properties, but of course
I'd appreciate any corrections here.

Fixes: e8f5f849ffce2 ("cifs: fix potential oops in cifs_oplock_break")
Cc: stable@vger.kernel.org
Signed-off-by: April Cardenas <april.cardenas@canonical.com>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Reviewed-by: Bharath S M <bharathsm@microsoft.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ Removed now-unused sb and cifs_sb declarations from cifs_oplock_break(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/smb/client/file.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

--- a/fs/smb/client/file.c
+++ b/fs/smb/client/file.c
@@ -3067,8 +3067,6 @@ void cifs_oplock_break(struct work_struc
 	struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
 						  oplock_break);
 	struct inode *inode = d_inode(cfile->dentry);
-	struct super_block *sb = inode->i_sb;
-	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
 	struct cifsInodeInfo *cinode = CIFS_I(inode);
 	struct cifs_tcon *tcon;
 	struct TCP_Server_Info *server;
@@ -3081,8 +3079,8 @@ void cifs_oplock_break(struct work_struc
 	wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS,
 			TASK_UNINTERRUPTIBLE);
 
-	tlink = cifs_sb_tlink(cifs_sb);
-	if (IS_ERR(tlink)) {
+	tlink = cifs_get_tlink(cfile->tlink);
+	if (IS_ERR_OR_NULL(tlink)) {
 		/* drop the reference taken when the break was queued */
 		_cifsFileInfo_put(cfile, false /* do not wait for ourself */, false);
 		goto out;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 816/877] arm64/boot: Disable trapping of PMZR_EL0 writes to EL2
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (814 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 815/877] smb/client: send lease break ACKs thru correct session for multiuser mounts Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 817/877] vlan: require the MAC header to be present in __vlan_insert_inner_tag() Greg Kroah-Hartman
                   ` (68 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Fuad Tabba, Anshuman Khandual,
	Oliver Upton, Will Deacon

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Fuad Tabba <fuad.tabba@linux.dev>

commit 2bc6b218717b9d08f466f88209251d54bc09b207 upstream.

__init_el2_fgt2() writes one mask to both HDFGRTR2_EL2 and HDFGWTR2_EL2.
PMZR_EL0 is write-only, so its trap bit, nPMZR_EL0, exists only in
HDFGWTR2_EL2 and is therefore never set: a PMZR_EL0 write from the host
traps to EL2, where the nVHE hypervisor has no handler and BUG()s. The
kernel never writes PMZR_EL0, but kernel.perf_user_access=1 has the PMU
driver set PMUSERENR_EL0.UEN for a task with a user-read event, so a
write from EL0 reaches the trap and takes the host down without a panic
message.

Accumulate the HDFGWTR2_EL2 bits separately, as __init_el2_fgt() already
does for HDFGWTR_EL2, and set nPMZR_EL0 with the other FEAT_PMUv3p9
bits.

Fixes: 858c7bfcb35e1 ("arm64/boot: Enable EL2 requirements for FEAT_PMUv3p9")
Cc: stable@vger.kernel.org
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
Reviewed-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Will Deacon <will@kernel.org>
[Fuad: dropped the nPMSDSFR_EL1 hunk, 6.12 lacks FEAT_SPE_FDS support]
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 Documentation/arch/arm64/booting.rst |    1 +
 arch/arm64/include/asm/el2_setup.h   |    8 +++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

--- a/Documentation/arch/arm64/booting.rst
+++ b/Documentation/arch/arm64/booting.rst
@@ -400,6 +400,7 @@ Before jumping into the kernel, the foll
     - HDFGWTR2_EL2.nPMICNTR_EL0 (bit 2) must be initialised to 0b1.
     - HDFGWTR2_EL2.nPMICFILTR_EL0 (bit 3) must be initialised to 0b1.
     - HDFGWTR2_EL2.nPMUACR_EL1 (bit 4) must be initialised to 0b1.
+    - HDFGWTR2_EL2.nPMZR_EL0 (bit 21) must be initialised to 0b1.
 
   For CPUs with Memory Copy and Memory Set instructions (FEAT_MOPS):
 
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -274,6 +274,7 @@
 	b.lt	.Lskip_fgt2_\@
 
 	mov	x0, xzr
+	mov	x2, xzr
 	mrs	x1, id_aa64dfr0_el1
 	ubfx	x1, x1, #ID_AA64DFR0_EL1_PMUVer_SHIFT, #4
 	cmp	x1, #ID_AA64DFR0_EL1_PMUVer_V3P9
@@ -282,9 +283,14 @@
 	orr	x0, x0, #HDFGRTR2_EL2_nPMICNTR_EL0
 	orr	x0, x0, #HDFGRTR2_EL2_nPMICFILTR_EL0
 	orr	x0, x0, #HDFGRTR2_EL2_nPMUACR_EL1
+	orr	x2, x2, #HDFGWTR2_EL2_nPMICNTR_EL0
+	orr	x2, x2, #HDFGWTR2_EL2_nPMICFILTR_EL0
+	orr	x2, x2, #HDFGWTR2_EL2_nPMUACR_EL1
+	/* PMZR_EL0 is write-only, so it has no read trap to disable */
+	orr	x2, x2, #HDFGWTR2_EL2_nPMZR_EL0
 .Lskip_pmuv3p9_\@:
 	msr_s   SYS_HDFGRTR2_EL2, x0
-	msr_s   SYS_HDFGWTR2_EL2, x0
+	msr_s   SYS_HDFGWTR2_EL2, x2
 	msr_s   SYS_HFGRTR2_EL2, xzr
 	msr_s   SYS_HFGWTR2_EL2, xzr
 	msr_s   SYS_HFGITR2_EL2, xzr



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 817/877] vlan: require the MAC header to be present in __vlan_insert_inner_tag()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (815 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 816/877] arm64/boot: Disable trapping of PMZR_EL0 writes to EL2 Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 818/877] gpio: cdev: fix kernel stack leak to user-space in error path Greg Kroah-Hartman
                   ` (67 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, co+0ea1ac045375cf05, Xiang Mei,
	Simon Horman, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Xiang Mei <xmei5@asu.edu>

[ Upstream commit ab888242fce4f16f6c4d4c6ec53939ad36aa3b3a ]

__vlan_insert_inner_tag() only guarantees head room via skb_cow_head(),
never that mac_len bytes of MAC header are present.  Its ETH_HLEN
wrappers - __vlan_insert_tag() under skb_vlan_push(), and
vlan_insert_tag() under validate_xmit_vlan() on the generic transmit
path - therefore rewrite the first 16 bytes at skb->data: a 12-byte
memmove plus two 2-byte stores at +12 and +14.  No caller supplies the
bound, while the pop helpers use skb_ensure_writable()/pskb_may_pull().

An IFF_TUN device has hard_header_len == 0, so packet_snd() accepts a
one-byte AF_PACKET/SOCK_RAW frame.  The first vlan push only sets a
hwaccel tag; the next - clsact "action vlan push" or
bpf_skb_vlan_push() - enters the helper with skb->len still 1.  The
head comes from skbuff_small_head without __GFP_ZERO, so each push
drags bytes from beyond skb->tail into the frame.  After three the
one-byte send leaves as 13 bytes carrying 11 bytes of uninitialised
slab:

  0000: 5a b3 62 12 80 88 ff ff 00 b3 62 12 81
           `------------------------------'
  only 0x5a was sent; the rest is slab, here the top 56 bits of a
  linear-map address

Require the MAC header the helper rewrites to be present, so such a
frame is dropped rather than transmitted.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: co+0ea1ac045375cf05@bugs.sh
Signed-off-by: Xiang Mei <xmei5@asu.edu>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260915083152.705309-1-xmei5@asu.edu
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ adjusted context around skb_cow_head(skb, VLAN_HLEN) because the branch lacks upstream meta_len handling. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/linux/if_vlan.h |    3 +++
 1 file changed, 3 insertions(+)

--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -356,6 +356,9 @@ static inline int __vlan_insert_inner_ta
 {
 	struct vlan_ethhdr *veth;
 
+	if (unlikely(!pskb_may_pull(skb, mac_len)))
+		return -EINVAL;
+
 	if (skb_cow_head(skb, VLAN_HLEN) < 0)
 		return -ENOMEM;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 818/877] gpio: cdev: fix kernel stack leak to user-space in error path
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (816 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 817/877] vlan: require the MAC header to be present in __vlan_insert_inner_tag() Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 819/877] ipe: fix use-after-free when auditing a newly loaded policy Greg Kroah-Hartman
                   ` (66 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Sashiko, Kent Gibson,
	Bartosz Golaszewski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>

[ Upstream commit 1feb5d39b05afd902ed9fc902ec5b15be03a4bdb ]

If we fail to acquire the GPIO chip guard in gpio_desc_to_lineinfo(), we
return immediately before zeroing the info struct we'll end up passing
to the user-space later in lineinfo_get_v1(). This may leak the kernel
stack contents. Make gpio_desc_to_lineinfo() return int so that the
-ENODEV returned on failure to acquire the guard can be propagated to
the callers.

While not strictly necessary: move the memset() before trying to acquire
the SRCU read lock too for good measure.

Fixes: d83cee3d2bb1 ("gpio: protect the pointer to gpio_chip in gpio_device with SRCU")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260912123529.7951-1-tzungbi%40kernel.org?part=3
Reviewed-by: Kent Gibson <warthog618@gmail.com>
Link: https://patch.msgid.link/20260922-gpio-cdev-stack-leak-fixes-v3-1-7a0c7a4299d5@oss.qualcomm.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
[ retained the two-argument gpio_desc_to_lineinfo() signature for Linux 6.12’s synchronous notifier. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpio/gpiolib-cdev.c |   30 +++++++++++++++++++++++-------
 1 file changed, 23 insertions(+), 7 deletions(-)

--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -2365,17 +2365,18 @@ static void gpio_v2_line_info_changed_to
 
 #endif /* CONFIG_GPIO_CDEV_V1 */
 
-static void gpio_desc_to_lineinfo(struct gpio_desc *desc,
-				  struct gpio_v2_line_info *info)
+static int gpio_desc_to_lineinfo(struct gpio_desc *desc,
+				 struct gpio_v2_line_info *info)
 {
 	unsigned long dflags;
 	const char *label;
 
+	memset(info, 0, sizeof(*info));
+
 	CLASS(gpio_chip_guard, guard)(desc);
 	if (!guard.gc)
-		return;
+		return -ENODEV;
 
-	memset(info, 0, sizeof(*info));
 	info->offset = gpio_chip_hwgpio(desc);
 
 	if (desc->name)
@@ -2440,6 +2441,8 @@ static void gpio_desc_to_lineinfo(struct
 		info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_REALTIME;
 	else if (test_bit(FLAG_EVENT_CLOCK_HTE, &dflags))
 		info->flags |= GPIO_V2_LINE_FLAG_EVENT_CLOCK_HTE;
+
+	return 0;
 }
 
 struct gpio_chardev_data {
@@ -2490,6 +2493,7 @@ static int lineinfo_get_v1(struct gpio_c
 	struct gpio_desc *desc;
 	struct gpioline_info lineinfo;
 	struct gpio_v2_line_info lineinfo_v2;
+	int ret;
 
 	if (copy_from_user(&lineinfo, ip, sizeof(lineinfo)))
 		return -EFAULT;
@@ -2507,7 +2511,10 @@ static int lineinfo_get_v1(struct gpio_c
 			return -EBUSY;
 	}
 
-	gpio_desc_to_lineinfo(desc, &lineinfo_v2);
+	ret = gpio_desc_to_lineinfo(desc, &lineinfo_v2);
+	if (ret)
+		return ret;
+
 	gpio_v2_line_info_to_v1(&lineinfo_v2, &lineinfo);
 
 	if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) {
@@ -2525,6 +2532,7 @@ static int lineinfo_get(struct gpio_char
 {
 	struct gpio_desc *desc;
 	struct gpio_v2_line_info lineinfo;
+	int ret;
 
 	if (copy_from_user(&lineinfo, ip, sizeof(lineinfo)))
 		return -EFAULT;
@@ -2544,7 +2552,11 @@ static int lineinfo_get(struct gpio_char
 		if (test_and_set_bit(lineinfo.offset, cdev->watched_lines))
 			return -EBUSY;
 	}
-	gpio_desc_to_lineinfo(desc, &lineinfo);
+
+	ret = gpio_desc_to_lineinfo(desc, &lineinfo);
+	if (ret)
+		return ret;
+
 	supinfo_to_lineinfo(desc, &lineinfo);
 
 	if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) {
@@ -2637,7 +2649,11 @@ static int lineinfo_changed_notify(struc
 	memset(&chg, 0, sizeof(chg));
 	chg.event_type = action;
 	chg.timestamp_ns = ktime_get_ns();
-	gpio_desc_to_lineinfo(desc, &chg.info);
+
+	ret = gpio_desc_to_lineinfo(desc, &chg.info);
+	if (ret)
+		return NOTIFY_DONE;
+
 	supinfo_to_lineinfo(desc, &chg.info);
 
 	ret = kfifo_in_spinlocked(&cdev->events, &chg, 1, &cdev->wait.lock);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 819/877] ipe: fix use-after-free when auditing a newly loaded policy
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (817 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 818/877] gpio: cdev: fix kernel stack leak to user-space in error path Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 820/877] bna: prevent IOC timer rearm during teardown Greg Kroah-Hartman
                   ` (65 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Fan Wu <wufan@kernel.org>

[ Upstream commit 9814077275eca36ebf8d510d2f076d235ff9f51a ]

new_policy() audits the policy after ipe_new_policyfs_node() publishes it
and drops the new directory's inode lock. A concurrent delete can free
the policy while ipe_audit_policy_load() is still using it.

Audit the successful load under that lock.

Fixes: f44554b5067b ("audit,ipe: add IPE auditing support")
Cc: stable@vger.kernel.org
Assisted-by: LLM
[FW: remove model name according to latest guideline]
Signed-off-by: Fan Wu <wufan@kernel.org>
[ adapted new_policy() changes to the older success-only auditing implementation. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 security/ipe/fs.c        |    4 ----
 security/ipe/policy_fs.c |    4 ++++
 2 files changed, 4 insertions(+), 4 deletions(-)

--- a/security/ipe/fs.c
+++ b/security/ipe/fs.c
@@ -155,10 +155,6 @@ static ssize_t new_policy(struct file *f
 	}
 
 	rc = ipe_new_policyfs_node(p);
-	if (rc)
-		goto out;
-
-	ipe_audit_policy_load(p);
 
 out:
 	if (rc < 0)
--- a/security/ipe/policy_fs.c
+++ b/security/ipe/policy_fs.c
@@ -12,6 +12,7 @@
 #include "policy.h"
 #include "eval.h"
 #include "fs.h"
+#include "audit.h"
 
 #define MAX_VERSION_SIZE ARRAY_SIZE("65535.65535.65535")
 
@@ -463,6 +464,9 @@ int ipe_new_policyfs_node(struct ipe_pol
 	inode_lock(root);
 	p->policyfs = policyfs;
 	root->i_private = p;
+	/* Only audit signed policies from userspace */
+	if (p->pkcs7)
+		ipe_audit_policy_load(p);
 	inode_unlock(root);
 
 	return 0;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 820/877] bna: prevent IOC timer rearm during teardown
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (818 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 819/877] ipe: fix use-after-free when auditing a newly loaded policy Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 821/877] i2c: qcom-geni: Fix hardcoded clock index in SE_GENI_CLK_SEL Greg Kroah-Hartman
                   ` (64 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak, Paolo Abeni,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Myeonghun Pak <mhun512@gmail.com>

[ Upstream commit 77b1718e39e5c9f6956fb60807326af20baf889d ]

bna: prevent IOC timer rearm during teardown

bnad_pci_remove() and the probe disable_ioceth path call
timer_delete_sync() for ioc_timer, sem_timer and hb_timer, but not for
iocpf_timer.  bnad_iocpf_timeout() then takes bnad->bna_lock after
free_netdev() has freed the struct bnad.

Deleting iocpf_timer last does not fix this.  sem_timer and
iocpf_timer rearm each other: bnad_iocpf_sem_timeout() can arm
iocpf_timer, and bnad_iocpf_timeout() arms sem_timer from
bfa_ioc_hw_sem_get() when the semaphore is busy.
timer_delete_sync() only waits out its own callback.
bnad_ioceth_disable() can time out and leave that callback live.

Shut all four IOC timers down with timer_shutdown_sync() on both
paths, so a later mod_timer() is ignored.

This issue was identified during our ongoing static-analysis research
while reviewing kernel code.

Fixes: 1d32f7696286 ("bna: IOC failure auto recovery fix")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Link: https://patch.msgid.link/20260922014605.588040-1-mhun512@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
[ inlined bnad_ioc_timers_shutdown() into the existing teardown functions. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/brocade/bna/bnad.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -3725,9 +3725,11 @@ probe_uninit:
 	bnad_res_free(bnad, &bnad->mod_res_info[0], BNA_MOD_RES_T_MAX);
 disable_ioceth:
 	bnad_ioceth_disable(bnad);
-	del_timer_sync(&bnad->bna.ioceth.ioc.ioc_timer);
-	del_timer_sync(&bnad->bna.ioceth.ioc.sem_timer);
-	del_timer_sync(&bnad->bna.ioceth.ioc.hb_timer);
+	/* The IOC timers rearm one another.  Shut down all of them. */
+	timer_shutdown_sync(&bnad->bna.ioceth.ioc.ioc_timer);
+	timer_shutdown_sync(&bnad->bna.ioceth.ioc.sem_timer);
+	timer_shutdown_sync(&bnad->bna.ioceth.ioc.hb_timer);
+	timer_shutdown_sync(&bnad->bna.ioceth.ioc.iocpf_timer);
 	spin_lock_irqsave(&bnad->bna_lock, flags);
 	bna_uninit(bna);
 	spin_unlock_irqrestore(&bnad->bna_lock, flags);
@@ -3768,9 +3770,11 @@ bnad_pci_remove(struct pci_dev *pdev)
 
 	mutex_lock(&bnad->conf_mutex);
 	bnad_ioceth_disable(bnad);
-	del_timer_sync(&bnad->bna.ioceth.ioc.ioc_timer);
-	del_timer_sync(&bnad->bna.ioceth.ioc.sem_timer);
-	del_timer_sync(&bnad->bna.ioceth.ioc.hb_timer);
+	/* The IOC timers rearm one another.  Shut down all of them. */
+	timer_shutdown_sync(&bnad->bna.ioceth.ioc.ioc_timer);
+	timer_shutdown_sync(&bnad->bna.ioceth.ioc.sem_timer);
+	timer_shutdown_sync(&bnad->bna.ioceth.ioc.hb_timer);
+	timer_shutdown_sync(&bnad->bna.ioceth.ioc.iocpf_timer);
 	spin_lock_irqsave(&bnad->bna_lock, flags);
 	bna_uninit(bna);
 	spin_unlock_irqrestore(&bnad->bna_lock, flags);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 821/877] i2c: qcom-geni: Fix hardcoded clock index in SE_GENI_CLK_SEL
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (819 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 820/877] bna: prevent IOC timer rearm during teardown Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 822/877] drm/amdgpu: Fix acpi device leak in amdgpu_acpi_enumerate_xcc() Greg Kroah-Hartman
                   ` (63 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Viken Dadhaniya,
	Mukesh Kumar Savaliya, Andi Shyti, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>

[ Upstream commit cb97bf3d4f91453b881acaf8e9f0cc47bb40b604 ]

qcom_geni_i2c_conf() writes a hardcoded 0 to SE_GENI_CLK_SEL, which
selects an index from the hardware clock performance table. This always
picks the first table entry regardless of the actual source clock
configuration. On platforms where the matching entry is not at index 0,
the wrong source clock divider is active and the I2C bus runs at an
incorrect frequency.

Use geni_se_clk_freq_match() in geni_i2c_clk_map_idx() to find the
performance table index for the source clock (32 MHz or 19.2 MHz). Store
the resolved index in a new clk_idx field in geni_i2c_dev and write it
to SE_GENI_CLK_SEL instead of the hardcoded 0.

Fixes: 37692de5d523 ("i2c: i2c-qcom-geni: Add bus driver for the Qualcomm GENI I2C controller")
Signed-off-by: Viken Dadhaniya <viken.dadhaniya@oss.qualcomm.com>
Cc: <stable@vger.kernel.org> # v4.19+
Reviewed-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://patch.msgid.link/20260921-i2c-fix-se-clk-conf-v2-1-8b5537ceff2d@oss.qualcomm.com
[ adapted clock initialization to the older driver’s 19.2 MHz-only table and existing probe path. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/i2c/busses/i2c-qcom-geni.c |   33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

--- a/drivers/i2c/busses/i2c-qcom-geni.c
+++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -77,6 +77,8 @@ enum geni_i2c_err_code {
 #define XFER_TIMEOUT		HZ
 #define RST_TIMEOUT		HZ
 
+#define GENI_SE_CLK_19P2MHZ	19200000UL
+
 struct geni_i2c_dev {
 	struct geni_se se;
 	u32 tx_wm;
@@ -91,6 +93,7 @@ struct geni_i2c_dev {
 	struct clk *core_clk;
 	u32 clk_freq_out;
 	const struct geni_i2c_clk_fld *clk_fld;
+	u32 clk_idx;
 	int suspended;
 	void *dma_buf;
 	size_t xfer_len;
@@ -157,13 +160,36 @@ static int geni_i2c_clk_map_idx(struct g
 {
 	int i;
 	const struct geni_i2c_clk_fld *itr = geni_i2c_clk_map;
+	unsigned long res_freq;
+
+	/*
+	 * Frequency counters are calibrated for a 19.2 MHz source clock
+	 * and are not valid for any multiple of it (e.g. 38.4 MHz).
+	 * Use exact=true and verify res_freq matches req_freq literally
+	 * to reject harmonics that would produce an incorrect I2C frequency.
+	 * ACPI systems have firmware-managed clocks and retain the default index.
+	 */
+	if (!has_acpi_companion(gi2c->se.dev) &&
+	    (geni_se_clk_freq_match(&gi2c->se, GENI_SE_CLK_19P2MHZ,
+				    &gi2c->clk_idx, &res_freq, true) ||
+	     res_freq != GENI_SE_CLK_19P2MHZ)) {
+		dev_err(gi2c->se.dev,
+			"Unsupported SE source clock: must be exactly 19.2 MHz\n");
+		return -EINVAL;
+	}
 
 	for (i = 0; i < ARRAY_SIZE(geni_i2c_clk_map); i++, itr++) {
 		if (itr->clk_freq_out == gi2c->clk_freq_out) {
 			gi2c->clk_fld = itr;
+			dev_dbg(gi2c->se.dev,
+				"I2C clk selected: freq: %u Hz, clk_idx: %u\n",
+				gi2c->clk_freq_out, gi2c->clk_idx);
 			return 0;
 		}
 	}
+
+	dev_err(gi2c->se.dev, "Unsupported I2C output frequency %u Hz\n", gi2c->clk_freq_out);
+
 	return -EINVAL;
 }
 
@@ -172,7 +198,7 @@ static void qcom_geni_i2c_conf(struct ge
 	const struct geni_i2c_clk_fld *itr = gi2c->clk_fld;
 	u32 val;
 
-	writel_relaxed(0, gi2c->se.base + SE_GENI_CLK_SEL);
+	writel_relaxed(gi2c->clk_idx, gi2c->se.base + SE_GENI_CLK_SEL);
 
 	val = (itr->clk_div << CLK_DIV_SHFT) | SER_CLK_EN;
 	writel_relaxed(val, gi2c->se.base + GENI_SER_M_CLK_CFG);
@@ -809,11 +835,8 @@ static int geni_i2c_probe(struct platfor
 		return gi2c->irq;
 
 	ret = geni_i2c_clk_map_idx(gi2c);
-	if (ret) {
-		dev_err(dev, "Invalid clk frequency %d Hz: %d\n",
-			gi2c->clk_freq_out, ret);
+	if (ret)
 		return ret;
-	}
 
 	gi2c->adap.algo = &geni_i2c_algo;
 	init_completion(&gi2c->done);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 822/877] drm/amdgpu: Fix acpi device leak in amdgpu_acpi_enumerate_xcc()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (820 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 821/877] i2c: qcom-geni: Fix hardcoded clock index in SE_GENI_CLK_SEL Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 823/877] drm/client: Pass force parameter to client restore Greg Kroah-Hartman
                   ` (62 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Lijo Lazar, Wentao Liang,
	Alex Deucher, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Wentao Liang <vulab@iscas.ac.cn>

[ Upstream commit a997baa61179b450bd55c4810c7ccfed3b753a54 ]

amdgpu_acpi_enumerate_xcc() looks up each XCC ACPI device with
acpi_dev_get_first_match_dev(), which takes a reference to the device.
The reference is dropped with acpi_dev_put() after the XCC info is
initialized, but if the kzalloc_obj() allocation of the XCC info fails
the function returns -ENOMEM without releasing the reference, leaking
the last reference to the ACPI device.

Drop the ACPI device reference on the allocation failure path before
returning.

Fixes: 4d5275ab0b18 ("drm/amdgpu: Add parsing of acpi xcc objects")
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 9211ef48b31ec66999cf55e04d0cbc60cd855fd5)
Cc: stable@vger.kernel.org
[ adapted the hunk to the existing kzalloc() failure block with braces and DRM_ERROR() logging. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
@@ -1114,6 +1114,7 @@ static int amdgpu_acpi_enumerate_xcc(voi
 				   GFP_KERNEL);
 		if (!xcc_info) {
 			DRM_ERROR("Failed to allocate memory for xcc info\n");
+			acpi_dev_put(acpi_dev);
 			return -ENOMEM;
 		}
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 823/877] drm/client: Pass force parameter to client restore
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (821 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 822/877] drm/amdgpu: Fix acpi device leak in amdgpu_acpi_enumerate_xcc() Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 824/877] drm/client: fix restore of partially initialized client Greg Kroah-Hartman
                   ` (61 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Thomas Zimmermann, Jocelyn Falempe,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Thomas Zimmermann <tzimmermann@suse.de>

[ Upstream commit 943240d342f148896733eb6c7b223a08aa1f520a ]

Add force parameter to client restore and pass value through the
layers. The only currently used value is false.

If force is true, the client should restore its display even if it
does not hold the DRM master lock. This is be required for emergency
output, such as sysrq.

While at it, inline drm_fb_helper_lastclose(), which is a trivial
wrapper around drm_fb_helper_restore_fbdev_mode_unlocked().

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20251110154616.539328-2-tzimmermann@suse.de

Backport to 6.12: client event handling is still in drm_client.c and
its declarations are in drm_client.h, so apply the force changes there
without introducing the later drm_client_event files. Keep the fbdev
client at its existing path.

Propagate force through the older DMA, shmem, TTM, Armada, Exynos,
GMA500, i915, MSM, OMAP, Radeon and Tegra restore callbacks, including
i915's restore helper and the existing !DRM_FBDEV_EMULATION stub.
Inline lastclose calls in the older clients using dev->fb_helper to
preserve their existing helper selection and initialization checks.
No functions are added.

The generic fbdev restore callback now has the upstream context needed
by 1fca688e9443003e33cf30453e7a7560367656c9.

[ sashal: Reduced backport -- upstream 943240d342f14 touches 7 file(s), this
  backport carries 17. Not backported here:
  drivers/gpu/drm/clients/drm_fbdev_client.c
  drivers/gpu/drm/drm_client_event.c
  include/drm/drm_client_event.h
  This note is generated from the file lists only; see the resolution record
  for the reasoning. ]

Stable-dep-of: 1fca688e9443 ("drm/client: fix restore of partially initialized client")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/armada/armada_fbdev.c      |    4 ++--
 drivers/gpu/drm/drm_client.c               |    4 ++--
 drivers/gpu/drm/drm_fb_helper.c            |   24 ++++++------------------
 drivers/gpu/drm/drm_fbdev_client.c         |    6 ++++--
 drivers/gpu/drm/drm_fbdev_dma.c            |    4 ++--
 drivers/gpu/drm/drm_fbdev_shmem.c          |    4 ++--
 drivers/gpu/drm/drm_fbdev_ttm.c            |    4 ++--
 drivers/gpu/drm/drm_file.c                 |    2 +-
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c  |    4 ++--
 drivers/gpu/drm/gma500/fbdev.c             |    4 ++--
 drivers/gpu/drm/i915/display/intel_fbdev.c |    8 ++++----
 drivers/gpu/drm/msm/msm_fbdev.c            |    4 ++--
 drivers/gpu/drm/omapdrm/omap_fbdev.c       |    4 ++--
 drivers/gpu/drm/radeon/radeon_fbdev.c      |    4 ++--
 drivers/gpu/drm/tegra/fbdev.c              |    4 ++--
 include/drm/drm_client.h                   |   10 ++++++----
 include/drm/drm_fb_helper.h                |   11 ++++-------
 17 files changed, 47 insertions(+), 58 deletions(-)

--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ b/drivers/gpu/drm/armada/armada_fbdev.c
@@ -137,9 +137,9 @@ static void armada_fbdev_client_unregist
 	}
 }
 
-static int armada_fbdev_client_restore(struct drm_client_dev *client)
+static int armada_fbdev_client_restore(struct drm_client_dev *client, bool force)
 {
-	drm_fb_helper_lastclose(client->dev);
+	drm_fb_helper_restore_fbdev_mode_unlocked(client->dev->fb_helper, force);
 
 	return 0;
 }
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -244,7 +244,7 @@ void drm_client_dev_hotplug(struct drm_d
 }
 EXPORT_SYMBOL(drm_client_dev_hotplug);
 
-void drm_client_dev_restore(struct drm_device *dev)
+void drm_client_dev_restore(struct drm_device *dev, bool force)
 {
 	struct drm_client_dev *client;
 	int ret;
@@ -257,7 +257,7 @@ void drm_client_dev_restore(struct drm_d
 		if (!client->funcs || !client->funcs->restore)
 			continue;
 
-		ret = client->funcs->restore(client);
+		ret = client->funcs->restore(client, force);
 		drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);
 		if (!ret) /* The first one to return zero gets the privilege to restore */
 			break;
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -249,6 +249,7 @@ __drm_fb_helper_restore_fbdev_mode_unloc
 /**
  * drm_fb_helper_restore_fbdev_mode_unlocked - restore fbdev configuration
  * @fb_helper: driver-allocated fbdev helper, can be NULL
+ * @force: ignore present DRM master
  *
  * This helper should be called from fbdev emulation's &drm_client_funcs.restore
  * callback. It ensures that the user isn't greeted with a black screen when the
@@ -257,9 +258,9 @@ __drm_fb_helper_restore_fbdev_mode_unloc
  * Returns:
  * 0 on success, or a negative errno code otherwise.
  */
-int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
+int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper, bool force)
 {
-	return __drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper, false);
+	return __drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper, force);
 }
 EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode_unlocked);
 
@@ -1306,9 +1307,9 @@ int drm_fb_helper_set_par(struct fb_info
 	 * the KDSET IOCTL with KD_TEXT, and only after that drops the master
 	 * status when exiting.
 	 *
-	 * In the past this was caught by drm_fb_helper_lastclose(), but on
-	 * modern systems where logind always keeps a drm fd open to orchestrate
-	 * the vt switching, this doesn't work.
+	 * In the past this was caught by drm_fb_helper_restore_fbdev_mode_unlocked(),
+	 * but on modern systems where logind always keeps a drm fd open to
+	 * orchestrate the vt switching, this doesn't work.
 	 *
 	 * To not break the userspace ABI we have this special case here, which
 	 * is only used for the above case. Everything else uses the normal
@@ -1936,16 +1937,3 @@ int drm_fb_helper_hotplug_event(struct d
 	return 0;
 }
 EXPORT_SYMBOL(drm_fb_helper_hotplug_event);
-
-/**
- * drm_fb_helper_lastclose - DRM driver lastclose helper for fbdev emulation
- * @dev: DRM device
- *
- * This function is obsolete. Call drm_fb_helper_restore_fbdev_mode_unlocked()
- * instead.
- */
-void drm_fb_helper_lastclose(struct drm_device *dev)
-{
-	drm_fb_helper_restore_fbdev_mode_unlocked(dev->fb_helper);
-}
-EXPORT_SYMBOL(drm_fb_helper_lastclose);
--- a/drivers/gpu/drm/drm_fbdev_client.c
+++ b/drivers/gpu/drm/drm_fbdev_client.c
@@ -25,9 +25,11 @@ static void drm_fbdev_client_unregister(
 	}
 }
 
-static int drm_fbdev_client_restore(struct drm_client_dev *client)
+static int drm_fbdev_client_restore(struct drm_client_dev *client, bool force)
 {
-	drm_fb_helper_lastclose(client->dev);
+	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
+
+	drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper, force);
 
 	return 0;
 }
--- a/drivers/gpu/drm/drm_fbdev_dma.c
+++ b/drivers/gpu/drm/drm_fbdev_dma.c
@@ -350,9 +350,9 @@ static void drm_fbdev_dma_client_unregis
 	}
 }
 
-static int drm_fbdev_dma_client_restore(struct drm_client_dev *client)
+static int drm_fbdev_dma_client_restore(struct drm_client_dev *client, bool force)
 {
-	drm_fb_helper_lastclose(client->dev);
+	drm_fb_helper_restore_fbdev_mode_unlocked(client->dev->fb_helper, force);
 
 	return 0;
 }
--- a/drivers/gpu/drm/drm_fbdev_shmem.c
+++ b/drivers/gpu/drm/drm_fbdev_shmem.c
@@ -216,9 +216,9 @@ static void drm_fbdev_shmem_client_unreg
 	}
 }
 
-static int drm_fbdev_shmem_client_restore(struct drm_client_dev *client)
+static int drm_fbdev_shmem_client_restore(struct drm_client_dev *client, bool force)
 {
-	drm_fb_helper_lastclose(client->dev);
+	drm_fb_helper_restore_fbdev_mode_unlocked(client->dev->fb_helper, force);
 
 	return 0;
 }
--- a/drivers/gpu/drm/drm_fbdev_ttm.c
+++ b/drivers/gpu/drm/drm_fbdev_ttm.c
@@ -257,9 +257,9 @@ static void drm_fbdev_ttm_client_unregis
 	}
 }
 
-static int drm_fbdev_ttm_client_restore(struct drm_client_dev *client)
+static int drm_fbdev_ttm_client_restore(struct drm_client_dev *client, bool force)
 {
-	drm_fb_helper_lastclose(client->dev);
+	drm_fb_helper_restore_fbdev_mode_unlocked(client->dev->fb_helper, force);
 
 	return 0;
 }
--- a/drivers/gpu/drm/drm_file.c
+++ b/drivers/gpu/drm/drm_file.c
@@ -388,7 +388,7 @@ EXPORT_SYMBOL(drm_open);
 
 static void drm_lastclose(struct drm_device *dev)
 {
-	drm_client_dev_restore(dev);
+	drm_client_dev_restore(dev, false);
 
 	if (dev_is_pci(dev->dev))
 		vga_switcheroo_process_delayed_switch();
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -149,9 +149,9 @@ static void exynos_drm_fbdev_client_unre
 	}
 }
 
-static int exynos_drm_fbdev_client_restore(struct drm_client_dev *client)
+static int exynos_drm_fbdev_client_restore(struct drm_client_dev *client, bool force)
 {
-	drm_fb_helper_lastclose(client->dev);
+	drm_fb_helper_restore_fbdev_mode_unlocked(client->dev->fb_helper, force);
 
 	return 0;
 }
--- a/drivers/gpu/drm/gma500/fbdev.c
+++ b/drivers/gpu/drm/gma500/fbdev.c
@@ -214,9 +214,9 @@ static void psb_fbdev_client_unregister(
 	}
 }
 
-static int psb_fbdev_client_restore(struct drm_client_dev *client)
+static int psb_fbdev_client_restore(struct drm_client_dev *client, bool force)
 {
-	drm_fb_helper_lastclose(client->dev);
+	drm_fb_helper_restore_fbdev_mode_unlocked(client->dev->fb_helper, force);
 
 	return 0;
 }
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -555,7 +555,7 @@ static int intel_fbdev_output_poll_chang
 	return 0;
 }
 
-static int intel_fbdev_restore_mode(struct drm_i915_private *dev_priv)
+static int intel_fbdev_restore_mode(struct drm_i915_private *dev_priv, bool force)
 {
 	struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev;
 	int ret;
@@ -566,7 +566,7 @@ static int intel_fbdev_restore_mode(stru
 	if (!ifbdev->vma)
 		return -ENOMEM;
 
-	ret = drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper);
+	ret = drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper, force);
 	if (ret)
 		return ret;
 
@@ -592,12 +592,12 @@ static void intel_fbdev_client_unregiste
 	}
 }
 
-static int intel_fbdev_client_restore(struct drm_client_dev *client)
+static int intel_fbdev_client_restore(struct drm_client_dev *client, bool force)
 {
 	struct drm_i915_private *dev_priv = to_i915(client->dev);
 	int ret;
 
-	ret = intel_fbdev_restore_mode(dev_priv);
+	ret = intel_fbdev_restore_mode(dev_priv, force);
 	if (ret)
 		return ret;
 
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -173,9 +173,9 @@ static void msm_fbdev_client_unregister(
 	}
 }
 
-static int msm_fbdev_client_restore(struct drm_client_dev *client)
+static int msm_fbdev_client_restore(struct drm_client_dev *client, bool force)
 {
-	drm_fb_helper_lastclose(client->dev);
+	drm_fb_helper_restore_fbdev_mode_unlocked(client->dev->fb_helper, force);
 
 	return 0;
 }
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -289,9 +289,9 @@ static void omap_fbdev_client_unregister
 	}
 }
 
-static int omap_fbdev_client_restore(struct drm_client_dev *client)
+static int omap_fbdev_client_restore(struct drm_client_dev *client, bool force)
 {
-	drm_fb_helper_lastclose(client->dev);
+	drm_fb_helper_restore_fbdev_mode_unlocked(client->dev->fb_helper, force);
 
 	return 0;
 }
--- a/drivers/gpu/drm/radeon/radeon_fbdev.c
+++ b/drivers/gpu/drm/radeon/radeon_fbdev.c
@@ -300,9 +300,9 @@ static void radeon_fbdev_client_unregist
 	}
 }
 
-static int radeon_fbdev_client_restore(struct drm_client_dev *client)
+static int radeon_fbdev_client_restore(struct drm_client_dev *client, bool force)
 {
-	drm_fb_helper_lastclose(client->dev);
+	drm_fb_helper_restore_fbdev_mode_unlocked(client->dev->fb_helper, force);
 	vga_switcheroo_process_delayed_switch();
 
 	return 0;
--- a/drivers/gpu/drm/tegra/fbdev.c
+++ b/drivers/gpu/drm/tegra/fbdev.c
@@ -154,9 +154,9 @@ static void tegra_fbdev_client_unregiste
 	}
 }
 
-static int tegra_fbdev_client_restore(struct drm_client_dev *client)
+static int tegra_fbdev_client_restore(struct drm_client_dev *client, bool force)
 {
-	drm_fb_helper_lastclose(client->dev);
+	drm_fb_helper_restore_fbdev_mode_unlocked(client->dev->fb_helper, force);
 
 	return 0;
 }
--- a/include/drm/drm_client.h
+++ b/include/drm/drm_client.h
@@ -47,12 +47,14 @@ struct drm_client_funcs {
 	 *
 	 * Note that the core does not guarantee exclusion against concurrent
 	 * drm_open(). Clients need to ensure this themselves, for example by
-	 * using drm_master_internal_acquire() and
-	 * drm_master_internal_release().
+	 * using drm_master_internal_acquire() and drm_master_internal_release().
+	 *
+	 * If the caller passes force, the client should ignore any present DRM
+	 * master and restore the display anyway.
 	 *
 	 * This callback is optional.
 	 */
-	int (*restore)(struct drm_client_dev *client);
+	int (*restore)(struct drm_client_dev *client, bool force);
 
 	/**
 	 * @hotplug:
@@ -123,7 +125,7 @@ void drm_client_register(struct drm_clie
 
 void drm_client_dev_unregister(struct drm_device *dev);
 void drm_client_dev_hotplug(struct drm_device *dev);
-void drm_client_dev_restore(struct drm_device *dev);
+void drm_client_dev_restore(struct drm_device *dev, bool force);
 
 /**
  * struct drm_client_buffer - DRM client buffer
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -244,7 +244,8 @@ int drm_fb_helper_set_par(struct fb_info
 int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
 			    struct fb_info *info);
 
-int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper);
+int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper,
+					      bool force);
 
 void drm_fb_helper_unregister_info(struct drm_fb_helper *fb_helper);
 void drm_fb_helper_fill_info(struct fb_info *info,
@@ -269,7 +270,6 @@ int drm_fb_helper_hotplug_event(struct d
 int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper);
 int drm_fb_helper_debug_enter(struct fb_info *info);
 int drm_fb_helper_debug_leave(struct fb_info *info);
-void drm_fb_helper_lastclose(struct drm_device *dev);
 #else
 static inline void drm_fb_helper_prepare(struct drm_device *dev,
 					 struct drm_fb_helper *helper,
@@ -321,7 +321,8 @@ static inline int drm_fb_helper_check_va
 }
 
 static inline int
-drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper)
+drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper,
+				       bool force)
 {
 	return 0;
 }
@@ -383,10 +384,6 @@ static inline int drm_fb_helper_debug_le
 {
 	return 0;
 }
-
-static inline void drm_fb_helper_lastclose(struct drm_device *dev)
-{
-}
 #endif
 
 #endif



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 824/877] drm/client: fix restore of partially initialized client
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (822 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 823/877] drm/client: Pass force parameter to client restore Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 825/877] drm/i915/mst: add mst sub-struct to struct intel_dp Greg Kroah-Hartman
                   ` (60 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, shechenglong, Thomas Zimmermann,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: shechenglong <shechenglong@xfusion.com>

[ Upstream commit 1fca688e9443003e33cf30453e7a7560367656c9 ]

I got a null-ptr-deref report when closing a DRM file descriptor:

WARNING: drivers/gpu/drm/drm_atomic.c:2031 at
__drm_atomic_helper_set_config+0x18e/0x1b0 [drm]

Call Trace:
drm_client_modeset_commit_atomic+0x16b/0x220 [drm]
drm_client_modeset_commit_locked+0x56/0x160 [drm]
drm_client_modeset_commit+0x21/0x40 [drm]
__drm_fb_helper_restore_fbdev_mode_unlocked.part.0+0x7b/0x80
drm_fbdev_client_restore+0xe/0x20 [drm_client_lib]
drm_client_dev_restore+0x9f/0xc0 [drm]
drm_release+0xc5/0xe0 [drm]

The warning is followed by a NULL pointer dereference:

BUG: kernel NULL pointer dereference, address: 0000000000000008

RIP:
__drm_fb_helper_restore_fbdev_mode_unlocked.part.0+0x41/0x80
[drm_kms_helper]

Call Trace:
drm_fbdev_client_restore+0xe/0x20 [drm_client_lib]
drm_client_dev_restore+0x9f/0xc0 [drm]
drm_release+0xc5/0xe0 [drm]
__fput+0xdc/0x2b0
__x64_sys_close+0x39/0x80
do_syscall_64+0x8d/0x460
entry_SYSCALL_64_after_hwframe+0x76/0x7e

drm_client_register() adds the DRM client to the device client list
before invoking the initial hotplug callback. If the hotplug callback
fails, the client remains registered.

For the fbdev client, a failure during drm_fb_helper_initial_config()
causes the partially initialized fbdev helper to be cleaned up.
drm_fb_helper_fini() releases fb_helper->info and leaves it NULL.

The fbdev client therefore remains registered even though there is no
fully initialized framebuffer device.

Later, when userspace closes the DRM file descriptor, drm_release()
can invoke the restore callbacks of registered DRM clients:

drm_release()
drm_client_dev_restore()
drm_fbdev_client_restore()
drm_fb_helper_restore_fbdev_mode_unlocked()

drm_fbdev_client_restore() currently restores the fbdev state
unconditionally. For a partially initialized fbdev client this can
submit an incomplete modeset state and subsequently access fbdev
state which has not been initialized, resulting in the warning and
NULL pointer dereference above.

drm_fbdev_client_unregister() already uses fb_helper->info to
distinguish a fully probed framebuffer device from a partially
initialized client.

Use the same condition in drm_fbdev_client_restore() and skip restore
if no framebuffer device has been successfully initialized.

Signed-off-by: shechenglong <shechenglong@xfusion.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Fixes: 5d08c44e47b9 ("drm/fbdev: Add memory-agnostic fbdev client")
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Cc: <stable@vger.kernel.org> # v6.13+
Link: https://patch.msgid.link/20260907035147.1339-1-shechenglong@xfusion.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/drm_fbdev_client.c |    8 ++++++++
 1 file changed, 8 insertions(+)

--- a/drivers/gpu/drm/drm_fbdev_client.c
+++ b/drivers/gpu/drm/drm_fbdev_client.c
@@ -29,6 +29,14 @@ static int drm_fbdev_client_restore(stru
 {
 	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
 
+	/*
+	 * The client is registered before the initial fbdev probe.
+	 * If probing failed, the client remains registered but there
+	 * is no valid fbdev framebuffer to restore.
+	 */
+	if (!fb_helper->info || !fb_helper->fb)
+		return 0;
+
 	drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper, force);
 
 	return 0;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 825/877] drm/i915/mst: add mst sub-struct to struct intel_dp
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (823 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 824/877] drm/client: fix restore of partially initialized client Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 826/877] drm/i915/dp_mst: Fix configuring FEC for a disconnected stream Greg Kroah-Hartman
                   ` (59 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Imre Deak, Jani Nikula, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jani Nikula <jani.nikula@intel.com>

[ Upstream commit abf874a328a885592a6bfe6f7db463974e14b615 ]

Move active_mst_links, mst_encoders[], and mst_mgr members of struct
intel_dp under an mst sub-struct to group mst related things together.

Rename them active_links, stream_encoders[] and mgr for clarity.

Note that is_mst and mst_detect are not included, as they're also
relevant for non-mst. The sub-struct is for active mst.

Cc: Imre Deak <imre.deak@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/6f282f90bfe2dd9162e2dee8f681c84313971992.1740746939.git.jani.nikula@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>

[ Backport to 6.12: retain the stable MST implementations, i915
  device references, bandwidth calculations and helper signatures.
  Update the corresponding field accesses in those implementations
  instead of importing newer upstream refactors.

  Fold in the connector MST field grouping from aa389adeaa856
  ("drm/i915/mst: add mst sub-struct to struct intel_connector"),
  including the stable-only users in link training and PSR. This
  provides connector->mst.dp and connector->mst.port as required
  by acbe9a3b60b9 ("drm/i915/dp_mst: Fix configuring FEC for a
  disconnected stream"), so that target applies unchanged.
  No functions or behavioral changes are introduced here. ]

Stable-dep-of: acbe9a3b60b9 ("drm/i915/dp_mst: Fix configuring FEC for a disconnected stream")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/i915/display/intel_connector.c        |    4 
 drivers/gpu/drm/i915/display/intel_ddi.c              |    4 
 drivers/gpu/drm/i915/display/intel_display_debugfs.c  |    8 
 drivers/gpu/drm/i915/display/intel_display_types.h    |   18 +-
 drivers/gpu/drm/i915/display/intel_dp.c               |   36 ++--
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c          |    6 
 drivers/gpu/drm/i915/display/intel_dp_link_training.c |    4 
 drivers/gpu/drm/i915/display/intel_dp_mst.c           |  154 +++++++++---------
 drivers/gpu/drm/i915/display/intel_hdcp.c             |    8 
 drivers/gpu/drm/i915/display/intel_psr.c              |    2 
 10 files changed, 123 insertions(+), 121 deletions(-)

--- a/drivers/gpu/drm/i915/display/intel_connector.c
+++ b/drivers/gpu/drm/i915/display/intel_connector.c
@@ -103,8 +103,8 @@ void intel_connector_destroy(struct drm_
 
 	drm_connector_cleanup(connector);
 
-	if (intel_connector->port)
-		drm_dp_mst_put_port_malloc(intel_connector->port);
+	if (intel_connector->mst.port)
+		drm_dp_mst_put_port_malloc(intel_connector->mst.port);
 
 	kfree(connector);
 }
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -2585,7 +2585,7 @@ static void mtl_ddi_pre_enable_dp(struct
 	 * Train Display Port" step.  Note that steps that are specific to
 	 * MST will be handled by intel_mst_pre_enable_dp() before/after it
 	 * calls into this function.  Also intel_mst_pre_enable_dp() only calls
-	 * us when active_mst_links==0, so any steps designated for "single
+	 * us when mst.active_links==0, so any steps designated for "single
 	 * stream or multi-stream master transcoder" can just be performed
 	 * unconditionally here.
 	 *
@@ -2674,7 +2674,7 @@ static void tgl_ddi_pre_enable_dp(struct
 	 * Train Display Port" step.  Note that steps that are specific to
 	 * MST will be handled by intel_mst_pre_enable_dp() before/after it
 	 * calls into this function.  Also intel_mst_pre_enable_dp() only calls
-	 * us when active_mst_links==0, so any steps designated for "single
+	 * us when mst.active_links==0, so any steps designated for "single
 	 * stream or multi-stream master transcoder" can just be performed
 	 * unconditionally here.
 	 */
--- a/drivers/gpu/drm/i915/display/intel_display_debugfs.c
+++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
@@ -275,7 +275,7 @@ static void intel_connector_info(struct
 	switch (connector->connector_type) {
 	case DRM_MODE_CONNECTOR_DisplayPort:
 	case DRM_MODE_CONNECTOR_eDP:
-		if (intel_connector->mst_port)
+		if (intel_connector->mst.dp)
 			intel_dp_mst_info(m, intel_connector);
 		else
 			intel_dp_info(m, intel_connector);
@@ -288,7 +288,7 @@ static void intel_connector_info(struct
 	}
 
 	seq_puts(m, "\tHDCP version: ");
-	if (intel_connector->mst_port) {
+	if (intel_connector->mst.dp) {
 		intel_hdcp_info(m, intel_connector, true);
 		seq_puts(m, "\tMST Hub HDCP version: ");
 	}
@@ -766,7 +766,7 @@ static int i915_dp_mst_info(struct seq_f
 		seq_printf(m, "MST Source Port [ENCODER:%d:%s]\n",
 			   dig_port->base.base.base.id,
 			   dig_port->base.base.name);
-		drm_dp_mst_dump_topology(m, &dig_port->dp.mst_mgr);
+		drm_dp_mst_dump_topology(m, &dig_port->dp.mst.mgr);
 	}
 	drm_connector_list_iter_end(&conn_iter);
 
@@ -1533,7 +1533,7 @@ void intel_connector_debugfs_add(struct
 	}
 
 	if (DISPLAY_VER(i915) >= 11 &&
-	    ((connector_type == DRM_MODE_CONNECTOR_DisplayPort && !connector->mst_port) ||
+	    ((connector_type == DRM_MODE_CONNECTOR_DisplayPort && !connector->mst.dp) ||
 	     connector_type == DRM_MODE_CONNECTOR_eDP)) {
 		debugfs_create_file("i915_dsc_fec_support", 0644, root,
 				    connector, &i915_dsc_fec_support_fops);
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -647,10 +647,6 @@ struct intel_connector {
 	   state of connector->polled in case hotplug storm detection changes it */
 	u8 polled;
 
-	struct drm_dp_mst_port *port;
-
-	struct intel_dp *mst_port;
-
 	bool force_bigjoiner_enable;
 
 	struct {
@@ -662,6 +658,11 @@ struct intel_connector {
 		u8 dsc_decompression_enabled:1;
 	} dp;
 
+	struct {
+		struct drm_dp_mst_port *port;
+		struct intel_dp *dp;
+	} mst;
+
 	/* Work struct to schedule a uevent on link train failure */
 	struct work_struct modeset_retry_work;
 
@@ -1834,7 +1835,6 @@ struct intel_dp {
 	struct intel_pps pps;
 
 	bool is_mst;
-	int active_mst_links;
 	enum drm_dp_mst_mode mst_detect;
 
 	/* connector directly attached - won't be use for modeset in mst world */
@@ -1844,9 +1844,11 @@ struct intel_dp {
 	struct drm_dp_tunnel *tunnel;
 	bool tunnel_suspended:1;
 
-	/* mst connector list */
-	struct intel_dp_mst_encoder *mst_encoders[I915_MAX_PIPES];
-	struct drm_dp_mst_topology_mgr mst_mgr;
+	struct {
+		struct intel_dp_mst_encoder *stream_encoders[I915_MAX_PIPES];
+		struct drm_dp_mst_topology_mgr mgr;
+		int active_links;
+	} mst;
 
 	u32 (*get_aux_clock_divider)(struct intel_dp *dp, int index);
 	/*
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -1290,7 +1290,7 @@ bool intel_dp_has_dsc(const struct intel
 	if (!HAS_DSC(i915))
 		return false;
 
-	if (connector->mst_port && !HAS_DSC_MST(i915))
+	if (connector->mst.dp && !HAS_DSC_MST(i915))
 		return false;
 
 	if (connector->base.connector_type == DRM_MODE_CONNECTOR_eDP &&
@@ -3016,7 +3016,7 @@ intel_dp_queue_modeset_retry_for_link(st
 		if (!conn_state->base.crtc)
 			continue;
 
-		if (connector->mst_port == intel_dp)
+		if (connector->mst.dp == intel_dp)
 			intel_dp_queue_modeset_retry_work(connector);
 	}
 }
@@ -3236,8 +3236,8 @@ intel_dp_sink_set_dsc_passthrough(const
 				  bool enable)
 {
 	struct drm_i915_private *i915 = to_i915(connector->base.dev);
-	struct drm_dp_aux *aux = connector->port ?
-				 connector->port->passthrough_aux : NULL;
+	struct drm_dp_aux *aux = connector->mst.port ?
+				 connector->mst.port->passthrough_aux : NULL;
 
 	if (!aux)
 		return;
@@ -3264,7 +3264,7 @@ static int intel_dp_dsc_aux_ref_count(st
 	 * On SST the decompression AUX device won't be shared, each connector
 	 * uses for this its own AUX targeting the sink device.
 	 */
-	if (!connector->mst_port)
+	if (!connector->mst.dp)
 		return connector->dp.dsc_decompression_enabled ? 1 : 0;
 
 	for_each_oldnew_connector_in_state(&state->base, _connector_iter,
@@ -3272,7 +3272,7 @@ static int intel_dp_dsc_aux_ref_count(st
 		const struct intel_connector *
 			connector_iter = to_intel_connector(_connector_iter);
 
-		if (connector_iter->mst_port != connector->mst_port)
+		if (connector_iter->mst.dp != connector->mst.dp)
 			continue;
 
 		if (!connector_iter->dp.dsc_decompression_enabled)
@@ -4291,7 +4291,7 @@ intel_dp_mst_configure(struct intel_dp *
 	if (intel_dp->is_mst)
 		intel_dp_mst_prepare_probe(intel_dp);
 
-	drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst);
+	drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst.mgr, intel_dp->is_mst);
 
 	/* Avoid stale info on the next detect cycle. */
 	intel_dp->mst_detect = DRM_DP_SST;
@@ -4306,9 +4306,9 @@ intel_dp_mst_disconnect(struct intel_dp
 		return;
 
 	drm_dbg_kms(&i915->drm, "MST device may have disappeared %d vs %d\n",
-		    intel_dp->is_mst, intel_dp->mst_mgr.mst_state);
+		    intel_dp->is_mst, intel_dp->mst.mgr.mst_state);
 	intel_dp->is_mst = false;
-	drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr, intel_dp->is_mst);
+	drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst.mgr, intel_dp->is_mst);
 }
 
 static bool
@@ -5154,7 +5154,7 @@ intel_dp_mst_hpd_irq(struct intel_dp *in
 {
 	bool handled = false;
 
-	drm_dp_mst_hpd_irq_handle_event(&intel_dp->mst_mgr, esi, ack, &handled);
+	drm_dp_mst_hpd_irq_handle_event(&intel_dp->mst.mgr, esi, ack, &handled);
 
 	if (esi[1] & DP_CP_IRQ) {
 		intel_hdcp_handle_cp_irq(intel_dp->attached_connector);
@@ -5203,7 +5203,7 @@ intel_dp_check_mst_status(struct intel_d
 	bool link_ok = true;
 	bool reprobe_needed = false;
 
-	drm_WARN_ON_ONCE(&i915->drm, intel_dp->active_mst_links < 0);
+	drm_WARN_ON_ONCE(&i915->drm, intel_dp->mst.active_links < 0);
 
 	for (;;) {
 		u8 esi[4] = {};
@@ -5219,7 +5219,7 @@ intel_dp_check_mst_status(struct intel_d
 
 		drm_dbg_kms(&i915->drm, "DPRX ESI: %4ph\n", esi);
 
-		if (intel_dp->active_mst_links > 0 && link_ok &&
+		if (intel_dp->mst.active_links > 0 && link_ok &&
 		    esi[3] & LINK_STATUS_CHANGED) {
 			if (!intel_dp_mst_link_status(intel_dp))
 				link_ok = false;
@@ -5242,7 +5242,7 @@ intel_dp_check_mst_status(struct intel_d
 			drm_dbg_kms(&i915->drm, "Failed to ack ESI\n");
 
 		if (ack[1] & (DP_DOWN_REP_MSG_RDY | DP_UP_REQ_MSG_RDY))
-			drm_dp_mst_hpd_irq_send_new_request(&intel_dp->mst_mgr);
+			drm_dp_mst_hpd_irq_send_new_request(&intel_dp->mst.mgr);
 	}
 
 	if (!link_ok || intel_dp->link.force_retrain)
@@ -5340,7 +5340,7 @@ static bool intel_dp_has_connector(struc
 
 	/* MST */
 	for_each_pipe(i915, pipe) {
-		encoder = &intel_dp->mst_encoders[pipe]->base;
+		encoder = &intel_dp->mst.stream_encoders[pipe]->base;
 		if (conn_state->best_encoder == &encoder->base)
 			return true;
 	}
@@ -6421,7 +6421,7 @@ static int intel_dp_connector_atomic_che
 		return ret;
 
 	if (intel_dp_mst_source_support(intel_dp)) {
-		ret = drm_dp_mst_root_conn_atomic_check(conn_state, &intel_dp->mst_mgr);
+		ret = drm_dp_mst_root_conn_atomic_check(conn_state, &intel_dp->mst.mgr);
 		if (ret)
 			return ret;
 	}
@@ -7000,7 +7000,7 @@ void intel_dp_mst_suspend(struct drm_i91
 			continue;
 
 		if (intel_dp->is_mst)
-			drm_dp_mst_topology_mgr_suspend(&intel_dp->mst_mgr);
+			drm_dp_mst_topology_mgr_suspend(&intel_dp->mst.mgr);
 	}
 }
 
@@ -7023,11 +7023,11 @@ void intel_dp_mst_resume(struct drm_i915
 		if (!intel_dp_mst_source_support(intel_dp))
 			continue;
 
-		ret = drm_dp_mst_topology_mgr_resume(&intel_dp->mst_mgr,
+		ret = drm_dp_mst_topology_mgr_resume(&intel_dp->mst.mgr,
 						     true);
 		if (ret) {
 			intel_dp->is_mst = false;
-			drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr,
+			drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst.mgr,
 							false);
 		}
 	}
--- a/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_hdcp.c
@@ -702,10 +702,10 @@ int intel_dp_hdcp_get_remote_capability(
 
 	*hdcp_capable = false;
 	*hdcp2_capable = false;
-	if (!connector->mst_port)
+	if (!connector->mst.dp)
 		return -EINVAL;
 
-	aux = &connector->port->aux;
+	aux = &connector->mst.port->aux;
 	ret =  _intel_dp_hdcp2_get_capability(aux, hdcp2_capable);
 	if (ret)
 		drm_dbg_kms(&i915->drm,
@@ -881,7 +881,7 @@ int intel_dp_hdcp_init(struct intel_digi
 	if (!is_hdcp_supported(dev_priv, port))
 		return 0;
 
-	if (intel_connector->mst_port)
+	if (intel_connector->mst.dp)
 		return intel_hdcp_init(intel_connector, dig_port,
 				       &intel_dp_mst_hdcp_shim);
 	else if (!intel_dp_is_edp(intel_dp))
--- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c
@@ -1692,8 +1692,8 @@ void intel_dp_128b132b_sdp_crc16(struct
 
 static struct intel_dp *intel_connector_to_intel_dp(struct intel_connector *connector)
 {
-	if (connector->mst_port)
-		return connector->mst_port;
+	if (connector->mst.dp)
+		return connector->mst.dp;
 	else
 		return enc_to_intel_dp(intel_attached_encoder(connector));
 }
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -183,7 +183,7 @@ static int intel_dp_mst_find_vcpi_slots_
 	int max_dpt_bpp;
 	int ret = 0;
 
-	mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst_mgr);
+	mst_state = drm_atomic_get_mst_topology_state(state, &intel_dp->mst.mgr);
 	if (IS_ERR(mst_state))
 		return PTR_ERR(mst_state);
 
@@ -197,7 +197,7 @@ static int intel_dp_mst_find_vcpi_slots_
 		crtc_state->fec_enable = !intel_dp_is_uhbr(crtc_state);
 	}
 
-	mst_state->pbn_div = drm_dp_get_vc_payload_bw(&intel_dp->mst_mgr,
+	mst_state->pbn_div = drm_dp_get_vc_payload_bw(&intel_dp->mst.mgr,
 						      crtc_state->port_clock,
 						      crtc_state->lane_count);
 
@@ -283,8 +283,8 @@ static int intel_dp_mst_find_vcpi_slots_
 		drm_WARN_ON(&i915->drm, remote_tu < crtc_state->dp_m_n.tu);
 		crtc_state->dp_m_n.tu = remote_tu;
 
-		slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst_mgr,
-						      connector->port,
+		slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst.mgr,
+						      connector->mst.port,
 						      crtc_state->pbn);
 		if (slots == -EDEADLK)
 			return slots;
@@ -423,7 +423,7 @@ static int intel_dp_mst_update_slots(str
 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
 	struct intel_dp_mst_encoder *intel_mst = enc_to_mst(encoder);
 	struct intel_dp *intel_dp = &intel_mst->primary->dp;
-	struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr;
+	struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst.mgr;
 	struct drm_dp_mst_topology_state *topology_state;
 	u8 link_coding_cap = intel_dp_is_uhbr(crtc_state) ?
 		DP_CAP_ANSI_128B132B : DP_CAP_ANSI_8B10B;
@@ -453,8 +453,8 @@ hblank_expansion_quirk_needs_dsc(const s
 {
 	const struct drm_display_mode *adjusted_mode =
 		&crtc_state->hw.adjusted_mode;
-	bool is_uhbr_sink = connector->mst_port &&
-			    drm_dp_128b132b_supported(connector->mst_port->dpcd);
+	bool is_uhbr_sink = connector->mst.dp &&
+			    drm_dp_128b132b_supported(connector->mst.dp->dpcd);
 	int hblank_limit = is_uhbr_sink ? 500 : 300;
 
 	if (!connector->dp.dsc_hblank_expansion_quirk)
@@ -708,7 +708,7 @@ intel_dp_mst_transcoder_mask(struct inte
 		const struct intel_crtc_state *crtc_state;
 		struct intel_crtc *crtc;
 
-		if (connector->mst_port != mst_port || !conn_state->base.crtc)
+		if (connector->mst.dp != mst_port || !conn_state->base.crtc)
 			continue;
 
 		crtc = to_intel_crtc(conn_state->base.crtc);
@@ -736,12 +736,12 @@ static u8 get_pipes_downstream_of_mst_po
 		if (!conn_state->base.crtc)
 			continue;
 
-		if (&connector->mst_port->mst_mgr != mst_mgr)
+		if (&connector->mst.dp->mst.mgr != mst_mgr)
 			continue;
 
-		if (connector->port != parent_port &&
+		if (connector->mst.port != parent_port &&
 		    !drm_dp_mst_port_downstream_of_parent(mst_mgr,
-							  connector->port,
+							  connector->mst.port,
 							  parent_port))
 			continue;
 
@@ -893,7 +893,7 @@ intel_dp_mst_atomic_topology_check(struc
 		struct intel_crtc_state *crtc_state;
 		struct intel_crtc *crtc;
 
-		if (connector_iter->mst_port != connector->mst_port ||
+		if (connector_iter->mst.dp != connector->mst.dp ||
 		    connector_iter == connector)
 			continue;
 
@@ -943,15 +943,15 @@ intel_dp_mst_atomic_check(struct drm_con
 
 	if (intel_connector_needs_modeset(state, connector)) {
 		ret = intel_dp_tunnel_atomic_check_state(state,
-							 intel_connector->mst_port,
+							 intel_connector->mst.dp,
 							 intel_connector);
 		if (ret)
 			return ret;
 	}
 
 	return drm_dp_atomic_release_time_slots(&state->base,
-						&intel_connector->mst_port->mst_mgr,
-						intel_connector->port);
+						&intel_connector->mst.dp->mst.mgr,
+						intel_connector->mst.port);
 }
 
 static void clear_act_sent(struct intel_encoder *encoder,
@@ -974,7 +974,7 @@ static void wait_for_act_sent(struct int
 				  DP_TP_STATUS_ACT_SENT, 1))
 		drm_err(&i915->drm, "Timed out waiting for ACT sent\n");
 
-	drm_dp_check_act_status(&intel_dp->mst_mgr);
+	drm_dp_check_act_status(&intel_dp->mst.mgr);
 }
 
 static void intel_mst_disable_dp(struct intel_atomic_state *state,
@@ -990,9 +990,9 @@ static void intel_mst_disable_dp(struct
 	struct drm_i915_private *i915 = to_i915(connector->base.dev);
 
 	drm_dbg_kms(&i915->drm, "active links %d\n",
-		    intel_dp->active_mst_links);
+		    intel_dp->mst.active_links);
 
-	if (intel_dp->active_mst_links == 1)
+	if (intel_dp->mst.active_links == 1)
 		intel_dp->link_trained = false;
 
 	intel_hdcp_disable(intel_mst->connector);
@@ -1011,19 +1011,19 @@ static void intel_mst_post_disable_dp(st
 	struct intel_connector *connector =
 		to_intel_connector(old_conn_state->connector);
 	struct drm_dp_mst_topology_state *old_mst_state =
-		drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst_mgr);
+		drm_atomic_get_old_mst_topology_state(&state->base, &intel_dp->mst.mgr);
 	struct drm_dp_mst_topology_state *new_mst_state =
-		drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
+		drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst.mgr);
 	const struct drm_dp_mst_atomic_payload *old_payload =
-		drm_atomic_get_mst_payload_state(old_mst_state, connector->port);
+		drm_atomic_get_mst_payload_state(old_mst_state, connector->mst.port);
 	struct drm_dp_mst_atomic_payload *new_payload =
-		drm_atomic_get_mst_payload_state(new_mst_state, connector->port);
+		drm_atomic_get_mst_payload_state(new_mst_state, connector->mst.port);
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct intel_crtc *pipe_crtc;
 	bool last_mst_stream;
 
-	intel_dp->active_mst_links--;
-	last_mst_stream = intel_dp->active_mst_links == 0;
+	intel_dp->mst.active_links--;
+	last_mst_stream = intel_dp->mst.active_links == 0;
 	drm_WARN_ON(&dev_priv->drm,
 		    DISPLAY_VER(dev_priv) >= 12 && last_mst_stream &&
 		    !intel_dp_mst_is_master_trans(old_crtc_state));
@@ -1038,7 +1038,7 @@ static void intel_mst_post_disable_dp(st
 
 	intel_disable_transcoder(old_crtc_state);
 
-	drm_dp_remove_payload_part1(&intel_dp->mst_mgr, new_mst_state, new_payload);
+	drm_dp_remove_payload_part1(&intel_dp->mst.mgr, new_mst_state, new_payload);
 
 	clear_act_sent(encoder, old_crtc_state);
 
@@ -1048,7 +1048,7 @@ static void intel_mst_post_disable_dp(st
 
 	wait_for_act_sent(encoder, old_crtc_state);
 
-	drm_dp_remove_payload_part2(&intel_dp->mst_mgr, new_mst_state,
+	drm_dp_remove_payload_part2(&intel_dp->mst.mgr, new_mst_state,
 				    old_payload, new_payload);
 
 	intel_ddi_disable_transcoder_func(old_crtc_state);
@@ -1070,7 +1070,7 @@ static void intel_mst_post_disable_dp(st
 	 * Power down mst path before disabling the port, otherwise we end
 	 * up getting interrupts from the sink upon detecting link loss.
 	 */
-	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port,
+	drm_dp_send_power_updown_phy(&intel_dp->mst.mgr, connector->mst.port,
 				     false);
 
 	/*
@@ -1096,7 +1096,7 @@ static void intel_mst_post_disable_dp(st
 						  old_crtc_state, NULL);
 
 	drm_dbg_kms(&dev_priv->drm, "active links %d\n",
-		    intel_dp->active_mst_links);
+		    intel_dp->mst.active_links);
 }
 
 static void intel_mst_post_pll_disable_dp(struct intel_atomic_state *state,
@@ -1108,7 +1108,7 @@ static void intel_mst_post_pll_disable_d
 	struct intel_digital_port *dig_port = intel_mst->primary;
 	struct intel_dp *intel_dp = &dig_port->dp;
 
-	if (intel_dp->active_mst_links == 0 &&
+	if (intel_dp->mst.active_links == 0 &&
 	    dig_port->base.post_pll_disable)
 		dig_port->base.post_pll_disable(state, encoder, old_crtc_state, old_conn_state);
 }
@@ -1122,7 +1122,7 @@ static void intel_mst_pre_pll_enable_dp(
 	struct intel_digital_port *dig_port = intel_mst->primary;
 	struct intel_dp *intel_dp = &dig_port->dp;
 
-	if (intel_dp->active_mst_links == 0)
+	if (intel_dp->mst.active_links == 0)
 		dig_port->base.pre_pll_enable(state, &dig_port->base,
 						    pipe_config, NULL);
 	else
@@ -1155,7 +1155,7 @@ static void intel_mst_reprobe_topology(s
 					       crtc_state->port_clock, crtc_state->lane_count))
 		return;
 
-	drm_dp_mst_topology_queue_probe(&intel_dp->mst_mgr);
+	drm_dp_mst_topology_queue_probe(&intel_dp->mst.mgr);
 
 	intel_mst_set_probed_link_params(intel_dp,
 					 crtc_state->port_clock, crtc_state->lane_count);
@@ -1173,7 +1173,7 @@ static void intel_mst_pre_enable_dp(stru
 	struct intel_connector *connector =
 		to_intel_connector(conn_state->connector);
 	struct drm_dp_mst_topology_state *mst_state =
-		drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
+		drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst.mgr);
 	int ret;
 	bool first_mst_stream;
 
@@ -1182,18 +1182,18 @@ static void intel_mst_pre_enable_dp(stru
 	 */
 	connector->encoder = encoder;
 	intel_mst->connector = connector;
-	first_mst_stream = intel_dp->active_mst_links == 0;
+	first_mst_stream = intel_dp->mst.active_links == 0;
 	drm_WARN_ON(&dev_priv->drm,
 		    DISPLAY_VER(dev_priv) >= 12 && first_mst_stream &&
 		    !intel_dp_mst_is_master_trans(pipe_config));
 
 	drm_dbg_kms(&dev_priv->drm, "active links %d\n",
-		    intel_dp->active_mst_links);
+		    intel_dp->mst.active_links);
 
 	if (first_mst_stream)
 		intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
 
-	drm_dp_send_power_updown_phy(&intel_dp->mst_mgr, connector->port, true);
+	drm_dp_send_power_updown_phy(&intel_dp->mst.mgr, connector->mst.port, true);
 
 	intel_dp_sink_enable_decompression(state, connector, pipe_config);
 
@@ -1204,10 +1204,10 @@ static void intel_mst_pre_enable_dp(stru
 		intel_mst_reprobe_topology(intel_dp, pipe_config);
 	}
 
-	intel_dp->active_mst_links++;
+	intel_dp->mst.active_links++;
 
-	ret = drm_dp_add_payload_part1(&intel_dp->mst_mgr, mst_state,
-				       drm_atomic_get_mst_payload_state(mst_state, connector->port));
+	ret = drm_dp_add_payload_part1(&intel_dp->mst.mgr, mst_state,
+				       drm_atomic_get_mst_payload_state(mst_state, connector->mst.port));
 	if (ret < 0)
 		intel_dp_queue_modeset_retry_for_link(state, &dig_port->base, pipe_config);
 
@@ -1269,9 +1269,9 @@ static void intel_mst_enable_dp(struct i
 	struct intel_connector *connector = to_intel_connector(conn_state->connector);
 	struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
 	struct drm_dp_mst_topology_state *mst_state =
-		drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst_mgr);
+		drm_atomic_get_new_mst_topology_state(&state->base, &intel_dp->mst.mgr);
 	enum transcoder trans = pipe_config->cpu_transcoder;
-	bool first_mst_stream = intel_dp->active_mst_links == 1;
+	bool first_mst_stream = intel_dp->mst.active_links == 1;
 	struct intel_crtc *pipe_crtc;
 	int ret;
 
@@ -1298,16 +1298,16 @@ static void intel_mst_enable_dp(struct i
 		     TRANS_DDI_DP_VC_PAYLOAD_ALLOC);
 
 	drm_dbg_kms(&dev_priv->drm, "active links %d\n",
-		    intel_dp->active_mst_links);
+		    intel_dp->mst.active_links);
 
 	wait_for_act_sent(encoder, pipe_config);
 
 	if (first_mst_stream)
 		intel_ddi_wait_for_fec_status(encoder, pipe_config, true);
 
-	ret = drm_dp_add_payload_part2(&intel_dp->mst_mgr,
+	ret = drm_dp_add_payload_part2(&intel_dp->mst.mgr,
 				       drm_atomic_get_mst_payload_state(mst_state,
-									connector->port));
+									connector->mst.port));
 	if (ret < 0)
 		intel_dp_queue_modeset_retry_for_link(state, &dig_port->base, pipe_config);
 
@@ -1363,7 +1363,7 @@ static int intel_dp_mst_get_ddc_modes(st
 {
 	struct intel_connector *intel_connector = to_intel_connector(connector);
 	struct drm_i915_private *i915 = to_i915(intel_connector->base.dev);
-	struct intel_dp *intel_dp = intel_connector->mst_port;
+	struct intel_dp *intel_dp = intel_connector->mst.dp;
 	const struct drm_edid *drm_edid;
 	int ret;
 
@@ -1373,7 +1373,7 @@ static int intel_dp_mst_get_ddc_modes(st
 	if (!intel_display_driver_check_access(i915))
 		return drm_edid_connector_add_modes(connector);
 
-	drm_edid = drm_dp_mst_edid_read(connector, &intel_dp->mst_mgr, intel_connector->port);
+	drm_edid = drm_dp_mst_edid_read(connector, &intel_dp->mst.mgr, intel_connector->mst.port);
 
 	ret = intel_connector_update_modes(connector, drm_edid);
 
@@ -1389,14 +1389,14 @@ intel_dp_mst_connector_late_register(str
 	int ret;
 
 	ret = drm_dp_mst_connector_late_register(connector,
-						 intel_connector->port);
+						 intel_connector->mst.port);
 	if (ret < 0)
 		return ret;
 
 	ret = intel_connector_register(connector);
 	if (ret < 0)
 		drm_dp_mst_connector_early_unregister(connector,
-						      intel_connector->port);
+						      intel_connector->mst.port);
 
 	return ret;
 }
@@ -1408,7 +1408,7 @@ intel_dp_mst_connector_early_unregister(
 
 	intel_connector_unregister(connector);
 	drm_dp_mst_connector_early_unregister(connector,
-					      intel_connector->port);
+					      intel_connector->mst.port);
 }
 
 static const struct drm_connector_funcs intel_dp_mst_connector_funcs = {
@@ -1435,9 +1435,9 @@ intel_dp_mst_mode_valid_ctx(struct drm_c
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_connector *intel_connector = to_intel_connector(connector);
-	struct intel_dp *intel_dp = intel_connector->mst_port;
-	struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr;
-	struct drm_dp_mst_port *port = intel_connector->port;
+	struct intel_dp *intel_dp = intel_connector->mst.dp;
+	struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst.mgr;
+	struct drm_dp_mst_port *port = intel_connector->mst.port;
 	const int min_bpp = 18;
 	int max_dotclk = to_i915(connector->dev)->display.cdclk.max_dotclk_freq;
 	int max_rate, mode_rate, max_lanes, max_link_clock;
@@ -1548,10 +1548,10 @@ static struct drm_encoder *intel_mst_ato
 	struct drm_connector_state *connector_state = drm_atomic_get_new_connector_state(state,
 											 connector);
 	struct intel_connector *intel_connector = to_intel_connector(connector);
-	struct intel_dp *intel_dp = intel_connector->mst_port;
+	struct intel_dp *intel_dp = intel_connector->mst.dp;
 	struct intel_crtc *crtc = to_intel_crtc(connector_state->crtc);
 
-	return &intel_dp->mst_encoders[crtc->pipe]->base.base;
+	return &intel_dp->mst.stream_encoders[crtc->pipe]->base.base;
 }
 
 static int
@@ -1560,7 +1560,7 @@ intel_dp_mst_detect(struct drm_connector
 {
 	struct drm_i915_private *i915 = to_i915(connector->dev);
 	struct intel_connector *intel_connector = to_intel_connector(connector);
-	struct intel_dp *intel_dp = intel_connector->mst_port;
+	struct intel_dp *intel_dp = intel_connector->mst.dp;
 
 	if (!intel_display_device_enabled(i915))
 		return connector_status_disconnected;
@@ -1571,8 +1571,8 @@ intel_dp_mst_detect(struct drm_connector
 	if (!intel_display_driver_check_access(i915))
 		return connector->status;
 
-	return drm_dp_mst_detect_port(connector, ctx, &intel_dp->mst_mgr,
-				      intel_connector->port);
+	return drm_dp_mst_detect_port(connector, ctx, &intel_dp->mst.mgr,
+				      intel_connector->mst.port);
 }
 
 static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = {
@@ -1661,10 +1661,10 @@ static bool detect_dsc_hblank_expansion_
 	 * A logical port's OUI (at least for affected sinks) is all 0, so
 	 * instead of that the parent port's OUI is used for identification.
 	 */
-	if (drm_dp_mst_port_is_logical(connector->port)) {
-		aux = drm_dp_mst_aux_for_parent(connector->port);
+	if (drm_dp_mst_port_is_logical(connector->mst.port)) {
+		aux = drm_dp_mst_aux_for_parent(connector->mst.port);
 		if (!aux)
-			aux = &connector->mst_port->aux;
+			aux = &connector->mst.dp->aux;
 	}
 
 	if (drm_dp_read_dpcd_caps(aux, dpcd) < 0)
@@ -1698,7 +1698,7 @@ static struct drm_connector *intel_dp_ad
 							struct drm_dp_mst_port *port,
 							const char *pathprop)
 {
-	struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
+	struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst.mgr);
 	struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
 	struct drm_device *dev = dig_port->base.base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
@@ -1713,8 +1713,8 @@ static struct drm_connector *intel_dp_ad
 
 	intel_connector->get_hw_state = intel_dp_mst_get_hw_state;
 	intel_connector->sync_state = intel_dp_connector_sync_state;
-	intel_connector->mst_port = intel_dp;
-	intel_connector->port = port;
+	intel_connector->mst.dp = intel_dp;
+	intel_connector->mst.port = port;
 	drm_dp_mst_get_port_malloc(port);
 
 	intel_dp_init_modeset_retry_work(intel_connector);
@@ -1737,7 +1737,7 @@ static struct drm_connector *intel_dp_ad
 
 	for_each_pipe(dev_priv, pipe) {
 		struct drm_encoder *enc =
-			&intel_dp->mst_encoders[pipe]->base.base;
+			&intel_dp->mst.stream_encoders[pipe]->base.base;
 
 		ret = drm_connector_attach_encoder(&intel_connector->base, enc);
 		if (ret)
@@ -1763,7 +1763,7 @@ err:
 static void
 intel_dp_mst_poll_hpd_irq(struct drm_dp_mst_topology_mgr *mgr)
 {
-	struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr);
+	struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst.mgr);
 
 	intel_hpd_trigger_irq(dp_to_dig_port(intel_dp));
 }
@@ -1833,14 +1833,14 @@ intel_dp_create_fake_mst_encoders(struct
 	enum pipe pipe;
 
 	for_each_pipe(dev_priv, pipe)
-		intel_dp->mst_encoders[pipe] = intel_dp_create_fake_mst_encoder(dig_port, pipe);
+		intel_dp->mst.stream_encoders[pipe] = intel_dp_create_fake_mst_encoder(dig_port, pipe);
 	return true;
 }
 
 int
 intel_dp_mst_encoder_active_links(struct intel_digital_port *dig_port)
 {
-	return dig_port->dp.active_mst_links;
+	return dig_port->dp.mst.active_links;
 }
 
 int
@@ -1860,14 +1860,14 @@ intel_dp_mst_encoder_init(struct intel_d
 	if (DISPLAY_VER(i915) < 11 && port == PORT_E)
 		return 0;
 
-	intel_dp->mst_mgr.cbs = &mst_cbs;
+	intel_dp->mst.mgr.cbs = &mst_cbs;
 
 	/* create encoders */
 	intel_dp_create_fake_mst_encoders(dig_port);
-	ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst_mgr, &i915->drm,
+	ret = drm_dp_mst_topology_mgr_init(&intel_dp->mst.mgr, &i915->drm,
 					   &intel_dp->aux, 16, 3, conn_base_id);
 	if (ret) {
-		intel_dp->mst_mgr.cbs = NULL;
+		intel_dp->mst.mgr.cbs = NULL;
 		return ret;
 	}
 
@@ -1876,7 +1876,7 @@ intel_dp_mst_encoder_init(struct intel_d
 
 bool intel_dp_mst_source_support(struct intel_dp *intel_dp)
 {
-	return intel_dp->mst_mgr.cbs;
+	return intel_dp->mst.mgr.cbs;
 }
 
 void
@@ -1887,10 +1887,10 @@ intel_dp_mst_encoder_cleanup(struct inte
 	if (!intel_dp_mst_source_support(intel_dp))
 		return;
 
-	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst_mgr);
+	drm_dp_mst_topology_mgr_destroy(&intel_dp->mst.mgr);
 	/* encoders will get killed by normal cleanup */
 
-	intel_dp->mst_mgr.cbs = NULL;
+	intel_dp->mst.mgr.cbs = NULL;
 }
 
 bool intel_dp_mst_is_master_trans(const struct intel_crtc_state *crtc_state)
@@ -1921,11 +1921,11 @@ intel_dp_mst_add_topology_state_for_conn
 {
 	struct drm_dp_mst_topology_state *mst_state;
 
-	if (!connector->mst_port)
+	if (!connector->mst.dp)
 		return 0;
 
 	mst_state = drm_atomic_get_mst_topology_state(&state->base,
-						      &connector->mst_port->mst_mgr);
+						      &connector->mst.dp->mst.mgr);
 	if (IS_ERR(mst_state))
 		return PTR_ERR(mst_state);
 
@@ -2023,7 +2023,7 @@ bool intel_dp_mst_crtc_needs_modeset(str
 		const struct intel_crtc_state *old_crtc_state;
 		struct intel_crtc *crtc_iter;
 
-		if (connector->mst_port != crtc_connector->mst_port ||
+		if (connector->mst.dp != crtc_connector->mst.dp ||
 		    !conn_state->crtc)
 			continue;
 
@@ -2046,7 +2046,7 @@ bool intel_dp_mst_crtc_needs_modeset(str
 		 * case.
 		 */
 		if (connector->dp.dsc_decompression_aux ==
-		    &connector->mst_port->aux)
+		    &connector->mst.dp->aux)
 			return true;
 	}
 
@@ -2107,7 +2107,7 @@ bool intel_dp_mst_verify_dpcd_state(stru
 	if (!intel_dp->is_mst)
 		return true;
 
-	ret = drm_dp_dpcd_readb(intel_dp->mst_mgr.aux, DP_MSTM_CTRL, &val);
+	ret = drm_dp_dpcd_readb(intel_dp->mst.mgr.aux, DP_MSTM_CTRL, &val);
 
 	/* Adjust the expected register value for SST + SideBand. */
 	if (ret < 0 || val != (DP_MST_EN | DP_UP_REQ_EN | DP_UPSTREAM_IS_SRC)) {
--- a/drivers/gpu/drm/i915/display/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/display/intel_hdcp.c
@@ -62,13 +62,13 @@ static int intel_conn_to_vcpi(struct int
 	int vcpi = 0;
 
 	/* For HDMI this is forced to be 0x0. For DP SST also this is 0x0. */
-	if (!connector->port)
+	if (!connector->mst.port)
 		return 0;
-	mgr = connector->port->mgr;
+	mgr = connector->mst.port->mgr;
 
 	drm_modeset_lock(&mgr->base.lock, state->base.acquire_ctx);
 	mst_state = to_drm_dp_mst_topology_state(mgr->base.state);
-	payload = drm_atomic_get_mst_payload_state(mst_state, connector->port);
+	payload = drm_atomic_get_mst_payload_state(mst_state, connector->mst.port);
 	if (drm_WARN_ON(mgr->dev, !payload))
 		goto out;
 
@@ -137,7 +137,7 @@ intel_hdcp_required_content_stream(struc
 		data->k++;
 
 		/* if there is only one active stream */
-		if (dig_port->dp.active_mst_links <= 1)
+		if (dig_port->dp.mst.active_links <= 1)
 			break;
 	}
 	drm_connector_list_iter_end(&conn_iter);
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -3951,7 +3951,7 @@ void intel_psr_connector_debugfs_add(str
 	/* TODO: Add support for MST connectors as well. */
 	if ((connector->base.connector_type != DRM_MODE_CONNECTOR_eDP &&
 	     connector->base.connector_type != DRM_MODE_CONNECTOR_DisplayPort) ||
-	    connector->mst_port)
+	    connector->mst.dp)
 		return;
 
 	debugfs_create_file("i915_psr_sink_status", 0444, root,



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 826/877] drm/i915/dp_mst: Fix configuring FEC for a disconnected stream
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (824 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 825/877] drm/i915/mst: add mst sub-struct to struct intel_dp Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 827/877] mm/rmap: allocate anon_vma_chain objects unlocked when possible Greg Kroah-Hartman
                   ` (58 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Luca Coelho, Imre Deak, Jani Nikula,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Imre Deak <imre.deak@intel.com>

[ Upstream commit acbe9a3b60b9a6ace8ef11fe898f586251c84592 ]

During an atomic commit after all the MST stream CRTC state is computed
the driver ensures that the FEC is configured the same way (enabled or
disabled) for all the streams on a given MST topology's link.
drm_dp_mst_port_downstream_of_parent() used to determine if a stream is
downstream of an MST port will return false if the whole topology is
disconnected, since in that case it can't verify that the port/
parent_port passed to it is in the given MST topology. This is a problem
during the above FEC configuration check, since
intel_dp_mst_check_dsc_change()->get_pipes_downstream_of_mst_ports()
will not return all the stream CRTCs/pipes for the topology as expected.
Since passing parent_port==NULL to get_pipes_downstream_of_mst_port()
is meant to return all the streams for the given topology (i.e. mst_mgr)
skip checking if an MST port is downstream of a parent port in this
case.

This fixes a problem where the FEC configuration check explained above
failed to ensure that all streams' FEC is configured the same way if the
topology was disconnected, leading to a FEC state mismatch error.

Cc: stable@vger.kernel.org # v6.10+
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/work_items/16073
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/work_items/16384
Reviewed-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Link: https://patch.msgid.link/20260907174413.741851-1-imre.deak@intel.com
(cherry picked from commit 270681fbffbba2b6ccf5b7e3c34b8b563b36167f)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/i915/display/intel_dp_mst.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -739,7 +739,8 @@ static u8 get_pipes_downstream_of_mst_po
 		if (&connector->mst.dp->mst.mgr != mst_mgr)
 			continue;
 
-		if (connector->mst.port != parent_port &&
+		if (parent_port &&
+		    connector->mst.port != parent_port &&
 		    !drm_dp_mst_port_downstream_of_parent(mst_mgr,
 							  connector->mst.port,
 							  parent_port))



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 827/877] mm/rmap: allocate anon_vma_chain objects unlocked when possible
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (825 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 826/877] drm/i915/dp_mst: Fix configuring FEC for a disconnected stream Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:28 ` [PATCH 6.12 828/877] mm/rmap: fix missing barrier between anon_vma init and vma->anon_vma publish Greg Kroah-Hartman
                   ` (57 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes, Suren Baghdasaryan,
	Liam R. Howlett, Barry Song, Chris Li, David Hildenbrand,
	Harry Yoo, Jann Horn, Michal Hocko, Mike Rapoport, Pedro Falcato,
	Rik van Riel, Shakeel Butt, Vlastimil Babka, Andrew Morton,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>

[ Upstream commit bfc2b13b05a1343bb60a85d840fd8956731866c5 ]

There is no reason to allocate the anon_vma_chain under the anon_vma write
lock when cloning - we can in fact assign these to the destination VMA
safely as we hold the exclusive mmap lock and therefore preclude anybody
else accessing these fields.

We only need take the anon_vma write lock when we link rbtree edges from
the anon_vma to the newly established AVCs.

This also allows us to eliminate the weird GFP_NOWAIT, GFP_KERNEL dance
introduced in commit dd34739c03f2 ("mm: avoid anon_vma_chain allocation
under anon_vma lock"), further simplifying this logic.

This should reduce lock anon_vma contention, and clarifies exactly where
the anon_vma lock is required.

We cannot adjust __anon_vma_prepare() in the same way as this is only
protected by VMA read lock, so we have to perform the allocation here
under the anon_vma write lock and page_table_lock (to protect against
racing threads), and we wish to retain the lock ordering.

With this change we can simplify cleanup_partial_anon_vmas() even further
- since we allocate AVC's without any lock taken and do not insert
anything into the interval tree until after the allocations are tried, we
can remove all logic pertaining to this and just free up AVC's only.

Link: https://lkml.kernel.org/r/624bf1ac0bde4871fcfca2c8c8e294b6d8f7ae7b.1768746221.git.lorenzo.stoakes@oracle.com
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Reviewed-by: Suren Baghdasaryan <surenb@google.com>
Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com>
Cc: Barry Song <v-songbaohua@oppo.com>
Cc: Chris Li <chriscli@google.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Harry Yoo <harry.yoo@oracle.com>
Cc: Jann Horn <jannh@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Pedro Falcato <pfalcato@suse.de>
Cc: Rik van Riel <riel@surriel.com>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

[Stable dependency adaptation for 6.18:
Keep the split of anon_vma_chain_link() into anon_vma_chain_assign() and
explicit interval-tree insertion at all three callers. Retain the fork
change that assigns the chain before taking the anon_vma write lock;
the interval-tree insertion remains protected by that lock.

Drop the two-pass clone allocation and cleanup_partial_anon_vmas() changes.
This tree lacks the prerequisite clone assertions, early unfaulted-VMA
handling, simplified root locking, and partial-clone cleanup. Preserve the
existing GFP_NOWAIT/GFP_KERNEL fallback, root locking, list traversal,
reference accounting, and allocation-failure cleanup instead. No new
functions are introduced.

The helper split supplies the context needed for b6ac0b3f6013 ("mm/rmap:
fix missing barrier between anon_vma init and vma->anon_vma publish") to
merge cleanly while retaining this tree's interval-tree API. The memory
barrier fix itself is left to that target commit.]

Stable-dep-of: b6ac0b3f6013 ("mm/rmap: fix missing barrier between anon_vma init and vma->anon_vma publish")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 mm/rmap.c |   17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -148,14 +148,13 @@ static void anon_vma_chain_free(struct a
 	kmem_cache_free(anon_vma_chain_cachep, anon_vma_chain);
 }
 
-static void anon_vma_chain_link(struct vm_area_struct *vma,
-				struct anon_vma_chain *avc,
-				struct anon_vma *anon_vma)
+static void anon_vma_chain_assign(struct vm_area_struct *vma,
+				  struct anon_vma_chain *avc,
+				  struct anon_vma *anon_vma)
 {
 	avc->vma = vma;
 	avc->anon_vma = anon_vma;
 	list_add(&avc->same_vma, &vma->anon_vma_chain);
-	anon_vma_interval_tree_insert(avc, &anon_vma->rb_root);
 }
 
 /**
@@ -212,7 +211,8 @@ int __anon_vma_prepare(struct vm_area_st
 	spin_lock(&mm->page_table_lock);
 	if (likely(!vma->anon_vma)) {
 		vma->anon_vma = anon_vma;
-		anon_vma_chain_link(vma, avc, anon_vma);
+		anon_vma_chain_assign(vma, avc, anon_vma);
+		anon_vma_interval_tree_insert(avc, &anon_vma->rb_root);
 		anon_vma->num_active_vmas++;
 		allocated = NULL;
 		avc = NULL;
@@ -296,7 +296,8 @@ int anon_vma_clone(struct vm_area_struct
 		}
 		anon_vma = pavc->anon_vma;
 		root = lock_anon_vma_root(root, anon_vma);
-		anon_vma_chain_link(dst, avc, anon_vma);
+		anon_vma_chain_assign(dst, avc, anon_vma);
+		anon_vma_interval_tree_insert(avc, &anon_vma->rb_root);
 
 		/*
 		 * Reuse existing anon_vma if it has no vma and only one
@@ -380,8 +381,10 @@ int anon_vma_fork(struct vm_area_struct
 	get_anon_vma(anon_vma->root);
 	/* Mark this anon_vma as the one where our new (COWed) pages go. */
 	vma->anon_vma = anon_vma;
+	anon_vma_chain_assign(vma, avc, anon_vma);
+	/* Now let rmap see it. */
 	anon_vma_lock_write(anon_vma);
-	anon_vma_chain_link(vma, avc, anon_vma);
+	anon_vma_interval_tree_insert(avc, &anon_vma->rb_root);
 	anon_vma->parent->num_children++;
 	anon_vma_unlock_write(anon_vma);
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 828/877] mm/rmap: fix missing barrier between anon_vma init and vma->anon_vma publish
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (826 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 827/877] mm/rmap: allocate anon_vma_chain objects unlocked when possible Greg Kroah-Hartman
@ 2026-09-30 15:28 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 829/877] drm/xe/vm: nuke PTs only after unlinking contested VMAs Greg Kroah-Hartman
                   ` (56 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:28 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jinjiang Tu, Andrew Morton,
	Lance Yang, Lorenzo Stoakes (ARM), David Hildenbrand (Arm),
	Vlastimil Babka (SUSE), Minchan Kim, Harry Yoo,
	Hiroyouki Kamezawa, Jann Horn, Kefeng Wang, Larry Woodman,
	Liam R. Howlett, Nanyong Sun, Rik van Riel, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jinjiang Tu <tujinjiang@huawei.com>

[ Upstream commit b6ac0b3f6013c168f22cad97e79967accacb08e1 ]

On arm64 server, we find that a task trying to grab the anon_vma lock
triggers hungtask.

INFO: task main:2354726 blocked for more than 120 seconds.
      Tainted: G            E     5.10.0-0021.aarch64 #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:main            state:D stack:    0 pid:2354726 ppid:2350673 flags:0x00000a01
Call trace:
 __switch_to+0x7c/0xbc
 __schedule+0x3b4/0x8a0
 schedule+0x50/0xe0
 rwsem_down_write_slowpath+0x3cc/0x6cc
 down_write+0x60/0x260
 __anon_vma_prepare+0x6c/0x210
 do_anonymous_page+0x258/0x660
 handle_pte_fault+0x188/0x214
 __handle_mm_fault+0x1b0/0x380
 handle_mm_fault+0xf4/0x284
 do_page_fault+0x19c/0x494
 do_translation_fault+0xcc/0xf8
 do_mem_abort+0x48/0xac
 el0_da+0x44/0x80
 el0_sync_handler+0x88/0xb4
 el0_sync+0x160/0x180

After analyzing the vmcore, we found the anon_vma->root->rwsem.count is
-1.  There is another anon_vma whose anon_vma->root->rwsem.count is 1, the
anon_vma->root->rwsem.owner shows the lock is held, but the stack of the
task shows the task doesn't hold the anon_vma lock.

After adding more debugging info, we found __anon_vma_prepare() reuses
anon_vma and triggers the UAF of anon_vma->root due to missing memory
barrier, leading to locking and unlocking two different anon_vma->root,
thus leading to an anon_vma will never be unlocked, and another anon_vma
couldn't be locked anymore.

This race requires two adjacent VMAs that are not merged but are
anon_vma-compatible (e.g., they differ in VMA_ACCESS_FLAGS that can be
changed by mprotect()).  Two threads fault on each VMA concurrently, both
calling __anon_vma_prepare() with only mmap_lock held for reading.

    THREAD A                             THREAD B
__anon_vma_prepare                __anon_vma_prepare
 find_mergeable_anon_vma() -> NULL
 anon_vma = anon_vma_alloc();
   anon_vma->root = anon_vma;
 // the two stores may be reordered
 vma->anon_vma = anon_vma;
                                   // finds A's anon_vma
                                   anon_vma = find_mergeable_anon_vma(vma);
                                   anon_vma_lock_write(anon_vma);
                                     // may still see the old root
                                     down_write(&anon_vma->root->rwsem);
                                   anon_vma_unlock_write(anon_vma);
                                     // see the new root, never unlock old
                                     up_write(&anon_vma->root->rwsem);

thread A triggers page fault and calls __anon_vma_prepare() to prepare
anon_vma for the faulting vma.  __anon_vma_prepare() allocates and
initializes a new anon_vma, and then publishes it to the vma with a plain
store.  anon_vma_prepare() only requires the mmap_lock to be held for
reading, so two threads can fault on adjacent VMAs at the same time.
While thread A publishes a new anon_vma, thread B could find the anon_vma
via find_mergeable_anon_vma() and then locks anon_vma->root->rwsem.

The store to anon_vma->root in anon_vma_alloc() and the store to
vma->anon_vma can be reordered.  The anon_vma_lock_write() and spin_lock()
only provide acquire semantics, which do not prevent prior stores from
being reordered after them.  The release semantics of the corresponding
spin_unlock() and anon_vma_unlock_write() come too late, the store to
vma->anon_vma is already published before they take effect.  As a result,
thread B can observe the following order:

    vma->anon_vma = anon_vma;
    anon_vma->root = anon_vma;

The anon_vma slab is SLAB_TYPESAFE_BY_RCU, so a newly allocated anon_vma
may reuse memory from a previously freed one.  The constructor
(anon_vma_ctor) does not reset anon_vma->root, and __put_anon_vma()
doesn't clear it either, so the old root value persists until
anon_vma_alloc() overwrites it.  If that store isn't visible, thread B
reads a root that points to the old anon_vma and locks it.

As a result, thread B can call anon_vma_lock_write() with the old root,
and call anon_vma_unlock_write() with the new root, leading to an anon_vma
will never be unlocked, and another anon_vma couldn't be locked anymore
(its count is dropped from 0 to -1 due to wrong unlock).

To fix it, change the plain store `vma->anon_vma = anon_vma` to store
release, so that the fields of anon_vma are visible before anon_vma is
published to vma->anon_vma.

At read side, the load of anon_vma and anon_vma->root have address
dependency.  According to Documentation/memory-barriers.txt and some
investigations, only Alpha needs address-dependency barriers and it has
been handled by READ_ONCE() in reusable_anon_vma().

We reproduced this issue in v5.10 with KSM enabled.  The kernel doesn't
merge commit cf7e7a3503df ("mm: prevent KSM from breaking VMA merging for
new VMAs"), so there are many adjacent VMAs that aren't merged but are
compatible for anon_vma.

Without this fix, our production environment could reproduce this issue
about 2-5 times each month.  After adding a smp_mb() before
anon_vma_lock_write(anon_vma) in __anon_vma_prepare(), which is different
to this patch, this issue hasn't been reproduced for one month.

Link: https://lore.kernel.org/20260908122924.554373-1-tujinjiang@huawei.com
Fixes: 5c341ee1dfc8 ("mm: track the root (oldest) anon_vma")
Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Harry Yoo <harry@kernel.org>
Cc: Hiroyouki Kamezawa <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Jann Horn <jannh@google.com>
Cc: Jinjiang Tu <tujinjiang@huawei.com>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: Larry Woodman <lwoodman@redhat.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Nanyong Sun <sunnanyong@huawei.com>
Cc: Rik van Riel <riel@surriel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 mm/rmap.c |    6 +++++-
 mm/vma.c  |    8 ++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -210,7 +210,11 @@ int __anon_vma_prepare(struct vm_area_st
 	/* page_table_lock to protect against threads */
 	spin_lock(&mm->page_table_lock);
 	if (likely(!vma->anon_vma)) {
-		vma->anon_vma = anon_vma;
+		/*
+		 * Make anon_vma fields visible before anon_vma is published.
+		 * Paired with an address dependency in reusable_anon_vma().
+		 */
+		smp_store_release(&vma->anon_vma, anon_vma);
 		anon_vma_chain_assign(vma, avc, anon_vma);
 		anon_vma_interval_tree_insert(avc, &anon_vma->rb_root);
 		anon_vma->num_active_vmas++;
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -1760,6 +1760,13 @@ static int anon_vma_compatible(struct vm
  * acceptable for merging, so we can do all of this optimistically. But
  * we do that READ_ONCE() to make sure that we never re-load the pointer.
  *
+ * The READ_ONCE() establishes an address dependency between anon_vma and
+ * any access to its fields, which pairs with the assignment to
+ * vma->anon_vma performed with release semantics in __anon_vma_prepare().
+ *
+ * This is especially important as anon_vma's are SLAB_TYPESAFE_BY_RCU so
+ * accessing an uninitialised anon_vma's fields may result in a UAF.
+ *
  * IOW: that the "list_is_singular()" test on the anon_vma_chain only
  * matters for the 'stable anon_vma' case (ie the thing we want to avoid
  * is to return an anon_vma that is "complex" due to having gone through
@@ -1774,6 +1781,7 @@ static struct anon_vma *reusable_anon_vm
 					  struct vm_area_struct *b)
 {
 	if (anon_vma_compatible(a, b)) {
+		/* Paired with a memory barrier in __anon_vma_prepare(). */
 		struct anon_vma *anon_vma = READ_ONCE(old->anon_vma);
 
 		if (anon_vma && list_is_singular(&old->anon_vma_chain))



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 829/877] drm/xe/vm: nuke PTs only after unlinking contested VMAs
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (827 preceding siblings ...)
  2026-09-30 15:28 ` [PATCH 6.12 828/877] mm/rmap: fix missing barrier between anon_vma init and vma->anon_vma publish Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 830/877] mm/damon/vaddr: avoid hw-driven pte updates during damon_hugetlb_mkold() Greg Kroah-Hartman
                   ` (55 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Matthew Auld, Thomas Hellström,
	Matthew Brost, Rodrigo Vivi, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Matthew Auld <matthew.auld@intel.com>

[ Upstream commit 24a22fb3c731474b68e986af6804db450fb88617 ]

In xe_vm_close_and_put(), external-BO VMAs are queued on the contested
list for deferred destruction via xe_vma_destroy_unlocked(). However,
xe_vm_pt_destroy() was previously invoked before processing contested
VMAs, destroying vm->pt_root while those VMAs were still linked to their
respective buffer objects (vm_bo->list.gpuva).

If a concurrent thread evicts one of those shared buffer objects,
xe_bo_trigger_rebind() holding only bo->resv walks the BO's VMAs and, in
fault mode, calls xe_vm_invalidate_vma() -> xe_pt_zap_ptes(). Because
vm->pt_root[tile->id] is already NULL, dereferencing pt->level causes a
NULL ptr deref.

Fix this by deferring xe_vm_free_scratch() and xe_vm_pt_destroy() until
after all contested VMAs have been unlinked and destroyed.

User is reporting hitting a NULL ptr deref in xe_pt_zap_ptes(), which
could be explained by this race.

Assisted-by: LLM
Fixes: b06d47be7c83 ("drm/xe: Port Xe to GPUVA")
Link: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/9290
Signed-off-by: Matthew Auld <matthew.auld@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: <stable@vger.kernel.org> # v6.12+
Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Link: https://patch.msgid.link/20260918131034.598078-2-matthew.auld@intel.com
(cherry picked from commit c2863648959489767f08892fd6e90577d2ea0b6a)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
[ adapted xe_vm_pt_destroy() cleanup to the existing inline page-table destruction loop. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/xe/xe_vm.c |   29 +++++++++++++----------------
 1 file changed, 13 insertions(+), 16 deletions(-)

--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -1678,13 +1678,21 @@ void xe_vm_close_and_put(struct xe_vm *v
 		vma->gpuva.flags |= XE_VMA_DESTROYED;
 	}
 
+	xe_vm_unlock(vm);
+
 	/*
-	 * All vm operations will add shared fences to resv.
-	 * The only exception is eviction for a shared object,
-	 * but even so, the unbind when evicted would still
-	 * install a fence to resv. Hence it's safe to
-	 * destroy the pagetables immediately.
+	 * Unlink and destroy all contested external-BO VMAs before destroying
+	 * the page tables. Otherwise, concurrent eviction holding only bo->resv
+	 * can walk the BO's VMAs and attempt to invalidate/zap page tables that
+	 * have already been freed.
 	 */
+	list_for_each_entry_safe(vma, next_vma, &contested,
+				 combined_links.destroy) {
+		list_del_init(&vma->combined_links.destroy);
+		xe_vma_destroy_unlocked(vma);
+	}
+
+	xe_vm_lock(vm, false);
 	xe_vm_free_scratch(vm);
 
 	for_each_tile(tile, xe, id) {
@@ -1695,17 +1703,6 @@ void xe_vm_close_and_put(struct xe_vm *v
 	}
 	xe_vm_unlock(vm);
 
-	/*
-	 * VM is now dead, cannot re-add nodes to vm->vmas if it's NULL
-	 * Since we hold a refcount to the bo, we can remove and free
-	 * the members safely without locking.
-	 */
-	list_for_each_entry_safe(vma, next_vma, &contested,
-				 combined_links.destroy) {
-		list_del_init(&vma->combined_links.destroy);
-		xe_vma_destroy_unlocked(vma);
-	}
-
 	up_write(&vm->lock);
 
 	down_write(&xe->usm.lock);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 830/877] mm/damon/vaddr: avoid hw-driven pte updates during damon_hugetlb_mkold()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (828 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 829/877] drm/xe/vm: nuke PTs only after unlinking contested VMAs Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 831/877] mm/hugetlb: fix surplus pages in dissolve_free_huge_page() Greg Kroah-Hartman
                   ` (54 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, SJ Park, Andrew Morton, Baolin Wang,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: SJ Park <sj@kernel.org>

[ Upstream commit 39c0ceedd54557bdc1542de08d22b2ed33e534e4 ]

damon_hugetlb_mkold() reads the page table entry into a local variable,
unsets the accessed bit in the variable, and updates the page table entry
with the updated variable value.  If hardware updates the same page table
entry in parallel, the hw updates could be lost.  For example,
hardware-updated dirty bits might be lost.

Avoid the parallel updates by clearing the page table entry when reading
it together, using huge_ptep_get_and_clear().  If a parallel write to the
memory is made after the clearing, the hw will see the page table entry is
cleared, trigger page fault and wait until it is handled.  The page fault
handling will wait for damon_hugetlb_mkold() due to the page table lock.

Because hugetlbfs is an in-memory file system and hugetlb pages cannot be
reclaimed, no critical issue is expected to my best knowledge.  But
definitely this is a nasty bug that should be fixed sooner rather than
later.

The issue was discovered [1] by Sashiko.

Link: https://lore.kernel.org/20260907170358.100168-1-sj@kernel.org
Link: https://lore.kernel.org/20260830160545.98969-1-sj@kernel.org [1]
Fixes: 49f4203aae06 ("mm/damon: add access checking for hugetlb pages")
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: <stable@vger.kernel.org> # 5.17.x
[ preserved CONFIG_MMU_NOTIFIER guards because this branch lacks the mmu_notifier_clear_young() fallback. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 mm/damon/vaddr.c |    1 +
 1 file changed, 1 insertion(+)

--- a/mm/damon/vaddr.c
+++ b/mm/damon/vaddr.c
@@ -347,6 +347,7 @@ static void damon_hugetlb_mkold(pte_t *p
 
 	if (pte_young(entry)) {
 		referenced = true;
+		entry = huge_ptep_get_and_clear(mm, addr, pte, psize);
 		entry = pte_mkold(entry);
 		set_huge_pte_at(mm, addr, pte, entry, psize);
 	}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 831/877] mm/hugetlb: fix surplus pages in dissolve_free_huge_page()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (829 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 830/877] mm/damon/vaddr: avoid hw-driven pte updates during damon_hugetlb_mkold() Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 832/877] mm/hugetlb: create hstate_is_gigantic_no_runtime helper Greg Kroah-Hartman
                   ` (53 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jinjiang Tu, David Hildenbrand,
	Oscar Salvador, Kefeng Wang, Muchun Song, Nanyong Sun,
	Andrew Morton, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jinjiang Tu <tujinjiang@huawei.com>

[ Upstream commit cb402bbdabcaa5a765068c5b8673bbfc1c264242 ]

In dissolve_free_huge_page(), free huge pages are dissolved without
adjusting surplus count. However, free huge pages may be accounted as
surplus pages, and will lead to wrong surplus count.

I reproduce this issue on qemu. The steps are:
1) Node1 is memory-less at first. Hot-add memory to node1 by executing
the two commands in qemu monitor:
  object_add memory-backend-ram,id=mem1,size=1G
  device_add pc-dimm,id=dimm1,memdev=mem1,node=1
2) online one memory block of Node1 with:
  echo online_movable > /sys/devices/system/node/node1/memoryX/state
3) create 64 huge pages for node1
4) run a program to reserve (don't consume) all the huge pages
5) echo 0 > nr_huge_pages for node1. After this step, free huge pages in
Node1 are surplus.
6) create 80 huge pages for node0
7) offline memory of node1, The memory range to offline contains the free
surplus huge pages created in step3) ~ step5)
  echo offline > /sys/devices/system/node/node1/memoryX/state
8) kill the program in step 4)

The result:
           Node0     Node1
total       80        0
free        80        0
surplus     0         61

To fix it, adjust surplus when destroying huge pages if the node has
surplus pages in dissolve_free_hugetlb_folio().

The result with this patch:
           Node0     Node1
total       80        0
free        80        0
surplus     0         0

Link: https://lkml.kernel.org/r/20250304132106.2872754-1-tujinjiang@huawei.com
Fixes: c8721bbbdd36 ("mm: memory-hotplug: enable memory hotplug to handle hugepage")
Signed-off-by: Jinjiang Tu <tujinjiang@huawei.com>
Acked-by: David Hildenbrand <david@redhat.com>
Acked-by: Oscar Salvador <osalvador@suse.de>
Cc: Jinjiang Tu <tujinjiang@huawei.com>
Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Nanyong Sun <sunnanyong@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: a363c62a653c ("mm/hugetlb: do not dissolve gigantic pages without runtime support")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 mm/hugetlb.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2201,6 +2201,8 @@ retry:
 
 	if (!folio_ref_count(folio)) {
 		struct hstate *h = folio_hstate(folio);
+		bool adjust_surplus = false;
+
 		if (!available_huge_pages(h))
 			goto out;
 
@@ -2223,7 +2225,9 @@ retry:
 			goto retry;
 		}
 
-		remove_hugetlb_folio(h, folio, false);
+		if (h->surplus_huge_pages_node[folio_nid(folio)])
+			adjust_surplus = true;
+		remove_hugetlb_folio(h, folio, adjust_surplus);
 		h->max_huge_pages--;
 		spin_unlock_irq(&hugetlb_lock);
 
@@ -2243,7 +2247,7 @@ retry:
 			rc = hugetlb_vmemmap_restore_folio(h, folio);
 			if (rc) {
 				spin_lock_irq(&hugetlb_lock);
-				add_hugetlb_folio(h, folio, false);
+				add_hugetlb_folio(h, folio, adjust_surplus);
 				h->max_huge_pages++;
 				goto out;
 			}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 832/877] mm/hugetlb: create hstate_is_gigantic_no_runtime helper
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (830 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 831/877] mm/hugetlb: fix surplus pages in dissolve_free_huge_page() Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 833/877] mm/hugetlb: do not dissolve gigantic pages without runtime support Greg Kroah-Hartman
                   ` (52 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Usama Arif, Andrew Morton,
	Shakeel Butt, Kefeng Wang, David Hildenbrand, Oscar Salvador,
	Johannes Weiner, Muchun Song, Rik van Riel, SeongJae Park,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Usama Arif <usamaarif642@gmail.com>

[ Upstream commit a743e0af503a633e4ca68a100d9b2a1a071fe8ae ]

This is a common condition used to skip operations that cannot be
performed on gigantic pages when runtime support is disabled.  This helper
is introduced as the condition will exist even more when allowing
"overcommit" of gigantic hugepages.  No functional change intended with
this patch.

Link: https://lkml.kernel.org/r/20251009172433.4158118-1-usamaarif642@gmail.com
Signed-off-by: Usama Arif <usamaarif642@gmail.com>
Suggested-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Shakeel Butt <shakeel.butt@linux.dev>
Reviewed-by: Kefeng Wang <wangkefeng.wang@huawei.com>
Acked-by: David Hildenbrand <david@redhat.com>
Acked-by: Oscar Salvador <osalvador@suse.de>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Rik van Riel <riel@surriel.com>
Cc: SeongJae Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: a363c62a653c ("mm/hugetlb: do not dissolve gigantic pages without runtime support")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 mm/hugetlb.c |   21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -104,6 +104,17 @@ static void hugetlb_free_folio(struct fo
 	folio_put(folio);
 }
 
+/*
+ * Check if the hstate represents gigantic pages but gigantic page
+ * runtime support is not available. This is a common condition used to
+ * skip operations that cannot be performed on gigantic pages when runtime
+ * support is disabled.
+ */
+static inline bool hstate_is_gigantic_no_runtime(struct hstate *h)
+{
+	return hstate_is_gigantic(h) && !gigantic_page_runtime_supported();
+}
+
 static inline bool subpool_is_free(struct hugepage_subpool *spool)
 {
 	if (spool->count)
@@ -1594,7 +1605,7 @@ static void remove_hugetlb_folio(struct
 	VM_BUG_ON_FOLIO(hugetlb_cgroup_from_folio_rsvd(folio), folio);
 
 	lockdep_assert_held(&hugetlb_lock);
-	if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported())
+	if (hstate_is_gigantic_no_runtime(h))
 		return;
 
 	list_del(&folio->lru);
@@ -1656,7 +1667,7 @@ static void __update_and_free_hugetlb_fo
 {
 	bool clear_flag = folio_test_hugetlb_vmemmap_optimized(folio);
 
-	if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported())
+	if (hstate_is_gigantic_no_runtime(h))
 		return;
 
 	/*
@@ -2564,7 +2575,7 @@ static void return_unused_surplus_pages(
 	/* Uncommit the reservation */
 	h->resv_huge_pages -= unused_resv_pages;
 
-	if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported())
+	if (hstate_is_gigantic_no_runtime(h))
 		goto out;
 
 	/*
@@ -3493,7 +3504,7 @@ static void __init hugetlb_init_hstates(
 		 * - If CMA allocation is possible, we can not demote
 		 *   HUGETLB_PAGE_ORDER or smaller size pages.
 		 */
-		if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported())
+		if (hstate_is_gigantic_no_runtime(h))
 			continue;
 		if (hugetlb_cma_size && h->order <= HUGETLB_PAGE_ORDER)
 			continue;
@@ -3938,7 +3949,7 @@ static ssize_t __nr_hugepages_store_comm
 	int err;
 	nodemask_t nodes_allowed, *n_mask;
 
-	if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported())
+	if (hstate_is_gigantic_no_runtime(h))
 		return -EINVAL;
 
 	if (nid == NUMA_NO_NODE) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 833/877] mm/hugetlb: do not dissolve gigantic pages without runtime support
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (831 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 832/877] mm/hugetlb: create hstate_is_gigantic_no_runtime helper Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 834/877] super: make iterate_supers_type() deletion-safe Greg Kroah-Hartman
                   ` (51 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Longlong Xia, Andrew Morton,
	Muchun Song, David Hildenbrand, Miaohe Lin, Michal Hocko,
	Oscar Salvador, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Longlong Xia <xialonglong@kylinos.cn>

[ Upstream commit a363c62a653cc8b3e21da9545fa4e028ef50f9c3 ]

dissolve_free_hugetlb_folio() doesn't check
hstate_is_gigantic_no_runtime(h) though remove_hugetlb_folio()/
update_and_free_hugetlb_folio() silently bail for such folios, so it frees
a still-listed folio and, on vmemmap restore failure, the
add_hugetlb_folio() rollback corrupts the free list.

Link: https://lore.kernel.org/20260823044118.1097121-2-xialonglong2025@163.com
Fixes: 6eb4e88a6d27 ("hugetlb: create remove_hugetlb_page() to separate functionality")
Signed-off-by: Longlong Xia <xialonglong@kylinos.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Assisted-by: Codex:gpt-5.6-sol
Acked-by: Muchun Song <muchun.song@linux.dev>
Cc: David Hildenbrand <david@kernel.org>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 mm/hugetlb.c |    9 +++++++++
 1 file changed, 9 insertions(+)

--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2214,6 +2214,15 @@ retry:
 		struct hstate *h = folio_hstate(folio);
 		bool adjust_surplus = false;
 
+		/*
+		 * remove_hugetlb_folio()/update_and_free_hugetlb_folio() bail
+		 * for gigantic hstates without runtime support, so dissolving one
+		 * here would leave it on the free list and, on vmemmap restore
+		 * failure, the add_hugetlb_folio() rollback corrupts that list.
+		 */
+		if (hstate_is_gigantic_no_runtime(h))
+			goto out;
+
 		if (!available_huge_pages(h))
 			goto out;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 834/877] super: make iterate_supers_type() deletion-safe
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (832 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 833/877] mm/hugetlb: do not dissolve gigantic pages without runtime support Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 835/877] PCI: Fix Resizable BAR restore order Greg Kroah-Hartman
                   ` (50 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Jan Kara,
	Christian Brauner (Amutable), Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Christian Brauner <brauner@kernel.org>

[ Upstream commit 2d2a2d7aa98741b58f54cacc99b52024e4d865f9 ]

iterate_supers_type() drops sb_lock while invoking the callback and keeps
only a passive reference to the current superblock. That reference keeps
the object allocated, but does not keep its s_instances node linked.

After the iterator releases s_umount, final teardown can unlink the current
s_instances node. The iterator then advances through a reinitialized node.
With the current hlist it stops without visiting the remaining superblocks.
The unlink moved from generic_shutdown_super() to kill_super_notify(), but
the cursor lifetime has been unsafe since the helper was introduced.

The CIFS DFS lookup can consequently miss a matching superblock and return
-EINVAL.

Move removal from fs_supers to put_super(), alongside removal from
super_blocks, so a passive reference keeps both list nodes linked. Keep
the filesystem module reference until then, since unlinking s_instances
may touch type->fs_supers.

Make sget_fc() skip SB_DEAD superblocks before invoking test(), and set
SB_DEAD under sb_lock to serialize with those callbacks. This allows
kernfs to free its private information after kill_anon_super() returns.
Keep matching SB_DYING superblocks until SB_DEAD is set so concurrent
mounts still wait for teardown before retrying.

Fixes: 43e15cdbefea ("new helper: iterate_supers_type()")
Reported-by: Karl Mehltretter <kmehltretter@gmail.com>
Closes: https://lore.kernel.org/r/20260903013336.92081-1-kmehltretter@gmail.com
Suggested-by: Jan Kara <jack@suse.cz>
Cc: stable@vger.kernel.org
Tested-by: Karl Mehltretter <kmehltretter@gmail.com>
[kmehltretter: supplied the commit message]
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://patch.msgid.link/20260909193034.7467-1-kmehltretter@gmail.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[ Adapted s_passive reference counting to s_count using the existing __put_super() helper. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 fs/kernfs/mount.c |    4 ++--
 fs/super.c        |   43 +++++++++++++++++++++++--------------------
 2 files changed, 25 insertions(+), 22 deletions(-)

--- a/fs/kernfs/mount.c
+++ b/fs/kernfs/mount.c
@@ -396,8 +396,8 @@ void kernfs_kill_sb(struct super_block *
 	up_write(&root->kernfs_supers_rwsem);
 
 	/*
-	 * Remove the superblock from fs_supers/s_instances
-	 * so we can't find it, before freeing kernfs_super_info.
+	 * Mark the superblock dead so sget_fc() can't find it,
+	 * before freeing kernfs_super_info.
 	 */
 	kill_anon_super(sb);
 	kfree(info);
--- a/fs/super.c
+++ b/fs/super.c
@@ -404,11 +404,16 @@ fail:
 static void __put_super(struct super_block *s)
 {
 	if (!--s->s_count) {
+		struct file_system_type *type = s->s_type;
+
 		list_del_init(&s->s_list);
+		hlist_del_init(&s->s_instances);
 		WARN_ON(s->s_dentry_lru.node);
 		WARN_ON(s->s_inode_lru.node);
 		WARN_ON(!list_empty(&s->s_mounts));
 		call_rcu(&s->rcu, destroy_super_rcu);
+		/* The unlink above may touch type->fs_supers, so drop it last. */
+		put_filesystem(type);
 	}
 }
 
@@ -435,23 +440,16 @@ static void kill_super_notify(struct sup
 		return;
 
 	/*
-	 * Remove it from @fs_supers so it isn't found by new
-	 * sget{_fc}() walkers anymore. Any concurrent mounter still
-	 * managing to grab a temporary reference is guaranteed to
-	 * already see SB_DYING and will wait until we notify them about
-	 * SB_DEAD.
-	 */
-	spin_lock(&sb_lock);
-	hlist_del_init(&sb->s_instances);
-	spin_unlock(&sb_lock);
-
-	/*
 	 * Let concurrent mounts know that this thing is really dead.
-	 * We don't need @sb->s_umount here as every concurrent caller
-	 * will see SB_DYING and either discard the superblock or wait
-	 * for SB_DEAD.
+	 * sget{_fc}() skips SB_DEAD superblocks and calls test() under
+	 * sb_lock, so set it under sb_lock: once we return no test()
+	 * runs on this superblock anymore and none will start. Everyone
+	 * else already saw SB_DYING and either discarded the superblock
+	 * or waits for SB_DEAD.
 	 */
+	spin_lock(&sb_lock);
 	super_wake(sb, SB_DEAD);
+	spin_unlock(&sb_lock);
 }
 
 /**
@@ -482,7 +480,6 @@ void deactivate_locked_super(struct supe
 		list_lru_destroy(&s->s_dentry_lru);
 		list_lru_destroy(&s->s_inode_lru);
 
-		put_filesystem(fs);
 		put_super(s);
 	} else {
 		super_unlock_excl(s);
@@ -668,12 +665,12 @@ void generic_shutdown_super(struct super
 	}
 	/*
 	 * Broadcast to everyone that grabbed a temporary reference to this
-	 * superblock before we removed it from @fs_supers that the superblock
-	 * is dying. Every walker of @fs_supers outside of sget{_fc}() will now
-	 * discard this superblock and treat it as dead.
+	 * superblock that it is dying. Every walker of @fs_supers outside
+	 * of sget{_fc}() will now discard this superblock and treat it as
+	 * dead.
 	 *
-	 * We leave the superblock on @fs_supers so it can be found by
-	 * sget{_fc}() until we passed sb->kill_sb().
+	 * sget{_fc}() keeps finding the superblock until SB_DEAD is set, so
+	 * a concurrent mounter waits until we passed sb->kill_sb().
 	 */
 	super_wake(sb, SB_DYING);
 	super_unlock_excl(sb);
@@ -751,6 +748,9 @@ retry:
 	spin_lock(&sb_lock);
 	if (test) {
 		hlist_for_each_entry(old, &fc->fs_type->fs_supers, s_instances) {
+			/* Only unlinked at the last passive reference. */
+			if (super_flags(old, SB_DEAD))
+				continue;
 			if (test(old, fc))
 				goto share_extant_sb;
 		}
@@ -834,6 +834,9 @@ retry:
 	spin_lock(&sb_lock);
 	if (test) {
 		hlist_for_each_entry(old, &type->fs_supers, s_instances) {
+			/* Only unlinked at the last passive reference. */
+			if (super_flags(old, SB_DEAD))
+				continue;
 			if (!test(old, data))
 				continue;
 			if (user_ns != old->s_user_ns) {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 835/877] PCI: Fix Resizable BAR restore order
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (833 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 834/877] super: make iterate_supers_type() deletion-safe Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 836/877] PCI: Fix BAR resize for devices on a root bus Greg Kroah-Hartman
                   ` (49 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ville Syrjälä,
	Ilpo Järvinen, Bjorn Helgaas, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

[ Upstream commit 5528fd38f230c906fcebb202cc94fbb8ed8f122a ]

The commit 337b1b566db0 ("PCI: Fix restoring BARs on BAR resize rollback
path") changed BAR resize to layer rebar code and resource setup/restore
code cleanly. Unfortunately, it did not consider how the value of the BAR
Size field impacts the read-only bits in the Base Address Register (PCIe7
spec, sec. 7.8.6.3). That is, it very much matters in which order the BAR
Size and Base Address Register are restored.

Post-337b1b566db0 ("PCI: Fix restoring BARs on BAR resize rollback path")
during BAR resize rollback, pci_do_resource_release_and_resize() attempts
to restore the old address to the BAR that was resized, but it can fail to
setup the address correctly if the address has low bits set that collide
with the bits that are still read-only. As a result, kernel's resource and
BAR will be out-of-sync.

Fix this by restoring BAR Size before rolling back the resource changes and
restoring the BAR.

Fixes: 337b1b566db0 ("PCI: Fix restoring BARs on BAR resize rollback path")
Reported-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://lore.kernel.org/linux-pci/aW_w1oFQCzUxGYtu@intel.com/
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Tested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260121131417.9582-3-ilpo.jarvinen@linux.intel.com

[6.12 dependency preparation for d58384c22739848efe14b34e9586e4f1242f33c0:
Keep the existing memory-decoding and supported-size checks in rebar.c.
Move BAR size programming and rollback into the resource release helper,
so the old size is restored before restoring BAR addresses.

Use the assigned parent window to select resources for release, retaining
the old flags-based selection when the resized BAR has no parent. Provide
file-local macro mappings for the follow-up's bridge reassignment and
resource assignment checks; no functions are added.

Retain the upstream pre-target pci_bus_sem placement to allow the target
to apply without conflicts. This preparatory dependency must be applied
together with d58384c22739848efe14b34e9586e4f1242f33c0, which takes the lock
before releasing resources and assigns released BARs on root buses.]

Stable-dep-of: d58384c22739 ("PCI: Fix BAR resize for devices on a root bus")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/pci/rebar.c     |   19 +------------------
 drivers/pci/setup-bus.c |   39 ++++++++++++++++++++++++++++++++-------
 2 files changed, 33 insertions(+), 25 deletions(-)

--- a/drivers/pci/rebar.c
+++ b/drivers/pci/rebar.c
@@ -156,7 +156,6 @@ int pci_resize_resource(struct pci_dev *
 			int exclude_bars)
 {
 	struct pci_host_bridge *host;
-	int old, ret;
 	u32 sizes;
 	u16 cmd;
 
@@ -176,22 +175,6 @@ int pci_resize_resource(struct pci_dev *
 	if (!(sizes & BIT(size)))
 		return -EINVAL;
 
-	old = pci_rebar_get_current_size(dev, resno);
-	if (old < 0)
-		return old;
-
-	ret = pci_rebar_set_size(dev, resno, size);
-	if (ret)
-		return ret;
-
-	ret = pci_do_resource_release_and_resize(dev, resno, size, exclude_bars);
-	if (ret)
-		goto error_resize;
-
-	return 0;
-
-error_resize:
-	pci_rebar_set_size(dev, resno, old);
-	return ret;
+	return pci_do_resource_release_and_resize(dev, resno, size, exclude_bars);
 }
 EXPORT_SYMBOL(pci_resize_resource);
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -2368,6 +2368,11 @@ static int pci_reassign_bridge_resources
 	return 0;
 }
 
+/* Keep the resize follow-up compatible with the 6.12 resource helpers. */
+#define pbus_reassign_bridge_resources(bus, res, saved) \
+	pci_reassign_bridge_resources((bus)->self, (res)->flags, (saved))
+#define resource_assigned(res) ((res)->parent != NULL)
+
 int pci_do_resource_release_and_resize(struct pci_dev *pdev, int resno, int size,
 				       int exclude_bars)
 {
@@ -2375,12 +2380,20 @@ int pci_do_resource_release_and_resize(s
 	unsigned long flags = res->flags;
 	struct pci_dev_resource *dev_res;
 	struct pci_bus *bus = pdev->bus;
-	struct resource *r;
+	struct resource *b_win, *r;
 	LIST_HEAD(saved);
 	unsigned int i;
-	int ret = 0;
+	int old, ret;
 
-	down_read(&pci_bus_sem);
+	b_win = res->parent;
+
+	old = pci_rebar_get_current_size(pdev, resno);
+	if (old < 0)
+		return old;
+
+	ret = pci_rebar_set_size(pdev, resno, size);
+	if (ret)
+		return ret;
 
 	pci_dev_for_each_resource(pdev, r, i) {
 		if (i >= PCI_BRIDGE_RESOURCES)
@@ -2389,7 +2402,10 @@ int pci_do_resource_release_and_resize(s
 		if (exclude_bars & BIT(i))
 			continue;
 
-		if (!pci_resource_len(pdev, i) || r->flags != flags)
+		if (!pci_resource_len(pdev, i))
+			continue;
+
+		if (b_win ? r->parent != b_win : r->flags != flags)
 			continue;
 
 		ret = add_to_list(&saved, pdev, r, 0, 0);
@@ -2403,7 +2419,8 @@ int pci_do_resource_release_and_resize(s
 	if (!bus->self)
 		goto out;
 
-	ret = pci_reassign_bridge_resources(bus->self, res->flags, &saved);
+	down_read(&pci_bus_sem);
+	ret = pbus_reassign_bridge_resources(bus, res, &saved);
 	if (ret)
 		goto restore;
 
@@ -2413,14 +2430,22 @@ out:
 	return ret;
 
 restore:
-	/* Revert to the old configuration */
+	/*
+	 * Revert to the old configuration.
+	 *
+	 * BAR Size must be restored first because it affects the read-only
+	 * bits in BAR (the old address might not be restorable otherwise
+	 * due to low address bits).
+	 */
+	pci_rebar_set_size(pdev, resno, old);
+
 	list_for_each_entry(dev_res, &saved, list) {
 		struct resource *res = dev_res->res;
 		struct pci_dev *dev = dev_res->dev;
 
 		i = res - dev->resource;
 
-		if (res->parent) {
+		if (resource_assigned(res)) {
 			release_child_resources(res);
 			pci_release_resource(dev, i);
 		}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 836/877] PCI: Fix BAR resize for devices on a root bus
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (834 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 835/877] PCI: Fix Resizable BAR restore order Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 837/877] packet: use ubuf_info completion for TX_RING packets Greg Kroah-Hartman
                   ` (48 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ilpo Järvinen, Liz Fong-Jones,
	Bjorn Helgaas, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Liz Fong-Jones <lizf@honeycomb.io>

[ Upstream commit d58384c22739848efe14b34e9586e4f1242f33c0 ]

pci_do_resource_release_and_resize() releases device BARs that share a
bridge window with the BAR being resized, but when the device sits directly
on a root bus (pdev->bus->self == NULL) it then skips resource assignment
entirely and returns success, leaving the BARs it just released unassigned
(IORESOURCE_UNSET).

Skipping pbus_reassign_bridge_resources() is correct in that case -- there
is no bridge window to adjust -- but the device BARs still have to be
reassigned. Before the BAR release was consolidated into the PCI core, this
case worked for amdgpu because the driver released the BARs itself and then
called pci_assign_unassigned_bus_resources() unconditionally after the
resize, which assigns unassigned device BARs also on a root bus. Commit
db92e3fef53e ("drm/amdgpu: Remove driver side BAR release before resize")
removed that call, so nothing assigns the released BARs anymore.

This breaks amdgpu completely on the SolidRun HoneyComb LX2K (NXP LX2160A,
arm64, ACPI), where ACPI doesn't expose the Root Port so the GPU endpoint
appears directly on a "root bus" of its segment:

  amdgpu 0004:01:00.0: BAR 0 [mem 0xa400000000-0xa40fffffff 64bit pref]: releasing
  amdgpu 0004:01:00.0: BAR 2 [mem 0xa410000000-0xa4101fffff 64bit pref]: releasing
  amdgpu 0004:01:00.0: sw_init of IP block <gmc_v8_0> failed -19
  amdgpu 0004:01:00.0: amdgpu_device_ip_init failed
  amdgpu 0004:01:00.0: Fatal error during GPU init

No error is logged because the resize path reports success; amdgpu then
finds BAR 0 IORESOURCE_UNSET and bails out with -ENODEV.

When there is no upstream bridge, call pci_bus_assign_resources() on the
root bus to place the BARs released above, using the same alignment-sorted
algorithm as normal enumeration instead of a manual per-BAR loop. This also
walks the rest of the hierarchy under the root bus, as
pci_assign_unassigned_bus_resources() used to for amdgpu before commit
db92e3fef53e ("drm/amdgpu: Remove driver side BAR release before resize")
removed that call -- the core-side fix that commit asked for ("such a
problem should be fixed inside pci_resize_resource() instead").

pci_bus_assign_resources() returns void, so failure is detected by checking
whether the released BARs are still assigned afterward; if not, roll back
as in the bridged case. This is stricter than the bridged path -- it fails
on any unplaced resource, not just required ones -- since a root bus
typically has one shared window, and failing loudly seemed better than
leaving something silently unassigned.

The root bus path also had a locking bug that any fix here necessarily
touches: the old "goto out" jumped to up_read(&pci_bus_sem) without a
matching down_read() (as does the "goto restore" taken when
pci_dev_res_add_to_list() fails in the release loop). Take pci_bus_sem
before the BAR release loop so every path through the function holds it
exactly once.

Fixes: 337b1b566db0 ("PCI: Fix restoring BARs on BAR resize rollback path")
Link: https://bugs.launchpad.net/ubuntu/+source/linux-hwe-7.0/+bug/2159596
Suggested-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Assisted-by: Claude:claude-fable-5 checkpatch
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Liz Fong-Jones <lizf@honeycomb.io>
[bhelgaas: commit log]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260918035633.566823-1-lizf@honeycomb.io
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/pci/setup-bus.c |   25 ++++++++++++++++++-------
 1 file changed, 18 insertions(+), 7 deletions(-)

--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -2380,6 +2380,7 @@ int pci_do_resource_release_and_resize(s
 	unsigned long flags = res->flags;
 	struct pci_dev_resource *dev_res;
 	struct pci_bus *bus = pdev->bus;
+	struct pci_dev *bridge = pci_upstream_bridge(pdev);
 	struct resource *b_win, *r;
 	LIST_HEAD(saved);
 	unsigned int i;
@@ -2395,6 +2396,8 @@ int pci_do_resource_release_and_resize(s
 	if (ret)
 		return ret;
 
+	down_read(&pci_bus_sem);
+
 	pci_dev_for_each_resource(pdev, r, i) {
 		if (i >= PCI_BRIDGE_RESOURCES)
 			break;
@@ -2416,13 +2419,21 @@ int pci_do_resource_release_and_resize(s
 
 	res->end = res->start + pci_rebar_size_to_bytes(size) - 1;
 
-	if (!bus->self)
-		goto out;
-
-	down_read(&pci_bus_sem);
-	ret = pbus_reassign_bridge_resources(bus, res, &saved);
-	if (ret)
-		goto restore;
+	if (bridge) {
+		ret = pbus_reassign_bridge_resources(bus, res, &saved);
+		if (ret)
+			goto restore;
+	} else {
+		/* No bridge window to adjust; let the core reassign the bus. */
+		pci_bus_assign_resources(bus);
+
+		list_for_each_entry(dev_res, &saved, list) {
+			if (!resource_assigned(dev_res->res)) {
+				ret = -ENOSPC;
+				goto restore;
+			}
+		}
+	}
 
 out:
 	up_read(&pci_bus_sem);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 837/877] packet: use ubuf_info completion for TX_RING packets
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (835 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 836/877] PCI: Fix BAR resize for devices on a root bus Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 838/877] HID: hid-alps: Use pm_ptr instead of #ifdef CONFIG_PM Greg Kroah-Hartman
                   ` (47 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Katherine Leaver, Bjoern Doebel,
	Willem de Bruijn, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Willem de Bruijn <willemb@google.com>

[ Upstream commit 9518405613863d0bf0700927a21367f5942cf058 ]

tpacket_snd sends skbs with frags pointing into its ring slots. Slots
are released when skb->destructor is called.

A call to skb_orphan calls skb->destructor before the skb is freed.
This can cause the slot to be reused while still linked into the skb.

Switch to standard zerocopy completion (ubuf_info) so the slot is only
released once all references to the payload are freed or copied.
Restore skb->destructor to standard sock_wfree.

The ubuf_info completion callback can be called with a NULL skb, but
only from net_zcopy_put and related API, used by zerocopy implementations
that hold their own reference on the uarg, such as MSG_ZEROCOPY. This
uarg is only ever completed from skb_zcopy_clear, so skb is always set.

To prevent userspace from aliasing in-flight state on shared ring
slots, allocate tpacket_uarg per packet, rather than per slot. This
adds a small allocation to the transmit path. Use standard kmalloc to
allow backporting to stable kernels.

The uarg holds an sk_wmem_alloc reference, rather than an sk_refcnt
reference. packet_free_tx_ring waits on sk_wmem_alloc before freeing
the ring pages. Always allocate vec->deferred for tx_ring so page-backed
rings also wait on sk_wmem_alloc when skb_copy_ubufs drops page refs
before calling tpacket_ubuf_complete.

Drop the tx_ring.pg_vec test that tpacket_destruct_skb performed before
accessing the slot. The sk_wmem_alloc reference now guarantees that the
slot is valid. The test is also not sufficient by itself, as it reads
pg_vec without pg_vec_lock, so it can race with packet_set_ring.

As a result a slot is released when its payload is copied, which can
be before transmission (e.g., in skb_orphan_frags_rx). If copied
before skb_tx_timestamp() is called, no slot timestamp is recorded,
similar to when skb_orphan() was called early in the datapath before
this patch.

Revert the now unused previous skb_zcopy_.._nouarg infra.

Depends on commit 992cc9f94ca9 ("net/packet: defer vmalloc TX_RING
free until skbs finish").

Reported-by: Katherine Leaver <kleaver@janestreet.com>
Reported-by: Bjoern Doebel <doebel@amazon.de>
Closes: https://lore.kernel.org/netdev/20260909085542.3370986-1-doebel@amazon.de/
Fixes: 5cd8d46ea156 ("packet: copy user buffers before orphan or clone")
Cc: stable@vger.kernel.org
Signed-off-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260919004748.1463985-3-willemdebruijn.kernel@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ Retained sockc->tsflags instead of sockc in skb_setup_tx_timestamp() for the older helper signature. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/linux/skbuff.h |   19 ---------
 net/packet/af_packet.c |  102 ++++++++++++++++++++++++++++++-------------------
 2 files changed, 65 insertions(+), 56 deletions(-)

--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1807,22 +1807,6 @@ static inline void skb_zcopy_set(struct
 	}
 }
 
-static inline void skb_zcopy_set_nouarg(struct sk_buff *skb, void *val)
-{
-	skb_shinfo(skb)->destructor_arg = (void *)((uintptr_t) val | 0x1UL);
-	skb_shinfo(skb)->flags |= SKBFL_ZEROCOPY_FRAG;
-}
-
-static inline bool skb_zcopy_is_nouarg(struct sk_buff *skb)
-{
-	return (uintptr_t) skb_shinfo(skb)->destructor_arg & 0x1UL;
-}
-
-static inline void *skb_zcopy_get_nouarg(struct sk_buff *skb)
-{
-	return (void *)((uintptr_t) skb_shinfo(skb)->destructor_arg & ~0x1UL);
-}
-
 static inline void net_zcopy_put(struct ubuf_info *uarg)
 {
 	if (uarg)
@@ -1845,8 +1829,7 @@ static inline void skb_zcopy_clear(struc
 	struct ubuf_info *uarg = skb_zcopy(skb);
 
 	if (uarg) {
-		if (!skb_zcopy_is_nouarg(skb))
-			uarg->ops->complete(skb, uarg, zerocopy_success);
+		uarg->ops->complete(skb, uarg, zerocopy_success);
 
 		skb_shinfo(skb)->flags &= ~SKBFL_ALL_ZEROCOPY;
 	}
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2582,26 +2582,6 @@ drop_n_account:
 	goto drop_n_restore;
 }
 
-static void tpacket_destruct_skb(struct sk_buff *skb)
-{
-	struct packet_sock *po = pkt_sk(skb->sk);
-
-	if (likely(po->tx_ring.pg_vec)) {
-		void *ph;
-		__u32 ts;
-
-		ph = skb_zcopy_get_nouarg(skb);
-
-		ts = __packet_set_timestamp(po, ph, skb);
-		__packet_set_status(po, ph, TP_STATUS_AVAILABLE | ts);
-
-		packet_dec_pending(&po->tx_ring);
-		complete(&po->skb_completion);
-	}
-
-	sock_wfree(skb);
-}
-
 static int __packet_snd_vnet_parse(struct virtio_net_hdr *vnet_hdr, size_t len)
 {
 	if ((vnet_hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
@@ -2641,27 +2621,56 @@ static int packet_snd_vnet_parse(struct
 	return 0;
 }
 
+struct tpacket_uarg {
+	struct ubuf_info	ubuf;
+	struct packet_sock	*po;
+	void			*ph;
+};
+
+static void tpacket_ubuf_complete(struct sk_buff *skb, struct ubuf_info *uarg,
+				  bool success)
+{
+	struct tpacket_uarg *tu = container_of(uarg, struct tpacket_uarg, ubuf);
+	struct packet_sock *po = tu->po;
+	void *ph = tu->ph;
+	__u32 ts;
+
+	DEBUG_NET_WARN_ON_ONCE(!skb);
+
+	if (!refcount_dec_and_test(&uarg->refcnt))
+		return;
+
+	ts = __packet_set_timestamp(po, ph, skb);
+	__packet_set_status(po, ph, TP_STATUS_AVAILABLE | ts);
+
+	packet_dec_pending(&po->tx_ring);
+	complete(&po->skb_completion);
+
+	kfree(tu);
+	sk_free(&po->sk);
+}
+
+static const struct ubuf_info_ops tpacket_ubuf_ops = {
+	.complete = tpacket_ubuf_complete,
+};
+
 static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
-		void *frame, struct net_device *dev, void *data, int tp_len,
+		struct net_device *dev, void *data, int tp_len,
 		__be16 proto, unsigned char *addr, int hlen, int copylen,
 		int hard_header_len,
 		const struct sockcm_cookie *sockc)
 {
-	union tpacket_uhdr ph;
 	int to_write, offset, len, nr_frags, len_max;
 	struct socket *sock = po->sk.sk_socket;
 	struct page *page;
 	int err;
 
-	ph.raw = frame;
-
 	skb->protocol = proto;
 	skb->dev = dev;
 	skb->priority = READ_ONCE(po->sk.sk_priority);
 	skb->mark = READ_ONCE(po->sk.sk_mark);
 	skb_set_delivery_type_by_clockid(skb, sockc->transmit_time, po->sk.sk_clockid);
 	skb_setup_tx_timestamp(skb, sockc->tsflags);
-	skb_zcopy_set_nouarg(skb, ph.raw);
 
 	skb_reserve(skb, hlen);
 	skb_reset_network_header(skb);
@@ -2801,6 +2810,7 @@ static int tpacket_snd(struct packet_soc
 	struct virtio_net_hdr vnet_hdr;
 	bool has_vnet_hdr = false;
 	struct sockcm_cookie sockc;
+	struct tpacket_uarg *uarg;
 	__be16 proto;
 	int err, reserve = 0;
 	void *ph;
@@ -2928,7 +2938,7 @@ static int tpacket_snd(struct packet_soc
 				err = len_sum;
 			goto out_status;
 		}
-		tp_len = tpacket_fill_skb(po, skb, ph, dev, data, tp_len, proto,
+		tp_len = tpacket_fill_skb(po, skb, dev, data, tp_len, proto,
 					  addr, hlen, copylen, hard_header_len,
 					  &sockc);
 		if (likely(tp_len >= 0) &&
@@ -2960,7 +2970,24 @@ tpacket_error:
 			virtio_net_hdr_set_proto(skb, &vnet_hdr);
 		}
 
-		skb->destructor = tpacket_destruct_skb;
+		uarg = kmalloc(sizeof(*uarg), GFP_KERNEL);
+		if (unlikely(!uarg)) {
+			if (likely(len_sum > 0))
+				err = len_sum;
+			else
+				err = -ENOMEM;
+			goto out_status;
+		}
+		uarg->po = po;
+		uarg->ph = ph;
+		uarg->ubuf.ops = &tpacket_ubuf_ops;
+		uarg->ubuf.flags = SKBFL_ZEROCOPY_FRAG;
+		refcount_set(&uarg->ubuf.refcnt, 1);
+
+		/* Hold a sk_wmem_alloc reference until completion */
+		refcount_inc(&po->sk.sk_wmem_alloc);
+		skb_zcopy_init(skb, &uarg->ubuf);
+
 		__packet_set_status(po, ph, TP_STATUS_SENDING);
 		packet_inc_pending(&po->tx_ring);
 
@@ -4529,21 +4556,20 @@ static struct pgv *alloc_pg_vec(struct t
 	vec->len = block_nr;
 	pg_vec = vec->pg_vec;
 
+	if (tx_ring) {
+		vec->deferred = kzalloc_obj(*vec->deferred,
+					    GFP_KERNEL | __GFP_NOWARN);
+		if (!vec->deferred)
+			goto out_free_pgvec;
+		vec->deferred->vec = vec;
+		INIT_DELAYED_WORK(&vec->deferred->work,
+				  packet_free_pg_vec_work);
+	}
+
 	for (i = 0; i < block_nr; i++) {
 		pg_vec[i].buffer = alloc_one_pg_vec_page(order);
 		if (unlikely(!pg_vec[i].buffer))
 			goto out_free_pgvec;
-
-		if (tx_ring && !vec->deferred &&
-		    is_vmalloc_addr(pg_vec[i].buffer)) {
-			vec->deferred = kzalloc_obj(*vec->deferred,
-						    GFP_KERNEL | __GFP_NOWARN);
-			if (!vec->deferred)
-				goto out_free_pgvec;
-			vec->deferred->vec = vec;
-			INIT_DELAYED_WORK(&vec->deferred->work,
-					  packet_free_pg_vec_work);
-		}
 	}
 
 out:



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 838/877] HID: hid-alps: Use pm_ptr instead of #ifdef CONFIG_PM
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (836 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 837/877] packet: use ubuf_info completion for TX_RING packets Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 839/877] HID: alps: unregister DualPoint Stick input device on remove Greg Kroah-Hartman
                   ` (46 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Bastien Nocera, Jiri Kosina,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bastien Nocera <hadess@hadess.net>

[ Upstream commit 5e130f58629a2819c9d053507ad368160d25eb65 ]

This increases build coverage and allows to drop an #ifdef.

Signed-off-by: Bastien Nocera <hadess@hadess.net>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Stable-dep-of: aa9dde93e05a ("HID: alps: unregister DualPoint Stick input device on remove")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/hid/hid-alps.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

--- a/drivers/hid/hid-alps.c
+++ b/drivers/hid/hid-alps.c
@@ -845,10 +845,8 @@ static struct hid_driver alps_driver = {
 	.raw_event		= alps_raw_event,
 	.input_mapping		= alps_input_mapping,
 	.input_configured	= alps_input_configured,
-#ifdef CONFIG_PM
-	.resume			= alps_post_resume,
-	.reset_resume		= alps_post_reset,
-#endif
+	.resume			= pm_ptr(alps_post_resume),
+	.reset_resume		= pm_ptr(alps_post_reset),
 };
 
 module_hid_driver(alps_driver);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 839/877] HID: alps: unregister DualPoint Stick input device on remove
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (837 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 838/877] HID: hid-alps: Use pm_ptr instead of #ifdef CONFIG_PM Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 840/877] net/sched: act_ct: fix helper UAF due to extensions realloc Greg Kroah-Hartman
                   ` (45 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Chen Changcheng, Jiri Kosina,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Chen Changcheng <chenchangcheng@kylinos.cn>

[ Upstream commit aa9dde93e05a837645fdfd577eea71f0733f0694 ]

alps_input_configured() allocates a second input device ("DualPoint
Stick") with input_allocate_device() and registers it, but the
alps_driver struct has no .remove handler and input2 is not tracked in
hdev->inputs.  The default remove path (hid_hw_stop -> hidinput_disconnect)
only iterates hdev->inputs, so input2 is never unregistered and leaks
on every device removal.

Add a .remove handler that stops the device first (preventing URB
callbacks from touching input2 during teardown) and then unregisters
input2.

Fixes: 2562756dde55 ("HID: add Alps I2C HID Touchpad-Stick support")
Cc: stable@vger.kernel.org
Signed-off-by: Chen Changcheng <chenchangcheng@kylinos.cn>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/hid/hid-alps.c |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

--- a/drivers/hid/hid-alps.c
+++ b/drivers/hid/hid-alps.c
@@ -825,6 +825,24 @@ static int alps_probe(struct hid_device
 	return 0;
 }
 
+static void alps_remove(struct hid_device *hdev)
+{
+	struct alps_dev *data = hid_get_drvdata(hdev);
+
+	/*
+	 * input2 ("DualPoint Stick") is allocated separately and is not
+	 * tracked in hdev->inputs, so the default remove path
+	 * (hid_hw_stop -> hidinput_disconnect) does not unregister it.
+	 *
+	 * Stop the device first so that no URB callback can touch input2
+	 * while it is being unregistered, then drop it explicitly.
+	 */
+	hid_hw_stop(hdev);
+
+	if (data->input2)
+		input_unregister_device(data->input2);
+}
+
 static const struct hid_device_id alps_id[] = {
 	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY,
 		USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) },
@@ -847,6 +865,7 @@ static struct hid_driver alps_driver = {
 	.input_configured	= alps_input_configured,
 	.resume			= pm_ptr(alps_post_resume),
 	.reset_resume		= pm_ptr(alps_post_reset),
+	.remove			= alps_remove,
 };
 
 module_hid_driver(alps_driver);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 840/877] net/sched: act_ct: fix helper UAF due to extensions realloc
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (838 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 839/877] HID: alps: unregister DualPoint Stick input device on remove Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 841/877] net/sched: act_ct: avoid modifying shared unconfirmed ct entry Greg Kroah-Hartman
                   ` (44 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Axel Mierczuk, Ilya Maximets,
	Xin Long, Jamal Hadi Salim, Aaron Conole, Jakub Kicinski,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ilya Maximets <i.maximets@ovn.org>

[ Upstream commit dad19b59da050cb60d3f7023dac2a042a84bf0bd ]

While calling the helpers, a raw pointer to the extensions area is
wired into expectations list:

  -> nf_ct_helper()
   -> helper->help()
    -> nf_ct_expect_related_report()
     -> nf_ct_expect_insert()
      -> hlist_add_head_rcu(&exp->lnode, &master_help->expectations)

In case the connection is not confirmed yet, more extensions can be
added afterwards with *_ext_add() calls reallocating the extension
space and leaving the now invalid pointer in the expectations list
that is later accessed while removing the expectation.

Make sure that helpers are called at the end after all the other
extensions are already added.

Note that the helper rejection now leaves the mark and labels set,
but that's not different from how the NAT was handled before or how
the mark and the labels were handled on confirmation failure.  And
there are no atomicity guarantees provided by the API anyway.

Fixes: a21b06e73191 ("net: sched: add helper support in act_ct")
Cc: stable@vger.kernel.org
Reported-by: Axel Mierczuk <axel.mierczuk@1password.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Reviewed-by: Xin Long <lucien.xin@gmail.com>
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/20260921145655.3167436-7-i.maximets@ovn.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ Preserved the existing add_helper condition that upstream had removed. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/sched/act_ct.c |   18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -1087,19 +1087,25 @@ do_nat:
 		}
 	}
 
-	if (nf_ct_is_confirmed(ct) ? ((!cached && !skip_add) || add_helper) : commit) {
-		err = nf_ct_helper(skb, ct, ctinfo, family);
-		if (err != NF_ACCEPT)
-			goto nf_error;
-	}
-
 	if (commit) {
 		tcf_ct_act_set_mark(ct, p->mark, p->mark_mask);
 		tcf_ct_act_set_labels(ct, p->labels, p->labels_mask);
 
 		if (!nf_ct_is_confirmed(ct))
 			nf_conn_act_ct_ext_add(skb, ct, ctinfo);
+	}
 
+	/* Run helpers for the connection if nf_conntrack_in() was executed
+	 * or if we're about to commit.  This has to be done after all the
+	 * extensions are already added.
+	 */
+	if (nf_ct_is_confirmed(ct) ? ((!cached && !skip_add) || add_helper) : commit) {
+		err = nf_ct_helper(skb, ct, ctinfo, family);
+		if (err != NF_ACCEPT)
+			goto nf_error;
+	}
+
+	if (commit) {
 		/* This will take care of sending queued events
 		 * even if the connection is already confirmed.
 		 */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 841/877] net/sched: act_ct: avoid modifying shared unconfirmed ct entry
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (839 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 840/877] net/sched: act_ct: fix helper UAF due to extensions realloc Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 842/877] net: ipconfig: Remove outdated comment and indent code block Greg Kroah-Hartman
                   ` (43 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Axel Mierczuk, Ilya Maximets,
	Aaron Conole, Xin Long, Jamal Hadi Salim, Jakub Kicinski,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ilya Maximets <i.maximets@ovn.org>

[ Upstream commit f85009dfcd65e5969526b0db7a49b5413746e630 ]

In a case where skb with an unconfirmed ct entry gets cloned, we may
end up processing both again but with different sets of extensions.

The series of events:

 1. The first clone wants to commit and runs the helpers wiring up
    the extension pointer into the expectation list.
 2. Then it looses the confirmation keeping the entry unconfirmed.
 3. Second clone now wants to commit labels or run NAT and adds the
    new extension for that breaking the pointer in the expectation
    list causing UAF on the destruction path later.

While this is possible to trigger, there should be no practical
network pipeline where we need to process both clones without
modifications in the same zone.  So, let's just reset the entry in
case for some reason we got an skb with a shared one.  This doesn't
affect any known use cases, but avoids any potential problems with
sharing and modification of the unconfirmed ct entry.

Unlike openvswitch module, act_ct allows for NAT without commit.
Changing that would be a uAPI break.  So, act_ct needs to reset on NAT
regardless of the commit flag to avoid reallocation of the extension
space.  This, however, doesn't really change the picture for sensible
networking cases as there should be no need to run the same packet
twice (before and after the clone) through conntrack without packet
header or zone changes and without commit.

The fixes tag points to the introduction of helpers, since that's the
main UAF trigger for the sharing.

Fixes: a21b06e73191 ("net: sched: add helper support in act_ct")
Cc: stable@vger.kernel.org
Reported-by: Axel Mierczuk <axel.mierczuk@1password.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Reviewed-by: Xin Long <lucien.xin@gmail.com>
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/20260921145655.3167436-5-i.maximets@ovn.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/sched/act_ct.c |   18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

--- a/net/sched/act_ct.c
+++ b/net/sched/act_ct.c
@@ -977,11 +977,11 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct
 				 struct tcf_result *res)
 {
 	struct net *net = dev_net(skb->dev);
+	bool cached, commit, clear, nat;
 	enum ip_conntrack_info ctinfo;
 	struct tcf_ct *c = to_ct(a);
 	struct nf_conn *tmpl = NULL;
 	struct nf_hook_state state;
-	bool cached, commit, clear;
 	int nh_ofs, err, retval;
 	struct tcf_ct_params *p;
 	bool add_helper = false;
@@ -996,6 +996,7 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct
 	retval = p->action;
 	commit = p->ct_action & TCA_CT_ACT_COMMIT;
 	clear = p->ct_action & TCA_CT_ACT_CLEAR;
+	nat = p->ct_action & TCA_CT_ACT_NAT;
 	tmpl = p->tmpl;
 
 	tcf_lastuse_update(&c->tcf_tm);
@@ -1044,6 +1045,19 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct
 	 * different zone.
 	 */
 	cached = tcf_ct_skb_nfct_cached(net, skb, p);
+
+	/* If the ct entry is not confirmed and shared with some other skb,
+	 * e.g., a cloned one, we can't just modify it with a commit or nat
+	 * as we must not modify the extension set.  Reset.
+	 */
+	if (cached && (commit || nat)) {
+		ct = nf_ct_get(skb, &ctinfo);
+		if (ct && !nf_ct_is_confirmed(ct) && nf_ct_shared(ct)) {
+			nf_reset_ct(skb);
+			cached = false;
+		}
+	}
+
 	if (!cached) {
 		if (tcf_ct_flow_table_lookup(p, skb, family)) {
 			skip_add = true;
@@ -1081,7 +1095,7 @@ do_nat:
 		if (err)
 			goto drop;
 		add_helper = true;
-		if (p->ct_action & TCA_CT_ACT_NAT && !nfct_seqadj(ct)) {
+		if (nat && !nfct_seqadj(ct)) {
 			if (!nfct_seqadj_ext_add(ct))
 				goto drop;
 		}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 842/877] net: ipconfig: Remove outdated comment and indent code block
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (840 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 841/877] net/sched: act_ct: avoid modifying shared unconfirmed ct entry Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 843/877] net: ipconfig: bound DHCP option construction Greg Kroah-Hartman
                   ` (42 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Thorsten Blum, Jakub Kicinski,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Thorsten Blum <thorsten.blum@linux.dev>

[ Upstream commit e405b3c9d4aaa10972525fe2ea5cf94224020561 ]

The comment has been around ever since commit 1da177e4c3f4
("Linux-2.6.12-rc2") and can be removed. Remove it and indent the code
block accordingly.

Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Link: https://patch.msgid.link/20260109121128.170020-2-thorsten.blum@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: e47a1958e12a ("net: ipconfig: bound DHCP option construction")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv4/ipconfig.c |   89 ++++++++++++++++++++++++----------------------------
 1 file changed, 42 insertions(+), 47 deletions(-)

--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -679,8 +679,18 @@ static const u8 ic_bootp_cookie[4] = { 9
 static void __init
 ic_dhcp_init_options(u8 *options, struct ic_device *d)
 {
-	u8 mt = ((ic_servaddr == NONE)
-		 ? DHCPDISCOVER : DHCPREQUEST);
+	static const u8 ic_req_params[] = {
+		1,	/* Subnet mask */
+		3,	/* Default gateway */
+		6,	/* DNS server */
+		12,	/* Host name */
+		15,	/* Domain name */
+		17,	/* Boot path */
+		26,	/* MTU */
+		40,	/* NIS domain name */
+		42,	/* NTP servers */
+	};
+	u8 mt = (ic_servaddr == NONE) ? DHCPDISCOVER : DHCPREQUEST;
 	u8 *e = options;
 	int len;
 
@@ -705,51 +715,36 @@ ic_dhcp_init_options(u8 *options, struct
 		e += 4;
 	}
 
-	/* always? */
-	{
-		static const u8 ic_req_params[] = {
-			1,	/* Subnet mask */
-			3,	/* Default gateway */
-			6,	/* DNS server */
-			12,	/* Host name */
-			15,	/* Domain name */
-			17,	/* Boot path */
-			26,	/* MTU */
-			40,	/* NIS domain name */
-			42,	/* NTP servers */
-		};
-
-		*e++ = 55;	/* Parameter request list */
-		*e++ = sizeof(ic_req_params);
-		memcpy(e, ic_req_params, sizeof(ic_req_params));
-		e += sizeof(ic_req_params);
-
-		if (ic_host_name_set) {
-			*e++ = 12;	/* host-name */
-			len = strlen(utsname()->nodename);
-			*e++ = len;
-			memcpy(e, utsname()->nodename, len);
-			e += len;
-		}
-		if (*vendor_class_identifier) {
-			pr_info("DHCP: sending class identifier \"%s\"\n",
-				vendor_class_identifier);
-			*e++ = 60;	/* Class-identifier */
-			len = strlen(vendor_class_identifier);
-			*e++ = len;
-			memcpy(e, vendor_class_identifier, len);
-			e += len;
-		}
-		len = strlen(dhcp_client_identifier + 1);
-		/* the minimum length of identifier is 2, include 1 byte type,
-		 * and can not be larger than the length of options
-		 */
-		if (len >= 1 && len < 312 - (e - options) - 1) {
-			*e++ = 61;
-			*e++ = len + 1;
-			memcpy(e, dhcp_client_identifier, len + 1);
-			e += len + 1;
-		}
+	*e++ = 55;	/* Parameter request list */
+	*e++ = sizeof(ic_req_params);
+	memcpy(e, ic_req_params, sizeof(ic_req_params));
+	e += sizeof(ic_req_params);
+
+	if (ic_host_name_set) {
+		*e++ = 12;	/* host-name */
+		len = strlen(utsname()->nodename);
+		*e++ = len;
+		memcpy(e, utsname()->nodename, len);
+		e += len;
+	}
+	if (*vendor_class_identifier) {
+		pr_info("DHCP: sending class identifier \"%s\"\n",
+			vendor_class_identifier);
+		*e++ = 60;	/* Class-identifier */
+		len = strlen(vendor_class_identifier);
+		*e++ = len;
+		memcpy(e, vendor_class_identifier, len);
+		e += len;
+	}
+	len = strlen(dhcp_client_identifier + 1);
+	/* the minimum length of identifier is 2, include 1 byte type,
+	 * and can not be larger than the length of options
+	 */
+	if (len >= 1 && len < 312 - (e - options) - 1) {
+		*e++ = 61;
+		*e++ = len + 1;
+		memcpy(e, dhcp_client_identifier, len + 1);
+		e += len + 1;
 	}
 
 	*e++ = 255;	/* End of the list */



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 843/877] net: ipconfig: bound DHCP option construction
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (841 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 842/877] net: ipconfig: Remove outdated comment and indent code block Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 844/877] net: ena: Remove autopolling mode Greg Kroah-Hartman
                   ` (41 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Vega, Yuqi Xu, Ren Wei, Simon Horman,
	Paolo Abeni, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Yuqi Xu <xuyuqiabc@gmail.com>

[ Upstream commit e47a1958e12abc3a17b5231a4f21c8f1bf662e08 ]

ic_dhcp_init_options() appends the hostname (option 12), vendor-class
(option 60) and client-ID (option 61) options into the fixed 312-byte
bootp_pkt.exten[] buffer.  Only the client-ID branch checked the
remaining space; the hostname and vendor-class writes were unbounded.

A 64-byte hostname together with the maximum 252-byte dhcpclass=
identifier needs 18 + (2 + 64) + (2 + 252) = 338 of the 312 available
bytes even before the terminating END marker, so the vendor-class memcpy
runs past the end of exten[].  With CONFIG_FORTIFY_SOURCE this is
reported as a field-spanning write and, when the kernel is booted with
panic_on_warn=1, aborts boot with a panic.

Route the optional options through a common helper that makes sure the
option, its 2-byte header and the END marker all fit and drops an option
that would not.  Configurations with short options keep sending exactly
the same bytes as before.

Fixes: 130c0f47fdf9 ("ipconfig: send host-name in DHCP requests")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
Reviewed-by: Ren Wei <weir@nebusec.ai>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/7808dfbfa2162dfd0b19f59aff5742d6e0db2abb.1789798023.git.xuyuqiabc@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv4/ipconfig.c |   45 ++++++++++++++++++++++++++-------------------
 1 file changed, 26 insertions(+), 19 deletions(-)

--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -676,6 +676,24 @@ static const u8 ic_bootp_cookie[4] = { 9
 
 #ifdef IPCONFIG_DHCP
 
+static bool __init
+ic_dhcp_add_option(u8 **options, const u8 *end, u8 type, const void *value,
+		   int len)
+{
+	u8 *e = *options;
+
+	/* leave room for the option header and the END marker */
+	if (len > U8_MAX || end - e < len + 3)
+		return false;
+
+	*e++ = type;
+	*e++ = len;
+	memcpy(e, value, len);
+	*options = e + len;
+
+	return true;
+}
+
 static void __init
 ic_dhcp_init_options(u8 *options, struct ic_device *d)
 {
@@ -691,6 +709,7 @@ ic_dhcp_init_options(u8 *options, struct
 		42,	/* NTP servers */
 	};
 	u8 mt = (ic_servaddr == NONE) ? DHCPDISCOVER : DHCPREQUEST;
+	u8 *end = options + sizeof(((struct bootp_pkt *)0)->exten);
 	u8 *e = options;
 	int len;
 
@@ -721,31 +740,19 @@ ic_dhcp_init_options(u8 *options, struct
 	e += sizeof(ic_req_params);
 
 	if (ic_host_name_set) {
-		*e++ = 12;	/* host-name */
 		len = strlen(utsname()->nodename);
-		*e++ = len;
-		memcpy(e, utsname()->nodename, len);
-		e += len;
+		ic_dhcp_add_option(&e, end, 12, utsname()->nodename, len);
 	}
 	if (*vendor_class_identifier) {
-		pr_info("DHCP: sending class identifier \"%s\"\n",
-			vendor_class_identifier);
-		*e++ = 60;	/* Class-identifier */
 		len = strlen(vendor_class_identifier);
-		*e++ = len;
-		memcpy(e, vendor_class_identifier, len);
-		e += len;
+		if (ic_dhcp_add_option(&e, end, 60, vendor_class_identifier, len))
+			pr_info("DHCP: sending class identifier \"%s\"\n",
+				vendor_class_identifier);
 	}
 	len = strlen(dhcp_client_identifier + 1);
-	/* the minimum length of identifier is 2, include 1 byte type,
-	 * and can not be larger than the length of options
-	 */
-	if (len >= 1 && len < 312 - (e - options) - 1) {
-		*e++ = 61;
-		*e++ = len + 1;
-		memcpy(e, dhcp_client_identifier, len + 1);
-		e += len + 1;
-	}
+	/* the minimum length of identifier is 2, include 1 byte type */
+	if (len >= 1)
+		ic_dhcp_add_option(&e, end, 61, dhcp_client_identifier, len + 1);
 
 	*e++ = 255;	/* End of the list */
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 844/877] net: ena: Remove autopolling mode
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (842 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 843/877] net: ipconfig: bound DHCP option construction Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 845/877] net: ena: fix MMIO read buffer leak on probe failure Greg Kroah-Hartman
                   ` (40 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, David Arinzon,
	Dr. David Alan Gilbert, Jakub Kicinski, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: "Dr. David Alan Gilbert" <linux@treblig.org>

[ Upstream commit b356b9170815f822394667010d478d53901ff581 ]

This manually reverts
commit a4e262cde3cd ("net: ena: allow automatic fallback to polling mode")

which is unused.

(I did it manually because there are other minor comment
and function changes surrounding it).
Build tested only.

Suggested-by: David Arinzon <darinzon@amazon.com>
Signed-off-by: Dr. David Alan Gilbert <linux@treblig.org>
Link: https://patch.msgid.link/20241103194149.293456-1-linux@treblig.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 9476b4468862 ("net: ena: fix MMIO read buffer leak on probe failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/amazon/ena/ena_com.c |   25 +++++--------------------
 drivers/net/ethernet/amazon/ena/ena_com.h |   14 --------------
 2 files changed, 5 insertions(+), 34 deletions(-)

--- a/drivers/net/ethernet/amazon/ena/ena_com.c
+++ b/drivers/net/ethernet/amazon/ena/ena_com.c
@@ -763,25 +763,16 @@ static int ena_com_wait_and_process_admi
 
 		if (comp_ctx->status == ENA_CMD_COMPLETED) {
 			netdev_err(admin_queue->ena_dev->net_device,
-				   "The ena device sent a completion but the driver didn't receive a MSI-X interrupt (cmd %d), autopolling mode is %s\n",
-				   comp_ctx->cmd_opcode, admin_queue->auto_polling ? "ON" : "OFF");
-			/* Check if fallback to polling is enabled */
-			if (admin_queue->auto_polling)
-				admin_queue->polling = true;
+				   "The ena device sent a completion but the driver didn't receive a MSI-X interrupt (cmd %d)\n",
+				   comp_ctx->cmd_opcode);
 		} else {
 			netdev_err(admin_queue->ena_dev->net_device,
 				   "The ena device didn't send a completion for the admin cmd %d status %d\n",
 				   comp_ctx->cmd_opcode, comp_ctx->status);
 		}
-		/* Check if shifted to polling mode.
-		 * This will happen if there is a completion without an interrupt
-		 * and autopolling mode is enabled. Continuing normal execution in such case
-		 */
-		if (!admin_queue->polling) {
-			admin_queue->running_state = false;
-			ret = -ETIME;
-			goto err;
-		}
+		admin_queue->running_state = false;
+		ret = -ETIME;
+		goto err;
 	}
 
 	ret = ena_com_comp_status_to_errno(admin_queue, comp_ctx->comp_status);
@@ -1650,12 +1641,6 @@ void ena_com_set_admin_polling_mode(stru
 	ena_dev->admin_queue.polling = polling;
 }
 
-void ena_com_set_admin_auto_polling_mode(struct ena_com_dev *ena_dev,
-					 bool polling)
-{
-	ena_dev->admin_queue.auto_polling = polling;
-}
-
 int ena_com_mmio_reg_read_request_init(struct ena_com_dev *ena_dev)
 {
 	struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
--- a/drivers/net/ethernet/amazon/ena/ena_com.h
+++ b/drivers/net/ethernet/amazon/ena/ena_com.h
@@ -224,9 +224,6 @@ struct ena_com_admin_queue {
 	/* Indicate if the admin queue should poll for completion */
 	bool polling;
 
-	/* Define if fallback to polling mode should occur */
-	bool auto_polling;
-
 	u16 curr_cmd_id;
 
 	/* Indicate that the ena was initialized and can
@@ -493,17 +490,6 @@ bool ena_com_get_admin_running_state(str
  */
 void ena_com_set_admin_polling_mode(struct ena_com_dev *ena_dev, bool polling);
 
-/* ena_com_set_admin_auto_polling_mode - Enable autoswitch to polling mode
- * @ena_dev: ENA communication layer struct
- * @polling: Enable/Disable polling mode
- *
- * Set the autopolling mode.
- * If autopolling is on:
- * In case of missing interrupt when data is available switch to polling.
- */
-void ena_com_set_admin_auto_polling_mode(struct ena_com_dev *ena_dev,
-					 bool polling);
-
 /* ena_com_admin_q_comp_intr_handler - admin queue interrupt handler
  * @ena_dev: ENA communication layer struct
  *



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 845/877] net: ena: fix MMIO read buffer leak on probe failure
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (843 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 844/877] net: ena: Remove autopolling mode Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 846/877] KVM: SVM: Flush cache only on CPUs running SEV guest Greg Kroah-Hartman
                   ` (39 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Jakub Kicinski,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Guangshuo Li <lgs201920130244@gmail.com>

[ Upstream commit 9476b4468862927297c94c440863cd8ed1e7cc83 ]

ena_device_init() initializes the MMIO read mechanism with
ena_com_mmio_reg_read_request_init(), which allocates a coherent DMA
buffer for MMIO read responses.

The normal removal path releases this buffer through
ena_com_mmio_reg_read_request_destroy(). However, if ena_probe() fails
after ena_device_init() succeeds, the error path destroys the admin
resources and eventually frees ena_dev without destroying the MMIO read
request, leaving the coherent DMA buffer allocated.

Call ena_com_mmio_reg_read_request_destroy() in the probe error path
before releasing the remaining device resources.

This issue was found by manual code inspection.

Fixes: 1738cd3ed342 ("net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Link: https://patch.msgid.link/20260921154202.471662-3-lgs201920130244@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ Adjusted cleanup context for missing PHC and devlink support. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/net/ethernet/amazon/ena/ena_netdev.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
@@ -4088,6 +4088,7 @@ err_worker_destroy:
 err_device_destroy:
 	ena_com_delete_host_info(ena_dev);
 	ena_com_admin_destroy(ena_dev);
+	ena_com_mmio_reg_read_request_destroy(ena_dev);
 err_metrics_destroy:
 	ena_com_delete_customer_metrics_buffer(ena_dev);
 err_netdev_destroy:



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 846/877] KVM: SVM: Flush cache only on CPUs running SEV guest
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (844 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 845/877] net: ena: fix MMIO read buffer leak on probe failure Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 847/877] KVM: SEV: Do cache maintenance on the source VM during intra-host migration Greg Kroah-Hartman
                   ` (38 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Srikanth Aithal, Tom Lendacky,
	Zheyun Shen, Sean Christopherson, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Zheyun Shen <szy0127@sjtu.edu.cn>

[ Upstream commit 6f38f8c574642a822f2e85f079fa29a49176c49c ]

On AMD CPUs without ensuring cache consistency, each memory page
reclamation in an SEV guest triggers a call to do WBNOINVD/WBINVD on all
CPUs, thereby affecting the performance of other programs on the host.

Typically, an AMD server may have 128 cores or more, while the SEV guest
might only utilize 8 of these cores. Meanwhile, host can use qemu-affinity
to bind these 8 vCPUs to specific physical CPUs.

Therefore, keeping a record of the physical core numbers each time a vCPU
runs can help avoid flushing the cache for all CPUs every time.

Take care to allocate the cpumask used to track which CPUs have run a
vCPU when copying or moving an "encryption context", as nothing guarantees
memory in a mirror VM is a strict subset of the ASID owner, and the
destination VM for intrahost migration needs to maintain it's own set of
CPUs.  E.g. for intrahost migration, if a CPU was used for the source VM
but not the destination VM, then it can only have cached memory that was
accessible to the source VM.  And a CPU that was run in the source is also
used by the destination is no different than a CPU that was run in the
destination only.

Note, KVM is guaranteed to do flush caches prior to sev_vm_destroy(),
thanks to kvm_arch_guest_memory_reclaimed for SEV and SEV-ES, and
kvm_arch_gmem_invalidate() for SEV-SNP.  I.e. it's safe to free the
cpumask prior to unregistering encrypted regions and freeing the ASID.

Opportunistically clean up sev_vm_destroy()'s comment regarding what is
(implicitly, what isn't) skipped  for mirror VMs.

Cc: Srikanth Aithal <sraithal@amd.com>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Zheyun Shen <szy0127@sjtu.edu.cn>
Link: https://lore.kernel.org/r/20250522233733.3176144-9-seanjc@google.com
Link: https://lore.kernel.org/all/935a82e3-f7ad-47d7-aaaf-f3d2b62ed768@amd.com
Co-developed-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>

Backport notes for Linux 6.12:

The WBNOINVD prerequisites are not present. Keep WBINVD semantics and
implement sev_writeback_caches as a local macro over the existing
wbinvd_on_cpu API. This preserves per-VM CPU tracking and the interface
needed by 93de2a6a4b91 without adding any functions or x86 cache helpers.
An empty mask naturally performs no flush; CPUs are never removed.

Keep the stable tree's sev_mirror_lock protection, relocated sev_free_vcpu
and GHCB cleanup, void pre_sev_run signature, do_wbinvd label, and existing
all-CPU flush during VM destruction. Add the kvm local needed by tracking.

Allocate the mask after SNP guest-request setup, with matching SNP cleanup
on allocation failure, so failed initialization never leaves a freed mask
in the VM. Free the mask even for a migrated source that is no longer SEV,
as in 12c1f6e03f944, to avoid leaking it on destruction. Destination and
mirror VMs receive independent zeroed masks. Keep the migration allocation
context so 93de2a6a4b91 applies unchanged.

Stable-dep-of: 93de2a6a4b91 ("KVM: SEV: Do cache maintenance on the source VM during intra-host migration")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/kvm/svm/sev.c |   67 +++++++++++++++++++++++++++++++++++++++++--------
 arch/x86/kvm/svm/svm.h |    1 
 2 files changed, 58 insertions(+), 10 deletions(-)

--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -458,6 +458,13 @@ static int __sev_guest_init(struct kvm *
 			goto e_free;
 	}
 
+	if (!zalloc_cpumask_var(&sev->have_run_cpus, GFP_KERNEL_ACCOUNT)) {
+		ret = -ENOMEM;
+		if (vm_type == KVM_X86_SNP_VM)
+			snp_guest_req_cleanup(kvm);
+		goto e_free;
+	}
+
 	INIT_LIST_HEAD(&sev->regions_list);
 	INIT_LIST_HEAD(&sev->mirror_vms);
 	sev->need_init = false;
@@ -715,6 +722,19 @@ static void sev_clflush_pages(struct pag
 	}
 }
 
+/*
+ * Write back guest-tagged cache entries before returning memory to the host.
+ * This tree has no WBNOINVD or masked WBINVD helper, so use WBINVD on each CPU
+ * that has entered the guest.  Keep CPUs in the mask to avoid racing concurrent
+ * flushes and VMRUN; callers must serialize memory reclaim against guest access.
+ */
+#define sev_writeback_caches(kvm) do { \
+	const struct cpumask *__mask = to_kvm_sev_info(kvm)->have_run_cpus; \
+	int __cpu; \
+	for_each_cpu(__cpu, __mask) \
+		wbinvd_on_cpu(__cpu); \
+} while (0)
+
 static unsigned long get_num_contig_pages(unsigned long idx,
 				struct page **inpages, unsigned long npages)
 {
@@ -2134,6 +2154,17 @@ int sev_vm_move_enc_context_from(struct
 	if (ret)
 		goto out_source_vcpu;
 
+	/*
+	 * Allocate a new have_run_cpus for the destination, i.e. don't copy
+	 * the set of CPUs from the source.  If a CPU was used to run a vCPU in
+	 * the source VM but is never used for the destination VM, then the CPU
+	 * can only have cached memory that was accessible to the source VM.
+	 */
+	if (!zalloc_cpumask_var(&dst_sev->have_run_cpus, GFP_KERNEL_ACCOUNT)) {
+		ret = -ENOMEM;
+		goto out_source_vcpu;
+	}
+
 	sev_migrate_from(kvm, source_kvm);
 	kvm_vm_dead(source_kvm);
 	cg_cleanup_sev = src_sev;
@@ -2795,12 +2826,7 @@ int sev_mem_enc_unregister_region(struct
 		goto failed;
 	}
 
-	/*
-	 * Ensure that all guest tagged cache entries are flushed before
-	 * releasing the pages back to the system for use. CLFLUSH will
-	 * not do this, so issue a WBINVD.
-	 */
-	wbinvd_on_all_cpus();
+	sev_writeback_caches(kvm);
 
 	__unregister_enc_region_locked(kvm, region);
 
@@ -2843,12 +2869,17 @@ int sev_vm_copy_enc_context_from(struct
 		goto e_unlock;
 	}
 
+	mirror_sev = to_kvm_sev_info(kvm);
+	if (!zalloc_cpumask_var(&mirror_sev->have_run_cpus, GFP_KERNEL_ACCOUNT)) {
+		ret = -ENOMEM;
+		goto e_unlock;
+	}
+
 	/*
 	 * The mirror kvm holds an enc_context_owner ref so its asid can't
 	 * disappear until we're done with it
 	 */
 	source_sev = to_kvm_sev_info(source_kvm);
-	mirror_sev = to_kvm_sev_info(kvm);
 
 	/* Set enc_context_owner and copy its encryption context over */
 	mutex_lock(&sev_mirror_lock);
@@ -2909,6 +2940,12 @@ void sev_vm_destroy(struct kvm *kvm)
 	struct list_head *head = &sev->regions_list;
 	struct list_head *pos, *q;
 
+	/*
+	 * Free the mask even if the VM is not *currently* an SEV VM, as it may
+	 * have been an SEV VM prior to intra-host migration.
+	 */
+	free_cpumask_var(sev->have_run_cpus);
+
 	if (!sev_guest(kvm))
 		return;
 
@@ -3217,7 +3254,7 @@ static void sev_flush_encrypted_page(str
 	return;
 
 do_wbinvd:
-	wbinvd_on_all_cpus();
+	sev_writeback_caches(vcpu->kvm);
 }
 
 void sev_guest_memory_reclaimed(struct kvm *kvm)
@@ -3231,7 +3268,7 @@ void sev_guest_memory_reclaimed(struct k
 	if (!sev_guest(kvm) || sev_snp_guest(kvm))
 		return;
 
-	wbinvd_on_all_cpus();
+	sev_writeback_caches(kvm);
 }
 
 static void dump_ghcb(struct vcpu_svm *svm)
@@ -3550,7 +3587,17 @@ skip_vmsa_free:
 void pre_sev_run(struct vcpu_svm *svm, int cpu)
 {
 	struct svm_cpu_data *sd = per_cpu_ptr(&svm_data, cpu);
-	unsigned int asid = sev_get_asid(svm->vcpu.kvm);
+	struct kvm *kvm = svm->vcpu.kvm;
+	unsigned int asid = sev_get_asid(kvm);
+
+	/*
+	 * To optimize cache flushes when memory is reclaimed from an SEV VM,
+	 * track physical CPUs that enter the guest for SEV VMs and thus can
+	 * have encrypted, dirty data in the cache, and flush caches only for
+	 * CPUs that have entered the guest.
+	 */
+	if (!cpumask_test_cpu(cpu, to_kvm_sev_info(kvm)->have_run_cpus))
+		cpumask_set_cpu(cpu, to_kvm_sev_info(kvm)->have_run_cpus);
 
 	/* Assign the asid allocated with this SEV guest */
 	svm->asid = asid;
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -113,6 +113,7 @@ struct kvm_sev_info {
 	void *guest_req_buf;    /* Bounce buffer for SNP Guest Request input */
 	void *guest_resp_buf;   /* Bounce buffer for SNP Guest Request output */
 	struct mutex guest_req_mutex; /* Must acquire before using bounce buffers */
+	cpumask_var_t have_run_cpus; /* CPUs that have done VMRUN for this VM. */
 };
 
 struct kvm_svm {



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 847/877] KVM: SEV: Do cache maintenance on the source VM during intra-host migration
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (845 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 846/877] KVM: SVM: Flush cache only on CPUs running SEV guest Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 848/877] perf/x86/intel: Update event constraints and cache_extra_regsfor LNL Greg Kroah-Hartman
                   ` (37 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Stefan Teodorescu,
	Sean Christopherson, Paolo Bonzini, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Sean Christopherson <seanjc@google.com>

[ Upstream commit 93de2a6a4b91b72607136dd656edf03fb399d27f ]

Manually perform cache maintenance on the source VM during intra-host
migration to ensure no stale data is left in CPU caches after the VM is
destroyed.  Because the source VM is "converted" to a non-SEV VM, KVM's
memory reclaim flows won't trigger cache maintenance, e.g. when all guest
memory is reclaimed in response to detaching from the mmu_notifier.

Note, relying on the destination VM to do cache maintenance isn't an option
as KVM doesn't require identical guest memory configurations, i.e. the
source VM may have access to memory that the destination VM does not.
Enforcing equivalent memory configurations is infeasible, as it would
require a *deep* comparison of memslots, e.g. to verify that not only are
the memslot identical, but what the memslots point at is also identical.

Fixes: b56639318bb2 ("KVM: SEV: Add support for SEV intra host migration")
Cc: stable@vger.kernel.org
Reported-by: Stefan Teodorescu <fane@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-ID: <20260923163721.1584779-3-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/kvm/svm/sev.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -2020,6 +2020,12 @@ static void sev_migrate_from(struct kvm
 	src->pages_locked = 0;
 	src->es_active = false;
 
+	/*
+	 * Do cache maintenance on the source VM as it is no longer an SEV VM,
+	 * i.e. memory reclaim flows won't trigger cache maintenance on the VM.
+	 */
+	sev_writeback_caches(src_kvm);
+
 	list_cut_before(&dst->regions_list, &src->regions_list, &src->regions_list);
 
 	mutex_lock(&sev_mirror_lock);
@@ -2159,6 +2165,10 @@ int sev_vm_move_enc_context_from(struct
 	 * the set of CPUs from the source.  If a CPU was used to run a vCPU in
 	 * the source VM but is never used for the destination VM, then the CPU
 	 * can only have cached memory that was accessible to the source VM.
+	 * Furthermore, KVM *must* perform cache maintenance on the source VM,
+	 * as the source VM may have access to memory that the destination VM
+	 * does not, i.e. KVM could skip flushes if memory is reclaimed from
+	 * the old VM but not the new VM.
 	 */
 	if (!zalloc_cpumask_var(&dst_sev->have_run_cpus, GFP_KERNEL_ACCOUNT)) {
 		ret = -ENOMEM;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 848/877] perf/x86/intel: Update event constraints and cache_extra_regsfor LNL
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (846 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 847/877] KVM: SEV: Do cache maintenance on the source VM during intra-host migration Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 849/877] perf/x86/intel: Remove incorrect LionCove PEBS data-source constraints Greg Kroah-Hartman
                   ` (36 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Dapeng Mi, Peter Zijlstra (Intel),
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dapeng Mi <dapeng1.mi@linux.intel.com>

[ Upstream commit 331c3e4fa39a87560c09bdd878652090ae040b69 ]

Update perf hard-coded event constraints and cache_extra_regs[] for
Lunarlake according to the latest LNL perfmon events (V1.22).

LNL introduces new extra register values for the OCR L3 cache events,
so introduce lnc_hw_cache_extra_regs[] and skt_hw_cache_extra_regs[] to
reflect the changes.

LNL perfmon events:
https://github.com/intel/perfmon/blob/main/LNL/events/lunarlake_lioncove_core.json
https://github.com/intel/perfmon/blob/main/LNL/events/lunarlake_skymont_core.json

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260515061143.338553-7-dapeng1.mi@linux.intel.com

[Backport to 6.18: retain the Lion Cove PEBS constraint additions needed
by 7c944595cc43 ("perf/x86/intel: Remove incorrect LionCove PEBS data-source
constraints"). Keep the matching regular counter masks for
TOPDOWN.MEMORY_BOUND_SLOTS (0x10a4, 0x8) and MEM_INST_RETIRED.ANY
(0x87d0, 0x3ff), since that fix removes their PEBS-specific entries and
falls back to the regular constraint table.

Omit the unrelated cache extra-register tables and PMU initialization
changes, which depend on cache-event refactoring and intel_pmu_init_cmt()
absent from 6.18. Also omit the unrelated fixed-counter, non-PEBS OCR,
0x00e0, and Skymont constraint updates. No functions are added.]

Stable-dep-of: 7c944595cc43 ("perf/x86/intel: Remove incorrect LionCove PEBS data-source constraints")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/events/intel/core.c |    3 ++-
 arch/x86/events/intel/ds.c   |    8 ++++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -411,11 +411,12 @@ static struct event_constraint intel_lnc
 	INTEL_UEVENT_CONSTRAINT(0x0ca3, 0x4),
 	INTEL_UEVENT_CONSTRAINT(0x04a4, 0x1),
 	INTEL_UEVENT_CONSTRAINT(0x08a4, 0x1),
-	INTEL_UEVENT_CONSTRAINT(0x10a4, 0x1),
+	INTEL_UEVENT_CONSTRAINT(0x10a4, 0x8),
 	INTEL_UEVENT_CONSTRAINT(0x01b1, 0x8),
 	INTEL_UEVENT_CONSTRAINT(0x01cd, 0x3fc),
 	INTEL_UEVENT_CONSTRAINT(0x02cd, 0x3),
 
+	INTEL_UEVENT_CONSTRAINT(0x87d0, 0x3ff),
 	INTEL_EVENT_CONSTRAINT_RANGE(0xd0, 0xdf, 0xf),
 
 	INTEL_UEVENT_CONSTRAINT(0x00e0, 0xf),
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -1179,6 +1179,13 @@ struct event_constraint intel_lnc_pebs_e
 	INTEL_FLAGS_UEVENT_CONSTRAINT(0x100, 0x100000000ULL),	/* INST_RETIRED.PREC_DIST */
 	INTEL_FLAGS_UEVENT_CONSTRAINT(0x0400, 0x800000000ULL),
 
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x012a, 0x1),		/* OCR.* events */
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x012b, 0x1),		/* OCR.* events */
+
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x04a4, 0x1),		/* TOPDOWN.BAD_SPEC_SLOTS */
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x08a4, 0x1),		/* TOPDOWN.BR_MISPREDICT_SLOTS */
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x10a4, 0x8),		/* TOPDOWN.MEMORY_BOUND_SLOTS */
+
 	INTEL_HYBRID_LDLAT_CONSTRAINT(0x1cd, 0x3fc),
 	INTEL_HYBRID_STLAT_CONSTRAINT(0x2cd, 0x3),
 	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf),	/* MEM_INST_RETIRED.STLB_MISS_LOADS */
@@ -1188,6 +1195,7 @@ struct event_constraint intel_lnc_pebs_e
 	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf),	/* MEM_INST_RETIRED.SPLIT_STORES */
 	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf),	/* MEM_INST_RETIRED.ALL_LOADS */
 	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf),	/* MEM_INST_RETIRED.ALL_STORES */
+	INTEL_FLAGS_UEVENT_CONSTRAINT(0x87d0, 0x3ff),		/* MEM_INST_RETIRED.ANY */
 
 	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(0xd1, 0xd4, 0xf),
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 849/877] perf/x86/intel: Remove incorrect LionCove PEBS data-source constraints
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (847 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 848/877] perf/x86/intel: Update event constraints and cache_extra_regsfor LNL Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 850/877] perf/x86/intel: Update event constraints and cache_extra_regsfor ADL Greg Kroah-Hartman
                   ` (35 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Dapeng Mi, Peter Zijlstra (Intel),
	Ingo Molnar, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dapeng Mi <dapeng1.mi@linux.intel.com>

[ Upstream commit 7c944595cc43a664019edc22505b6d6f6039be5e ]

On Lion Cove, PEBS data source is valid only for these events:

- MEM_TRANS_RETIRED.LOAD_LATENCY (0x1cd)
- MEM_TRANS_RETIRED.STORE_SAMPLE (0x2cd)

The perfmon database (https://github.com/intel/perfmon) previously
tagged additional memory events such as MEM_INST_RETIRED.STLB_MISS_LOADS
with L1_Hit_Indication, implying PEBS data-source support, which is
incorrect. The database has since been fixed, but
intel_lnc_pebs_event_constraints[] still follows the old definition and
marks those events as data-source capable.

As a result, get_data_src() may decode data-source information for
events that do not provide valid PEBS data-source data and mislead
users.

Remove those non-data-source memory events from the Lion Cove PEBS
constraint table so matching falls back to the regular non-PEBS
constraints, which already provide the same counter constraints.

Also update lnc_latency_data() to decode LOAD/STORE flags explicitly
when setting memory operation direction, for consistency with other
*_latency_data() helpers.

Fixes: a932aa0e868f ("perf/x86: Add Lunar Lake and Arrow Lake support")
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: <stable@vger.kernel.org>
Link: https://patch.msgid.link/20260917015234.981153-6-dapeng1.mi@linux.intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/events/intel/ds.c |   22 +++++-----------------
 1 file changed, 5 insertions(+), 17 deletions(-)

--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -373,7 +373,11 @@ static u64 lnc_latency_data(struct perf_
 		val |= P(BLK, NA);
 
 	src.val = val;
-	if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW)
+	if (event->hw.flags &
+	    (PERF_X86_EVENT_PEBS_LDLAT | PERF_X86_EVENT_PEBS_LD_HSW))
+		src.mem_op = P(OP, LOAD);
+	if (event->hw.flags &
+	    (PERF_X86_EVENT_PEBS_STLAT | PERF_X86_EVENT_PEBS_ST_HSW))
 		src.mem_op = P(OP, STORE);
 
 	return src.val;
@@ -1182,24 +1186,8 @@ struct event_constraint intel_lnc_pebs_e
 	INTEL_FLAGS_UEVENT_CONSTRAINT(0x012a, 0x1),		/* OCR.* events */
 	INTEL_FLAGS_UEVENT_CONSTRAINT(0x012b, 0x1),		/* OCR.* events */
 
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x04a4, 0x1),		/* TOPDOWN.BAD_SPEC_SLOTS */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x08a4, 0x1),		/* TOPDOWN.BR_MISPREDICT_SLOTS */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x10a4, 0x8),		/* TOPDOWN.MEMORY_BOUND_SLOTS */
-
 	INTEL_HYBRID_LDLAT_CONSTRAINT(0x1cd, 0x3fc),
 	INTEL_HYBRID_STLAT_CONSTRAINT(0x2cd, 0x3),
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf),	/* MEM_INST_RETIRED.STLB_MISS_LOADS */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf),	/* MEM_INST_RETIRED.STLB_MISS_STORES */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf),	/* MEM_INST_RETIRED.LOCK_LOADS */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf),	/* MEM_INST_RETIRED.SPLIT_LOADS */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf),	/* MEM_INST_RETIRED.SPLIT_STORES */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf),	/* MEM_INST_RETIRED.ALL_LOADS */
-	INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf),	/* MEM_INST_RETIRED.ALL_STORES */
-	INTEL_FLAGS_UEVENT_CONSTRAINT(0x87d0, 0x3ff),		/* MEM_INST_RETIRED.ANY */
-
-	INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD_RANGE(0xd1, 0xd4, 0xf),
-
-	INTEL_FLAGS_EVENT_CONSTRAINT(0xd0, 0xf),
 
 	/*
 	 * Everything else is handled by PMU_FL_PEBS_ALL, because we



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 850/877] perf/x86/intel: Update event constraints and cache_extra_regsfor ADL
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (848 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 849/877] perf/x86/intel: Remove incorrect LionCove PEBS data-source constraints Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 851/877] perf/x86/intel: Fix GRT PEBS load/store direction for latency events, to fix sample classification Greg Kroah-Hartman
                   ` (34 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Dapeng Mi, Peter Zijlstra (Intel),
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dapeng Mi <dapeng1.mi@linux.intel.com>

[ Upstream commit 4ef863352bcde482d65722ed721c3fd3967a67d6 ]

Update perf hard-coded event constraints and cache_extra_regs[] for
Alderlake according to the latest ADL perfmon events (V1.39).

One important note is that ADL has differences on the L3/node related
OCR events although it shares same uarch with SPR server, e.g.,
ADL has different extra MSR values and no node events. So some variants
of structures and functions are introduced to reflect these
differences, like adl_glc_hw_cache_event_ids[],
adl_glc_hw_cache_extra_regs[] and intel_pmu_init_glc_hybrid(), etc.

Please note these changes would temporarily impact other platforms like
MTL/ARL-U which shares hard-coded event structures, but it would be
fixed soon in subsequent patches.

ADL perfmon events:
https://github.com/intel/perfmon/blob/main/ADL/events/alderlake_goldencove_core.json
https://github.com/intel/perfmon/blob/main/ADL/events/alderlake_gracemont_core.json

Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260515061143.338553-5-dapeng1.mi@linux.intel.com

[Stable dependency adaptation]
Retain only the Gracemont STORE_LATENCY (event 0x6d0) PEBS counter-mask
update from 0xf to 0x3f in intel_grt_pebs_event_constraints[]. This is the
preimage required by target 89dc568e8c0be60e05e5fcd0b528c79077d7b84b.
The existing latency decoder and LOAD/STORE constraint macros are already
available in this stable tree, so no new functions are needed.

Drop all core.c changes: the cache-event tables, offcore MSR masks,
fixed-event aliases and hybrid initialization changes are unrelated to the
target. Their upstream context includes cache tables absent from 6.18,
and retaining them would bring in an unnecessary helper function and
broader platform changes.

[ sashal: Reduced backport -- upstream 4ef863352bcde touches 2 file(s), this
  backport carries 1. Not backported here:
  arch/x86/events/intel/core.c
  This note is generated from the file lists only; see the resolution record
  for the reasoning. ]

Stable-dep-of: 89dc568e8c0b ("perf/x86/intel: Fix GRT PEBS load/store direction for latency events, to fix sample classification")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/events/intel/ds.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -986,7 +986,7 @@ struct event_constraint intel_glm_pebs_e
 struct event_constraint intel_grt_pebs_event_constraints[] = {
 	/* Allow all events as PEBS with no flags */
 	INTEL_HYBRID_LAT_CONSTRAINT(0x5d0, 0x3),
-	INTEL_HYBRID_LAT_CONSTRAINT(0x6d0, 0xf),
+	INTEL_HYBRID_LAT_CONSTRAINT(0x6d0, 0x3f),
 	EVENT_CONSTRAINT_END
 };
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 851/877] perf/x86/intel: Fix GRT PEBS load/store direction for latency events, to fix sample classification
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (849 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 850/877] perf/x86/intel: Update event constraints and cache_extra_regsfor ADL Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 852/877] RISC-V: KVM: Fix null pointer dereference in kvm_riscv_aia_imsic_rw_attr() Greg Kroah-Hartman
                   ` (33 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Dapeng Mi, Peter Zijlstra (Intel),
	Ingo Molnar, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Dapeng Mi <dapeng1.mi@linux.intel.com>

[ Upstream commit 89dc568e8c0be60e05e5fcd0b528c79077d7b84b ]

On Gracemont, intel_grt_pebs_event_constraints[] applies LAT_CONSTRAINT
constraints to MEM_UOPS_RETIRED.{LOAD,STORE}_LATENCY, but does not set
explicit LOAD/STORE flags for those events.

The PEBS latency path (pebs_latency_data(), via __grt_latency_data())
uses the event flags to determine memory operation direction. Without an
explicit STORE flag, samples from MEM_UOPS_RETIRED.STORE_LATENCY can be
misclassified as LOADs.

Set explicit LOAD/STORE flags in intel_grt_pebs_event_constraints[] for:

- MEM_UOPS_RETIRED.LOAD_LATENCY
- MEM_UOPS_RETIRED.STORE_LATENCY

Also update __grt_latency_data() to explicitly interpret these flags when
assigning the sampled memory operation direction.

This fixes incorrect STORE sample classification.

Fixes: 39a41278f041 ("perf/x86/intel: Fix PEBS memory access info encoding for ADL")
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: <stable@vger.kernel.org> # v7.2+
Link: https://patch.msgid.link/20260917015234.981153-2-dapeng1.mi@linux.intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/x86/events/intel/ds.c |   16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -303,6 +303,7 @@ static inline void pebs_set_tlb_lock(u64
 static u64 __grt_latency_data(struct perf_event *event, u64 status,
 			       u8 dse, bool tlb, bool lock, bool blk)
 {
+	union perf_mem_data_src src;
 	u64 val;
 
 	WARN_ON_ONCE(is_hybrid() &&
@@ -318,7 +319,16 @@ static u64 __grt_latency_data(struct per
 	else
 		val |= P(BLK, NA);
 
-	return val;
+	src.val = val;
+
+	if (event->hw.flags &
+	    (PERF_X86_EVENT_PEBS_LDLAT | PERF_X86_EVENT_PEBS_LD_HSW))
+		src.mem_op = P(OP, LOAD);
+	if (event->hw.flags &
+	    (PERF_X86_EVENT_PEBS_STLAT | PERF_X86_EVENT_PEBS_ST_HSW))
+		src.mem_op = P(OP, STORE);
+
+	return src.val;
 }
 
 u64 grt_latency_data(struct perf_event *event, u64 status)
@@ -985,8 +995,8 @@ struct event_constraint intel_glm_pebs_e
 
 struct event_constraint intel_grt_pebs_event_constraints[] = {
 	/* Allow all events as PEBS with no flags */
-	INTEL_HYBRID_LAT_CONSTRAINT(0x5d0, 0x3),
-	INTEL_HYBRID_LAT_CONSTRAINT(0x6d0, 0x3f),
+	INTEL_HYBRID_LDLAT_CONSTRAINT(0x5d0, 0x3),
+	INTEL_HYBRID_STLAT_CONSTRAINT(0x6d0, 0x3f),
 	EVENT_CONSTRAINT_END
 };
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 852/877] RISC-V: KVM: Fix null pointer dereference in kvm_riscv_aia_imsic_rw_attr()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (850 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 851/877] perf/x86/intel: Fix GRT PEBS load/store direction for latency events, to fix sample classification Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 853/877] RISC-V: KVM: Serialize IMSIC attributes with vCPU migration Greg Kroah-Hartman
                   ` (32 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Jiakai Xu, Jiakai Xu, Anup Patel,
	Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jiakai Xu <jiakaipeanut@gmail.com>

[ Upstream commit aeb1d17d1af5924f7357d7204a293bd8fc06ea13 ]

Add a null pointer check for imsic_state before dereferencing it in
kvm_riscv_aia_imsic_rw_attr(). While the function checks that the
vcpu exists, it doesn't verify that the vcpu's imsic_state has been
initialized, leading to a null pointer dereference when accessed.

The crash manifests as:
  Unable to handle kernel paging request at virtual address
  dfffffff00000006
  ...
  kvm_riscv_aia_imsic_rw_attr+0x2d8/0x854 arch/riscv/kvm/aia_imsic.c:958
  aia_set_attr+0x2ee/0x1726 arch/riscv/kvm/aia_device.c:354
  kvm_device_ioctl_attr virt/kvm/kvm_main.c:4744 [inline]
  kvm_device_ioctl+0x296/0x374 virt/kvm/kvm_main.c:4761
  vfs_ioctl fs/ioctl.c:51 [inline]
  ...

The fix adds a check to return -ENODEV if imsic_state is NULL and moves
isel assignment after imsic_state NULL check.

Fixes: 5463091a51cfaa ("RISC-V: KVM: Expose IMSIC registers as attributes of AIA irqchip")
Signed-off-by: Jiakai Xu <xujiakai2025@iscas.ac.cn>
Signed-off-by: Jiakai Xu <jiakaiPeanut@gmail.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260127072219.3366607-1-xujiakai2025@iscas.ac.cn
Signed-off-by: Anup Patel <anup@brainfault.org>
Stable-dep-of: 8ae12ccaec6e ("RISC-V: KVM: Serialize IMSIC attributes with vCPU migration")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/riscv/kvm/aia_imsic.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

--- a/arch/riscv/kvm/aia_imsic.c
+++ b/arch/riscv/kvm/aia_imsic.c
@@ -895,8 +895,10 @@ int kvm_riscv_aia_imsic_rw_attr(struct k
 	if (!vcpu)
 		return -ENODEV;
 
-	isel = KVM_DEV_RISCV_AIA_IMSIC_GET_ISEL(type);
 	imsic = vcpu->arch.aia_context.imsic_state;
+	if (!imsic)
+		return -ENODEV;
+	isel = KVM_DEV_RISCV_AIA_IMSIC_GET_ISEL(type);
 
 	read_lock_irqsave(&imsic->vsfile_lock, flags);
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 853/877] RISC-V: KVM: Serialize IMSIC attributes with vCPU migration
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (851 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 852/877] RISC-V: KVM: Fix null pointer dereference in kvm_riscv_aia_imsic_rw_attr() Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 854/877] rose: fix dev_put() leak in rose_loopback_timer() Greg Kroah-Hartman
                   ` (31 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Xie Bo, Anup Patel, Sasha Levin

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Xie Bo <xb@ultrarisc.com>

[ Upstream commit 8ae12ccaec6ec74945d8c1ef39f2c1b8df779abc ]

KVM device ioctls are not serialized against KVM_RUN. As a result,
kvm_riscv_aia_imsic_rw_attr() can snapshot the physical CPU and HGEI of
an IMSIC VS-file before a concurrent vCPU migration releases it.

The HGEI can then be allocated to another vCPU before imsic_vsfile_rw()
uses the stale tuple. A GET or SET attribute may consequently access the
new owner's interrupt file.

Serialize the entire IMSIC attribute operation with the target vCPU
mutex. This prevents the VS-file from being migrated and recycled until
the attribute access completes. Acquire the mutex killably so that the
device ioctl remains interruptible while waiting for KVM_RUN to finish.

Fixes: db8b7e97d613 ("RISC-V: KVM: Add in-kernel virtualization of AIA IMSIC")
Cc: stable@vger.kernel.org
Signed-off-by: Xie Bo <xb@ultrarisc.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20260810-imsic-attr-race-v2-1-00ed95ad321e@ultrarisc.com
Signed-off-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 arch/riscv/kvm/aia_imsic.c |   11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

--- a/arch/riscv/kvm/aia_imsic.c
+++ b/arch/riscv/kvm/aia_imsic.c
@@ -895,9 +895,14 @@ int kvm_riscv_aia_imsic_rw_attr(struct k
 	if (!vcpu)
 		return -ENODEV;
 
+	if (mutex_lock_killable(&vcpu->mutex))
+		return -EINTR;
+
 	imsic = vcpu->arch.aia_context.imsic_state;
-	if (!imsic)
-		return -ENODEV;
+	if (!imsic) {
+		rc = -ENODEV;
+		goto out_unlock;
+	}
 	isel = KVM_DEV_RISCV_AIA_IMSIC_GET_ISEL(type);
 
 	read_lock_irqsave(&imsic->vsfile_lock, flags);
@@ -921,6 +926,8 @@ int kvm_riscv_aia_imsic_rw_attr(struct k
 		rc = imsic_vsfile_rw(vsfile_hgei, vsfile_cpu, imsic->nr_eix,
 				     isel, write, val);
 
+out_unlock:
+	mutex_unlock(&vcpu->mutex);
 	return rc;
 }
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 854/877] rose: fix dev_put() leak in rose_loopback_timer()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (852 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 853/877] RISC-V: KVM: Serialize IMSIC attributes with vCPU migration Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 855/877] rose: hold loopback neighbour reference across timer callback Greg Kroah-Hartman
                   ` (30 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit ff91adc54db2b62c7cdf063ff761eceb5adf2215 upstream.

rose_rx_call_request() always consumes or returns the skb but never
releases the device reference obtained from rose_dev_get().  When
rose_rx_call_request() succeeds (returns non-zero) dev_put() was never
called, leaking one reference per loopback CALL_REQUEST.

Move dev_put() outside the conditional so it is called unconditionally
after rose_rx_call_request() in all cases.

Also remove the dead check (!rose_loopback_neigh->dev &&
!rose_loopback_neigh->loopback) that immediately precedes it: the
loopback neighbour always has loopback=1 so this condition can never
be true.

Fixes: 0453c6824595 ("net/rose: fix unbound loop in rose_loopback_timer()")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/rose_loopback.c |   11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

--- a/net/rose/rose_loopback.c
+++ b/net/rose/rose_loopback.c
@@ -96,22 +96,15 @@ static void rose_loopback_timer(struct t
 		}
 
 		if (frametype == ROSE_CALL_REQUEST) {
-			if (!rose_loopback_neigh->dev &&
-			    !rose_loopback_neigh->loopback) {
-				kfree_skb(skb);
-				continue;
-			}
-
 			dev = rose_dev_get(dest);
 			if (!dev) {
 				kfree_skb(skb);
 				continue;
 			}
 
-			if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0) {
-				dev_put(dev);
+			if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0)
 				kfree_skb(skb);
-			}
+			dev_put(dev);
 		} else {
 			kfree_skb(skb);
 		}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 855/877] rose: hold loopback neighbour reference across timer callback
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (853 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 854/877] rose: fix dev_put() leak in rose_loopback_timer() Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 856/877] rose: fix race between loopback timer and module removal Greg Kroah-Hartman
                   ` (29 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit d270a7a5793af84555c40dd1eb80f1d497fdf53c upstream.

rose_loopback_timer() dereferences rose_loopback_neigh throughout its
body but holds no reference on it.  A concurrent rose_loopback_clear()
followed by rose_add_loopback_neigh() could free and reallocate the
neighbour while the timer body is running, causing a use-after-free.

Take a reference with rose_neigh_hold() at the start of the callback
(bailing out if the pointer is already NULL) and release it with
rose_neigh_put() at the single exit point.  The neigh cannot be freed
while the callback holds a reference.

Fixes: d860d1faa6b2 ("net: rose: convert 'use' field to refcount_t")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/rose_loopback.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

--- a/net/rose/rose_loopback.c
+++ b/net/rose/rose_loopback.c
@@ -66,10 +66,15 @@ static void rose_loopback_timer(struct t
 	unsigned int lci_i, lci_o;
 	int count;
 
+	if (rose_loopback_neigh)
+		rose_neigh_hold(rose_loopback_neigh);
+	else
+		return;
+
 	for (count = 0; count < ROSE_LOOPBACK_LIMIT; count++) {
 		skb = skb_dequeue(&loopback_queue);
 		if (!skb)
-			return;
+			goto out;
 		if (skb->len < ROSE_MIN_LEN) {
 			kfree_skb(skb);
 			continue;
@@ -109,6 +114,10 @@ static void rose_loopback_timer(struct t
 			kfree_skb(skb);
 		}
 	}
+
+out:
+	rose_neigh_put(rose_loopback_neigh);
+
 	if (!skb_queue_empty(&loopback_queue))
 		mod_timer(&loopback_timer, jiffies + 1);
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 856/877] rose: fix race between loopback timer and module removal
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (854 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 855/877] rose: hold loopback neighbour reference across timer callback Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 857/877] rose: clear neighbour pointer after rose_neigh_put() in state machines Greg Kroah-Hartman
                   ` (28 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit 47dd6ec1a77d77895afb00aa2e68373a48289108 upstream.

rose_loopback_clear() called timer_delete() which returns immediately
without waiting for any running callback to complete.  If the timer
fired concurrently with module removal, rose_loopback_timer() could
re-arm the timer after timer_delete() returned and then access
rose_loopback_neigh after it was freed.

Two complementary changes close the race:

1. Add a loopback_stopping atomic flag.  rose_loopback_timer() checks
   it at entry (before acquiring a reference) and again inside the
   loop; when set it drains the queue and exits without re-arming the
   timer.

2. Switch rose_loopback_clear() to timer_delete_sync() so it blocks
   until any in-flight callback has returned before freeing resources.

The smp_mb() between setting the flag and calling timer_delete_sync()
ensures the flag is visible to any callback that is about to run.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/rose_loopback.c |   31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

--- a/net/rose/rose_loopback.c
+++ b/net/rose/rose_loopback.c
@@ -12,13 +12,15 @@
 #include <net/rose.h>
 #include <linux/init.h>
 
-static struct sk_buff_head loopback_queue;
 #define ROSE_LOOPBACK_LIMIT 1000
-static struct timer_list loopback_timer;
 
+static struct timer_list loopback_timer;
+static struct sk_buff_head loopback_queue;
 static void rose_set_loopback_timer(void);
 static void rose_loopback_timer(struct timer_list *unused);
 
+static atomic_t loopback_stopping = ATOMIC_INIT(0);
+
 void rose_loopback_init(void)
 {
 	skb_queue_head_init(&loopback_queue);
@@ -66,6 +68,9 @@ static void rose_loopback_timer(struct t
 	unsigned int lci_i, lci_o;
 	int count;
 
+	if (atomic_read(&loopback_stopping))
+		return;
+
 	if (rose_loopback_neigh)
 		rose_neigh_hold(rose_loopback_neigh);
 	else
@@ -75,6 +80,13 @@ static void rose_loopback_timer(struct t
 		skb = skb_dequeue(&loopback_queue);
 		if (!skb)
 			goto out;
+
+		if (atomic_read(&loopback_stopping)) {
+			kfree_skb(skb);
+			skb_queue_purge(&loopback_queue);
+			goto out;
+		}
+
 		if (skb->len < ROSE_MIN_LEN) {
 			kfree_skb(skb);
 			continue;
@@ -118,7 +130,7 @@ static void rose_loopback_timer(struct t
 out:
 	rose_neigh_put(rose_loopback_neigh);
 
-	if (!skb_queue_empty(&loopback_queue))
+	if (!atomic_read(&loopback_stopping) && !skb_queue_empty(&loopback_queue))
 		mod_timer(&loopback_timer, jiffies + 1);
 }
 
@@ -126,10 +138,15 @@ void __exit rose_loopback_clear(void)
 {
 	struct sk_buff *skb;
 
-	del_timer(&loopback_timer);
+	atomic_set(&loopback_stopping, 1);
+	/* Pairs with atomic_read() in rose_loopback_timer(): ensure the
+	 * stopping flag is visible before we cancel, so a concurrent
+	 * callback aborts its loop early rather than re-arming the timer.
+	 */
+	smp_mb();
+
+	timer_delete_sync(&loopback_timer);
 
-	while ((skb = skb_dequeue(&loopback_queue)) != NULL) {
-		skb->sk = NULL;
+	while ((skb = skb_dequeue(&loopback_queue)) != NULL)
 		kfree_skb(skb);
-	}
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 857/877] rose: clear neighbour pointer after rose_neigh_put() in state machines
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (855 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 856/877] rose: fix race between loopback timer and module removal Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 858/877] rose: guard rose_neigh_put() against NULL in timer expiry Greg Kroah-Hartman
                   ` (27 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit e8eb0c6faa8849ba7769516c1a8c84d9f612acf6 upstream.

After calling rose_neigh_put() in rose_state1_machine() through
rose_state5_machine(), rose->neighbour was left pointing at the
potentially freed neighbour structure.  A subsequent timer expiry or
concurrent teardown path could dereference the stale pointer, causing
a use-after-free.

Set rose->neighbour to NULL immediately after each rose_neigh_put()
call in the state machine functions.

Fixes: d860d1faa6b2 ("net: rose: convert 'use' field to refcount_t")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/rose_in.c |    6 ++++++
 1 file changed, 6 insertions(+)

--- a/net/rose/rose_in.c
+++ b/net/rose/rose_in.c
@@ -57,6 +57,7 @@ static int rose_state1_machine(struct so
 		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
 		rose_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
 		rose_neigh_put(rose->neighbour);
+		rose->neighbour = NULL;
 		break;
 
 	default:
@@ -80,11 +81,13 @@ static int rose_state2_machine(struct so
 		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
 		rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
 		rose_neigh_put(rose->neighbour);
+		rose->neighbour = NULL;
 		break;
 
 	case ROSE_CLEAR_CONFIRMATION:
 		rose_disconnect(sk, 0, -1, -1);
 		rose_neigh_put(rose->neighbour);
+		rose->neighbour = NULL;
 		break;
 
 	default:
@@ -121,6 +124,7 @@ static int rose_state3_machine(struct so
 		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
 		rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
 		rose_neigh_put(rose->neighbour);
+		rose->neighbour = NULL;
 		break;
 
 	case ROSE_RR:
@@ -234,6 +238,7 @@ static int rose_state4_machine(struct so
 		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
 		rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
 		rose_neigh_put(rose->neighbour);
+		rose->neighbour = NULL;
 		break;
 
 	default:
@@ -254,6 +259,7 @@ static int rose_state5_machine(struct so
 		rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
 		rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
 		rose_neigh_put(rose_sk(sk)->neighbour);
+		rose_sk(sk)->neighbour = NULL;
 	}
 
 	return 0;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 858/877] rose: guard rose_neigh_put() against NULL in timer expiry
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (856 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 857/877] rose: clear neighbour pointer after rose_neigh_put() in state machines Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 859/877] rose: fix netdev double-hold in rose_rx_call_request() Greg Kroah-Hartman
                   ` (26 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit 2b67342c6ff899a0b83359517146a5b7b243af97 upstream.

In rose_timer_expiry(), the ROSE_STATE_2 branch calls
rose_neigh_put(rose->neighbour) without first checking whether the
pointer is NULL.  After commit 5de7665e0a07 ("net: rose: fix timer
races against user threads") the timer is re-armed when the socket is
owned by a user thread; between the re-arm and the next firing, a
device-down event or concurrent teardown via rose_kill_by_device() can
set rose->neighbour to NULL, leading to a NULL-pointer dereference
inside rose_neigh_put().

Add a NULL check before the put and clear the pointer afterwards.

Fixes: 5de7665e0a07 ("net: rose: fix timer races against user threads")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/rose_timer.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

--- a/net/rose/rose_timer.c
+++ b/net/rose/rose_timer.c
@@ -180,7 +180,10 @@ static void rose_timer_expiry(struct tim
 		break;
 
 	case ROSE_STATE_2:	/* T3 */
-		rose_neigh_put(rose->neighbour);
+		if (rose->neighbour) {
+			rose_neigh_put(rose->neighbour);
+			rose->neighbour = NULL;
+		}
 		rose_disconnect(sk, ETIMEDOUT, -1, -1);
 		break;
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 859/877] rose: fix netdev double-hold in rose_rx_call_request()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (857 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 858/877] rose: guard rose_neigh_put() against NULL in timer expiry Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 860/877] rose: fix notifier unregistered too early in rose_exit() Greg Kroah-Hartman
                   ` (25 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit c675277c3ba0d2310e0825577d58308c39931e14 upstream.

rose_rx_call_request() used netdev_tracker_alloc() after assigning
make_rose->device, intending to take ownership of the reference passed
by the caller.  But every caller -- rose_route_frame() and
rose_loopback_timer() -- already calls dev_put() for its own hold after
the function returns, so the socket ended up with a tracker entry
pointing at a reference that had already been released.

The result was spurious refcount_t warnings ("saturated", "decrement
hit 0") on every incoming CALL_REQUEST, leading to refcount corruption
and eventual silent freeze.

Replace netdev_tracker_alloc() with netdev_hold() so that
rose_rx_call_request() acquires its own independent reference.  Each
caller retains its own hold from rose_dev_get() and releases it via
dev_put() as before; socket cleanup releases the socket's separate hold
via netdev_put().

Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/af_rose.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1078,9 +1078,11 @@ int rose_rx_call_request(struct sk_buff
 		make_rose->source_digis[n] = facilities.source_digis[n];
 	make_rose->neighbour     = neigh;
 	make_rose->device        = dev;
-	/* Caller got a reference for us. */
-	netdev_tracker_alloc(make_rose->device, &make_rose->dev_tracker,
-			     GFP_ATOMIC);
+	/* Take an independent reference for this socket; callers keep their
+	 * own reference (from rose_dev_get / dev_hold) and will release it
+	 * themselves via dev_put().
+	 */
+	netdev_hold(make_rose->device, &make_rose->dev_tracker, GFP_ATOMIC);
 	make_rose->facilities    = facilities;
 
 	rose_neigh_hold(make_rose->neighbour);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 860/877] rose: fix notifier unregistered too early in rose_exit()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (858 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 859/877] rose: fix netdev double-hold in rose_rx_call_request() Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 861/877] rose: set SOCK_DESTROY in rose_kill_by_device() for prompt cleanup Greg Kroah-Hartman
                   ` (24 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit f71a8a1edc14dba746edde38adddd654ba202b4d upstream.

rose_exit() called unregister_netdevice_notifier() before the loop that
calls unregister_netdev() on each ROSE virtual device.  As a result,
the NETDEV_DOWN event fired by unregister_netdev() was never delivered
to rose_device_event(), so rose_kill_by_device() never ran.

Every socket whose rose->device pointed at a ROSE device therefore kept
its netdev_tracker entry live until free_netdev() destroyed the
ref_tracker_dir, at which point the kernel reported all of them as
leaked references (165 entries in a typical FPAC setup).  Worse, those
sockets retained stale device pointers and live timers that could fire
into freed module text after module unload, causing a silent system
freeze with no kernel panic logged.

Fix by moving unregister_netdevice_notifier() to after the device-
unregistration loop.  unregister_netdev() then delivers NETDEV_DOWN
while the notifier is still registered, rose_kill_by_device() runs for
each device, releases all netdev references held by open sockets, and
calls rose_disconnect() which stops the per-socket timers.

Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/af_rose.c |   13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1669,19 +1669,28 @@ static void __exit rose_exit(void)
 #ifdef CONFIG_SYSCTL
 	rose_unregister_sysctl();
 #endif
-	unregister_netdevice_notifier(&rose_dev_notifier);
-
 	sock_unregister(PF_ROSE);
 
 	for (i = 0; i < rose_ndevs; i++) {
 		struct net_device *dev = dev_rose[i];
 
 		if (dev) {
+			/* unregister_netdev() fires NETDEV_DOWN, which -- while the
+			 * notifier is still registered below -- invokes
+			 * rose_kill_by_device(dev).  That releases every socket's
+			 * netdev reference and disconnects all active circuits.
+			 * Unregistering the notifier before this loop was the
+			 * original bug: NETDEV_DOWN was never delivered, leaving
+			 * 165 netdev_tracker entries leaked and stale timers live.
+			 */
 			unregister_netdev(dev);
 			free_netdev(dev);
 		}
 	}
 
+	/* Now safe to remove the notifier -- all ROSE devices are gone. */
+	unregister_netdevice_notifier(&rose_dev_notifier);
+
 	kfree(dev_rose);
 	proto_unregister(&rose_proto);
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 861/877] rose: set SOCK_DESTROY in rose_kill_by_device() for prompt cleanup
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (859 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 860/877] rose: fix notifier unregistered too early in rose_exit() Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 862/877] rose: disconnect orphaned STATE_2 sockets when device is gone Greg Kroah-Hartman
                   ` (23 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit 741a4863ad570889c75f7a8e404567d8f3e46335 upstream.

When rose_kill_by_device() is called (via NETDEV_DOWN on module exit
or interface removal), it calls rose_disconnect() which transitions
sockets to ROSE_STATE_0 and sets SOCK_DEAD.  However,
rose_heartbeat_expiry() only calls rose_destroy_socket() at
ROSE_STATE_0 if SOCK_DESTROY is set -- the SOCK_DEAD path is reserved
for TCP_LISTEN sockets.  Without SOCK_DESTROY, orphaned sockets in
ROSE_STATE_2 (clearing) loop indefinitely in the heartbeat without
ever being freed, keeping the module use-count elevated and blocking
modprobe -r rose until the T1 timer (up to 200 s) expires.

Set SOCK_DESTROY immediately after rose_disconnect() so the heartbeat
destroys the socket at its next tick (within 5 s), allowing clean
module unload.

Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/af_rose.c |    5 +++++
 1 file changed, 5 insertions(+)

--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -211,6 +211,11 @@ start:
 		spin_lock_bh(&rose_list_lock);
 		if (rose->device == dev) {
 			rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+			/* Mark for destruction so rose_heartbeat_expiry()
+			 * cleans up the socket at its next tick rather than
+			 * looping forever in ROSE_STATE_0 with no owner.
+			 */
+			sock_set_flag(sk, SOCK_DESTROY);
 			if (rose->neighbour)
 				rose_neigh_put(rose->neighbour);
 			netdev_put(rose->device, &rose->dev_tracker);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 862/877] rose: disconnect orphaned STATE_2 sockets when device is gone
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (860 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 861/877] rose: set SOCK_DESTROY in rose_kill_by_device() for prompt cleanup Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 863/877] rose: fix netdev double-hold in rose_make_new() Greg Kroah-Hartman
                   ` (22 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit d4f4cf9f09a3f5fafa8f09110a7c1b5d10f2f261 upstream.

When ax25stop brings down ROSE interfaces, sockets in ROSE_STATE_2
(awaiting CLEAR CONFIRM) whose device pointer is already NULL are not
reached by rose_kill_by_device() and wait for T3 (up to 180s) before
self-cleaning via rose_timer_expiry().  This keeps the rose module
usecount at 1, blocking rmmod for the full T3 duration.

In rose_heartbeat_expiry(), detect ROSE_STATE_2 sockets with no device,
cancel T3, release the neighbour reference, and call rose_disconnect()
+ sock_set_flag(SOCK_DESTROY).  The next heartbeat tick (<=5s) then
destroys the socket via the existing ROSE_STATE_0/SOCK_DESTROY path,
allowing clean module unload within 10s instead of up to 180s.

Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/rose_timer.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)

--- a/net/rose/rose_timer.c
+++ b/net/rose/rose_timer.c
@@ -139,6 +139,20 @@ static void rose_heartbeat_expiry(struct
 		}
 		break;
 
+	case ROSE_STATE_2:
+		/* Device gone before CLEAR CONFIRM arrived: stop waiting for T3
+		 * and disconnect now instead of blocking rmmod for up to 180s. */
+		if (!rose->device) {
+			rose_stop_timer(sk);
+			if (rose->neighbour) {
+				rose_neigh_put(rose->neighbour);
+				rose->neighbour = NULL;
+			}
+			rose_disconnect(sk, ENETDOWN, -1, -1);
+			sock_set_flag(sk, SOCK_DESTROY);
+		}
+		break;
+
 	case ROSE_STATE_3:
 		/*
 		 * Check for the state of the receive buffer.



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 863/877] rose: fix netdev double-hold in rose_make_new()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (861 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 862/877] rose: disconnect orphaned STATE_2 sockets when device is gone Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 864/877] rose: release netdev ref and destroy orphaned incoming sockets Greg Kroah-Hartman
                   ` (21 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit b9fb21ceb4f0d043767a1eba60786ec84809033b upstream.

rose_make_new() copies orose->device from the listener socket and calls
netdev_hold(), storing the tracker in rose->dev_tracker.  The only
caller, rose_rx_call_request(), then overwrites both make_rose->device
and make_rose->dev_tracker with a fresh netdev_hold() for the actual
incoming-call device.

This orphans the tracker allocated by rose_make_new(): it remains in
the device's refcount_tracker list but no pointer exists to free it
via netdev_put().  The result is one spurious outstanding reference per
accepted CALL_REQUEST, visible at rmmod time as:

  ref_tracker: netdev@X has 2/2 users at
      rose_rx_call_request+0xba3/0x1d50 [rose]
      rose_loopback_timer+0x3eb/0x670 [rose]

The second entry is the orphaned tracker from rose_make_new(); the
first is the correctly-managed socket reference from rose_rx_call_request().

Fix: initialise rose->device to NULL in rose_make_new() and let
rose_rx_call_request() -- the sole caller -- assign the correct device
and take the sole netdev_hold() as it already does.

Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/af_rose.c |    4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -631,9 +631,7 @@ static struct sock *rose_make_new(struct
 	rose->hb	= orose->hb;
 	rose->idle	= orose->idle;
 	rose->defer	= orose->defer;
-	rose->device	= orose->device;
-	if (rose->device)
-		netdev_hold(rose->device, &rose->dev_tracker, GFP_ATOMIC);
+	rose->device	= NULL;  /* rose_rx_call_request() sets this */
 	rose->qbitincl	= orose->qbitincl;
 
 	return sk;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 864/877] rose: release netdev ref and destroy orphaned incoming sockets
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (862 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 863/877] rose: fix netdev double-hold in rose_make_new() Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-10-01  9:42   ` Bernard Pidoux
  2026-09-30 15:29 ` [PATCH 6.12 865/877] rose: drop CALL_REQUEST in loopback timer when device is not running Greg Kroah-Hartman
                   ` (20 subsequent siblings)
  884 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit df12be096302d2c947388acc25764456c7f18cc1 upstream.

Two related cleanup gaps left the module unremovable after a loopback
session:

1. rose_destroy_socket() did not release the device reference.  When
   an unaccepted incoming socket (created by rose_rx_call_request()) is
   destroyed via rose_heartbeat_expiry(), it is removed from rose_list
   before rose_kill_by_device() can find it, so the netdev_hold() taken
   in rose_rx_call_request() was never matched by netdev_put().  Add the
   release at the top of rose_destroy_socket() guarded by a NULL check
   so that rose_release() and rose_kill_by_device(), which already call
   netdev_put() and set device = NULL, are not affected.

2. rose_heartbeat_expiry() STATE_0 cleanup required TCP_LISTEN in
   addition to SOCK_DEAD.  Unaccepted incoming sockets are
   TCP_ESTABLISHED, so the condition was never true and those sockets
   lingered forever, holding the module use count above zero and
   blocking rmmod.  Drop the TCP_LISTEN restriction: any STATE_0 +
   SOCK_DEAD socket is orphaned and should be destroyed.

Together with the earlier rose_make_new() double-hold fix these three
patches allow clean rmmod after loopback sessions.

Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/af_rose.c    |    9 +++++++++
 net/rose/rose_timer.c |    9 +++++----
 2 files changed, 14 insertions(+), 4 deletions(-)

--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -363,6 +363,7 @@ static void rose_destroy_timer(struct ti
  */
 void rose_destroy_socket(struct sock *sk)
 {
+	struct rose_sock *rose = rose_sk(sk);
 	struct sk_buff *skb;
 
 	rose_remove_socket(sk);
@@ -370,6 +371,14 @@ void rose_destroy_socket(struct sock *sk
 	rose_stop_idletimer(sk);
 	rose_stop_timer(sk);
 
+	/* Drop any device reference not already released by rose_kill_by_device()
+	 * or rose_release() -- e.g. incoming sockets that were never accepted.
+	 */
+	if (rose->device) {
+		netdev_put(rose->device, &rose->dev_tracker);
+		rose->device = NULL;
+	}
+
 	rose_clear_queues(sk);		/* Flush the queues */
 
 	while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
--- a/net/rose/rose_timer.c
+++ b/net/rose/rose_timer.c
@@ -128,10 +128,11 @@ static void rose_heartbeat_expiry(struct
 	}
 	switch (rose->state) {
 	case ROSE_STATE_0:
-		/* Magic here: If we listen() and a new link dies before it
-		   is accepted() it isn't 'dead' so doesn't get removed. */
-		if (sock_flag(sk, SOCK_DESTROY) ||
-		    (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) {
+		/* Destroy any orphaned STATE_0 socket: either explicitly
+		 * flagged SOCK_DESTROY, or SOCK_DEAD (covers both unaccepted
+		 * incoming connections and listening sockets whose link died).
+		 */
+		if (sock_flag(sk, SOCK_DESTROY) || sock_flag(sk, SOCK_DEAD)) {
 			bh_unlock_sock(sk);
 			rose_destroy_socket(sk);
 			sock_put(sk);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 865/877] rose: drop CALL_REQUEST in loopback timer when device is not running
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (863 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 864/877] rose: release netdev ref and destroy orphaned incoming sockets Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 866/877] rose: cancel neighbour timers in rose_neigh_put() before freeing Greg Kroah-Hartman
                   ` (19 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit cf5567a2652e44866eae8987dff4c1ea507680df upstream.

When ax25stop brings down rose0 while the loopback timer has pending
CALL_REQUEST frames, rose_loopback_timer() calls rose_dev_get() and
finds the device still registered (unregister_netdevice waits for
refs to drop), then calls rose_rx_call_request() which takes a
netdev_hold() for the new socket.

But NETDEV_DOWN fires only once: rose_kill_by_device() already ran
before this timer tick, so the new socket is never cleaned up.  The
stuck reference prevents unregister_netdevice from completing, and the
orphan socket's timers eventually fire on freed memory (KASAN
slab-use-after-free in __run_timers).

The kernel clears IFF_UP via dev_close() before sending NETDEV_DOWN,
so checking netif_running() after rose_dev_get() is sufficient: if the
device is no longer running, the CALL_REQUEST is silently dropped and
no socket is created.  This closes the race without touching the
module-exit path (which already stops the timer via loopback_stopping).

Tested: unregister_netdevice completes immediately after ax25stop with
active loopback connections; no ref_tracker warnings, no KASAN.

Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/rose_loopback.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

--- a/net/rose/rose_loopback.c
+++ b/net/rose/rose_loopback.c
@@ -118,6 +118,16 @@ static void rose_loopback_timer(struct t
 				kfree_skb(skb);
 				continue;
 			}
+			/* rose_kill_by_device() runs on NETDEV_DOWN (IFF_UP cleared)
+			 * before the device is unregistered.  If we create a new
+			 * socket here after that cleanup, the ref never gets released
+			 * because NETDEV_DOWN fires only once.  Drop the call instead.
+			 */
+			if (!netif_running(dev)) {
+				dev_put(dev);
+				kfree_skb(skb);
+				continue;
+			}
 
 			if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0)
 				kfree_skb(skb);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 866/877] rose: cancel neighbour timers in rose_neigh_put() before freeing
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (864 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 865/877] rose: drop CALL_REQUEST in loopback timer when device is not running Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 867/877] rose: clear neighbour pointer in rose_kill_by_device() Greg Kroah-Hartman
                   ` (18 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit 9b222cb1d23ff210975e9df5ebab7b011acb6fad upstream.

rose_neigh_put() kfree()s the neighbour but never cancels its ftimer and
t0timer. Until now every caller that dropped the final reference first
called rose_remove_neigh(), which deletes those timers. The socket
heartbeat reaping path drops the last reference directly, so a neighbour
could be freed with t0timer still armed -- it re-arms itself in
rose_t0timer_expiry() -- leading to a use-after-free write in
enqueue_timer().

Cancel both timers with timer_delete_sync() (the synchronous variant, to
wait out a concurrently running, self-rearming handler) in the
refcount-zero branch of rose_neigh_put().

Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 include/net/rose.h |   12 ++++++++++++
 1 file changed, 12 insertions(+)

--- a/include/net/rose.h
+++ b/include/net/rose.h
@@ -160,6 +160,18 @@ static inline void rose_neigh_hold(struc
 static inline void rose_neigh_put(struct rose_neigh *rose_neigh)
 {
 	if (refcount_dec_and_test(&rose_neigh->use)) {
+		/* We are dropping the last reference, so we are about to free the
+		 * neighbour.  Its timers may still be armed -- t0timer in particular
+		 * re-arms itself in rose_t0timer_expiry().  rose_remove_neigh()
+		 * cancels them before its own put, but callers that drop the final
+		 * reference without first calling rose_remove_neigh() (the socket
+		 * heartbeat reaping path) would otherwise kfree() a neighbour with a
+		 * live timer -> use-after-free.  timer_delete_sync() (not the async
+		 * variant) is required: it waits out a concurrently running handler
+		 * and loops until the self-rearming timer stays stopped.
+		 */
+		timer_delete_sync(&rose_neigh->ftimer);
+		timer_delete_sync(&rose_neigh->t0timer);
 		if (rose_neigh->ax25)
 			ax25_cb_put(rose_neigh->ax25);
 		kfree(rose_neigh->digipeat);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 867/877] rose: clear neighbour pointer in rose_kill_by_device()
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (865 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 866/877] rose: cancel neighbour timers in rose_neigh_put() before freeing Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 868/877] rose: dont free fd-owned sockets when reaping in the heartbeat Greg Kroah-Hartman
                   ` (17 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit 606e42d195b467480d4d405f8814c48d1651a76a upstream.

rose_kill_by_device() drops the neighbour reference but leaves
rose->neighbour pointing at it, unlike every other rose_neigh_put() site
(see "rose: clear neighbour pointer after rose_neigh_put() in state
machines"). The heartbeat STATE_0 reaping path then puts the same
neighbour a second time, causing a rose_neigh refcount underflow and a
use-after-free.

Set rose->neighbour = NULL after the put, restoring the invariant.

Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/af_rose.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -216,8 +216,16 @@ start:
 			 * looping forever in ROSE_STATE_0 with no owner.
 			 */
 			sock_set_flag(sk, SOCK_DESTROY);
-			if (rose->neighbour)
+			if (rose->neighbour) {
 				rose_neigh_put(rose->neighbour);
+				/* Clear the pointer after dropping the reference, as
+				 * every other rose_neigh_put() site does.  Otherwise
+				 * rose_heartbeat_expiry() (STATE_0 reaping) sees a stale
+				 * rose->neighbour and puts it a second time -> rose_neigh
+				 * refcount underflow / use-after-free.
+				 */
+				rose->neighbour = NULL;
+			}
 			netdev_put(rose->device, &rose->dev_tracker);
 			rose->device = NULL;
 		}



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 868/877] rose: dont free fd-owned sockets when reaping in the heartbeat
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (866 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 867/877] rose: clear neighbour pointer in rose_kill_by_device() Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 869/877] drm/amdgpu: fix ring timeout issue in gfx10 sr-iov environment Greg Kroah-Hartman
                   ` (16 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Bernard Pidoux <bernard.f6bvp@gmail.com>

commit 56576518920edd7b6c3479477d8d490fe2ebdaaa upstream.

The heartbeat reaps orphaned ROSE sockets after their bound device goes
down. A socket still attached to a struct socket (sk->sk_socket != NULL --
e.g. an incoming connection an fpad client has accepted and kept open) is
owned by that userspace fd: rose_release() frees it on close(). Freeing it
from the heartbeat left the fd dangling, so the eventual close() touched
freed memory -- slab-use-after-free in rose_release().

Reap only sockets with sk->sk_socket == NULL (unaccepted incoming
connections and post-close orphans). For an fd-owned socket whose device
went down, disconnect it and fall through to the switch so close() does
the teardown. Also release the neighbour reference held by orphaned
incoming sockets before tearing them down.

Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/rose/rose_timer.c |   57 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)

--- a/net/rose/rose_timer.c
+++ b/net/rose/rose_timer.c
@@ -126,13 +126,68 @@ static void rose_heartbeat_expiry(struct
 		sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ/20);
 		goto out;
 	}
+
+	/* The bound device went down while we still hold a reference on it.
+	 * This catches the narrow race where rose_loopback_timer() created a
+	 * socket in the window after rose_kill_by_device()'s NETDEV_DOWN sweep
+	 * but before rose_insert_socket() -- leaving a STATE_3 socket that no
+	 * other branch reaps.  A down device means the link is dead, so tear
+	 * the socket down regardless of state.  rose_destroy_socket() releases
+	 * the held netdev reference (rose->device still set).
+	 */
+	if (rose->device && !netif_running(rose->device)) {
+		if (rose->neighbour) {
+			rose_neigh_put(rose->neighbour);
+			rose->neighbour = NULL;
+		}
+		rose_disconnect(sk, ENETDOWN, -1, -1);
+
+		/* Only reap the socket if userspace no longer holds it.  A socket
+		 * still attached to a struct socket (sk->sk_socket != NULL -- e.g.
+		 * a connection an fpad client has accepted and kept open) is owned
+		 * by that fd: rose_release() will destroy it on close().  Dropping
+		 * the last reference here leaves the open fd dangling, so the
+		 * eventual close() touches freed memory -> slab-use-after-free in
+		 * rose_release().  Unaccepted incoming sockets and post-close
+		 * orphans have sk->sk_socket == NULL and stay safe to reap here.
+		 */
+		if (!sk->sk_socket) {
+			sock_set_flag(sk, SOCK_DESTROY);
+			bh_unlock_sock(sk);
+			rose_destroy_socket(sk);
+			sock_put(sk);
+			return;
+		}
+
+		/* Owned by userspace: the link is down and the socket is now
+		 * disconnected (rose_disconnect() moved it to STATE_0).  Fall
+		 * through to the switch, which re-arms the heartbeat; the close()
+		 * will tear the socket down. */
+	}
+
 	switch (rose->state) {
 	case ROSE_STATE_0:
 		/* Destroy any orphaned STATE_0 socket: either explicitly
 		 * flagged SOCK_DESTROY, or SOCK_DEAD (covers both unaccepted
 		 * incoming connections and listening sockets whose link died).
 		 */
-		if (sock_flag(sk, SOCK_DESTROY) || sock_flag(sk, SOCK_DEAD)) {
+		if ((sock_flag(sk, SOCK_DESTROY) || sock_flag(sk, SOCK_DEAD)) &&
+		    !sk->sk_socket) {
+			/* Reap only orphaned sockets (sk->sk_socket == NULL).  A
+			 * socket still owned by a userspace fd reaches here via the
+			 * STATE_2 device-gone branch, which sets SOCK_DESTROY without
+			 * knowing about the fd; freeing it would race rose_release()
+			 * at close() -> use-after-free.  Leave it for close().
+			 *
+			 * Orphaned incoming sockets (rose_rx_call_request) hold a
+			 * neighbour reference; release it before teardown, as the
+			 * STATE_2 and device-down branches do.  rose_destroy_socket()
+			 * does not drop it.
+			 */
+			if (rose->neighbour) {
+				rose_neigh_put(rose->neighbour);
+				rose->neighbour = NULL;
+			}
 			bh_unlock_sock(sk);
 			rose_destroy_socket(sk);
 			sock_put(sk);



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 869/877] drm/amdgpu: fix ring timeout issue in gfx10 sr-iov environment
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (867 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 868/877] rose: dont free fd-owned sockets when reaping in the heartbeat Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 870/877] nvme: revert the cross-controller atomic write size validation Greg Kroah-Hartman
                   ` (15 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Lin.Cao, Alex Deucher

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Lin.Cao <lincao12@amd.com>

commit b529093999ff052916b35356dc66eddb83258ead upstream.

commit 26c95e838e63 ("drm/amdgpu: set the VM pointer to NULL in
amdgpu_job_prepare") set job->vm as NULL if there is no fence. It will
cause emit switch buffer be skippen if job->vm set as NULL.

Check job rather than vm could solve this problem.

Fixes: 26c95e838e63 ("drm/amdgpu: set the VM pointer to NULL in amdgpu_job_prepare")
Signed-off-by: Lin.Cao <lincao12@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -300,7 +300,7 @@ int amdgpu_ib_schedule(struct amdgpu_rin
 	amdgpu_ring_patch_cond_exec(ring, cond_exec);
 
 	ring->current_ctx = fence_ctx;
-	if (vm && ring->funcs->emit_switch_buffer)
+	if (job && ring->funcs->emit_switch_buffer)
 		amdgpu_ring_emit_switch_buffer(ring);
 
 	if (ring->funcs->emit_wave_limit &&



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 870/877] nvme: revert the cross-controller atomic write size validation
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (868 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 869/877] drm/amdgpu: fix ring timeout issue in gfx10 sr-iov environment Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 871/877] bootconfig: Fix negative seeks on 32-bit with LFS enabled Greg Kroah-Hartman
                   ` (14 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Alan Adamson,
	Keith Busch, John Garry, Chaitanya Kulkarni

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Christoph Hellwig <hch@lst.de>

commit 1fc09f2961f5c6d8bb53bc989f17b12fdc6bc93d upstream.

This was originally added by commit 8695f060a029 ("nvme: all namespaces
in a subsystem must adhere to a common atomic write size") to check
the all controllers in a subsystem report the same atomic write size,
but the check wasn't quite correct and caused problems for devices
with multiple namespaces that report different LBA sizes.  Commit
f46d273449ba ("nvme: fix atomic write size validation") tried to fix
this, but then caused problems for namespace rediscovery after a
format with an LBA size change that changes the AWUPF value.

This drops the validation and essentially reverts those two commits while
keeping the cleanup that went in between the two.  We'll need to figure
out how to properly check for the mouse trap that nvme left us, but for
now revert the check to keep devices working for users who couldn't care
less about the atomic write feature.

Fixes: 8695f060a029 ("nvme: all namespaces in a subsystem must adhere to a common atomic write size")
Fixes: f46d273449ba ("nvme: fix atomic write size validation")
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Alan Adamson <alan.adamson@oracle.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Tested-by: Alan Adamson <alan.adamson@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/nvme/host/core.c |    9 ---------
 1 file changed, 9 deletions(-)

--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -3373,15 +3373,6 @@ static int nvme_init_identify(struct nvm
 		if (ret)
 			goto out_free;
 	}
-
-	if (le16_to_cpu(id->awupf) != ctrl->subsys->awupf) {
-		dev_err_ratelimited(ctrl->device,
-			"inconsistent AWUPF, controller not added (%u/%u).\n",
-			le16_to_cpu(id->awupf), ctrl->subsys->awupf);
-		ret = -EINVAL;
-		goto out_free;
-	}
-
 	memcpy(ctrl->subsys->firmware_rev, id->fr,
 	       sizeof(ctrl->subsys->firmware_rev));
 



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 871/877] bootconfig: Fix negative seeks on 32-bit with LFS enabled
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (869 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 870/877] nvme: revert the cross-controller atomic write size validation Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 872/877] tracing: Move d_max_latency out of CONFIG_FSNOTIFY protection Greg Kroah-Hartman
                   ` (13 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Ben Hutchings,
	Masami Hiramatsu (Google)

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ben Hutchings <benh@debian.org>

commit 729dc340a4ed1267774fc8518284e976e2210bdc upstream.

Commit 26dda5769509 "tools/bootconfig: Cleanup bootconfig footer size
calculations" replaced some expressions of type int with the
BOOTCONFIG_FOOTER_SIZE macro, which expands to an expression of type
size_t, which is unsigned.

On 32-bit architectures with LFS enabled (i.e. off_t is 64-bit), the
seek offset of -BOOTCONFIG_FOOTER_SIZE now turns into a positive
value.

Fix this by casting the size to off_t before negating it.

Just in case someone changes BOOTCONFIG_MAGIC_LEN to have type size_t
later, do the same thing to the seek offset of -BOOTCONFIG_MAGIC_LEN.

Link: https://lore.kernel.org/all/aKHlevxeg6Y7UQrz@decadent.org.uk/

Fixes: 26dda5769509 ("tools/bootconfig: Cleanup bootconfig footer size calculations")
Signed-off-by: Ben Hutchings <benh@debian.org>
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 tools/bootconfig/main.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/tools/bootconfig/main.c
+++ b/tools/bootconfig/main.c
@@ -205,7 +205,7 @@ static int load_xbc_from_initrd(int fd,
 	if (stat.st_size < BOOTCONFIG_FOOTER_SIZE)
 		return 0;
 
-	if (lseek(fd, -BOOTCONFIG_MAGIC_LEN, SEEK_END) < 0)
+	if (lseek(fd, -(off_t)BOOTCONFIG_MAGIC_LEN, SEEK_END) < 0)
 		return pr_errno("Failed to lseek for magic", -errno);
 
 	if (read(fd, magic, BOOTCONFIG_MAGIC_LEN) < 0)
@@ -215,7 +215,7 @@ static int load_xbc_from_initrd(int fd,
 	if (memcmp(magic, BOOTCONFIG_MAGIC, BOOTCONFIG_MAGIC_LEN) != 0)
 		return 0;
 
-	if (lseek(fd, -BOOTCONFIG_FOOTER_SIZE, SEEK_END) < 0)
+	if (lseek(fd, -(off_t)BOOTCONFIG_FOOTER_SIZE, SEEK_END) < 0)
 		return pr_errno("Failed to lseek for size", -errno);
 
 	if (read(fd, &size, sizeof(uint32_t)) < 0)



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 872/877] tracing: Move d_max_latency out of CONFIG_FSNOTIFY protection
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (870 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 871/877] bootconfig: Fix negative seeks on 32-bit with LFS enabled Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 873/877] mtd: rawnand: pl353: Fix debug prints Greg Kroah-Hartman
                   ` (12 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Masami Hiramatsu, Mathieu Desnoyers,
	kernel test robot, Steven Rostedt (Google)

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Steven Rostedt <rostedt@goodmis.org>

commit b4bade506b18eb2e5e34ac84f915d7ee6156d4e2 upstream.

The tracing_max_latency shouldn't be limited if CONFIG_FSNOTIFY is defined
or not and it was moved out of that protection to be always available with
CONFIG_TRACER_MAX_TRACE. All was moved out except the dentry descriptor
for it (d_max_latency) and it failed to build on some configs.

Move that out of the CONFIG_FSNOTIFY protection too.

Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Link: https://patch.msgid.link/20260209194631.788bfc85@fedora
Fixes: ba73713da50e ("tracing: Clean up use of trace_create_maxlat_file()")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202602092133.fTdojd95-lkp@intel.com/
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/trace/trace.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -341,8 +341,8 @@ struct trace_array {
 	spinlock_t		snapshot_trigger_lock;
 	unsigned int		snapshot;
 	unsigned long		max_latency;
-#ifdef CONFIG_FSNOTIFY
 	struct dentry		*d_max_latency;
+#ifdef CONFIG_FSNOTIFY
 	struct work_struct	fsnotify_work;
 	struct irq_work		fsnotify_irqwork;
 #endif



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 873/877] mtd: rawnand: pl353: Fix debug prints
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (871 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 872/877] tracing: Move d_max_latency out of CONFIG_FSNOTIFY protection Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 874/877] platform/x86/amd/pmc: Fix LPS0 and debugfs leaks when STB init fails Greg Kroah-Hartman
                   ` (11 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable; +Cc: Greg Kroah-Hartman, patches, Miquel Raynal (DAVE), Michal Simek

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Miquel Raynal (DAVE) <miquel.raynal@bootlin.com>

commit 2b7baaddf1bc3e39206a0354449fdc349945b86b upstream.

They are partially incorrect since "software" engine does not mean
hamming, the "none" cae is also falling into this print, and on-die
means there is some kind of hardware support; we prefer to use the
wording on-host vs. on-die.

Fix all those prints.

Fixes: 1e06dbfdfb85 ("mtd: rawnand: pl353: Add message about ECC mode")
Signed-off-by: Miquel Raynal (DAVE) <miquel.raynal@bootlin.com>
Acked-by: Michal Simek <michal.simek@amd.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/mtd/nand/raw/pl35x-nand-controller.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

--- a/drivers/mtd/nand/raw/pl35x-nand-controller.c
+++ b/drivers/mtd/nand/raw/pl35x-nand-controller.c
@@ -972,17 +972,19 @@ static int pl35x_nand_attach_chip(struct
 
 	switch (chip->ecc.engine_type) {
 	case NAND_ECC_ENGINE_TYPE_ON_DIE:
-		dev_dbg(nfc->dev, "Using on-die ECC\n");
+		dev_dbg(nfc->dev, "Using on-die hardware ECC\n");
 		/* Keep these legacy BBT descriptors for ON_DIE situations */
 		chip->bbt_td = &bbt_main_descr;
 		chip->bbt_md = &bbt_mirror_descr;
 		fallthrough;
 	case NAND_ECC_ENGINE_TYPE_NONE:
+		dev_dbg(nfc->dev, "Using no ECC engine\n");
+		break;
 	case NAND_ECC_ENGINE_TYPE_SOFT:
-		dev_dbg(nfc->dev, "Using software ECC (Hamming 1-bit/512B)\n");
+		dev_dbg(nfc->dev, "Using software ECC\n");
 		break;
 	case NAND_ECC_ENGINE_TYPE_ON_HOST:
-		dev_dbg(nfc->dev, "Using hardware ECC\n");
+		dev_dbg(nfc->dev, "Using on-host hardware ECC\n");
 		ret = pl35x_nand_init_hw_ecc_controller(nfc, chip);
 		if (ret)
 			return ret;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 874/877] platform/x86/amd/pmc: Fix LPS0 and debugfs leaks when STB init fails
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (872 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 873/877] mtd: rawnand: pl353: Fix debug prints Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 875/877] usb: dwc3: gadget: Fix use-after-free in dwc3_gadget_free_endpoints due to race condition Greg Kroah-Hartman
                   ` (10 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Francis De Brabandere,
	Mario Limonciello, Ilpo Järvinen

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Mario Limonciello <mario.limonciello@amd.com>

commit 76f650a76d6a36a4bee79d94db90a0e935a95477 upstream.

amd_pmc_probe() registers the LPS0 s2idle handler with
acpi_register_lps0_dev() and creates the driver's debugfs directory before
calling amd_stb_s2d_init(), which is the last step in probe that can fail.

When amd_stb_s2d_init() fails (for example the S2D telemetry region cannot
be ioremapped on a long-running system, or the SMU rejects the S2D setup)
the error path only calls pci_dev_put() and returns.  This leaves
amd_pmc_s2idle_dev_ops on the global lps0_s2idle_devops_head list and leaks
the debugfs directory, while the devm-managed resources backing the handler
are torn down.

Reloading the module then walks the corrupted list in
acpi_register_lps0_dev() and hits:

  list_add corruption. next->prev should be prev, but was NULL.
  kernel BUG at lib/list_debug.c:29!
   acpi_register_lps0_dev+0x44/0x80
   amd_pmc_probe+0x224/0x380 [amd_pmc]
   platform_probe+0x67/0x90

Even without a reload, the stale registration means the next s2idle
transition calls into torn-down driver state.

Unwind the debugfs directory and the LPS0 registration on the
amd_stb_s2d_init() error path.  acpi_unregister_lps0_dev() is safe to call
unconditionally here: it is guarded on the same conditions as
acpi_register_lps0_dev(), which is exactly what amd_pmc_remove() already
relies on.

Reported-by: Francis De Brabandere <francisdb@gmail.com>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221759
Tested-by: Francis De Brabandere <francisdb@gmail.com>
Fixes: 83ad6974dd3b ("platform/x86/amd/pmc: Move STB block into amd_pmc_s2d_init()")
Cc: stable@vger.kernel.org
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://patch.msgid.link/20260721181756.143084-6-mario.limonciello@amd.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/platform/x86/amd/pmc/pmc.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

--- a/drivers/platform/x86/amd/pmc/pmc.c
+++ b/drivers/platform/x86/amd/pmc/pmc.c
@@ -933,13 +933,17 @@ static int amd_pmc_probe(struct platform
 	amd_pmc_dbgfs_register(dev);
 	err = amd_stb_s2d_init(dev);
 	if (err)
-		goto err_pci_dev_put;
+		goto err_dbgfs_unregister;
 
 	if (IS_ENABLED(CONFIG_AMD_MP2_STB))
 		amd_mp2_stb_init(dev);
 	pm_report_max_hw_sleep(U64_MAX);
 	return 0;
 
+err_dbgfs_unregister:
+	amd_pmc_dbgfs_unregister(dev);
+	if (IS_ENABLED(CONFIG_SUSPEND))
+		acpi_unregister_lps0_dev(&amd_pmc_s2idle_dev_ops);
 err_pci_dev_put:
 	pci_dev_put(rdev);
 	return err;



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 875/877] usb: dwc3: gadget: Fix use-after-free in dwc3_gadget_free_endpoints due to race condition
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (873 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 874/877] platform/x86/amd/pmc: Fix LPS0 and debugfs leaks when STB init fails Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 876/877] bpf: Reject key-less BTF for hash maps Greg Kroah-Hartman
                   ` (9 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Thinh Nguyen, Pei Xiao,
	Radhey Shyam Pandey

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Pei Xiao <xiaopei01@kylinos.cn>

commit 9c855832790cd488d87de1885974f4c37cfe7358 upstream.

In dwc3_gadget_init_endpoint, &dep->nostream_work is bound with
dwc3_nostream_work, and dwc3_gadget_endpoint_stream_event can queue
this delayed work on system_percpu_wq when a DEPEVT_STREAM_NOSTREAM
event is received.

If we remove the gadget, dwc3_gadget_free_endpoints makes cleanup and
the memory allocated for dep with kzalloc() is released by kfree(dep),
while the delayed work mentioned above may still be pending or
running. The sequence of operations that may lead to a UAF bug is as
follows:

CPU0                                      CPU1

                                          | dwc3_thread_interrupt
                                          | dwc3_endpoint_interrupt
                                          | dwc3_gadget_endpoint_stream_event
                                          | queue_delayed_work(system_percpu_wq,
                                          |                    &dep->nostream_work)
dwc3_gadget_free_endpoints                |
dwc3_free_trb_pool(dep)                   |
list_del(&dep->endpoint.ep_list)          |
dwc3_debugfs_remove_endpoint_dir(dep)     |
kfree(dep)                                |
// dep is freed                           |
                                          | dwc3_nostream_work
                                          | // use dep (use-after-free)

Fix it by canceling the delayed work before kfree(dep) in
dwc3_gadget_free_endpoints.

Fixes: dcfe437492e2 ("usb: dwc3: gadget: Reinitiate stream for all host NoStream behavior")
Assisted-by: Codex:deepseek-v4-flash
Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Cc: stable@vger.kernel.org
Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
Link: https://patch.msgid.link/331d1d5133496d2b4184e05f8848adb06930a138.1785893865.git.xiaopei01@kylinos.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/dwc3/gadget.c |    1 +
 1 file changed, 1 insertion(+)

--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -3450,6 +3450,7 @@ static void dwc3_gadget_free_endpoints(s
 		}
 
 		dwc3_debugfs_remove_endpoint_dir(dep);
+		cancel_delayed_work_sync(&dep->nostream_work);
 		kfree(dep);
 	}
 }



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 876/877] bpf: Reject key-less BTF for hash maps
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (874 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 875/877] usb: dwc3: gadget: Fix use-after-free in dwc3_gadget_free_endpoints due to race condition Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 15:29 ` [PATCH 6.12 877/877] mm/hugetlb: keep max_huge_pages when dissolving surplus folios Greg Kroah-Hartman
                   ` (8 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, syzbot+37b56485bbbf90ad8489,
	Jiayuan Chen, Ihor Solodrai, Alexei Starovoitov

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Jiayuan Chen <jiayuan.chen@linux.dev>

commit 0895a0c0734703be5532f3883c42db95615fd98b upstream.

map_check_btf() allows a key-less BTF (btf_key_type_id == 0) only for
maps that have a ->map_check_btf callback, and leaves the actual
decision to that callback. Hash maps used to have no ->map_check_btf,
so a key-less BTF was rejected outright.

That changed when htab and rhtab gained a ->map_check_btf to register a
dtor - htab in commit 1df97a7453ee ("bpf: Register dtor for freeing
special fields") and rhtab in commit 6905f8601298 ("bpf: Allow special
fields in resizable hashtab"). Neither looks at the key, so a key-less
hash map now passes map_check_btf() and gets created. Reading it back
through bpffs feeds the key type_id 0 into btf_type_seq_show();
btf_type_by_id() returns the void type, kind_ops[BTF_KIND_UNKN] is NULL,
and btf_type_show() dereferences it:

RIP: 0010:btf_type_show+0x223/0x2e0 kernel/bpf/btf.c:8232
RSP: 0018:ffffc9000399f868 EFLAGS: 00010206
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: 0000000000000005 RSI: 0000000000000000 RDI: 0000000000000028
RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000
R10: ffffc9000399f970 R11: 0000000000000001 R12: ffffffff9b96b140
R13: ffffc9000399f8e0 R14: ffff88803d393c00 R15: 0000000000000003
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000200000000000 CR3: 000000003d213000 CR4: 0000000000352ef0
DR0: 0000000039ae8f55 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Call Trace:
 <TASK>
 btf_type_seq_show_flags+0xca/0x120 kernel/bpf/btf.c:8250
 htab_map_seq_show_elem+0x12e/0x350 kernel/bpf/hashtab.c:1669
 map_seq_show+0x13d/0x1e0 kernel/bpf/inode.c:293
 traverse.part.0.constprop.0+0x107/0x650 fs/seq_file.c:112
 traverse fs/seq_file.c:99 [inline]
 seq_read_iter+0x93f/0x1270 fs/seq_file.c:196
 seq_read+0x344/0x4d0 fs/seq_file.c:163
 vfs_read+0x1e4/0xb40 fs/read_write.c:572
 ksys_pread64 fs/read_write.c:764 [inline]
 __do_sys_pread64 fs/read_write.c:772 [inline]
 __se_sys_pread64 fs/read_write.c:769 [inline]
 __x64_sys_pread64+0x1eb/0x250 fs/read_write.c:769
 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
 do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

Reject a key-less BTF in htab_map_check_btf() and rhtab_map_check_btf(),
restoring the previous behavior.

Fixes: 1df97a7453ee ("bpf: Register dtor for freeing special fields")
Fixes: 6905f8601298 ("bpf: Allow special fields in resizable hashtab")
Reported-by: syzbot+37b56485bbbf90ad8489@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/6a8f4e88.27659fcc.2ceef7.0008.GAE@google.com/T/
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Link: https://lore.kernel.org/r/20260901104924.346187-2-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/bpf/hashtab.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -546,6 +546,9 @@ static int htab_map_check_btf(const stru
 {
 	struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
 
+	if (btf_type_is_void(key_type))
+		return -EINVAL;
+
 	if (htab_is_prealloc(htab))
 		return 0;
 	/*



^ permalink raw reply	[flat|nested] 922+ messages in thread

* [PATCH 6.12 877/877] mm/hugetlb: keep max_huge_pages when dissolving surplus folios
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (875 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 876/877] bpf: Reject key-less BTF for hash maps Greg Kroah-Hartman
@ 2026-09-30 15:29 ` Greg Kroah-Hartman
  2026-09-30 19:08 ` [PATCH 6.12 000/877] 6.12.112-rc1 review Florian Fainelli
                   ` (7 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-30 15:29 UTC (permalink / raw)
  To: stable
  Cc: Greg Kroah-Hartman, patches, Longlong Xia, Muchun Song,
	David Hildenbrand, Jinjiang Tu, Oscar Salvador, Andrew Morton

6.12-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Longlong Xia <xialonglong@kylinos.cn>

commit 267bede12d3b108ca29997ce280e927a570ec97f upstream.

dissolve_free_hugetlb_folio() can remove a free folio as surplus when its
node has surplus pages.  In that case remove_hugetlb_folio() decrements
both nr_huge_pages and surplus_huge_pages, leaving the persistent pool
size unchanged.

Updating max_huge_pages as if a persistent folio had been removed can
therefore corrupt the persistent pool target and underflow it when
max_huge_pages is zero.  Keep max_huge_pages unchanged for surplus folios,
including the vmemmap restoration rollback path.

Link: https://lore.kernel.org/20260814083027.1419487-1-xialonglong2025@163.com
Fixes: cb402bbdabca ("mm/hugetlb: fix surplus pages in dissolve_free_huge_page()")
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Longlong Xia <xialonglong@kylinos.cn>
Reviewed-by: Muchun Song <muchun.song@linux.dev>
Cc: David Hildenbrand <david@kernel.org>
Cc: Jinjiang Tu <tujinjiang@huawei.com>
Cc: Longlong Xia <xialonglong@kylinos.cn>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 mm/hugetlb.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2248,7 +2248,8 @@ retry:
 		if (h->surplus_huge_pages_node[folio_nid(folio)])
 			adjust_surplus = true;
 		remove_hugetlb_folio(h, folio, adjust_surplus);
-		h->max_huge_pages--;
+		if (!adjust_surplus)
+			h->max_huge_pages--;
 		spin_unlock_irq(&hugetlb_lock);
 
 		/*
@@ -2268,7 +2269,8 @@ retry:
 			if (rc) {
 				spin_lock_irq(&hugetlb_lock);
 				add_hugetlb_folio(h, folio, adjust_surplus);
-				h->max_huge_pages++;
+				if (!adjust_surplus)
+					h->max_huge_pages++;
 				goto out;
 			}
 		} else



^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 000/877] 6.12.112-rc1 review
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (876 preceding siblings ...)
  2026-09-30 15:29 ` [PATCH 6.12 877/877] mm/hugetlb: keep max_huge_pages when dissolving surplus folios Greg Kroah-Hartman
@ 2026-09-30 19:08 ` Florian Fainelli
  2026-09-30 22:35 ` Peter Schneider
                   ` (6 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Florian Fainelli @ 2026-09-30 19:08 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
	lkft-triage, pavel, jonathanh, sudipm.mukherjee, rwarsow, conor,
	hargar, broonie, achill, sr



On 9/30/2026 8:15 AM, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 6.12.112 release.
> There are 877 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 Fri, 02 Oct 2026 15:23:04 +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.12.112-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.12.y
> and the diffstat can be found below.
> 
> thanks,
> 
> greg k-h

On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on 
BMIPS_GENERIC:

Tested-by: Florian Fainelli <florian.fainelli@broadcom.com>
-- 
Florian


^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 000/877] 6.12.112-rc1 review
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (877 preceding siblings ...)
  2026-09-30 19:08 ` [PATCH 6.12 000/877] 6.12.112-rc1 review Florian Fainelli
@ 2026-09-30 22:35 ` Peter Schneider
  2026-10-01  5:25 ` Barry K. Nathan
                   ` (5 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Peter Schneider @ 2026-09-30 22:35 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
	lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
	rwarsow, conor, hargar, broonie, achill, sr

Am 30.09.2026 um 17:15 schrieb Greg Kroah-Hartman:
> This is the start of the stable review cycle for the 6.12.112 release.
> There are 877 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.

Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697v2 server. No dmesg oddities or regressions found.

Tested-by: Peter Schneider <pschneider1968@googlemail.com>


Beste Grüße,
Peter Schneider

-- 
Climb the mountain not to plant your flag, but to embrace the challenge,
enjoy the air and behold the view. Climb it so you can see the world,
not so the world can see you.                    -- David McCullough Jr.

OpenPGP:  0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244
Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc
https://keys.mailvelope.com/pks/lookup?op=get&search=pschneider1968@googlemail.com
https://keys.mailvelope.com/pks/lookup?op=get&search=pschneider1968@gmail.com

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 000/877] 6.12.112-rc1 review
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (878 preceding siblings ...)
  2026-09-30 22:35 ` Peter Schneider
@ 2026-10-01  5:25 ` Barry K. Nathan
  2026-10-01  9:17 ` Pavel Machek
                   ` (4 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Barry K. Nathan @ 2026-10-01  5:25 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
	lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
	rwarsow, conor, hargar, broonie, achill, sr

On 9/30/26 8:15 AM, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 6.12.112 release.
> There are 877 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 Fri, 02 Oct 2026 15:23:04 +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.12.112-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.12.y
> and the diffstat can be found below.
> 
> thanks,
> 
> greg k-h

Tested on an amd64 laptop (Lenovo ThinkPad T14 Gen 1). Working well,
no regressions observed.

Tested-by: Barry K. Nathan <barryn@pobox.com>

-- 
-Barry K. Nathan  <barryn@pobox.com>

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits when offloading
  2026-09-30 15:22 ` [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits " Greg Kroah-Hartman
@ 2026-10-01  5:27   ` Karl Mehltretter
  2026-10-01 11:31     ` Sasha Levin
  2026-10-01 20:12   ` Harshit Mogalapalli
  1 sibling, 1 reply; 922+ messages in thread
From: Karl Mehltretter @ 2026-10-01  5:27 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Karl Mehltretter, stable, patches, Sabrina Dubroca, Simon Horman,
	Jakub Kicinski, Sasha Levin

I object to this patch as queued. The backport is missing prerequisite
f29d24a2106a ("macsec: clean up local variables in macsec_notify"), so
NETDEV_FEAT_CHANGE dereferences an uninitialized rxd.

Clang 21 reports this in an allmodconfig W=1 build:

  warning: variable 'rxd' is uninitialized when used here
           [-Wuninitialized]

In QEMU, the exact review tip f4ffa8dc360b hits a NULL-pointer oops at
macsec_notify+0x130/0x1e0. With f29d24a2106a applied before this patch,
the same test passes and the MACsec device inherits the changed TSO
limits. A three-device test covering feature changes, MTU changes,
down/up, and unregister also passes. The corrected file builds cleanly
with Clang W=1.

Please add the prerequisite before this patch.

An LLM agent assisted with the review and QEMU A/B testing.

Thanks,
Karl

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 000/877] 6.12.112-rc1 review
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (879 preceding siblings ...)
  2026-10-01  5:25 ` Barry K. Nathan
@ 2026-10-01  9:17 ` Pavel Machek
  2026-10-01 10:06 ` Ron Economos
                   ` (3 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Pavel Machek @ 2026-10-01  9:17 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
	patches, lkft-triage, pavel, jonathanh, f.fainelli,
	sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr

[-- Attachment #1: Type: text/plain, Size: 505 bytes --]

Hi!

> This is the start of the stable review cycle for the 6.12.112 release.
> There are 877 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.

CIP testing did not find any problems here:

https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-6.12.y

Tested-by: Pavel Machek (CIP) <pavel@nabladev.com>

Best regards,
                                                                Pavel

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 864/877] rose: release netdev ref and destroy orphaned incoming sockets
  2026-09-30 15:29 ` [PATCH 6.12 864/877] rose: release netdev ref and destroy orphaned incoming sockets Greg Kroah-Hartman
@ 2026-10-01  9:42   ` Bernard Pidoux
  2026-10-01 11:31     ` Sasha Levin
  0 siblings, 1 reply; 922+ messages in thread
From: Bernard Pidoux @ 2026-10-01  9:42 UTC (permalink / raw)
  To: gregkh; +Cc: stable, patches, kuba

Hi Greg,

Thanks a lot for queuing the ROSE series for 6.12.y and the four extra
fixes for 6.18.y.

One heads-up on this particular patch (commit df12be096302), before the
6.12.y release goes out: since it was written I have found a regression
in it, and the fix is not merged yet.

The problem: with this patch, rose_heartbeat_expiry() reaps an incoming
socket that was cleared by the caller before accept(). But the skb of
that call is still on the listening socket's receive queue, with
skb->sk pointing at the socket that has just been freed (no reference
is held for the queue). Then:

- closing the listening socket makes rose_destroy_socket() walk the
queue and touch the freed socket, or
- accept() can hand the freed socket to user space.

I hit it on 26 September on one of my live nodes, on a 6.12.94 KASAN
kernel carrying this series, while stopping the FPAC daemons:

BUG: KASAN: slab-use-after-free in rose_destroy_socket+0x24a/0x570 [rose]
Write of size 8 ... by task fpacwpd
rose_destroy_socket
rose_release
Allocated by task 0: ... rose_rx_call_request <- rose_loopback_timer
Freed by task ...: ... sk_free <- rose_heartbeat_expiry
refcount_t: addition on 0; use-after-free.

followed a few seconds later by a page fault in the re-armed heartbeat
and a panic. It needs an incoming call dropped before accept() and then
the listener being closed (or accepting), so it is not frequent, but it
is a real use-after-free.

The fix is "rose: hold a reference on incoming sockets queued for
accept()", with

Fixes: df12be096302 ("rose: release netdev ref and destroy orphaned
incoming sockets")

It is pull request #25 in linux-netdev/mod-orphan, waiting for review,
so it has no upstream commit id yet. It has been running on all seven
of my nodes since 26 September (6.1, 6.12, 6.18 and 7.0 based kernels)
without any recurrence.

So, as things stand, 6.18.y already carries the regression (this patch
was part of the first fifteen-patch series) and 6.12.y is about to get
it. I do not know which you prefer:

- keep 864 in this 6.12.y round and take the fix as soon as it is
merged, for both 6.18.y and 6.12.y; or
- hold 864 back until the fix is available. Note that 868/877 ("rose:
don't free fd-owned sockets when reaping in the heartbeat") changes
the same reaping code, so dropping 864 alone may not be
straightforward.

Either way I will send you the backport of the fix for 6.18.y and
6.12.y, tested with "git am" on both, as soon as it has a commit id.
Sorry for not flagging this earlier.

Jakub, I put you in Cc only so that you know why I would be grateful
if #25 could be looked at before the rest of the pending ROSE/NetRom
pull requests.

Thanks,
Bernard Pidoux, F6BVP


Le mer. 30 sept. 2026 à 19:49, Greg Kroah-Hartman
<gregkh@linuxfoundation.org> a écrit :
>
> 6.12-stable review patch.  If anyone has any objections, please let me know.
>
> ------------------
>
> From: Bernard Pidoux <bernard.f6bvp@gmail.com>
>
> commit df12be096302d2c947388acc25764456c7f18cc1 upstream.
>
> Two related cleanup gaps left the module unremovable after a loopback
> session:
>
> 1. rose_destroy_socket() did not release the device reference.  When
>    an unaccepted incoming socket (created by rose_rx_call_request()) is
>    destroyed via rose_heartbeat_expiry(), it is removed from rose_list
>    before rose_kill_by_device() can find it, so the netdev_hold() taken
>    in rose_rx_call_request() was never matched by netdev_put().  Add the
>    release at the top of rose_destroy_socket() guarded by a NULL check
>    so that rose_release() and rose_kill_by_device(), which already call
>    netdev_put() and set device = NULL, are not affected.
>
> 2. rose_heartbeat_expiry() STATE_0 cleanup required TCP_LISTEN in
>    addition to SOCK_DEAD.  Unaccepted incoming sockets are
>    TCP_ESTABLISHED, so the condition was never true and those sockets
>    lingered forever, holding the module use count above zero and
>    blocking rmmod.  Drop the TCP_LISTEN restriction: any STATE_0 +
>    SOCK_DEAD socket is orphaned and should be destroyed.
>
> Together with the earlier rose_make_new() double-hold fix these three
> patches allow clean rmmod after loopback sessions.
>
> Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
>  net/rose/af_rose.c    |    9 +++++++++
>  net/rose/rose_timer.c |    9 +++++----
>  2 files changed, 14 insertions(+), 4 deletions(-)
>
> --- a/net/rose/af_rose.c
> +++ b/net/rose/af_rose.c
> @@ -363,6 +363,7 @@ static void rose_destroy_timer(struct ti
>   */
>  void rose_destroy_socket(struct sock *sk)
>  {
> +       struct rose_sock *rose = rose_sk(sk);
>         struct sk_buff *skb;
>
>         rose_remove_socket(sk);
> @@ -370,6 +371,14 @@ void rose_destroy_socket(struct sock *sk
>         rose_stop_idletimer(sk);
>         rose_stop_timer(sk);
>
> +       /* Drop any device reference not already released by rose_kill_by_device()
> +        * or rose_release() -- e.g. incoming sockets that were never accepted.
> +        */
> +       if (rose->device) {
> +               netdev_put(rose->device, &rose->dev_tracker);
> +               rose->device = NULL;
> +       }
> +
>         rose_clear_queues(sk);          /* Flush the queues */
>
>         while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
> --- a/net/rose/rose_timer.c
> +++ b/net/rose/rose_timer.c
> @@ -128,10 +128,11 @@ static void rose_heartbeat_expiry(struct
>         }
>         switch (rose->state) {
>         case ROSE_STATE_0:
> -               /* Magic here: If we listen() and a new link dies before it
> -                  is accepted() it isn't 'dead' so doesn't get removed. */
> -               if (sock_flag(sk, SOCK_DESTROY) ||
> -                   (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) {
> +               /* Destroy any orphaned STATE_0 socket: either explicitly
> +                * flagged SOCK_DESTROY, or SOCK_DEAD (covers both unaccepted
> +                * incoming connections and listening sockets whose link died).
> +                */
> +               if (sock_flag(sk, SOCK_DESTROY) || sock_flag(sk, SOCK_DEAD)) {
>                         bh_unlock_sock(sk);
>                         rose_destroy_socket(sk);
>                         sock_put(sk);
>
>

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 000/877] 6.12.112-rc1 review
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (880 preceding siblings ...)
  2026-10-01  9:17 ` Pavel Machek
@ 2026-10-01 10:06 ` Ron Economos
  2026-10-01 12:01 ` Miguel Ojeda
                   ` (2 subsequent siblings)
  884 siblings, 0 replies; 922+ messages in thread
From: Ron Economos @ 2026-10-01 10:06 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
	lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
	rwarsow, conor, hargar, broonie, achill, sr

On 9/30/26 08:15, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 6.12.112 release.
> There are 877 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 Fri, 02 Oct 2026 15:23:04 +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.12.112-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.12.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h

Built and booted successfully on RISC-V RV64 (HiFive Unmatched).

Tested-by: Ron Economos <re@w6rz.net>


^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits when offloading
  2026-10-01  5:27   ` Karl Mehltretter
@ 2026-10-01 11:31     ` Sasha Levin
  0 siblings, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-01 11:31 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Sasha Levin, Karl Mehltretter, stable, patches, Sabrina Dubroca,
	Simon Horman, Jakub Kicinski

On Thu, Oct 01, 2026 at 07:27:46AM +0200, Karl Mehltretter wrote:
> I object to this patch as queued. The backport is missing prerequisite
> f29d24a2106a ("macsec: clean up local variables in macsec_notify"), so
> NETDEV_FEAT_CHANGE dereferences an uninitialized rxd.

I've dropped it and the pre-reqs for now, thanks!

-- 
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 864/877] rose: release netdev ref and destroy orphaned incoming sockets
  2026-10-01  9:42   ` Bernard Pidoux
@ 2026-10-01 11:31     ` Sasha Levin
  0 siblings, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-01 11:31 UTC (permalink / raw)
  To: gregkh; +Cc: Sasha Levin, Bernard Pidoux, stable, patches, kuba

On Thu, Oct 01, 2026 at 11:42:03AM +0200, Bernard Pidoux wrote:
> - hold 864 back until the fix is available. Note that 868/877 ("rose:
> don't free fd-owned sockets when reaping in the heartbeat") changes
> the same reaping code, so dropping 864 alone may not be
> straightforward.

Dropped with pre-reqs, thanks!

-- 
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 000/877] 6.12.112-rc1 review
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (881 preceding siblings ...)
  2026-10-01 10:06 ` Ron Economos
@ 2026-10-01 12:01 ` Miguel Ojeda
  2026-10-01 16:44 ` Brett A C Sheffield
  2026-10-01 22:24 ` Richard Narron
  884 siblings, 0 replies; 922+ messages in thread
From: Miguel Ojeda @ 2026-10-01 12:01 UTC (permalink / raw)
  To: gregkh
  Cc: achill, akpm, broonie, conor, f.fainelli, hargar, jonathanh,
	linux-kernel, linux, lkft-triage, patches, patches, pavel,
	rwarsow, shuah, sr, stable, sudipm.mukherjee, torvalds,
	Miguel Ojeda

On Wed, 30 Sep 2026 17:15:11 +0200 Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote:
>
> This is the start of the stable review cycle for the 6.12.112 release.
> There are 877 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 Fri, 02 Oct 2026 15:23:04 +0000.
> Anything received after that time might be too late.

Boot-tested under QEMU for Rust x86_64, arm64 and riscv64; built-tested
for loongarch64:

Tested-by: Miguel Ojeda <ojeda@kernel.org>

Thanks!

Cheers,
Miguel

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 000/877] 6.12.112-rc1 review
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (882 preceding siblings ...)
  2026-10-01 12:01 ` Miguel Ojeda
@ 2026-10-01 16:44 ` Brett A C Sheffield
  2026-10-01 22:24 ` Richard Narron
  884 siblings, 0 replies; 922+ messages in thread
From: Brett A C Sheffield @ 2026-10-01 16:44 UTC (permalink / raw)
  To: gregkh
  Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
	patches, lkft-triage, pavel, jonathanh, f.fainelli,
	sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr,
	Brett A C Sheffield

# Librecast Test Results

044/044 [ OK ] liblcrq
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast

CPU/kernel: Linux auntie 6.12.112-rc1-gf4ffa8dc360b #1 SMP PREEMPT_DYNAMIC Thu Oct  1 15:05:55 -00 2026 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux

Tested-by: Brett A C Sheffield <bacs@librecast.net>

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 092/877] neighbour: Use rtnl_register_many().
  2026-09-30 15:16 ` [PATCH 6.12 092/877] neighbour: Use rtnl_register_many() Greg Kroah-Hartman
@ 2026-10-01 19:19   ` Harshit Mogalapalli
  2026-10-02  8:48     ` Greg Kroah-Hartman
  2026-10-02 21:10     ` Sasha Levin
  0 siblings, 2 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 19:19 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: patches, Kuniyuki Iwashima, Eric Dumazet, Jakub Kicinski,
	Sasha Levin



On 30/09/26 8:46 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch.  If anyone has any objections, please let me know.
> 
> ------------------
> 
> From: Kuniyuki Iwashima <kuniyu@amazon.com>
> 
> [ Upstream commit d0d14aef50a6184426c5a05b9815fb2697d6d42c ]
> 
> We will remove rtnl_register() in favour of rtnl_register_many().
> 
> When it succeeds, rtnl_register_many() guarantees all rtnetlink types
> in the passed array are supported, and there is no chance that a part
> of message types is not supported.
> 
> Let's use rtnl_register_many() instead.
> 
> Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
> Reviewed-by: Eric Dumazet <edumazet@google.com>
> Link: https://patch.msgid.link/20241014201828.91221-4-kuniyu@amazon.com
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
>   net/core/neighbour.c | 19 ++++++++++---------
>   1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index bf07438d6dfa5..1dd9f85b74997 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -3898,17 +3898,18 @@ EXPORT_SYMBOL(neigh_sysctl_unregister);
>   
>   #endif	/* CONFIG_SYSCTL */
>   
> +static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
> +	{.msgtype = RTM_NEWNEIGH, .doit = neigh_add},
> +	{.msgtype = RTM_DELNEIGH, .doit = neigh_delete},
> +	{.msgtype = RTM_GETNEIGH, .doit = neigh_get, .dumpit = neigh_dump_info,
> +	 .flags = RTNL_FLAG_DUMP_UNLOCKED},
> +	{.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info},
> +	{.msgtype = RTM_SETNEIGHTBL, .doit = neightbl_set},
> +};
> +

I ran an AI-assisted backport review and it flagged this; I 
independently checked the upstream code and 6.12.y at f4ffa8dc360b.

Upstream __rtnl_register_many() at
d0d14aef50a6184426c5a05b9815fb2697d6d42c, net/core/rtnetlink.c:

if (err) {
     if (!handler->owner)
         panic("Unable to register rtnetlink message "
               "handlers, %pS\n", handlers);

     __rtnl_unregister_many(handlers, i);
     break;
}

6.12.y's net/core/rtnetlink.c:

if (err) {
     __rtnl_unregister_many(handlers, i);
     break;
}

neigh_init() ignores the helper's return value. On allocation failure,
the helper rolls back the batch, so boot can continue with none of the
five neighbour handlers. Previously, failures were logged and the
other registrations continued. This boot-time failure path remains at
the review tip; upstream makes failed built-in registration fatal.

I think 6.12 should take 09aec57d8379f14ffde566621b920d97cc0c46e1
("rtnetlink: Panic when __rtnl_register_many() fails for builtin
callers.") before this conversion so the ignored failure cannot silently
continue, thoughts?

Lets drop this until we also take a prereq ?

thanks,
Harshit

>   static int __init neigh_init(void)
>   {
> -	rtnl_register(PF_UNSPEC, RTM_NEWNEIGH, neigh_add, NULL, 0);
> -	rtnl_register(PF_UNSPEC, RTM_DELNEIGH, neigh_delete, NULL, 0);
> -	rtnl_register(PF_UNSPEC, RTM_GETNEIGH, neigh_get, neigh_dump_info,
> -		      RTNL_FLAG_DUMP_UNLOCKED);
> -
> -	rtnl_register(PF_UNSPEC, RTM_GETNEIGHTBL, NULL, neightbl_dump_info,
> -		      0);
> -	rtnl_register(PF_UNSPEC, RTM_SETNEIGHTBL, neightbl_set, NULL, 0);
> -
> +	rtnl_register_many(neigh_rtnl_msg_handlers);
>   	return 0;
>   }
>   


^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL to RCU.
  2026-09-30 15:16 ` [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL " Greg Kroah-Hartman
@ 2026-10-01 19:34   ` Harshit Mogalapalli
  2026-10-02 12:06     ` Greg Kroah-Hartman
  2026-10-02 21:10     ` Sasha Levin
  0 siblings, 2 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 19:34 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: patches, Kuniyuki Iwashima, Eric Dumazet, Jakub Kicinski,
	Sasha Levin



On 30/09/26 8:46 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch.  If anyone has any objections, please let me know.
> 
> ------------------
> 
> From: Kuniyuki Iwashima <kuniyu@google.com>
> 
> [ Upstream commit 4ae34be500649ec452ac1fc2748958683ad9b55d ]
> 
> neightbl_dump_info() calls these functions for each neigh_tables[]
> entry:
> 
>    1. neightbl_fill_info() for tbl->parms
>    2. neightbl_fill_param_info() for tbl->parms_list (except tbl->parms)
> 
> Both functions rely on the table lock (read_lock_bh(&tbl->lock))
> and RTNL is not needed.
> 
> Let's fetch the table under RCU and convert RTM_GETNEIGHTBL to RCU.
> 
> Note that the first entry of tbl->parms_list is tbl->parms.list and
> embedded in neigh_table, so list_next_entry() is safe.
> 
> Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
> Reviewed-by: Eric Dumazet <edumazet@google.com>
> Link: https://patch.msgid.link/20251022054004.2514876-4-kuniyu@google.com
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
> Signed-off-by: Sasha Levin <sashal@kernel.org>

Hi Greg/Sasha,

An AI-assisted review flagged a reader/writer mismatch. I independently
checked upstream and 6.12.y at f4ffa8dc360b.

Upstream neigh_parms_release() in net/core/neighbour.c has:

write_lock_bh(&tbl->lock);
list_del_rcu(&parms->list);
parms->dead = 1;
write_unlock_bh(&tbl->lock);
netdev_put(parms->dev, &parms->dev_tracker);
call_rcu(&parms->rcu_head, neigh_rcu_free_parms);

6.12.y has
net/core/neighbour.c:

write_lock_bh(&tbl->lock);
list_del(&parms->list);
parms->dead = 1;
write_unlock_bh(&tbl->lock);
netdev_put(parms->dev, &parms->dev_tracker);
call_rcu(&parms->rcu_head, neigh_rcu_free_parms);

neightbl_dump_info() now uses RCU, but list_del() poisons the removed
node's forward link. A reader can follow that poisoned pointer despite
delayed free.

I think 6.12 should take 06d6322280d95757cef1e3ee0fc62c644629523e
("neighbour: Use RCU list helpers for neigh_parms.list writers.") and
35d7c70870338aa6a367b9e4ed528914320b0be0 ("neighbour: Annotate access to
neigh_parms fields.") before this conversion, retaining the later dump
fixes, thoughts?

thanks,
Harshit> ---
>   net/core/neighbour.c | 23 +++++++++--------------
>   1 file changed, 9 insertions(+), 14 deletions(-)
> 
> diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> index 50a18ae55409e..d38c309e7fa61 100644
> --- a/net/core/neighbour.c
> +++ b/net/core/neighbour.c
> @@ -2131,7 +2131,7 @@ static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)
>   		return -ENOBUFS;
>   
>   	if ((parms->dev &&
> -	     nla_put_u32(skb, NDTPA_IFINDEX, parms->dev->ifindex)) ||
> +	     nla_put_u32(skb, NDTPA_IFINDEX, READ_ONCE(parms->dev->ifindex))) ||
>   	    nla_put_u32(skb, NDTPA_REFCNT, refcount_read(&parms->refcnt)) ||
>   	    nla_put_u32(skb, NDTPA_QUEUE_LENBYTES,
>   			NEIGH_VAR(parms, QUEUE_LEN_BYTES)) ||
> @@ -2183,8 +2183,6 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
>   		return -EMSGSIZE;
>   
>   	ndtmsg = nlmsg_data(nlh);
> -
> -	read_lock_bh(&tbl->lock);
>   	ndtmsg->ndtm_family = tbl->family;
>   	ndtmsg->ndtm_pad1   = 0;
>   	ndtmsg->ndtm_pad2   = 0;
> @@ -2210,11 +2208,9 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
>   			.ndtc_proxy_qlen	= READ_ONCE(tbl->proxy_queue.qlen),
>   		};
>   
> -		rcu_read_lock();
>   		nht = rcu_dereference(tbl->nht);
>   		ndc.ndtc_hash_rnd = nht->hash_rnd[0];
>   		ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1);
> -		rcu_read_unlock();
>   
>   		if (nla_put(skb, NDTA_CONFIG, sizeof(ndc), &ndc))
>   			goto nla_put_failure;
> @@ -2252,12 +2248,10 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl,
>   	if (neightbl_fill_parms(skb, &tbl->parms) < 0)
>   		goto nla_put_failure;
>   
> -	read_unlock_bh(&tbl->lock);
>   	nlmsg_end(skb, nlh);
>   	return 0;
>   
>   nla_put_failure:
> -	read_unlock_bh(&tbl->lock);
>   	nlmsg_cancel(skb, nlh);
>   	return -EMSGSIZE;
>   }
> @@ -2276,8 +2270,6 @@ static int neightbl_fill_param_info(struct sk_buff *skb,
>   		return -EMSGSIZE;
>   
>   	ndtmsg = nlmsg_data(nlh);
> -
> -	read_lock_bh(&tbl->lock);
>   	ndtmsg->ndtm_family = tbl->family;
>   	ndtmsg->ndtm_pad1   = 0;
>   	ndtmsg->ndtm_pad2   = 0;
> @@ -2286,11 +2278,9 @@ static int neightbl_fill_param_info(struct sk_buff *skb,
>   	    neightbl_fill_parms(skb, parms) < 0)
>   		goto errout;
>   
> -	read_unlock_bh(&tbl->lock);
>   	nlmsg_end(skb, nlh);
>   	return 0;
>   errout:
> -	read_unlock_bh(&tbl->lock);
>   	nlmsg_cancel(skb, nlh);
>   	return -EMSGSIZE;
>   }
> @@ -2531,10 +2521,12 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
>   
>   	family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family;
>   
> +	rcu_read_lock();
> +
>   	for (tidx = 0; tidx < NEIGH_NR_TABLES; tidx++) {
>   		struct neigh_parms *p;
>   
> -		tbl = rcu_dereference_rtnl(neigh_tables[tidx]);
> +		tbl = rcu_dereference(neigh_tables[tidx]);
>   		if (!tbl)
>   			continue;
>   
> @@ -2548,7 +2540,7 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
>   
>   		nidx = 0;
>   		p = list_next_entry(&tbl->parms, list);
> -		list_for_each_entry_from(p, &tbl->parms_list, list) {
> +		list_for_each_entry_from_rcu(p, &tbl->parms_list, list) {
>   			if (!net_eq(neigh_parms_net(p), net))
>   				continue;
>   
> @@ -2568,6 +2560,8 @@ static int neightbl_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
>   		neigh_skip = 0;
>   	}
>   out:
> +	rcu_read_unlock();
> +
>   	cb->args[0] = tidx;
>   	cb->args[1] = nidx;
>   
> @@ -3882,7 +3876,8 @@ static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
>   	{.msgtype = RTM_DELNEIGH, .doit = neigh_delete},
>   	{.msgtype = RTM_GETNEIGH, .doit = neigh_get, .dumpit = neigh_dump_info,
>   	 .flags = RTNL_FLAG_DOIT_UNLOCKED | RTNL_FLAG_DUMP_UNLOCKED},
> -	{.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info},
> +	{.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info,
> +	 .flags = RTNL_FLAG_DUMP_UNLOCKED},
>   	{.msgtype = RTM_SETNEIGHTBL, .doit = neightbl_set},
>   };
>   


^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes()
  2026-09-30 15:20 ` [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes() Greg Kroah-Hartman
@ 2026-10-01 19:58   ` Harshit Mogalapalli
  2026-10-02 12:09     ` Greg Kroah-Hartman
  0 siblings, 1 reply; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 19:58 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: patches, Julian Sun, Jan Kara, Christian Brauner (Amutable),
	Sasha Levin



On 30/09/26 8:50 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch.  If anyone has any objections, please let me know.
> 
> ------------------
> 
> From: Julian Sun <sunjunchao@bytedance.com>
> 
> [ Upstream commit 7459c021874246c196f397686e100702f059b9e7 ]
> 
> We observed hung tasks when users attempted to unmount a filesystem
> after its disk had been removed while still in use. During device
> removal, fs_bdev_mark_dead() calls evict_inodes() while holding s_umount.
> 
> Each time evict_inodes() drops s_inode_list_lock to reschedule, it
> restarts the walk from the head of s_inodes. With many referenced inodes
> at the head of the list, these restarts repeatedly scan the same inodes
> without reclaiming them. This can keep s_umount held for a long time,
> blocking concurrent umount attempts and triggering hung-task reports.
> 
> Keep the current inode, already marked I_FREEING, out of the disposal
> batch until s_inode_list_lock is reacquired. Resume the walk from this
> inode and dispose of it in a later batch or at the end of the walk.
> 
> The zero-refcount and state checks under i_lock allow this walker to
> claim the inode by setting I_FREEING and removing it from the LRU.
> Other reclaimers skip the inode, leaving this walker responsible for
> eviction. Only evict() removes it from s_inodes, so keeping it out of
> the disposal batch ensures that it remains on the list while the lock
> is dropped. After reacquiring the lock, reading its current next pointer
> accounts for concurrent removal of following inodes.
> 
> The existing inode lifetime rules prohibit acquiring a reference to an
> inode marked I_FREEING or I_WILL_FREE. __iget() requires its caller to
> hold i_lock and establish that taking a reference is valid. Inode lookup
> and igrab() check these flags under i_lock when acquiring a reference
> from zero. ihold() requires an existing reference, which would keep
> i_count nonzero and prevent this walker from claiming the inode. These
> rules already allow iput_final() and the inode shrinker to release
> i_lock after setting I_FREEING and before eviction completes.
> 
> A temporary __iget() reference would also keep the inode on the list,
> but its release must preserve last-reference handling. Another user can
> acquire a reference, update lazy timestamps and drop its reference while
> the pin is held. If the pin becomes the last reference, dropping it with
> atomic_dec_and_test() and evicting directly bypasses iput()'s lazytime
> handling and can lose those timestamp updates.
> 
> Releasing the pin with iput() preserves that handling, but does not
> guarantee eviction. fs_bdev_mark_dead() runs with SB_ACTIVE set, so iput()
> may retain the inode in cache, whereas evict_inodes() must evict eligible
> zero-reference inodes. The inode may also have been freed when iput()
> returns, so the walker cannot then use it to force eviction. Using
> I_FREEING preserves the existing eviction behavior without introducing
> an additional last-reference transition.
> 
> The xfstests auto group passed on ext4 and XFS with known unrelated
> failures excluded. No new issues were observed, and the previously
> reproducible hung task no longer occurs with this patch.
> 
> Fixes: ac05fbb40062 ("inode: don't softlockup when evicting inodes")
> Signed-off-by: Julian Sun <sunjunchao@bytedance.com>
> Link: https://patch.msgid.link/20260915044912.3183440-1-sunjunchao@bytedance.com
> Reviewed-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>

Hi Greg/Sasha,

An AI assisted backport review flagged this, and I checked the upstream
code against the 6.12.y tip f4ffa8dc360b.

Upstream 7459c0218742 uses the current inode's successor after
relocking:

     struct inode *inode;
     LIST_HEAD(dispose);

     spin_lock(&sb->s_inode_list_lock);
     list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
         /* ... intervening source omitted ... */
         if (need_resched()) {
             spin_unlock(&sb->s_inode_list_lock);
             cond_resched();
             dispose_list(&dispose);
             spin_lock(&sb->s_inode_list_lock);
         }
         list_add(&inode->i_lru, &dispose);

6.12.y retains the cached-successor iterator:

     struct inode *inode, *next;
     LIST_HEAD(dispose);

     spin_lock(&sb->s_inode_list_lock);
     list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
         /* ... intervening source omitted ... */
         if (need_resched()) {
             spin_unlock(&sb->s_inode_list_lock);
             cond_resched();
             dispose_list(&dispose);
             spin_lock(&sb->s_inode_list_lock);
         }
         list_add(&inode->i_lru, &dispose);

I_FREEING protects inode, but the safe iterator's cached next can be
detached or freed while the lock is dropped.  The 6.12's 
invalidate_inodes() differs from upstream's disk-removal trigger.

I think 6.12.y needs the two-line iterator change from
3bc4e4410830d556b0f40dfa6671bfcaeacc1599 ("vfs: Remove unnecessary
list_for_each_entry_safe() from evict_inodes()") before this backport,
thoughts?

thanks,
Harshit


> ---
>   fs/inode.c | 11 +++++------
>   1 file changed, 5 insertions(+), 6 deletions(-)
> 
> diff --git a/fs/inode.c b/fs/inode.c
> index 8dabb224f941c..8592fd1a18526 100644
> --- a/fs/inode.c
> +++ b/fs/inode.c
> @@ -790,7 +790,6 @@ void evict_inodes(struct super_block *sb)
>   	struct inode *inode, *next;
>   	LIST_HEAD(dispose);
>   
> -again:
>   	spin_lock(&sb->s_inode_list_lock);
>   	list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
>   		if (atomic_read(&inode->i_count))
> @@ -809,19 +808,19 @@ void evict_inodes(struct super_block *sb)
>   		inode->i_state |= I_FREEING;
>   		inode_lru_list_del(inode);
>   		spin_unlock(&inode->i_lock);
> -		list_add(&inode->i_lru, &dispose);
>   
>   		/*
> -		 * We can have a ton of inodes to evict at unmount time given
> -		 * enough memory, check to see if we need to go to sleep for a
> -		 * bit so we don't livelock.
> +		 * Keep this inode out of dispose so it stays on s_inodes while
> +		 * the list lock is dropped. I_FREEING prevents new references
> +		 * and leaves eviction to us, so we can resume the walk from it.
>   		 */
>   		if (need_resched()) {
>   			spin_unlock(&sb->s_inode_list_lock);
>   			cond_resched();
>   			dispose_list(&dispose);
> -			goto again;
> +			spin_lock(&sb->s_inode_list_lock);
>   		}
> +		list_add(&inode->i_lru, &dispose);
>   	}
>   	spin_unlock(&sb->s_inode_list_lock);
>   


^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices
  2026-09-30 15:21 ` [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices Greg Kroah-Hartman
@ 2026-10-01 20:09   ` Harshit Mogalapalli
  2026-10-02 20:59     ` Harshit Mogalapalli
  2026-10-02 21:10     ` Sasha Levin
  0 siblings, 2 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 20:09 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: patches, co+ac0a8c41de69121d, Weiming Shi, Alexei Starovoitov,
	Sasha Levin



On 30/09/26 8:51 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch.  If anyone has any objections, please let me know.
> 
> ------------------
> 
> From: Weiming Shi <bestswngs@gmail.com>
> 
> [ Upstream commit 6db1ce73e9853f533eb7f413f14ba00f8ec6f80d ]
> 
> __bpf_offload_dev_match() falls back to comparing offdev pointers after an
> exact netdev mismatch. Bound-only programs normally have NULL offdevs, so
> unrelated netdevs compare equal. A bound-only program on an
> offload-registered netdev can instead inherit a real offdev and match a
> sibling port. With CAP_BPF and CAP_NET_ADMIN, a caller can use
> bpf(BPF_LINK_CREATE) with a different target ifindex to run metadata kfuncs
> specialized for the bound driver on the target driver's xdp_buff. Running a
> veth-bound program on tun reads beyond tun's bare stack xdp_buff as a
> veth_xdp_buff.
> 
>    Oops: general protection fault, probably for non-canonical address
>    KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
>    RIP: 0010:veth_xdp_rx_timestamp (drivers/net/veth.c:1673)
>    Call Trace:
>     ...
>     tun_build_skb (drivers/net/tun.c:1739)
>     tun_get_user (drivers/net/tun.c:1856)
>     tun_chr_write_iter (drivers/net/tun.c:2091)
>     vfs_write (fs/read_write.c:595 fs/read_write.c:687)
>     ksys_write (fs/read_write.c:739)
>     do_syscall_64 (arch/x86/entry/syscall_64.c:84)
>     entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
>    Kernel panic - not syncing: Fatal exception in interrupt
> 
> Restrict non-offloaded programs to exact netdev matches and retain the
> shared-offdev fallback only for genuinely offloaded multi-port programs.
> 
> Fixes: 2b3486bc2d23 ("bpf: Introduce device-bound XDP programs")
> Reported-by: <co+ac0a8c41de69121d@bugs.sh>
> Signed-off-by: Weiming Shi <bestswngs@gmail.com>
> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
> Link: https://lore.kernel.org/bpf/20260917161335.1020405-2-bestswngs@gmail.com/
> Link: https://patch.msgid.link/20260920132303.4109240-3-bestswngs@gmail.com
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
>   kernel/bpf/offload.c | 2 ++
>   1 file changed, 2 insertions(+)
> 
> diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c
> index 56115739fcfdd..1b6f9e7175666 100644
> --- a/kernel/bpf/offload.c
> +++ b/kernel/bpf/offload.c
> @@ -703,6 +703,8 @@ static bool __bpf_offload_dev_match(struct bpf_prog *prog,
>   		return false;
>   	if (offload->netdev == netdev)
>   		return true;
> +	if (!bpf_prog_is_offloaded(prog->aux))
> +		return false;


Hi Greg/Sasha,

An AI assisted backport review flagged this, and I checked the upstream
code against the 6.12.y tip f4ffa8dc360b.

Upstream 6db1ce73e985 checks device binding in dev_xdp_install():

         if (bpf_prog_is_dev_bound(prog->aux) &&
             !bpf_offload_dev_match(prog, dev)) {
             NL_SET_ERR_MSG(extack, "Program bound to different device");
             return -EINVAL;
         }

6.12.y bpf_xdp_link_update() goes directly to that installer:

     mode = dev_xdp_mode(xdp_link->dev, xdp_link->flags);
     bpf_op = dev_xdp_bpf_op(xdp_link->dev, mode);
     err = dev_xdp_install(xdp_link->dev, mode, bpf_op, NULL,
                           xdp_link->flags, new_prog);
     if (err)
         goto out_unlock;

Link update calls dev_xdp_install() directly, bypassing 6.12's binding
check in dev_xdp_attach(). Type checks and tun's callback cannot prevent
wrong-device installation, leaving metadata kfuncs with an incompatible
context. The matcher fix is correct; this bypass predates it. No
destination kernel crash was reproduced.

I think 6.12.y needs ad27ed7d2309419a129078d781504f486b1b469a ("bpf,
xdp: move offload check into dev_xdp_install()"), adapted to the 6.12
installer, alongside this fix, thoughts?

thanks,
Harshit>
>   	ondev1 = bpf_offload_find_netdev(offload->netdev);
>   	ondev2 = bpf_offload_find_netdev(netdev);


^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits when offloading
  2026-09-30 15:22 ` [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits " Greg Kroah-Hartman
  2026-10-01  5:27   ` Karl Mehltretter
@ 2026-10-01 20:12   ` Harshit Mogalapalli
  2026-10-02 12:10     ` Greg Kroah-Hartman
  1 sibling, 1 reply; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 20:12 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: patches, Sabrina Dubroca, Simon Horman, Jakub Kicinski,
	Sasha Levin



On 30/09/26 8:52 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch.  If anyone has any objections, please let me know.
> 
> ------------------
> 
> From: Sabrina Dubroca <sd@queasysnail.net>
> 
> [ Upstream commit de187a390838c0b3dfd00ae5399aa406d0a79f13 ]
> 
> If macsec is offloaded, we need to follow the lower device's
> capabilities, like VLAN devices do.
> 
> Leave the limits unchanged when the offload is disabled.
> 
> Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
> Reviewed-by: Simon Horman <horms@kernel.org>
> Link: https://patch.msgid.link/8240c0181e851f169d815f59658a01fb9dfc5073.1730929545.git.sd@queasysnail.net
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Stable-dep-of: c2de369c5c5b ("macsec: initialize SecY before registering the netdevice")
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
>   drivers/net/macsec.c | 22 ++++++++++++++++++++++
>   1 file changed, 22 insertions(+)
> 
> diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
> index b1eb6b5dde0fe..ce4a08f77724f 100644
> --- a/drivers/net/macsec.c
> +++ b/drivers/net/macsec.c
> @@ -2650,6 +2650,17 @@ static void macsec_set_head_tail_room(struct net_device *dev)
>   	dev->needed_tailroom = real_dev->needed_tailroom + needed_tailroom;
>   }
>   
> +static void macsec_inherit_tso_max(struct net_device *dev)
> +{
> +	struct macsec_dev *macsec = macsec_priv(dev);
> +
> +	/* if macsec is offloaded, we need to follow the lower
> +	 * device's capabilities. otherwise, we can ignore them.
> +	 */
> +	if (macsec_is_offloaded(macsec))
> +		netif_inherit_tso_max(dev, macsec->real_dev);
> +}
> +
>   static int macsec_update_offload(struct net_device *dev, enum macsec_offload offload)
>   {
>   	enum macsec_offload prev_offload;
> @@ -2695,6 +2706,8 @@ static int macsec_update_offload(struct net_device *dev, enum macsec_offload off
>   	macsec_set_head_tail_room(dev);
>   	macsec->insert_tx_tag = macsec_needs_tx_tag(macsec, ops);
>   
> +	macsec_inherit_tso_max(dev);
> +
>   	netdev_update_features(dev);
>   
>   	return ret;
> @@ -3566,6 +3579,8 @@ static int macsec_dev_init(struct net_device *dev)
>   	if (err)
>   		return err;
>   
> +	macsec_inherit_tso_max(dev);
> +
>   	dev->hw_features = real_dev->hw_features & MACSEC_OFFLOAD_FEATURES;
>   	dev->hw_features |= NETIF_F_GSO_SOFTWARE;
>   
> @@ -4521,6 +4536,13 @@ static int macsec_notify(struct notifier_block *this, unsigned long event,
>   			if (dev->mtu > mtu)
>   				dev_set_mtu(dev, mtu);
>   		}
> +		break;
> +	case NETDEV_FEAT_CHANGE:
> +		list_for_each_entry(m, &rxd->secys, secys) {
> +			macsec_inherit_tso_max(m->secy.netdev);
> +			netdev_update_features(m->secy.netdev);
> +		}
> +		break;

Hi Greg/Sasha,

An AI assisted backport review flagged this, and I checked the upstream
code against the 6.12.y tip f4ffa8dc360b.

Upstream de187a390838 initializes rxd before macsec_notify() dispatches:

     struct macsec_rxh_data *rxd;
     struct macsec_dev *m, *n;
     LIST_HEAD(head);

     if (!is_macsec_master(real_dev))
         return NOTIFY_DONE;

     rxd = macsec_data_rtnl(real_dev);

     switch (event) {

6.12.y inserts the new label inside the older MTU case's block:

     case NETDEV_CHANGEMTU: {
         struct macsec_dev *m;
         struct macsec_rxh_data *rxd;

         rxd = macsec_data_rtnl(real_dev);
         /* ... intervening source omitted ... */
         break;
     case NETDEV_FEAT_CHANGE:
         list_for_each_entry(m, &rxd->secys, secys) {
             macsec_inherit_tso_max(m->secy.netdev);
             netdev_update_features(m->secy.netdev);
         }
         break;
     }

NETDEV_FEAT_CHANGE skips the rxd assignment and dereferences an
uninitialized pointer. Software MACsec reaches it too, before the
offload check.

I think 6.12.y needs f29d24a2106ae28a9b257503a615ee438efa3f95 ("macsec:
clean up local variables in macsec_notify") before this backport,
thoughts?

thanks,
harshit

>   	}
>   	}
>   


^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush
  2026-09-30 15:24 ` [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush Greg Kroah-Hartman
@ 2026-10-01 20:21   ` Harshit Mogalapalli
  2026-10-02  6:24     ` Greg Kroah-Hartman
  2026-10-03  1:30     ` Sasha Levin
  0 siblings, 2 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 20:21 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable, Sasha Levin
  Cc: patches, Darrick J. Wong, Christoph Hellwig, Carlos Maiolino



On 30/09/26 8:54 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch.  If anyone has any objections, please let me know.
> 
> ------------------
> 
> From: Darrick J. Wong <djwong@kernel.org>
> 
> commit ffb48dccce1960a9ea24463a2f3c21d124d6b672 upstream.
> 
> LOLLM noticed that xfs_qm_flush_one fails to drop the dquot flush lock
> if it can't grab the buffer associated with the dquot.  Since there's no
> buffer, nobody else is going to drop the dqflock, so we need to do it
> ourselves.
> 
> Cc: stable@vger.kernel.org # v6.13
> Fixes: ca378189fdfa89 ("xfs: convert quotacheck to attach dquot buffers")
> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> Assisted-by: LOLLM # finding obvious bugs
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Carlos Maiolino <cem@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
>   fs/xfs/xfs_qm.c |   10 ++++++++--
>   1 file changed, 8 insertions(+), 2 deletions(-)
> 
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -1317,16 +1317,22 @@ xfs_qm_flush_one(
>   
>   	error = xfs_dquot_use_attached_buf(dqp, &bp);
>   	if (error)
> -		goto out_unlock;
> +		goto out_dqflock;
>   	if (!bp) {
>   		error = -EFSCORRUPTED;
> -		goto out_unlock;
> +		goto out_dqflock;
>   	}
>   
>   	error = xfs_qm_dqflush(dqp, bp);
>   	if (!error)
>   		xfs_buf_delwri_queue(bp, buffer_list);
>   	xfs_buf_relse(bp);
> +	mutex_unlock(&dqp->q_qlock);
> +	xfs_qm_dqrele(dqp);


^^

Hi Greg,

An AI assisted backport review flagged this, and I checked the upstream
code against the 6.12.y tip f4ffa8dc360b.

Upstream ffb48dccce19 acquires a temporary dquot reference and balances
it on the buffer-bearing return path:

     if (!lockref_get_not_dead(&dqp->q_lockref))
         return 0;

     mutex_lock(&dqp->q_qlock);
     /* ... intervening source omitted ... */
     xfs_buf_relse(bp);
     mutex_unlock(&dqp->q_qlock);
     xfs_qm_dqrele(dqp);
     return error;

6.12.y starts with a mutex-only xfs_dqlock(), but copies the release:

     xfs_dqlock(dqp);
     if (dqp->q_flags & XFS_DQFLAG_FREEING)
         goto out_unlock;
     if (!XFS_DQ_IS_DIRTY(dqp))
         goto out_unlock;
     /* ... intervening source omitted ... */
     xfs_buf_relse(bp);
     mutex_unlock(&dqp->q_qlock);
     xfs_qm_dqrele(dqp);
     return error;

Neither xfs_dqlock() nor the walker takes a reference. The new
xfs_qm_dqrele() releases an unowned reference and can assert/underflow
q_nrefs on dirty zero-reference dquots after quotacheck, potentially
blocking purge/teardown.

Could we replace the new mutex_unlock()/xfs_qm_dqrele() pair with
xfs_dqunlock(dqp), keeping the early return and out_dqflock cleanup?

or drop this fix for 6.12.y ?

thanks,
Harshit> +	return error;
> +
> +out_dqflock:
> +	xfs_dqfunlock(dqp);
>   out_unlock:
>   	xfs_dqunlock(dqp);
>   	return error;
> 
> 
> 


^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 746/877] ipv4: remove fib_devindex_hashfn()
  2026-09-30 15:27 ` [PATCH 6.12 746/877] ipv4: remove fib_devindex_hashfn() Greg Kroah-Hartman
@ 2026-10-01 20:24   ` Harshit Mogalapalli
  2026-10-02 21:04     ` Harshit Mogalapalli
  2026-10-02 21:10     ` Sasha Levin
  0 siblings, 2 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 20:24 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: patches, Eric Dumazet, Kuniyuki Iwashima, David Ahern,
	Jakub Kicinski, Sasha Levin



On 30/09/26 8:57 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch.  If anyone has any objections, please let me know.
> 
> ------------------
> 
> From: Eric Dumazet <edumazet@google.com>
> 
> [ Upstream commit 8a0f62fdeb9ea66ad3d0e959c7c4addbabeac1be ]
> 
> fib_devindex_hashfn() converts a 32bit ifindex value to a 8bit hash.
> 
> It makes no sense doing this from fib_info_hashfn() and
> fib_find_info_nh().
> 
> It is better to keep as many bits as possible to let
> fib_info_hashfn_result() have better spread.
> 
> Only fib_info_devhash_bucket() needs to make this operation,
> we can 'inline' trivial fib_devindex_hashfn() in it.
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
> Reviewed-by: David Ahern <dsahern@kernel.org>
> Link: https://patch.msgid.link/20241004134720.579244-2-edumazet@google.com
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Stable-dep-of: 8d6cd1885085 ("ipv6: flowlabel: cap duplicate leases per socket")
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
>   net/ipv4/fib_semantics.c |   13 ++++---------
>   1 file changed, 4 insertions(+), 9 deletions(-)
> 
> --- a/net/ipv4/fib_semantics.c
> +++ b/net/ipv4/fib_semantics.c
> @@ -322,17 +322,12 @@ static inline int nh_comp(struct fib_inf
>   	return 0;
>   }
>   
> -static inline unsigned int fib_devindex_hashfn(unsigned int val)
> -{
> -	return hash_32(val, DEVINDEX_HASHBITS);
> -}
> -

Hi Greg/Sasha,

An AI-assisted review flagged this, and I checked the upstream and 6.12
code. Removing fib_devindex_hashfn() also needs the upstream finalizer.

Upstream, net/ipv4/fib_semantics.c:

     return hash_32(val ^ net_hash_mix(net), fib_info_hash_bits);

6.12.y still has:

     unsigned int mask = (fib_info_hash_size - 1);
     return (val ^ (val >> 7) ^ (val >> 12)) & mask;

The old finalizer ignores upper bits of raw nexthop IDs/ifindices at
ordinary table sizes. In a 256-bucket check with equal route metadata,
128 IDs differing only in their upper byte use 128 buckets before, one
after, and 128 upstream.

I think 6.12 needs 9b8ca04854fd1253a58aeb1bd089c191cb5a074c ("ipv4:
avoid quadratic behavior in FIB insertion of common address") before
this change, including both finalizer callers, thoughts?

thanks,
Harshit>   static struct hlist_head *
>   fib_info_devhash_bucket(const struct net_device *dev)
>   {
>   	u32 val = net_hash_mix(dev_net(dev)) ^ dev->ifindex;
>   
> -	return &fib_info_devhash[fib_devindex_hashfn(val)];
> +	return &fib_info_devhash[hash_32(val, DEVINDEX_HASHBITS)];
>   }
>   
>   static unsigned int fib_info_hashfn_1(int init_val, u8 protocol, u8 scope,
> @@ -363,10 +358,10 @@ static inline unsigned int fib_info_hash
>   				fi->fib_priority);
>   
>   	if (fi->nh) {
> -		val ^= fib_devindex_hashfn(fi->nh->id);
> +		val ^= fi->nh->id;
>   	} else {
>   		for_nexthops(fi) {
> -			val ^= fib_devindex_hashfn(nh->fib_nh_oif);
> +			val ^= nh->fib_nh_oif;
>   		} endfor_nexthops(fi)
>   	}
>   
> @@ -381,7 +376,7 @@ static struct fib_info *fib_find_info_nh
>   	struct fib_info *fi;
>   	unsigned int hash;
>   
> -	hash = fib_info_hashfn_1(fib_devindex_hashfn(cfg->fc_nh_id),
> +	hash = fib_info_hashfn_1(cfg->fc_nh_id,
>   				 cfg->fc_protocol, cfg->fc_scope,
>   				 (__force u32)cfg->fc_prefsrc,
>   				 cfg->fc_priority);
> 
> 
> 


^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 773/877] mptcp: prevent race between disconnect() and rtx
  2026-09-30 15:28 ` [PATCH 6.12 773/877] mptcp: prevent race between disconnect() and rtx Greg Kroah-Hartman
@ 2026-10-01 20:30   ` Harshit Mogalapalli
  2026-10-02 12:11     ` Greg Kroah-Hartman
  0 siblings, 1 reply; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 20:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: patches, Paolo Abeni, Matthieu Baerts (NGI0), Jakub Kicinski,
	Sasha Levin



On 30/09/26 8:58 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch.  If anyone has any objections, please let me know.
> 
> ------------------
> 
> From: Paolo Abeni <pabeni@redhat.com>
> 
> [ Upstream commit 85c580b0d8590520ae00a15c29e9fb9c99427a3e ]
> 
> Sashiko noted that the two event can race, leading to inconsistent
> status. Prevent the race using the synchronous timer stop operation.
> 
> Cc: stable@vger.kernel.org
> Fixes: b29fcfb54cd7 ("mptcp: full disconnect implementation")
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-6-df1de70348b6@kernel.org
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
>   net/mptcp/protocol.c |   10 ++++++++--
>   1 file changed, 8 insertions(+), 2 deletions(-)
> 
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -3367,6 +3367,7 @@ static void mptcp_copy_inaddrs(struct so
>   
>   static int mptcp_disconnect(struct sock *sk, int flags)
>   {
> +	struct inet_connection_sock *icsk = inet_csk(sk);
>   	struct mptcp_sock *msk = mptcp_sk(sk);
>   
>   	/* We are on the fastopen error path. We can't call straight into the
> @@ -3379,8 +3380,13 @@ static int mptcp_disconnect(struct sock
>   	mptcp_check_listen_stop(sk);
>   	mptcp_set_state(sk, TCP_CLOSE);
>   
> -	mptcp_stop_rtx_timer(sk);
> -	mptcp_stop_tout_timer(sk);
> +	/* The later subflow close can not kick again the tout timer,
> +	 * as the msk is already in closed status.
> +	 */
> +	msk->timer_ival = icsk->icsk_rto_min;
^^^

Hi Greg/Sasha,

An AI-assisted review flagged the reset expression, and I checked the
MPTCP parent-socket initialization on 6.12.

Upstream, net/mptcp/protocol.c, __mptcp_init_sock():

     icsk->icsk_rto_min =
         usecs_to_jiffies(READ_ONCE(net->ipv4.sysctl_tcp_rto_min_us));

Then mptcp_disconnect() uses:

     msk->timer_ival = icsk->icsk_rto_min;

6.12's initializer instead has:

     msk->timer_ival = TCP_RTO_MIN;

6.12 never initializes the parent's icsk_rto_min or calls
tcp_init_sock(), so disconnect reads zero; the subflow's initialized
field does not help. Upstream's broader RTO feature,
ea4eb2adb0d3414abeddaba72dbf8876fa66528f ("mptcp: honour configured
min/max RTO in retransmit paths"), supplies the missing initialization.

Could we use msk->timer_ival = TCP_RTO_MIN on 6.12, matching its
initializer while retaining the synchronous stops?


should we drop this for now ?

thanks,
Harshit


> +	sk_stop_timer_sync(sk, &sk->mptcp_retransmit_timer);
> +	icsk->icsk_mtup.probe_timestamp = 0;
> +	sk_stop_timer_sync(sk, &icsk->mptcp_tout_timer);
>   
>   	if (msk->token)
>   		mptcp_event(MPTCP_EVENT_CLOSED, msk, NULL, GFP_KERNEL);
> 
> 
> 


^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params
  2026-09-30 15:16 ` [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params Greg Kroah-Hartman
@ 2026-10-01 20:39   ` Harshit Mogalapalli
  2026-10-02 12:07     ` Greg Kroah-Hartman
  2026-10-02 21:10     ` Sasha Levin
  0 siblings, 2 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-01 20:39 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: patches, Richard Fitzgerald, Mark Brown, Sasha Levin



On 30/09/26 8:46 pm, Greg Kroah-Hartman wrote:
> 6.12-stable review patch.  If anyone has any objections, please let me know.
> 
> ------------------
> 
> From: Richard Fitzgerald <rf@opensource.cirrus.com>
> 
> [ Upstream commit 6b382bdfe26a2232091bf743e454e6794295783e ]
> 
> In __soc_pcm_hw_params() if there is a snd_soc_dai_link_ch_map with
> non-zero codec_ch_mask, use that channel mask to restrict which channels
> are enabled on the codec. But only if there isn't a TDM mask.
> 
> It is possible that a snd_soc_dai_link_ch_map could include the same codec
> multiple times on different CPUs so the for_each_rtd_ch_maps() loop
> accumulates the channel masks for all entries of that codec.
> 
> If a TDM mask was also set, it takes priority and is used instead of any
> possible snd_soc_dai_link_ch_map entries. (They cannot be ANDed together
> because the bit positions are indicating different things: TDM is a bit
> for each TDM slot, codec_ch_mask is a bit for each codec channel.)
> 
> This fixes a problem of incorrect TX channels enabled on the codec when
> multiple codecs are aggregated on a single capture link. For example:
> 
> - Two CPUs with six 4-channel codecs.
> - The machine driver chooses to assign one channel from each codec to
>    one channel on the CPU
> - But the codec hw_params() would be passed a channel count of 6, which
>    (a) is more channels than the codec has and (b) allows enabling channels
>    that should not be driving the audio bus.
> 
> Fixes: ac950278b087 ("ASoC: add N cpus to M codecs dai link support")
> Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
> Link: https://patch.msgid.link/20260910114500.1586637-4-rf@opensource.cirrus.com
> Signed-off-by: Mark Brown <broonie@kernel.org>
> Signed-off-by: Sasha Levin <sashal@kernel.org>

Hi Greg/Sasha,

An AI-assisted review flagged a possible omission. I independently
checked the core and SoundWire producer at 6.12.y f4ffa8dc360b.

The core backport correctly preserves TDM precedence and combines
codec_ch_mask entries for each codec. The question is its missing
SoundWire producer.

Upstream's companion has: 290845e151cd4e307cc1f25319583aaceb4eeb30,
sound/soc/sdw_utils/soc_sdw_utils.c:

for_each_link_ch_maps(rtd->dai_link, i, ch_maps) {
     ch_maps->cpu_ch_mask = cpu_ch_mask << (i * step);
     ch_maps->codec_ch_mask = codec_ch_mask;
}

6.12.y asoc_sdw_hw_params() at f4ffa8dc360bce834e6ea7b0148eab0118f4a42e,
sound/soc/sdw_utils/soc_sdw_utils.c:

for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
     ch_maps->cpu_ch_mask = ch_mask << (i * step);

Only the declaration and core consumer use codec_ch_mask in include/ and
sound/. SoundWire leaves it zero, so without a TDM mask the codec keeps
the aggregate channel count and capture restriction stays inactive.
Hardware impact was not tested.

Could the ASoC maintainer confirm whether
290845e151cd4e307cc1f25319583aaceb4eeb30 ("ASoC: sdw_utils: Set
snd_soc_dai_link_ch_map.codec_ch_mask for capture") should accompany
this 6.12 series to complete the SoundWire capture fix?


this is all in a series: 
https://lore.kernel.org/all/20260910114500.1586637-1-rf@opensource.cirrus.com/

thanks
Harshit> ---
>   sound/soc/soc-pcm.c | 16 ++++++++++++----
>   1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
> index 440acec700a56..d52771a4a723b 100644
> --- a/sound/soc/soc-pcm.c
> +++ b/sound/soc/soc-pcm.c
> @@ -1122,7 +1122,9 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
>   		goto out;
>   
>   	for_each_rtd_codec_dais(rtd, i, codec_dai) {
> -		unsigned int tdm_mask = snd_soc_dai_tdm_mask_get(codec_dai, substream->stream);
> +		unsigned int ch_mask = snd_soc_dai_tdm_mask_get(codec_dai, substream->stream);
> +		struct snd_soc_dai_link_ch_map *ch_maps;
> +		int j;
>   
>   		/*
>   		 * Skip CODECs which don't support the current stream type,
> @@ -1144,9 +1146,15 @@ static int __soc_pcm_hw_params(struct snd_soc_pcm_runtime *rtd,
>   		/* copy params for each codec */
>   		tmp_params = *params;
>   
> -		/* fixup params based on TDM slot masks */
> -		if (tdm_mask)
> -			soc_pcm_codec_params_fixup(&tmp_params, tdm_mask);
> +		/* fixup params based on TDM or ch_map masks */
> +		if (!ch_mask) {
> +			for_each_rtd_ch_maps(rtd, j, ch_maps)
> +				if (ch_maps->codec == i)
> +					ch_mask |= ch_maps->codec_ch_mask;
> +		}
> +
> +		if (ch_mask)
> +			soc_pcm_codec_params_fixup(&tmp_params, ch_mask);
>   
>   		ret = snd_soc_dai_hw_params(codec_dai, substream,
>   					    &tmp_params);


^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 000/877] 6.12.112-rc1 review
  2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
                   ` (883 preceding siblings ...)
  2026-10-01 16:44 ` Brett A C Sheffield
@ 2026-10-01 22:24 ` Richard Narron
  884 siblings, 0 replies; 922+ messages in thread
From: Richard Narron @ 2026-10-01 22:24 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Linux stable, patches, Linux kernel, Linus Torvalds, akpm, linux,
	shuah, patches, lkft-triage, pavel, jonathanh, f.fainelli,
	sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr

On Wed, 30 Sep 2026, Greg Kroah-Hartman wrote:

> This is the start of the stable review cycle for the 6.12.112 release.
> There are 877 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 Fri, 02 Oct 2026 15:23:04 +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.12.112-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.12.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h

Tested on AMD64 12-core and 4-core systems
and    on Intel x86-64 4-core and x86 1-core systems

Tested-by: Richard Narron <richard@aaazen.com>

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush
  2026-10-01 20:21   ` Harshit Mogalapalli
@ 2026-10-02  6:24     ` Greg Kroah-Hartman
  2026-10-03  1:30     ` Sasha Levin
  1 sibling, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-02  6:24 UTC (permalink / raw)
  To: Harshit Mogalapalli
  Cc: stable, Sasha Levin, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino

On Fri, Oct 02, 2026 at 01:51:58AM +0530, Harshit Mogalapalli wrote:
> 
> 
> On 30/09/26 8:54 pm, Greg Kroah-Hartman wrote:
> > 6.12-stable review patch.  If anyone has any objections, please let me know.
> > 
> > ------------------
> > 
> > From: Darrick J. Wong <djwong@kernel.org>
> > 
> > commit ffb48dccce1960a9ea24463a2f3c21d124d6b672 upstream.
> > 
> > LOLLM noticed that xfs_qm_flush_one fails to drop the dquot flush lock
> > if it can't grab the buffer associated with the dquot.  Since there's no
> > buffer, nobody else is going to drop the dqflock, so we need to do it
> > ourselves.
> > 
> > Cc: stable@vger.kernel.org # v6.13
> > Fixes: ca378189fdfa89 ("xfs: convert quotacheck to attach dquot buffers")
> > Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> > Assisted-by: LOLLM # finding obvious bugs
> > Reviewed-by: Christoph Hellwig <hch@lst.de>
> > Signed-off-by: Carlos Maiolino <cem@kernel.org>
> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > ---
> >   fs/xfs/xfs_qm.c |   10 ++++++++--
> >   1 file changed, 8 insertions(+), 2 deletions(-)
> > 
> > --- a/fs/xfs/xfs_qm.c
> > +++ b/fs/xfs/xfs_qm.c
> > @@ -1317,16 +1317,22 @@ xfs_qm_flush_one(
> >   	error = xfs_dquot_use_attached_buf(dqp, &bp);
> >   	if (error)
> > -		goto out_unlock;
> > +		goto out_dqflock;
> >   	if (!bp) {
> >   		error = -EFSCORRUPTED;
> > -		goto out_unlock;
> > +		goto out_dqflock;
> >   	}
> >   	error = xfs_qm_dqflush(dqp, bp);
> >   	if (!error)
> >   		xfs_buf_delwri_queue(bp, buffer_list);
> >   	xfs_buf_relse(bp);
> > +	mutex_unlock(&dqp->q_qlock);
> > +	xfs_qm_dqrele(dqp);
> 
> 
> ^^
> 
> Hi Greg,
> 
> An AI assisted backport review flagged this, and I checked the upstream
> code against the 6.12.y tip f4ffa8dc360b.
> 
> Upstream ffb48dccce19 acquires a temporary dquot reference and balances
> it on the buffer-bearing return path:
> 
>     if (!lockref_get_not_dead(&dqp->q_lockref))
>         return 0;
> 
>     mutex_lock(&dqp->q_qlock);
>     /* ... intervening source omitted ... */
>     xfs_buf_relse(bp);
>     mutex_unlock(&dqp->q_qlock);
>     xfs_qm_dqrele(dqp);
>     return error;
> 
> 6.12.y starts with a mutex-only xfs_dqlock(), but copies the release:
> 
>     xfs_dqlock(dqp);
>     if (dqp->q_flags & XFS_DQFLAG_FREEING)
>         goto out_unlock;
>     if (!XFS_DQ_IS_DIRTY(dqp))
>         goto out_unlock;
>     /* ... intervening source omitted ... */
>     xfs_buf_relse(bp);
>     mutex_unlock(&dqp->q_qlock);
>     xfs_qm_dqrele(dqp);
>     return error;
> 
> Neither xfs_dqlock() nor the walker takes a reference. The new
> xfs_qm_dqrele() releases an unowned reference and can assert/underflow
> q_nrefs on dirty zero-reference dquots after quotacheck, potentially
> blocking purge/teardown.
> 
> Could we replace the new mutex_unlock()/xfs_qm_dqrele() pair with
> xfs_dqunlock(dqp), keeping the early return and out_dqflock cleanup?
> 
> or drop this fix for 6.12.y ?

Now dropped from the 6.12.y queue, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 092/877] neighbour: Use rtnl_register_many().
  2026-10-01 19:19   ` Harshit Mogalapalli
@ 2026-10-02  8:48     ` Greg Kroah-Hartman
  2026-10-02 21:10     ` Sasha Levin
  1 sibling, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-02  8:48 UTC (permalink / raw)
  To: Harshit Mogalapalli
  Cc: stable, patches, Kuniyuki Iwashima, Eric Dumazet, Jakub Kicinski,
	Sasha Levin

On Fri, Oct 02, 2026 at 12:49:41AM +0530, Harshit Mogalapalli wrote:
> 
> 
> On 30/09/26 8:46 pm, Greg Kroah-Hartman wrote:
> > 6.12-stable review patch.  If anyone has any objections, please let me know.
> > 
> > ------------------
> > 
> > From: Kuniyuki Iwashima <kuniyu@amazon.com>
> > 
> > [ Upstream commit d0d14aef50a6184426c5a05b9815fb2697d6d42c ]
> > 
> > We will remove rtnl_register() in favour of rtnl_register_many().
> > 
> > When it succeeds, rtnl_register_many() guarantees all rtnetlink types
> > in the passed array are supported, and there is no chance that a part
> > of message types is not supported.
> > 
> > Let's use rtnl_register_many() instead.
> > 
> > Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
> > Reviewed-by: Eric Dumazet <edumazet@google.com>
> > Link: https://patch.msgid.link/20241014201828.91221-4-kuniyu@amazon.com
> > Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> > Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
> > Signed-off-by: Sasha Levin <sashal@kernel.org>
> > ---
> >   net/core/neighbour.c | 19 ++++++++++---------
> >   1 file changed, 10 insertions(+), 9 deletions(-)
> > 
> > diff --git a/net/core/neighbour.c b/net/core/neighbour.c
> > index bf07438d6dfa5..1dd9f85b74997 100644
> > --- a/net/core/neighbour.c
> > +++ b/net/core/neighbour.c
> > @@ -3898,17 +3898,18 @@ EXPORT_SYMBOL(neigh_sysctl_unregister);
> >   #endif	/* CONFIG_SYSCTL */
> > +static const struct rtnl_msg_handler neigh_rtnl_msg_handlers[] __initconst = {
> > +	{.msgtype = RTM_NEWNEIGH, .doit = neigh_add},
> > +	{.msgtype = RTM_DELNEIGH, .doit = neigh_delete},
> > +	{.msgtype = RTM_GETNEIGH, .doit = neigh_get, .dumpit = neigh_dump_info,
> > +	 .flags = RTNL_FLAG_DUMP_UNLOCKED},
> > +	{.msgtype = RTM_GETNEIGHTBL, .dumpit = neightbl_dump_info},
> > +	{.msgtype = RTM_SETNEIGHTBL, .doit = neightbl_set},
> > +};
> > +
> 
> I ran an AI-assisted backport review and it flagged this; I independently
> checked the upstream code and 6.12.y at f4ffa8dc360b.
> 
> Upstream __rtnl_register_many() at
> d0d14aef50a6184426c5a05b9815fb2697d6d42c, net/core/rtnetlink.c:
> 
> if (err) {
>     if (!handler->owner)
>         panic("Unable to register rtnetlink message "
>               "handlers, %pS\n", handlers);
> 
>     __rtnl_unregister_many(handlers, i);
>     break;
> }
> 
> 6.12.y's net/core/rtnetlink.c:
> 
> if (err) {
>     __rtnl_unregister_many(handlers, i);
>     break;
> }
> 
> neigh_init() ignores the helper's return value. On allocation failure,
> the helper rolls back the batch, so boot can continue with none of the
> five neighbour handlers. Previously, failures were logged and the
> other registrations continued. This boot-time failure path remains at
> the review tip; upstream makes failed built-in registration fatal.
> 
> I think 6.12 should take 09aec57d8379f14ffde566621b920d97cc0c46e1
> ("rtnetlink: Panic when __rtnl_register_many() fails for builtin
> callers.") before this conversion so the ignored failure cannot silently
> continue, thoughts?
> 
> Lets drop this until we also take a prereq ?

I've dropped the whole series now, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL to RCU.
  2026-10-01 19:34   ` Harshit Mogalapalli
@ 2026-10-02 12:06     ` Greg Kroah-Hartman
  2026-10-02 21:10     ` Sasha Levin
  1 sibling, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-02 12:06 UTC (permalink / raw)
  To: Harshit Mogalapalli
  Cc: stable, patches, Kuniyuki Iwashima, Eric Dumazet, Jakub Kicinski,
	Sasha Levin

On Fri, Oct 02, 2026 at 01:04:58AM +0530, Harshit Mogalapalli wrote:
> 
> 
> On 30/09/26 8:46 pm, Greg Kroah-Hartman wrote:
> > 6.12-stable review patch.  If anyone has any objections, please let me know.
> > 
> > ------------------
> > 
> > From: Kuniyuki Iwashima <kuniyu@google.com>
> > 
> > [ Upstream commit 4ae34be500649ec452ac1fc2748958683ad9b55d ]
> > 
> > neightbl_dump_info() calls these functions for each neigh_tables[]
> > entry:
> > 
> >    1. neightbl_fill_info() for tbl->parms
> >    2. neightbl_fill_param_info() for tbl->parms_list (except tbl->parms)
> > 
> > Both functions rely on the table lock (read_lock_bh(&tbl->lock))
> > and RTNL is not needed.
> > 
> > Let's fetch the table under RCU and convert RTM_GETNEIGHTBL to RCU.
> > 
> > Note that the first entry of tbl->parms_list is tbl->parms.list and
> > embedded in neigh_table, so list_next_entry() is safe.
> > 
> > Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
> > Reviewed-by: Eric Dumazet <edumazet@google.com>
> > Link: https://patch.msgid.link/20251022054004.2514876-4-kuniyu@google.com
> > Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> > Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
> > Signed-off-by: Sasha Levin <sashal@kernel.org>
> 
> Hi Greg/Sasha,
> 
> An AI-assisted review flagged a reader/writer mismatch. I independently
> checked upstream and 6.12.y at f4ffa8dc360b.
> 
> Upstream neigh_parms_release() in net/core/neighbour.c has:
> 
> write_lock_bh(&tbl->lock);
> list_del_rcu(&parms->list);
> parms->dead = 1;
> write_unlock_bh(&tbl->lock);
> netdev_put(parms->dev, &parms->dev_tracker);
> call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
> 
> 6.12.y has
> net/core/neighbour.c:
> 
> write_lock_bh(&tbl->lock);
> list_del(&parms->list);
> parms->dead = 1;
> write_unlock_bh(&tbl->lock);
> netdev_put(parms->dev, &parms->dev_tracker);
> call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
> 
> neightbl_dump_info() now uses RCU, but list_del() poisons the removed
> node's forward link. A reader can follow that poisoned pointer despite
> delayed free.
> 
> I think 6.12 should take 06d6322280d95757cef1e3ee0fc62c644629523e
> ("neighbour: Use RCU list helpers for neigh_parms.list writers.") and
> 35d7c70870338aa6a367b9e4ed528914320b0be0 ("neighbour: Annotate access to
> neigh_parms fields.") before this conversion, retaining the later dump
> fixes, thoughts?

Already dropped, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params
  2026-10-01 20:39   ` Harshit Mogalapalli
@ 2026-10-02 12:07     ` Greg Kroah-Hartman
  2026-10-02 13:09       ` Richard Fitzgerald
  2026-10-02 21:10     ` Sasha Levin
  1 sibling, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-02 12:07 UTC (permalink / raw)
  To: Harshit Mogalapalli
  Cc: stable, patches, Richard Fitzgerald, Mark Brown, Sasha Levin

On Fri, Oct 02, 2026 at 02:09:11AM +0530, Harshit Mogalapalli wrote:
> 
> 
> On 30/09/26 8:46 pm, Greg Kroah-Hartman wrote:
> > 6.12-stable review patch.  If anyone has any objections, please let me know.
> > 
> > ------------------
> > 
> > From: Richard Fitzgerald <rf@opensource.cirrus.com>
> > 
> > [ Upstream commit 6b382bdfe26a2232091bf743e454e6794295783e ]
> > 
> > In __soc_pcm_hw_params() if there is a snd_soc_dai_link_ch_map with
> > non-zero codec_ch_mask, use that channel mask to restrict which channels
> > are enabled on the codec. But only if there isn't a TDM mask.
> > 
> > It is possible that a snd_soc_dai_link_ch_map could include the same codec
> > multiple times on different CPUs so the for_each_rtd_ch_maps() loop
> > accumulates the channel masks for all entries of that codec.
> > 
> > If a TDM mask was also set, it takes priority and is used instead of any
> > possible snd_soc_dai_link_ch_map entries. (They cannot be ANDed together
> > because the bit positions are indicating different things: TDM is a bit
> > for each TDM slot, codec_ch_mask is a bit for each codec channel.)
> > 
> > This fixes a problem of incorrect TX channels enabled on the codec when
> > multiple codecs are aggregated on a single capture link. For example:
> > 
> > - Two CPUs with six 4-channel codecs.
> > - The machine driver chooses to assign one channel from each codec to
> >    one channel on the CPU
> > - But the codec hw_params() would be passed a channel count of 6, which
> >    (a) is more channels than the codec has and (b) allows enabling channels
> >    that should not be driving the audio bus.
> > 
> > Fixes: ac950278b087 ("ASoC: add N cpus to M codecs dai link support")
> > Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
> > Link: https://patch.msgid.link/20260910114500.1586637-4-rf@opensource.cirrus.com
> > Signed-off-by: Mark Brown <broonie@kernel.org>
> > Signed-off-by: Sasha Levin <sashal@kernel.org>
> 
> Hi Greg/Sasha,
> 
> An AI-assisted review flagged a possible omission. I independently
> checked the core and SoundWire producer at 6.12.y f4ffa8dc360b.
> 
> The core backport correctly preserves TDM precedence and combines
> codec_ch_mask entries for each codec. The question is its missing
> SoundWire producer.
> 
> Upstream's companion has: 290845e151cd4e307cc1f25319583aaceb4eeb30,
> sound/soc/sdw_utils/soc_sdw_utils.c:
> 
> for_each_link_ch_maps(rtd->dai_link, i, ch_maps) {
>     ch_maps->cpu_ch_mask = cpu_ch_mask << (i * step);
>     ch_maps->codec_ch_mask = codec_ch_mask;
> }
> 
> 6.12.y asoc_sdw_hw_params() at f4ffa8dc360bce834e6ea7b0148eab0118f4a42e,
> sound/soc/sdw_utils/soc_sdw_utils.c:
> 
> for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
>     ch_maps->cpu_ch_mask = ch_mask << (i * step);
> 
> Only the declaration and core consumer use codec_ch_mask in include/ and
> sound/. SoundWire leaves it zero, so without a TDM mask the codec keeps
> the aggregate channel count and capture restriction stays inactive.
> Hardware impact was not tested.
> 
> Could the ASoC maintainer confirm whether
> 290845e151cd4e307cc1f25319583aaceb4eeb30 ("ASoC: sdw_utils: Set
> snd_soc_dai_link_ch_map.codec_ch_mask for capture") should accompany
> this 6.12 series to complete the SoundWire capture fix?

If that is true, then that needs to be backported to all stable kernel
trees.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes()
  2026-10-01 19:58   ` Harshit Mogalapalli
@ 2026-10-02 12:09     ` Greg Kroah-Hartman
  2026-10-02 20:47       ` Harshit Mogalapalli
  0 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-02 12:09 UTC (permalink / raw)
  To: Harshit Mogalapalli
  Cc: stable, patches, Julian Sun, Jan Kara,
	Christian Brauner (Amutable), Sasha Levin

On Fri, Oct 02, 2026 at 01:28:39AM +0530, Harshit Mogalapalli wrote:
> 
> 
> On 30/09/26 8:50 pm, Greg Kroah-Hartman wrote:
> > 6.12-stable review patch.  If anyone has any objections, please let me know.
> > 
> > ------------------
> > 
> > From: Julian Sun <sunjunchao@bytedance.com>
> > 
> > [ Upstream commit 7459c021874246c196f397686e100702f059b9e7 ]
> > 
> > We observed hung tasks when users attempted to unmount a filesystem
> > after its disk had been removed while still in use. During device
> > removal, fs_bdev_mark_dead() calls evict_inodes() while holding s_umount.
> > 
> > Each time evict_inodes() drops s_inode_list_lock to reschedule, it
> > restarts the walk from the head of s_inodes. With many referenced inodes
> > at the head of the list, these restarts repeatedly scan the same inodes
> > without reclaiming them. This can keep s_umount held for a long time,
> > blocking concurrent umount attempts and triggering hung-task reports.
> > 
> > Keep the current inode, already marked I_FREEING, out of the disposal
> > batch until s_inode_list_lock is reacquired. Resume the walk from this
> > inode and dispose of it in a later batch or at the end of the walk.
> > 
> > The zero-refcount and state checks under i_lock allow this walker to
> > claim the inode by setting I_FREEING and removing it from the LRU.
> > Other reclaimers skip the inode, leaving this walker responsible for
> > eviction. Only evict() removes it from s_inodes, so keeping it out of
> > the disposal batch ensures that it remains on the list while the lock
> > is dropped. After reacquiring the lock, reading its current next pointer
> > accounts for concurrent removal of following inodes.
> > 
> > The existing inode lifetime rules prohibit acquiring a reference to an
> > inode marked I_FREEING or I_WILL_FREE. __iget() requires its caller to
> > hold i_lock and establish that taking a reference is valid. Inode lookup
> > and igrab() check these flags under i_lock when acquiring a reference
> > from zero. ihold() requires an existing reference, which would keep
> > i_count nonzero and prevent this walker from claiming the inode. These
> > rules already allow iput_final() and the inode shrinker to release
> > i_lock after setting I_FREEING and before eviction completes.
> > 
> > A temporary __iget() reference would also keep the inode on the list,
> > but its release must preserve last-reference handling. Another user can
> > acquire a reference, update lazy timestamps and drop its reference while
> > the pin is held. If the pin becomes the last reference, dropping it with
> > atomic_dec_and_test() and evicting directly bypasses iput()'s lazytime
> > handling and can lose those timestamp updates.
> > 
> > Releasing the pin with iput() preserves that handling, but does not
> > guarantee eviction. fs_bdev_mark_dead() runs with SB_ACTIVE set, so iput()
> > may retain the inode in cache, whereas evict_inodes() must evict eligible
> > zero-reference inodes. The inode may also have been freed when iput()
> > returns, so the walker cannot then use it to force eviction. Using
> > I_FREEING preserves the existing eviction behavior without introducing
> > an additional last-reference transition.
> > 
> > The xfstests auto group passed on ext4 and XFS with known unrelated
> > failures excluded. No new issues were observed, and the previously
> > reproducible hung task no longer occurs with this patch.
> > 
> > Fixes: ac05fbb40062 ("inode: don't softlockup when evicting inodes")
> > Signed-off-by: Julian Sun <sunjunchao@bytedance.com>
> > Link: https://patch.msgid.link/20260915044912.3183440-1-sunjunchao@bytedance.com
> > Reviewed-by: Jan Kara <jack@suse.cz>
> > Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
> > Signed-off-by: Sasha Levin <sashal@kernel.org>
> 
> Hi Greg/Sasha,
> 
> An AI assisted backport review flagged this, and I checked the upstream
> code against the 6.12.y tip f4ffa8dc360b.
> 
> Upstream 7459c0218742 uses the current inode's successor after
> relocking:
> 
>     struct inode *inode;
>     LIST_HEAD(dispose);
> 
>     spin_lock(&sb->s_inode_list_lock);
>     list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
>         /* ... intervening source omitted ... */
>         if (need_resched()) {
>             spin_unlock(&sb->s_inode_list_lock);
>             cond_resched();
>             dispose_list(&dispose);
>             spin_lock(&sb->s_inode_list_lock);
>         }
>         list_add(&inode->i_lru, &dispose);
> 
> 6.12.y retains the cached-successor iterator:
> 
>     struct inode *inode, *next;
>     LIST_HEAD(dispose);
> 
>     spin_lock(&sb->s_inode_list_lock);
>     list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
>         /* ... intervening source omitted ... */
>         if (need_resched()) {
>             spin_unlock(&sb->s_inode_list_lock);
>             cond_resched();
>             dispose_list(&dispose);
>             spin_lock(&sb->s_inode_list_lock);
>         }
>         list_add(&inode->i_lru, &dispose);
> 
> I_FREEING protects inode, but the safe iterator's cached next can be
> detached or freed while the lock is dropped.  The 6.12's invalidate_inodes()
> differs from upstream's disk-removal trigger.
> 
> I think 6.12.y needs the two-line iterator change from
> 3bc4e4410830d556b0f40dfa6671bfcaeacc1599 ("vfs: Remove unnecessary
> list_for_each_entry_safe() from evict_inodes()") before this backport,
> thoughts?

If it's needed, it needs to be backported here and to older stable
kernels, and it needs a manual backport as it doesn't apply cleanly.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits when offloading
  2026-10-01 20:12   ` Harshit Mogalapalli
@ 2026-10-02 12:10     ` Greg Kroah-Hartman
  2026-10-02 20:43       ` Harshit Mogalapalli
  0 siblings, 1 reply; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-02 12:10 UTC (permalink / raw)
  To: Harshit Mogalapalli
  Cc: stable, patches, Sabrina Dubroca, Simon Horman, Jakub Kicinski,
	Sasha Levin

On Fri, Oct 02, 2026 at 01:42:28AM +0530, Harshit Mogalapalli wrote:
> 
> 
> On 30/09/26 8:52 pm, Greg Kroah-Hartman wrote:
> > 6.12-stable review patch.  If anyone has any objections, please let me know.
> > 
> > ------------------
> > 
> > From: Sabrina Dubroca <sd@queasysnail.net>
> > 
> > [ Upstream commit de187a390838c0b3dfd00ae5399aa406d0a79f13 ]
> > 
> > If macsec is offloaded, we need to follow the lower device's
> > capabilities, like VLAN devices do.
> > 
> > Leave the limits unchanged when the offload is disabled.
> > 
> > Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
> > Reviewed-by: Simon Horman <horms@kernel.org>
> > Link: https://patch.msgid.link/8240c0181e851f169d815f59658a01fb9dfc5073.1730929545.git.sd@queasysnail.net
> > Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> > Stable-dep-of: c2de369c5c5b ("macsec: initialize SecY before registering the netdevice")
> > Signed-off-by: Sasha Levin <sashal@kernel.org>
> > ---
> >   drivers/net/macsec.c | 22 ++++++++++++++++++++++
> >   1 file changed, 22 insertions(+)
> > 
> > diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
> > index b1eb6b5dde0fe..ce4a08f77724f 100644
> > --- a/drivers/net/macsec.c
> > +++ b/drivers/net/macsec.c
> > @@ -2650,6 +2650,17 @@ static void macsec_set_head_tail_room(struct net_device *dev)
> >   	dev->needed_tailroom = real_dev->needed_tailroom + needed_tailroom;
> >   }
> > +static void macsec_inherit_tso_max(struct net_device *dev)
> > +{
> > +	struct macsec_dev *macsec = macsec_priv(dev);
> > +
> > +	/* if macsec is offloaded, we need to follow the lower
> > +	 * device's capabilities. otherwise, we can ignore them.
> > +	 */
> > +	if (macsec_is_offloaded(macsec))
> > +		netif_inherit_tso_max(dev, macsec->real_dev);
> > +}
> > +
> >   static int macsec_update_offload(struct net_device *dev, enum macsec_offload offload)
> >   {
> >   	enum macsec_offload prev_offload;
> > @@ -2695,6 +2706,8 @@ static int macsec_update_offload(struct net_device *dev, enum macsec_offload off
> >   	macsec_set_head_tail_room(dev);
> >   	macsec->insert_tx_tag = macsec_needs_tx_tag(macsec, ops);
> > +	macsec_inherit_tso_max(dev);
> > +
> >   	netdev_update_features(dev);
> >   	return ret;
> > @@ -3566,6 +3579,8 @@ static int macsec_dev_init(struct net_device *dev)
> >   	if (err)
> >   		return err;
> > +	macsec_inherit_tso_max(dev);
> > +
> >   	dev->hw_features = real_dev->hw_features & MACSEC_OFFLOAD_FEATURES;
> >   	dev->hw_features |= NETIF_F_GSO_SOFTWARE;
> > @@ -4521,6 +4536,13 @@ static int macsec_notify(struct notifier_block *this, unsigned long event,
> >   			if (dev->mtu > mtu)
> >   				dev_set_mtu(dev, mtu);
> >   		}
> > +		break;
> > +	case NETDEV_FEAT_CHANGE:
> > +		list_for_each_entry(m, &rxd->secys, secys) {
> > +			macsec_inherit_tso_max(m->secy.netdev);
> > +			netdev_update_features(m->secy.netdev);
> > +		}
> > +		break;
> 
> Hi Greg/Sasha,
> 
> An AI assisted backport review flagged this, and I checked the upstream
> code against the 6.12.y tip f4ffa8dc360b.
> 
> Upstream de187a390838 initializes rxd before macsec_notify() dispatches:
> 
>     struct macsec_rxh_data *rxd;
>     struct macsec_dev *m, *n;
>     LIST_HEAD(head);
> 
>     if (!is_macsec_master(real_dev))
>         return NOTIFY_DONE;
> 
>     rxd = macsec_data_rtnl(real_dev);
> 
>     switch (event) {
> 
> 6.12.y inserts the new label inside the older MTU case's block:
> 
>     case NETDEV_CHANGEMTU: {
>         struct macsec_dev *m;
>         struct macsec_rxh_data *rxd;
> 
>         rxd = macsec_data_rtnl(real_dev);
>         /* ... intervening source omitted ... */
>         break;
>     case NETDEV_FEAT_CHANGE:
>         list_for_each_entry(m, &rxd->secys, secys) {
>             macsec_inherit_tso_max(m->secy.netdev);
>             netdev_update_features(m->secy.netdev);
>         }
>         break;
>     }
> 
> NETDEV_FEAT_CHANGE skips the rxd assignment and dereferences an
> uninitialized pointer. Software MACsec reaches it too, before the
> offload check.
> 
> I think 6.12.y needs f29d24a2106ae28a9b257503a615ee438efa3f95 ("macsec:
> clean up local variables in macsec_notify") before this backport,
> thoughts?

This patch is now dropped, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 773/877] mptcp: prevent race between disconnect() and rtx
  2026-10-01 20:30   ` Harshit Mogalapalli
@ 2026-10-02 12:11     ` Greg Kroah-Hartman
  0 siblings, 0 replies; 922+ messages in thread
From: Greg Kroah-Hartman @ 2026-10-02 12:11 UTC (permalink / raw)
  To: Harshit Mogalapalli
  Cc: stable, patches, Paolo Abeni, Matthieu Baerts (NGI0),
	Jakub Kicinski, Sasha Levin

On Fri, Oct 02, 2026 at 02:00:40AM +0530, Harshit Mogalapalli wrote:
> 
> 
> On 30/09/26 8:58 pm, Greg Kroah-Hartman wrote:
> > 6.12-stable review patch.  If anyone has any objections, please let me know.
> > 
> > ------------------
> > 
> > From: Paolo Abeni <pabeni@redhat.com>
> > 
> > [ Upstream commit 85c580b0d8590520ae00a15c29e9fb9c99427a3e ]
> > 
> > Sashiko noted that the two event can race, leading to inconsistent
> > status. Prevent the race using the synchronous timer stop operation.
> > 
> > Cc: stable@vger.kernel.org
> > Fixes: b29fcfb54cd7 ("mptcp: full disconnect implementation")
> > Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> > Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> > Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> > Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-6-df1de70348b6@kernel.org
> > Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> > Signed-off-by: Sasha Levin <sashal@kernel.org>
> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > ---
> >   net/mptcp/protocol.c |   10 ++++++++--
> >   1 file changed, 8 insertions(+), 2 deletions(-)
> > 
> > --- a/net/mptcp/protocol.c
> > +++ b/net/mptcp/protocol.c
> > @@ -3367,6 +3367,7 @@ static void mptcp_copy_inaddrs(struct so
> >   static int mptcp_disconnect(struct sock *sk, int flags)
> >   {
> > +	struct inet_connection_sock *icsk = inet_csk(sk);
> >   	struct mptcp_sock *msk = mptcp_sk(sk);
> >   	/* We are on the fastopen error path. We can't call straight into the
> > @@ -3379,8 +3380,13 @@ static int mptcp_disconnect(struct sock
> >   	mptcp_check_listen_stop(sk);
> >   	mptcp_set_state(sk, TCP_CLOSE);
> > -	mptcp_stop_rtx_timer(sk);
> > -	mptcp_stop_tout_timer(sk);
> > +	/* The later subflow close can not kick again the tout timer,
> > +	 * as the msk is already in closed status.
> > +	 */
> > +	msk->timer_ival = icsk->icsk_rto_min;
> ^^^
> 
> Hi Greg/Sasha,
> 
> An AI-assisted review flagged the reset expression, and I checked the
> MPTCP parent-socket initialization on 6.12.
> 
> Upstream, net/mptcp/protocol.c, __mptcp_init_sock():
> 
>     icsk->icsk_rto_min =
>         usecs_to_jiffies(READ_ONCE(net->ipv4.sysctl_tcp_rto_min_us));
> 
> Then mptcp_disconnect() uses:
> 
>     msk->timer_ival = icsk->icsk_rto_min;
> 
> 6.12's initializer instead has:
> 
>     msk->timer_ival = TCP_RTO_MIN;
> 
> 6.12 never initializes the parent's icsk_rto_min or calls
> tcp_init_sock(), so disconnect reads zero; the subflow's initialized
> field does not help. Upstream's broader RTO feature,
> ea4eb2adb0d3414abeddaba72dbf8876fa66528f ("mptcp: honour configured
> min/max RTO in retransmit paths"), supplies the missing initialization.
> 
> Could we use msk->timer_ival = TCP_RTO_MIN on 6.12, matching its
> initializer while retaining the synchronous stops?
> 
> 
> should we drop this for now ?

Now dropped, thanks.

greg k-h

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params
  2026-10-02 12:07     ` Greg Kroah-Hartman
@ 2026-10-02 13:09       ` Richard Fitzgerald
  0 siblings, 0 replies; 922+ messages in thread
From: Richard Fitzgerald @ 2026-10-02 13:09 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Harshit Mogalapalli
  Cc: stable, patches, Mark Brown, Sasha Levin

On 02/10/2026 1:07 pm, Greg Kroah-Hartman wrote:
> On Fri, Oct 02, 2026 at 02:09:11AM +0530, Harshit Mogalapalli wrote:
>>
>>
>> On 30/09/26 8:46 pm, Greg Kroah-Hartman wrote:
>>> 6.12-stable review patch.  If anyone has any objections, please let me know.
>>>
>>> ------------------
>>>
>>> From: Richard Fitzgerald <rf@opensource.cirrus.com>
>>>
>>> [ Upstream commit 6b382bdfe26a2232091bf743e454e6794295783e ]
>>>
>>> In __soc_pcm_hw_params() if there is a snd_soc_dai_link_ch_map with
>>> non-zero codec_ch_mask, use that channel mask to restrict which channels
>>> are enabled on the codec. But only if there isn't a TDM mask.
>>>
>>> It is possible that a snd_soc_dai_link_ch_map could include the same codec
>>> multiple times on different CPUs so the for_each_rtd_ch_maps() loop
>>> accumulates the channel masks for all entries of that codec.
>>>
>>> If a TDM mask was also set, it takes priority and is used instead of any
>>> possible snd_soc_dai_link_ch_map entries. (They cannot be ANDed together
>>> because the bit positions are indicating different things: TDM is a bit
>>> for each TDM slot, codec_ch_mask is a bit for each codec channel.)
>>>
>>> This fixes a problem of incorrect TX channels enabled on the codec when
>>> multiple codecs are aggregated on a single capture link. For example:
>>>
>>> - Two CPUs with six 4-channel codecs.
>>> - The machine driver chooses to assign one channel from each codec to
>>>     one channel on the CPU
>>> - But the codec hw_params() would be passed a channel count of 6, which
>>>     (a) is more channels than the codec has and (b) allows enabling channels
>>>     that should not be driving the audio bus.
>>>
>>> Fixes: ac950278b087 ("ASoC: add N cpus to M codecs dai link support")
>>> Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
>>> Link: https://patch.msgid.link/20260910114500.1586637-4-rf@opensource.cirrus.com
>>> Signed-off-by: Mark Brown <broonie@kernel.org>
>>> Signed-off-by: Sasha Levin <sashal@kernel.org>
>>
>> Hi Greg/Sasha,
>>
>> An AI-assisted review flagged a possible omission. I independently
>> checked the core and SoundWire producer at 6.12.y f4ffa8dc360b.
>>
>> The core backport correctly preserves TDM precedence and combines
>> codec_ch_mask entries for each codec. The question is its missing
>> SoundWire producer.
>>
>> Upstream's companion has: 290845e151cd4e307cc1f25319583aaceb4eeb30,
>> sound/soc/sdw_utils/soc_sdw_utils.c:
>>
>> for_each_link_ch_maps(rtd->dai_link, i, ch_maps) {
>>      ch_maps->cpu_ch_mask = cpu_ch_mask << (i * step);
>>      ch_maps->codec_ch_mask = codec_ch_mask;
>> }
>>
>> 6.12.y asoc_sdw_hw_params() at f4ffa8dc360bce834e6ea7b0148eab0118f4a42e,
>> sound/soc/sdw_utils/soc_sdw_utils.c:
>>
>> for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
>>      ch_maps->cpu_ch_mask = ch_mask << (i * step);
>>
>> Only the declaration and core consumer use codec_ch_mask in include/ and
>> sound/. SoundWire leaves it zero, so without a TDM mask the codec keeps
>> the aggregate channel count and capture restriction stays inactive.
>> Hardware impact was not tested.
>>
>> Could the ASoC maintainer confirm whether
>> 290845e151cd4e307cc1f25319583aaceb4eeb30 ("ASoC: sdw_utils: Set
>> snd_soc_dai_link_ch_map.codec_ch_mask for capture") should accompany
>> this 6.12 series to complete the SoundWire capture fix?
> 
> If that is true, then that needs to be backported to all stable kernel
> trees.
> 
> thanks,
> 
> greg k-h
It's likely not a critical omission if nobody has noticed the bug before
now.

So I'd guess all currently shipping products just happen to work (either
it's a single codec so no aggregation, or 2 stereo amp so the incorrect
channel count of 2 is supported by the codec driver anyway).

However, I can only speak for Cirrus Logic amps, which aren't
_currently_ using this (but will in future). I can't say whether there
is other silicon that uses this and is in fact broken without anyone
having noticed.

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits when offloading
  2026-10-02 12:10     ` Greg Kroah-Hartman
@ 2026-10-02 20:43       ` Harshit Mogalapalli
  0 siblings, 0 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-02 20:43 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: stable, patches, Sabrina Dubroca, Simon Horman, Jakub Kicinski,
	Sasha Levin

Hi Greg,

>> 6.12.y inserts the new label inside the older MTU case's block:
>> 
>>     case NETDEV_CHANGEMTU: {
>>         struct macsec_dev *m;
>>         struct macsec_rxh_data *rxd;
>> 
>>         rxd = macsec_data_rtnl(real_dev);
>>         /* ... intervening source omitted ... */
>>         break;
>>     case NETDEV_FEAT_CHANGE:
>>         list_for_each_entry(m, &rxd->secys, secys) {
>>             macsec_inherit_tso_max(m->secy.netdev);
>>             netdev_update_features(m->secy.netdev);
>>         }
>>         break;
>>     }
>> 
>> NETDEV_FEAT_CHANGE skips the rxd assignment and dereferences an
>> uninitialized pointer. Software MACsec reaches it too, before the
>> offload check.
>> 
>> I think 6.12.y needs f29d24a2106ae28a9b257503a615ee438efa3f95 ("macsec:
>> clean up local variables in macsec_notify") before this backport,
>> thoughts?
> 
> This patch is now dropped, thanks.
> 

thanks for dealing with this and other report Greg!


Harshit

> greg k-h
> 

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes()
  2026-10-02 12:09     ` Greg Kroah-Hartman
@ 2026-10-02 20:47       ` Harshit Mogalapalli
  2026-10-03  1:30         ` Sasha Levin
  0 siblings, 1 reply; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-02 20:47 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: stable, patches, Julian Sun, Jan Kara,
	Christian Brauner (Amutable), Sasha Levin

Hi Greg,

>> 
>> Hi Greg/Sasha,
>> 
>> An AI assisted backport review flagged this, and I checked the upstream
>> code against the 6.12.y tip f4ffa8dc360b.
>> 
>> Upstream 7459c0218742 uses the current inode's successor after
>> relocking:
>> 
>>     struct inode *inode;
>>     LIST_HEAD(dispose);
>> 
>>     spin_lock(&sb->s_inode_list_lock);
>>     list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
>>         /* ... intervening source omitted ... */
>>         if (need_resched()) {
>>             spin_unlock(&sb->s_inode_list_lock);
>>             cond_resched();
>>             dispose_list(&dispose);
>>             spin_lock(&sb->s_inode_list_lock);
>>         }
>>         list_add(&inode->i_lru, &dispose);
>> 
>> 6.12.y retains the cached-successor iterator:
>> 
>>     struct inode *inode, *next;
>>     LIST_HEAD(dispose);
>> 
>>     spin_lock(&sb->s_inode_list_lock);
>>     list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
>>         /* ... intervening source omitted ... */
>>         if (need_resched()) {
>>             spin_unlock(&sb->s_inode_list_lock);
>>             cond_resched();
>>             dispose_list(&dispose);
>>             spin_lock(&sb->s_inode_list_lock);
>>         }
>>         list_add(&inode->i_lru, &dispose);
>> 
>> I_FREEING protects inode, but the safe iterator's cached next can be
>> detached or freed while the lock is dropped.  The 6.12's invalidate_inodes()
>> differs from upstream's disk-removal trigger.
>> 
>> I think 6.12.y needs the two-line iterator change from
>> 3bc4e4410830d556b0f40dfa6671bfcaeacc1599 ("vfs: Remove unnecessary
>> list_for_each_entry_safe() from evict_inodes()") before this backport,
>> thoughts?
> 
> If it's needed, it needs to be backported here and to older stable
> kernels, and it needs a manual backport as it doesn't apply cleanly.
> 

Please drop this stable backport.

They retain:

	list_for_each_entry_safe(inode, next, &sb->s_inodes,
                                    i_sb_list) {
              ...
              spin_unlock(&sb->s_inode_list_lock);
              dispose_list(&dispose);
              spin_lock(&sb->s_inode_list_lock);
         }

The safe iterator cached next before the unlock. A concurrent final
iput() can remove and free next while the lock is dropped. The loop
then dereferences that freed inode:

        inode = next;
        next = list_next_entry(next, i_sb_list);

I_FREEING protects only inode, not next. This creates a use-after-free 
risk that can cause a crash or memory corruption.

3bc4e4410830 changes the walk to:

           list_for_each_entry(inode, &sb->s_inodes, i_sb_list)

This reads inode's updated successor after relocking. So until we take 
both the backport and its prereq together I think we better drop this.

thanks,
Harshit

> thanks,
> 
> greg k-h
> 

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices
  2026-10-01 20:09   ` Harshit Mogalapalli
@ 2026-10-02 20:59     ` Harshit Mogalapalli
  2026-10-03  1:30       ` Sasha Levin
  2026-10-02 21:10     ` Sasha Levin
  1 sibling, 1 reply; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-02 20:59 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable, Sasha Levin
  Cc: patches, co+ac0a8c41de69121d, Weiming Shi, Alexei Starovoitov

Hi Greg/Sasha,

On 02/10/26 1:39 am, Harshit Mogalapalli wrote:
> 
> 
...
>> Signed-off-by: Sasha Levin <sashal@kernel.org>
>> ---
>>   kernel/bpf/offload.c | 2 ++
>>   1 file changed, 2 insertions(+)
>>
>> diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c
>> index 56115739fcfdd..1b6f9e7175666 100644
>> --- a/kernel/bpf/offload.c
>> +++ b/kernel/bpf/offload.c
>> @@ -703,6 +703,8 @@ static bool __bpf_offload_dev_match(struct 
>> bpf_prog *prog,
>>           return false;
>>       if (offload->netdev == netdev)
>>           return true;
>> +    if (!bpf_prog_is_offloaded(prog->aux))
>> +        return false;
> 
> 
> Hi Greg/Sasha,
> 
> An AI assisted backport review flagged this, and I checked the upstream
> code against the 6.12.y tip f4ffa8dc360b.
> 
> Upstream 6db1ce73e985 checks device binding in dev_xdp_install():
> 
>          if (bpf_prog_is_dev_bound(prog->aux) &&
>              !bpf_offload_dev_match(prog, dev)) {
>              NL_SET_ERR_MSG(extack, "Program bound to different device");
>              return -EINVAL;
>          }
> 
> 6.12.y bpf_xdp_link_update() goes directly to that installer:
> 
>      mode = dev_xdp_mode(xdp_link->dev, xdp_link->flags);
>      bpf_op = dev_xdp_bpf_op(xdp_link->dev, mode);
>      err = dev_xdp_install(xdp_link->dev, mode, bpf_op, NULL,
>                            xdp_link->flags, new_prog);
>      if (err)
>          goto out_unlock;
> 
> Link update calls dev_xdp_install() directly, bypassing 6.12's binding
> check in dev_xdp_attach(). Type checks and tun's callback cannot prevent
> wrong-device installation, leaving metadata kfuncs with an incompatible
> context. The matcher fix is correct; this bypass predates it. No
> destination kernel crash was reproduced.
> 
> I think 6.12.y needs ad27ed7d2309419a129078d781504f486b1b469a ("bpf,
> xdp: move offload check into dev_xdp_install()"), adapted to the 6.12
> installer, alongside this fix, thoughts?
> 

https://git.kernel.org/pub/scm/linux/kernel/git/stable/stable-queue.git/tree/queue-6.12 
I still see this.

I think we need to drop this until we take the prereq as well Greg.

Sorry for the ping.

thanks,
Harshit



> thanks,
> Harshit>
>>       ondev1 = bpf_offload_find_netdev(offload->netdev);
>>       ondev2 = bpf_offload_find_netdev(netdev);
> 


^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 746/877] ipv4: remove fib_devindex_hashfn()
  2026-10-01 20:24   ` Harshit Mogalapalli
@ 2026-10-02 21:04     ` Harshit Mogalapalli
  2026-10-03  1:30       ` Sasha Levin
  2026-10-02 21:10     ` Sasha Levin
  1 sibling, 1 reply; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-02 21:04 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable, Sasha Levin
  Cc: patches, Eric Dumazet, Kuniyuki Iwashima, David Ahern,
	Jakub Kicinski

Hi Greg/Sasha,

On 02/10/26 1:54 am, Harshit Mogalapalli wrote:
> 
> 
> On 30/09/26 8:57 pm, Greg Kroah-Hartman wrote:
>> 6.12-stable review patch.  If anyone has any objections, please let me 
>> know.
>>
>> ------------------
>>
>> From: Eric Dumazet <edumazet@google.com>
>>
....


> 
> An AI-assisted review flagged this, and I checked the upstream and 6.12
> code. Removing fib_devindex_hashfn() also needs the upstream finalizer.
> 
> Upstream, net/ipv4/fib_semantics.c:
> 
>      return hash_32(val ^ net_hash_mix(net), fib_info_hash_bits);
> 
> 6.12.y still has:
> 
>      unsigned int mask = (fib_info_hash_size - 1);
>      return (val ^ (val >> 7) ^ (val >> 12)) & mask;
> 
> The old finalizer ignores upper bits of raw nexthop IDs/ifindices at
> ordinary table sizes. In a 256-bucket check with equal route metadata,
> 128 IDs differing only in their upper byte use 128 buckets before, one
> after, and 128 upstream.
> 
> I think 6.12 needs 9b8ca04854fd1253a58aeb1bd089c191cb5a074c ("ipv4:
> avoid quadratic behavior in FIB insertion of common address") before
> this change, including both finalizer callers, thoughts?
This also belongs to - we need not/should not take the fix until we take 
a prerequisite category. Could we drop this until we have a proper 
backport ?

Sorry for the ping.

thanks,
Harshit

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL to RCU.
  2026-10-01 19:34   ` Harshit Mogalapalli
  2026-10-02 12:06     ` Greg Kroah-Hartman
@ 2026-10-02 21:10     ` Sasha Levin
  1 sibling, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-02 21:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: Sasha Levin, patches, Kuniyuki Iwashima, Eric Dumazet,
	Jakub Kicinski, Harshit Mogalapalli

> I think 6.12 should take 06d6322280d95757cef1e3ee0fc62c644629523e
> ("neighbour: Use RCU list helpers for neigh_parms.list writers.") and
> 35d7c70870338aa6a367b9e4ed528914320b0be0 ("neighbour: Annotate access to
> neigh_parms fields.") before this conversion, retaining the later dump
> fixes, thoughts?

Greg dropped this from 6.12, but 6.18 already shipped the conversion in
6.18.54 without the writer side, so I've queued both of these for 6.18,
thanks.

-- 
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices
  2026-10-01 20:09   ` Harshit Mogalapalli
  2026-10-02 20:59     ` Harshit Mogalapalli
@ 2026-10-02 21:10     ` Sasha Levin
  1 sibling, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-02 21:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: Sasha Levin, patches, co+ac0a8c41de69121d, Weiming Shi,
	Alexei Starovoitov, Harshit Mogalapalli

> I think 6.12.y needs ad27ed7d2309419a129078d781504f486b1b469a ("bpf,
> xdp: move offload check into dev_xdp_install()"), adapted to the 6.12
> installer, alongside this fix, thoughts?

Queued for 6.12 and 6.6, thanks.

-- 
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params
  2026-10-01 20:39   ` Harshit Mogalapalli
  2026-10-02 12:07     ` Greg Kroah-Hartman
@ 2026-10-02 21:10     ` Sasha Levin
  1 sibling, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-02 21:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: Sasha Levin, patches, Richard Fitzgerald, Mark Brown,
	Harshit Mogalapalli

> Could the ASoC maintainer confirm whether
> 290845e151cd4e307cc1f25319583aaceb4eeb30 ("ASoC: sdw_utils: Set
> snd_soc_dai_link_ch_map.codec_ch_mask for capture") should accompany
> this 6.12 series to complete the SoundWire capture fix?

Queued for 7.2, 6.18 and 6.12, thanks.

-- 
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 092/877] neighbour: Use rtnl_register_many().
  2026-10-01 19:19   ` Harshit Mogalapalli
  2026-10-02  8:48     ` Greg Kroah-Hartman
@ 2026-10-02 21:10     ` Sasha Levin
  2026-10-02 21:23       ` Harshit Mogalapalli
  1 sibling, 1 reply; 922+ messages in thread
From: Sasha Levin @ 2026-10-02 21:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: Sasha Levin, patches, Kuniyuki Iwashima, Eric Dumazet,
	Jakub Kicinski, Harshit Mogalapalli

> > Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")

[...]

> Lets drop this until we also take a prereq ?

Greg dropped the series. I've queued the neightbl_dump_info() fix by
itself for 6.12, thanks.

-- 
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 746/877] ipv4: remove fib_devindex_hashfn()
  2026-10-01 20:24   ` Harshit Mogalapalli
  2026-10-02 21:04     ` Harshit Mogalapalli
@ 2026-10-02 21:10     ` Sasha Levin
  2026-10-02 21:17       ` Harshit Mogalapalli
  1 sibling, 1 reply; 922+ messages in thread
From: Sasha Levin @ 2026-10-02 21:10 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: Sasha Levin, patches, Eric Dumazet, Kuniyuki Iwashima,
	David Ahern, Jakub Kicinski, Harshit Mogalapalli

> The old finalizer ignores upper bits of raw nexthop IDs/ifindices at
> ordinary table sizes. In a 256-bucket check with equal route metadata,
> 128 IDs differing only in their upper byte use 128 buckets before, one
> after, and 128 upstream.
>
> I think 6.12 needs 9b8ca04854fd1253a58aeb1bd089c191cb5a074c ("ipv4:
> avoid quadratic behavior in FIB insertion of common address") before
> this change, including both finalizer callers, thoughts?

Right, 6.12 still has the old finalizer. The cost is longer fib_info
hash chains when inserting routes; nothing becomes incorrect. I'm not
going to pull that commit into 6.12 for now.

-- 
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 746/877] ipv4: remove fib_devindex_hashfn()
  2026-10-02 21:10     ` Sasha Levin
@ 2026-10-02 21:17       ` Harshit Mogalapalli
  0 siblings, 0 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-02 21:17 UTC (permalink / raw)
  To: Sasha Levin, Greg Kroah-Hartman, stable
  Cc: patches, Eric Dumazet, Kuniyuki Iwashima, David Ahern,
	Jakub Kicinski

Hi Sasha,

On 03/10/26 2:40 am, Sasha Levin wrote:
>> The old finalizer ignores upper bits of raw nexthop IDs/ifindices at
>> ordinary table sizes. In a 256-bucket check with equal route metadata,
>> 128 IDs differing only in their upper byte use 128 buckets before, one
>> after, and 128 upstream.
>>
>> I think 6.12 needs 9b8ca04854fd1253a58aeb1bd089c191cb5a074c ("ipv4:
>> avoid quadratic behavior in FIB insertion of common address") before
>> this change, including both finalizer callers, thoughts?
> 
> Right, 6.12 still has the old finalizer. The cost is longer fib_info
> hash chains when inserting routes; nothing becomes incorrect. I'm not
> going to pull that commit into 6.12 for now.

Sure, sounds good.

Regards,
Harshit>


^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 092/877] neighbour: Use rtnl_register_many().
  2026-10-02 21:10     ` Sasha Levin
@ 2026-10-02 21:23       ` Harshit Mogalapalli
  0 siblings, 0 replies; 922+ messages in thread
From: Harshit Mogalapalli @ 2026-10-02 21:23 UTC (permalink / raw)
  To: Sasha Levin, Greg Kroah-Hartman, stable
  Cc: patches, Kuniyuki Iwashima, Eric Dumazet, Jakub Kicinski



On 03/10/26 2:40 am, Sasha Levin wrote:
>>> Stable-dep-of: 979aabdad8dd ("neighbour: Skip default parms when resumed in neightbl_dump_info().")
> 
> [...]
> 
>> Lets drop this until we also take a prereq ?
> 
> Greg dropped the series. I've queued the neightbl_dump_info() fix by
> itself for 6.12, thanks.


thanks Sasha.

Regards,
Harshit>


^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes()
  2026-10-02 20:47       ` Harshit Mogalapalli
@ 2026-10-03  1:30         ` Sasha Levin
  0 siblings, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-03  1:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Sasha Levin, stable, patches, Julian Sun, Jan Kara,
	Christian Brauner (Amutable), Harshit Mogalapalli

> Please drop this stable backport.

Dropped from the 6.12, 6.6, 6.1, 5.15 and 5.10 queues, thanks.

It stays in 7.2 and 6.18: their bases already have 3bc4e4410830
("vfs: Remove unnecessary list_for_each_entry_safe() from
evict_inodes()"), so evict_inodes() there already walks the list with
list_for_each_entry().

-- 
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush
  2026-10-01 20:21   ` Harshit Mogalapalli
  2026-10-02  6:24     ` Greg Kroah-Hartman
@ 2026-10-03  1:30     ` Sasha Levin
  1 sibling, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-03  1:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: Sasha Levin, patches, Darrick J. Wong, Christoph Hellwig,
	Carlos Maiolino, Harshit Mogalapalli

> Could we replace the new mutex_unlock()/xfs_qm_dqrele() pair with
> xfs_dqunlock(dqp), keeping the early return and out_dqflock cleanup?
>
> or drop this fix for 6.12.y ?

Greg already dropped the 6.12 copy. The 6.18 queue had the same
unbalanced xfs_qm_dqrele(): 6.18 doesn't have 0c5e80bd579f7 ("xfs: use
a lockref for the xfs_dquot reference count", v6.19-rc1), so its
xfs_qm_flush_one() never takes the lockref_get_not_dead() reference
that the new exit path releases. I've dropped it from 6.18 as well.

7.2 has that reference, so it keeps the patch.

-- 
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 746/877] ipv4: remove fib_devindex_hashfn()
  2026-10-02 21:04     ` Harshit Mogalapalli
@ 2026-10-03  1:30       ` Sasha Levin
  0 siblings, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-03  1:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: Sasha Levin, patches, Eric Dumazet, Kuniyuki Iwashima,
	David Ahern, Jakub Kicinski, Harshit Mogalapalli

> This also belongs to - we need not/should not take the fix until we take 
> a prerequisite category. Could we drop this until we have a proper 
> backport ?

Dropped from the 6.12 queue, together with fc38b28365e5 ("ipv4: use
rcu in ip_fib_check_default()") and a3f5f4c2f9b6 ("ipv4: remove
fib_info_devhash[]"), which were queued alongside it, thanks.

The ipv6 flowlabel fix they were pulled in for, 8d6cd1885085 ("ipv6:
flowlabel: cap duplicate leases per socket"), doesn't actually depend
on any of the three, so it stays.

-- 
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 922+ messages in thread

* Re: [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices
  2026-10-02 20:59     ` Harshit Mogalapalli
@ 2026-10-03  1:30       ` Sasha Levin
  0 siblings, 0 replies; 922+ messages in thread
From: Sasha Levin @ 2026-10-03  1:30 UTC (permalink / raw)
  To: Greg Kroah-Hartman, stable
  Cc: Sasha Levin, patches, co+ac0a8c41de69121d, Weiming Shi,
	Alexei Starovoitov, Harshit Mogalapalli

> I think we need to drop this until we take the prereq as well Greg.

ad27ed7d2309 ("bpf, xdp: move offload check into dev_xdp_install()")
is queued for the next 6.12 and 6.6 releases.

I'm keeping 6db1ce73e985 in this release, because it independently
closes the BPF_LINK_CREATE/netlink path. Without the prereq the
LINK_UPDATE path stays open, as it already is today, so the fix is
incomplete but not a regression. Dropping it would leave both paths
open.

-- 
Thanks,
Sasha

^ permalink raw reply	[flat|nested] 922+ messages in thread

end of thread, other threads:[~2026-10-03  1:30 UTC | newest]

Thread overview: 922+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-30 15:15 [PATCH 6.12 000/877] 6.12.112-rc1 review Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 001/877] Revert "hwmon: (emc1403) Drop hysteresis for low limit temperature" Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 002/877] Revert "hwmon: (emc1403) Rely on subsystem locking" Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 003/877] landlock: Fix TCP Fast Open connection bypass Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 004/877] selftests/landlock: Add test for TCP fast open Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 005/877] selftests/landlock: Add missing connect(minimal AF_UNSPEC) test Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 006/877] selftests/landlock: Add tests for access through disconnected paths Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 007/877] selftests/landlock: Add disconnected leafs and branch test suites Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 008/877] s390/boot: Add sized_strscpy() to enable strscpy() usage Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 009/877] s390/boot: Avoid IPL parameter append past command line Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 010/877] selftests/landlock: Add tests for whiteout object creation Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 011/877] sunvdc: fix -EIO issue due to lack of retries Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 012/877] net: cpsw_new: Execute ndo_set_rx_mode callback in a work queue Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 013/877] net: cpsw: " Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 014/877] ipv6: mcast: Use in6_dev_get() in ipv6_dev_mc_dec() Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 015/877] ipv6: mcast: Dont hold RTNL for IPV6_ADD_MEMBERSHIP and MCAST_JOIN_GROUP Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 016/877] ipv6: mcast: Dont hold RTNL for IPV6_DROP_MEMBERSHIP and MCAST_LEAVE_GROUP Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 017/877] ipv6: mcast: Dont hold RTNL for MCAST_ socket options Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 018/877] ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source() Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 019/877] media: video-i2c: fix buffer queue ordering Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 020/877] ipv6: Select best matching nexthop object in fib6_table_lookup() Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 021/877] ipv6: Honor oif when choosing nexthop for locally generated traffic Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 022/877] pidfd: hold exec_update_lock around namespace ioctl Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 023/877] xfrm: avoid RCU warnings around the per-netns netlink socket Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 024/877] xfrm: fix compat ALLOCSPI request use-after-free Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 025/877] xfrm: add missing rcu_read_lock(), skb_dst_force() and dev_hold() for xfrm_trans_reinject() Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 026/877] esp: downgrade zerocopy managed frags before mutating skb frags Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 027/877] ARM: socfpga: select the PL310 erratum 753970 workaround Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 028/877] RDMA/siw: Clear association under lock if siw_qp_modify fails in siw_accept Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 029/877] RDMA/rxe: validate access flags before swapping the MRs PD Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 030/877] RDMA/rxe: Fix integer overflow in mr_check_range() leading to OOB access Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 031/877] firmware: arm_scpi: reject DVFS OPP count above MAX_DVFS_OPPS Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 032/877] clk: scpi: bound-check DVFS index in scpi_dvfs_recalc_rate Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 033/877] RDMA/rxe: insert mcg into mcg_tree only after rxe_mcast_add() succeeds Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 034/877] RDMA/core: Reject unregistering netdevs in ib_get_eth_speed Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 035/877] IB/iser: reject a remote invalidation of an unregistered direction Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 036/877] IB/isert: wait for deferred control PDU completions before releasing the connection Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 037/877] RDMA/mad: Fix receive buffer leak when PKey enforcement fails Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 038/877] RDMA/irdma: Enforce local fence for IB_WR_REG_MR Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 039/877] RDMA/rtrs-clt: Fix CQ pool leak when connect is interrupted Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 040/877] dmaengine: sprd: Fix runtime PM reference leak in probe Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 041/877] wifi: virt_wifi: free skb when disconnected Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 042/877] wifi: mwifiex: fix IRQ leak using wrong index in MSI-X error path Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 043/877] wifi: libipw: reject too-short beacon and probe responses Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 044/877] wifi: libipw: reject too-short association responses Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 045/877] IB/IPoIB: Avoid restoring OPER_UP after multicast flush Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 046/877] wifi: cfg80211: dont get the radio mask for netdev-less wdevs Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 047/877] wifi: cfg80211: check IP header size in cfg80211_classify8021d() Greg Kroah-Hartman
2026-09-30 15:15 ` [PATCH 6.12 048/877] soundwire: cadence_master: wait and cancel cdns->work before clock stop Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 049/877] MIPS: Octeon: apply USB FDT fixups also when USB is modular Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 050/877] dma-coherent: Warn if OF reserved memory is beyond current coherent DMA mask Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 051/877] dma-coherent: report a failed reserved memory assignment Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 052/877] dmaengine: Fix device kref underflow in dma_chan_put() Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 053/877] dmaengine: fix use-after-free in dma_chan_put() and dma_release_channel() Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 054/877] dmaengine: wait for RCU readers before releasing dma_device Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 055/877] wifi: cfg80211: only group hidden BSSes with beacon entries Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 056/877] wifi: cfg80211: dont filter by BSS type when removing stale entries Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 057/877] wifi: mac80211: dont start a ROC while scanning Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 058/877] wifi: cfg80211: add option for vif allowed radios Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 059/877] wifi: mac80211: use vif radio mask to limit ibss scan frequencies Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 060/877] wifi: mac80211: dont warn when an IBSS has no channel to scan Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 061/877] wifi: mac80211: dont offload TC setup on AP_VLAN interfaces Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 062/877] wifi: mac80211: suppress chanctx warning for debugfs reset Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 063/877] wifi: mac80211: abort chanswitch when leaving a mesh Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 064/877] wifi: mac80211: reset state when starting AP fails Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 065/877] wifi: mac80211: unlist vifs when their netdev is unregistered Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 066/877] wifi: mac80211_hwsim: dont hand frames to mac80211 while stopping Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 067/877] wifi: cfg80211: skip regulatory for punctured subchannels Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 068/877] wifi: cfg80211: expose cfg80211_chandef_get_width() Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 069/877] wifi: mac80211: dont allow injecting frames wider than the chanctx Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 070/877] wifi: mac80211: reset the AP_VLAN tailroom counter on ifdown Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 071/877] wifi: mac80211: require a peer station for TDLS setup confirm Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 072/877] wifi: mac80211: dont allow link changes when iface is down Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 073/877] wifi: mac80211: dont RCU-dereference the mesh CSA settings we just set Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 074/877] wifi: mac80211: dont access the TSF of a down interface Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 075/877] wifi: mac80211: add HE 6 GHz capability in the scan elems len Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 076/877] wifi: mac80211: mesh: reset the CSA state when leaving Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 077/877] wifi: mac80211: mesh: release the channel if start fails Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 078/877] wifi: mac80211: set up the TX info early to fix failure paths Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 079/877] mm: memblock: show all region flags in debugfs Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 080/877] scsi: qla2xxx: Fix the ql2xfc2target parameter description Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 081/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor reuse order Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 082/877] dmaengine: xilinx_dma: Fix hardware buffer descriptor chain after cyclic DMA Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 083/877] RDMA/efa: Keep admin queues alive while IRQ is registered Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 084/877] RDMA/efa: Keep EQ resources " Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 085/877] RDMA/siw: Bound fragmented header copies by the remaining length Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 086/877] netfilter: nft_nat: fully initialise new_addr in netmap setup Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 087/877] netfilter: flowtable: hold reference on ct until flow is released Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 088/877] perf/arm-cmn: Fix wp_dev_sel2 setting for multi-DTM configurations Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 089/877] arm64: hibernate: clone only the linear map that exists at runtime Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 090/877] drm: Fix drm_pending_vblank_event leak in error path for out_fence_ptr Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 091/877] keys: fix lost wakeup when reaping a dead key type Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 092/877] neighbour: Use rtnl_register_many() Greg Kroah-Hartman
2026-10-01 19:19   ` Harshit Mogalapalli
2026-10-02  8:48     ` Greg Kroah-Hartman
2026-10-02 21:10     ` Sasha Levin
2026-10-02 21:23       ` Harshit Mogalapalli
2026-09-30 15:16 ` [PATCH 6.12 093/877] neighbour: Make neigh_valid_get_req() return ndmsg Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 094/877] neighbour: Move two validations from neigh_get() to neigh_valid_get_req() Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 095/877] neighbour: Allocate skb in neigh_get() Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 096/877] neighbour: Move neigh_find_table() to neigh_get() Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 097/877] neighbour: Convert RTM_GETNEIGH to RCU Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 098/877] neighbour: Convert RTM_GETNEIGHTBL " Greg Kroah-Hartman
2026-10-01 19:34   ` Harshit Mogalapalli
2026-10-02 12:06     ` Greg Kroah-Hartman
2026-10-02 21:10     ` Sasha Levin
2026-09-30 15:16 ` [PATCH 6.12 099/877] neighbour: Add missing RCU annotation for neightbl_dump_info() Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 100/877] neighbour: Skip default parms when resumed in neightbl_dump_info() Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 101/877] ALSA: bcd2000: Fix race between rawmidi and disconnect Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 102/877] phy: mediatek: phy-mtk-hdmi-mt8195: Fix PLL calc divisor overflow Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 103/877] phy: mediatek: phy-mtk-hdmi-mt8195: Fix TMDS clk bit ratio setting Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 104/877] ALSA: pcm: set timer->private_data before registering the PCM timer Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 105/877] ASoC: Rename snd_soc_dai_link_ch_map.ch_mask to cpu_ch_mask Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 106/877] ASoC: Add codec_ch_mask to snd_soc_dai_link_ch_map Greg Kroah-Hartman
2026-09-30 15:16 ` [PATCH 6.12 107/877] ASoC: soc-pcm: Apply snd_soc_dai_link_ch_map.codec_ch_mask to codec params Greg Kroah-Hartman
2026-10-01 20:39   ` Harshit Mogalapalli
2026-10-02 12:07     ` Greg Kroah-Hartman
2026-10-02 13:09       ` Richard Fitzgerald
2026-10-02 21:10     ` Sasha Levin
2026-09-30 15:16 ` [PATCH 6.12 108/877] Input: trackpoint - fix the inertia attribute name in the ABI document Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 109/877] gpio: virtuser: skip free_irq when no IRQ is installed Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 110/877] ALSA: 6fire: Clean ups with guard() Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 111/877] ALSA: usb: 6fire: Avoid embedded URBs Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 112/877] ALSA: 6fire: fix OOB write from device-reported iso length Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 113/877] wifi: virt_wifi: dont transfer operstate before register Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 114/877] drm/vc4: Use managed KMS polling to fix UAF on unbind Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 115/877] ALSA: hda: trace PCM open only after assigning a stream Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 116/877] wifi: ath11k: cleanup arsta in ath11k_mac_peer_cleanup_all() Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 117/877] btrfs: tree-checker: print dev extent offset in error message Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 118/877] drm/msm/dsi: round the byte clock rate after reparenting to the PHY PLL Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 119/877] seg6: set IPSKB_L3SLAVE from IP6SKB_L3SLAVE on IPIP decapsulation Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 120/877] ipv4: icmp: reject RTN_UNREACHABLE input routes in icmp_route_lookup Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 121/877] net: fddi: skfp: fix NULL deref when setting the MAC address while down Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 122/877] wifi: brcmfmac: fix lost 802.1x TX completion wakeup Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 123/877] net: bridge: mst: move switchdev call outside rcu Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 124/877] tcp: Dont call skb_clone_and_charge_r() for close()d listener in tcp_v6_do_rcv() Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 125/877] tcp: do not let tcp_rmem be set below 4096 Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 126/877] ksmbd: return buffer overflow for partial filesystem info Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 127/877] ksmbd: fix partial file information responses Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 128/877] ksmbd: keep compound responses on query info errors Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 129/877] dmaengine: mmp_pdma: fix wrong sg length in mmp_pdma_prep_slave_sg() Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 130/877] Bluetooth: hci_core: Print number of packets in conn->data_q Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 131/877] Bluetooth: hci_core: Fix queuing tx_work after workqueue is drained Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 132/877] Bluetooth: coredump: Quiesce dump work on unregister Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 133/877] Bluetooth: ISO: Fix parent socket leak in iso_conn_ready() Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 134/877] Bluetooth: ISO: set BT_LISTEN before requesting a BIG sync Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 135/877] Bluetooth: btmtk: fix wrong status for short WMT FUNC_CTRL events Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 136/877] Bluetooth: btmtksdio: Fix PM runtime reference leak in shutdown Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 137/877] Bluetooth: btintel_pcie: fix off-by-one bounds check in RX submit Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 138/877] Bluetooth: RFCOMM: avoid socket lock inversion in listener cleanup Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 139/877] pppoatm: ensure a writable skb header and linear data Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 140/877] drop_monitor: synchronize tracepoint unregistration on error path Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 141/877] drop_monitor: fix out-of-bounds write in reset_per_cpu_data() Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 142/877] net: stmmac: do not overwrite phc_index when no PTP clock is registered Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 143/877] KVM: PPC: Book3S HV: fix use-after-free in kvmhv_emulate_tlbie_all_lpid() Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 144/877] KVM: PPC: Book3S HV: fix secure device page leak on uv_page_in() failure Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 145/877] powerpc/iommu: Fix the overflow validation in iommu_tce_check_ioba Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 146/877] ASoC: ux500: Parenthesize MSP_{RX,TX}_CLKPOL_BIT() arguments Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 147/877] ASoC: hdmi-codec: Report a change when the channel status moves Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 148/877] net: netsec: fix device_node reference leak on phy_np Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 149/877] net: lock the socket in sock_gettstamp() Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 150/877] net: ethernet: cortina: Ack RX overrun interrupt correctly Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 151/877] net: stmmac: propagate FPE preemption-class mapping errors Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 152/877] net: macb: fix ordering around PTP timestamp read Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 153/877] net: mvpp2: prevent buffer overflow in page_pool allocation Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 154/877] net: skbuff: do not leave stale header offsets after pskb_carve() Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 155/877] drm/amdgpu: check ras and obj before dereference Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 156/877] btrfs: abort transaction on failure to update inode for hole punching and reflinking Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 157/877] x86/fred: Reconstruct the #GP context for rejected INT instructions Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 158/877] mm/huge_memory: use folios memcg inside __folio_split() Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 159/877] wifi: rtw88: TX QOS Null data the same way as Null data Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 160/877] wifi: rtw88: Fix the random "error beacon valid" messages for USB Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 161/877] Input: xpad - add support for Victrix Pro BFG Controller Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 162/877] Input: xpad - add support for Azeron devices Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 163/877] Input: xpad - fix PDP Marvel Xbox 360 controller Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 164/877] ALSA: core: Fix potential UAF after asynchronous card release Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 165/877] ALSA: virtio: reset device before deleting virtqueues Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 166/877] ASoC: codecs: rt712-sdca-dmic: fix uninitialized stream_config->type Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 167/877] ata: libahci: clear PxCLBU and PxFBU for AHCI_HFLAG_32BIT_ONLY Greg Kroah-Hartman
2026-09-30 15:17 ` [PATCH 6.12 168/877] ata: libahci_platform: Fix device reference leak in ahci_platform_get_resources() Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 169/877] cifs: Fix server use-after-free in cifs_chan_skip_or_disable() Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 170/877] exec: Cleanup POSIX timers right after de_thread() Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 171/877] rds: ib: use rds_conn_drop() on protocol version mismatch Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 172/877] x86/microcode/intel: Reject problematic loading on Granite Rapids systems Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 173/877] tcp: exclude old ACKs from tcp fast path Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 174/877] RDMA/ucma: Serialize join and leave on copy_to_user failure Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 175/877] RDMA/core: fix refcount bug in iwpm_get_nlmsg_request() Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 176/877] openvswitch: avoid reallocating confirmed conntrack labels Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 177/877] net: xfrm: reject unrepresentable espintcp transport headers Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 178/877] HID: logitech-hidpp: fix race condition when accessing stale stack pointer Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 179/877] kselftest/arm64: Fix size of thread_data values for pthread_join() Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 180/877] arm64: hibernate: pass HVC_SET_VECTORS args to the resume hvc Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 181/877] arm64: dts: renesas: r8a779f0: Set UFS lane count Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 182/877] arm64: percpu: Fix this_cpu_write() casting Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 183/877] arm64: percpu: Fix this_cpu_and() mask generation Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 184/877] Bluetooth: btusb: fix NXP IW610 composite device handling Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 185/877] Bluetooth: eir: validate service data length before reading UUID Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 186/877] Bluetooth: hci_codec: validate vendor codec count length Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 187/877] Bluetooth: hci_sync: Serialize local codec list cleanup Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 188/877] dmaengine: sun6i: fix non-atomic read of DMA position registers Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 189/877] dmaengine: sun6i: fix undefined behaviour in sun6i_dma_tx_status Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 190/877] dmaengine: ti: k3-udma-glue: fix NULL dereference in k3_udma_glue_release_rx_chn() Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 191/877] ipv6: xfrm: use full sockets in local error paths Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 192/877] net: lan743x: fix RX checksum use-after-free Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 193/877] net: wwan: t7xx: validate the netif index in t7xx_ccmni_recv_skb() Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 194/877] net: wwan: mhi_wwan_mbim: guard against a cyclic NDP chain Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 195/877] net: wwan: mhi_wwan_mbim: check skb_copy_bits() return value Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 196/877] net/sched: act_api: release tail references on DELACTION failure Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 197/877] net/sched: hhf: cap hh_flows_limit at change time Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 198/877] net/packet: clear RX owner on VNET header error Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 199/877] net/packet: avoid truncating TPACKET_V3 private size Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 200/877] scsi: core: Validate MODE SENSE lengths in scsi_cdl_enable() Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 201/877] xfrm: serialize state GC with device state flush Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 202/877] xfrm: use hlist_del_init_rcu for state_cache and state_cache_input Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 203/877] memstick: ms_block: destroy io_queue workqueue on removal Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 204/877] mm/mlock: use the IRQ-safe accessor for NR_MLOCK in __munlock_folio() Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 205/877] KEYS: encrypted: fix integer overflow of datablob_len Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 206/877] keys: translate request_key_auth pid for the reading procfs instance Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 207/877] KEYS: trusted: Fix tpm2_load_cmd() boundary check Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 208/877] i2c: at91: release DMA channels on remove and probe error Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 209/877] i2c: atr: fix dangling adapter pointer on add failure Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 210/877] i2c: imx: release DMA channels on probe error Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 211/877] i2c: imx: disable autosuspend on remove Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 212/877] IB/mlx4: Fix use-after-free on pkey sysfs registration failure Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 213/877] IB/hfi1: Resolve the credit-return buffer through the send contexts node Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 214/877] IB/hfi1: Fix the PIO_CRED credit-return mmap Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 215/877] selinux: preserve user SID across nested backing files Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 216/877] selinux: recheck intermediate backing files on mprotect() Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 217/877] selinux: always fill AVC decision in avc_has_perm_noaudit() Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 218/877] power: sequencing: dont call .post_enable() if pwrseq_unit_enable() failed Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 219/877] power: sequencing: fix NULL-pointer dereference in pwrseq_unit_new() Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 220/877] power: sequencing: fix NULL-pointer dereference in pwrseq_device_register() Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 221/877] mmc: core: Cancel SDIO IRQ work before freeing host Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 222/877] mmc: core: Fix OF node reference leak on card add failure Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 223/877] mmc: hsq: Fix use-after-free in retry work Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 224/877] mmc: mmci: Fix use-after-free in busy-timeout work Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 225/877] mmc: mxcmmc: cancel data work and watchdog on remove Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 226/877] mmc: rtsx_pci_sdmmc: ignore broken write-protect on ThinkPad X260 Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 227/877] mmc: sdhci-of-aspeed: Remove children before releasing SDC resources Greg Kroah-Hartman
2026-09-30 15:18 ` [PATCH 6.12 228/877] mmc: sdio_uart: fix xmit_fifo leak when the port table is full Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 229/877] mmc: sh_mmcif: initialize IRQ-thread mutex before requesting interrupt Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 230/877] mmc: spi: reset bytes_xfered before retrying CRC failures Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 231/877] mmc: sdhci_am654: Move tuning_loop to local variable Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 232/877] mmc: sdhci_am654: Reset command and data lines on failed tuning Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 233/877] mmc: sdhci_am654: Clear ITAPDLY on tuning failure Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 234/877] mmc: sdhci_am654: Fallback to DT-provided itap delay on DDR50 " Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 235/877] Input: adp5588-keys - cache GPIO state before registering the gpiochip Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 236/877] Input: atkbd - skip deactivate for Xiaomi Redmi Book Pro 16 2026 Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 237/877] Input: cyttsp5 - clamp the HID report size before memcpy Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 238/877] Input: evdev - zero absinfo before partial copy in EVIOCSABS Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 239/877] Input: i8042 - add quirk for Acer Aspire Go 15 AG15-42P Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 240/877] Input: rmi_smbus - fix out-of-bounds read in rmi_smb_write_block() Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 241/877] Input: soc_button_array - fix MS Surface Pro 11 probe failure Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 242/877] Input: soc_button_array - check btns_desc->package.count Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 243/877] Input: synaptics - disable InterTouch on ThinkPad T440p (board id 2722) Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 244/877] Input: synaptics-rmi4 - fix GPF in suspend and resume when unbound Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 245/877] Input: zero ff_effect before compat copy in input_ff_effect_from_user Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 246/877] hwmon: (hp-wmi-sensors) Fix use-after-free in fungible_show() Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 247/877] hwmon: (pmbus/core) increase number of phases and add new mask Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 248/877] hwmon: (pmbus/tps53679) Fix TPS53676 phase page decoding Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 249/877] hwmon: (pmbus/tps53679) Select page 0 for single-page TPS53676 Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 250/877] hwmon: (w83791d) remove fan/pwm 4-5 sysfs group on remove Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 251/877] hwmon: (w83793) release probe data through kref Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 252/877] watchdog: da9063: fix suspend/resume handling of HW_RUNNING watchdog Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 253/877] watchdog: digicolor: Avoid division by zero Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 254/877] watchdog: msc313e: Fix premature reset during timeout update Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 255/877] watchdog: msc313e: Propagate error code in resume() Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 256/877] watchdog: rtd119x: Avoid division by zero Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 257/877] watchdog: sp5100_tco: Fix pci_dev reference leak in sp5100_tco_init() Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 258/877] watchdog: starfive-wdt: Fix runtime PM leak in starfive_wdt_pm_start() Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 259/877] wifi: brcmsmac: fix UAF in brcms_free_timer() Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 260/877] wifi: iwlegacy: fix broadcast stations deallocation Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 261/877] wifi: libertas_tf: fix UAF in lbtf_free_adapter() Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 262/877] wifi: rsi: fix heap OOB write on key removal Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 263/877] wifi: wlcore: release runtime PM ref on regdomain config failure Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 264/877] wifi: wilc1000: fix out-of-bounds read in P2P public action frames Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 265/877] wifi: wilc1000: fix RX buffer OOB-write in wilc_wlan_handle_isr_ext() Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 266/877] wifi: p54: validate curve data length in the calibration curve converters Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 267/877] wifi: p54: require a full exp_if record in PDR_INTERFACE_LIST Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 268/877] wifi: mwifiex: bound the pairwise-cipher OUI walk to the IE length Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 269/877] wifi: mwifiex: validate scan response extents Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 270/877] wifi: mwifiex: prevent authentication frame length truncation Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 271/877] wifi: mwifiex: validate action frame fixed fields Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 272/877] wifi: mac80211: avoid WARN in set_bitrate_mask when sdata not in driver Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 273/877] drm/gud: fix out-of-bounds write in gud_plane_atomic_check() Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 274/877] drm/msm/adreno: fix autosuspend cleanup during teardown Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 275/877] drm/msm/hdmi_phy: fix runtime PM cleanup on probe failure Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 276/877] smb: client: cancel reconnect work in clean_demultiplex_info() Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 277/877] smb: client: fix rlist race and missing initialization Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 278/877] smb: client: reject short Next offsets in parse_server_interfaces() Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 279/877] smb: client: fix smbd_connection leak on cifs_get_tcp_session() error Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 280/877] smb: client: fix unaligned access in WSL reparse point parser Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 281/877] smb: client: fix next_buffer UAF and NextCommand bounds in compound PDUs Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 282/877] smb: client: fix potential OOB read in smb3_enum_snapshots() Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 283/877] smb: client: fix server->total_read for compound encrypted PDUs Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 284/877] smb: client: fix missing lower-bound check on DFS referral string offsets Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 285/877] smb: client: fix missing iov bounds check in parse_posix_sids() Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 286/877] HID: asus: fortify keyboard handshake Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 287/877] ksmbd: fix partial normalized name responses Greg Kroah-Hartman
2026-09-30 15:19 ` [PATCH 6.12 288/877] spi: spi-zynqmp-gqspi: stop the controller on shutdown Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 289/877] smb: client: fix busy dentry warning on unmount after DIO Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 290/877] xfs: dont stash removename operations with unknown ftype Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 291/877] erofs: fix large folio race in erofs_fscache_req_complete Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 292/877] ALSA: hda/realtek: Limit Star Labs internal mic boost Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 293/877] ALSA: hda/realtek: Add StarFighter HDA SSID Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 294/877] netfilter: nf_tables: Tolerate chains with no remaining hooks Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 295/877] netfilter: nf_tables: Simplify chain netdev notifier Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 296/877] xfrm: Refactor xfrm_input lock to reduce contention with RSS Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 297/877] xfrm: Fix dev use-after-free in xfrm async resumption Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 298/877] xfrm: save input state data before secpath resets Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 299/877] remoteproc: qcom_q6v5_adsp: Fix iommu_unmap() usage Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 300/877] KVM: s390: Fix IRQ injection with SIGP Stop and Store Status Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 301/877] bpf: Fix bpf_skb_change_tail wrt csum partial skbs Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 302/877] bpf: Disallow bpf_skb_pull_data() for LWT_SEG6LOCAL Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 303/877] selftests/ftrace: Fix unique symbol check in kprobe_non_uniq_symbol.tc Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 304/877] bpf: Fix divide-by-zero in btf_struct_walk() Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 305/877] bpf: Fix out-of-bounds read of sk_protocol in bpf_sock_destroy() Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 306/877] tcp: Skip cond_resched() in inet_csk_listen_stop() under BPF context Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 307/877] HID: elecom: fix bus type for M-XGL20DLBK Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 308/877] KVM: x86/pmu: Move Intel PMU global MSRs to intel_is_valid_msr() Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 309/877] bpf: Avoid soft lockup in __htab_map_lookup_and_delete_batch() Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 310/877] bpf: Fix out-of-bounds read of rtt_min in sock_ops Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 311/877] bpf: Remove migrate_{disable|enable} in ->map_for_each_callback Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 312/877] bpf: Bail out early in __htab_map_lookup_and_delete_elem() Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 313/877] bpf: Factor out htab_elem_value helper() Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 314/877] bpf: Register dtor for freeing special fields Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 315/877] bpf: Fix UAF due to concurrent consumption of ttrace lists in alloc_bulk Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 316/877] bpf, sockmap: Fix self-redirect copied_seq double-counting Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 317/877] bpf, arm64: set up the frame pointer for the exception callback Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 318/877] pinctrl: meson: Fix typo in s4 group name Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 319/877] HID: amd_sfh: Validate PCI BAR size before mapping Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 320/877] HID: bpf: fix __hid_bpf_hw_check_params report length Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 321/877] RISC-V: KVM: Preserve firmware counter value across stop/start Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 322/877] RISC-V: KVM: Report snapshot write failure to the guest Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 323/877] RISC-V: KVM: Fix perf-backed counter accounting across stop and read Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 324/877] KVM: arm64: vgic-its: Free the caches when GITS_BASER changes Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 325/877] KVM: arm64: vgic-its: Add stronger type-checking to the ITS entry sizes Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 326/877] KVM: arm64: vgic-its: Skip unreachable devices instead of failing the save Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 327/877] KVM: arm64: Return -EINVAL for an empty SMCCC filter range at base 0 Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 328/877] KVM: arm64: Fix FGT mapping for HFGITR_EL2.nGCSEPP Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 329/877] squashfs: Add dictionary size range check to prevent shift-out-of-bounds Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 330/877] scsi: sd_zbc: Reject disks with too many zones Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 331/877] Bluetooth: SMP: reject Security Request over BR/EDR Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 332/877] Bluetooth: mgmt: Dequeue pending mesh_send_sync entries on cancel Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 333/877] cgroup: selftests: Move memcontrol specific helpers out of common cgroup_util.c Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 334/877] selftests: cgroup: give the O_TMPFILE open in get_temp_fd() a mode Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 335/877] scsi: megaraid_sas: Protect megasas_get_ctrl_info() in megasas_resume() Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 336/877] docs: s390/pci: Improve and update PCI documentation Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 337/877] s390/pci/docs: Fix sriov_numvfs attribute name Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 338/877] s390/cio: Fix cio_update_schib() to not cache invalid schib Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 339/877] s390/cio: Check pmcw.dnv before pmcw.ena in I/O entry points Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 340/877] s390/cio: Guard PMCW field accesses with dnv check Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 341/877] fs: avoid repeated scans in evict_inodes() Greg Kroah-Hartman
2026-10-01 19:58   ` Harshit Mogalapalli
2026-10-02 12:09     ` Greg Kroah-Hartman
2026-10-02 20:47       ` Harshit Mogalapalli
2026-10-03  1:30         ` Sasha Levin
2026-09-30 15:20 ` [PATCH 6.12 342/877] xsk: Use a 32-bit compare in xsk_map_gen_lookup Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 343/877] bpf: Skip unsettled links in link iterator Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 344/877] net/sched: cls_u32: fix manual hash table handle IDR aliasing Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 345/877] net/mlx5: devcom, Base component size on linked devices Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 346/877] bpf: Restrict CO-RE poisoning to relocatable instructions Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 347/877] libbpf: Reject truncated ldimm64 CO-RE relocations Greg Kroah-Hartman
2026-09-30 15:20 ` [PATCH 6.12 348/877] netfilter: flowtable: publish HW_DEAD after worker is done Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 349/877] netfilter: nfnetlink_queue: hold nfnl mutex in event notifier Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 350/877] netfilter: nft_synproxy: use the family-aware checksum helper Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 351/877] ipvs: revalidate ihl before icmp_send Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 352/877] netfilter: ctnetlink: fix suspicious RCU usage in expect_iter_name Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 353/877] arm64: io: Reject non-user protection in ioremap_prot() Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 354/877] ocfs2: make ocfs2_calc_xattr_init() return void Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 355/877] drm/nouveau/clk: fix list cursor use after loop in nvkm_clk_ustate_update Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 356/877] drm/nouveau/clk: dont clobber reclock status when restoring volt/fan Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 357/877] drm/nouveau/disp: dont reject HDMI config on cards without SCDC Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 358/877] net/sched: act_ct: dont WARN on benign flow_offload_alloc() failure Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 359/877] net: gue: reject invalid REMCSUM offsets Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 360/877] net: ethernet: mtk_eth_soc: unregister net_devices in case of probe failure Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 361/877] ip6_gre: Call ip6erspan_tunnel_unlink_md() in ip6erspan_changelink() Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 362/877] eth: fbnic: Handle maximum standalone channels Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 363/877] eth: fbnic: Set AW_FLUSH_MODE alongside AW_FLUSH when flushing the mailbox Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 364/877] sctp: avoid livelock while updating retransmit path Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 365/877] bpf: Bound ownership depth through local kptrs and graph roots Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 366/877] net: usb: catc: bound the RX packet length in catc_rx_done() Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 367/877] bpf: Check params size before reading reserved fields Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 368/877] net/sched: sch_hfsc: bound the classify inner-filter walk with a drift budget Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 369/877] drm/virtio: fix object leak when drm_gem_handle_create() fails Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 370/877] drm/virtio: fix object leak in virtio_gpu_resource_create_ioctl() Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 371/877] drm/virtio: fix object leaks in virtio_gpu_resource_create_blob_ioctl() Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 372/877] drm/virtio: release the GEM object on virtio_gpu_vram_create() errors Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 373/877] drm/bridge: samsung-dsim: fix TE GPIO lifetime for host attach Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 374/877] Bluetooth: bnep: fix out-of-bounds reads on short RX/TX frames and control fallthrough Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 375/877] Bluetooth: btintel_pcie: validate device-supplied DMA indices Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 376/877] Bluetooth: RFCOMM: Reject short EA=0 frames in rfcomm_recv_frame() Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 377/877] octeontx2-af: Fix memory scaling limitation in SR-IOV mode Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 378/877] dpll: use exact lookup for reference sync pin id Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 379/877] net: usb: sr9700: include receive overhead in the length check Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 380/877] ipv6: Fix dst leak for uncached routes Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 381/877] tg3: clean up PHYLIB resources on probe failure Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 382/877] drm/i915/psr: Add new SU area calculation helper to apply workarounds Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 383/877] drm/i915/psr: Clear stale sel fetch enable bits on sel fetch disable Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 384/877] s390/debug: Do not register views for failed static debug areas Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 385/877] s390/debug: Fix NULL pointer dereference in debug_info_copy() Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 386/877] net: ethernet: ti: netcp: fix pm_runtime usage counter leak on error Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 387/877] genetlink: report the real command id for dump-only ops in policy dumps Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 388/877] net: pcs: xpcs: fix clock reference leak on xpcs_init_clks failure Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 389/877] thermal: gov_step_wise: Fix stale mitigation vote with non-zero lower bounds Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 390/877] bpf: Fix bounds check for skb-backed dynptrs Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 391/877] bpf: Fix bpf_sock context code generation Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 392/877] bpf, sockmap: Reject max_entries > INT_MAX in sock_map_alloc Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 393/877] net/mlx5: Bridge, dont fail switchdev events of sibling eswitch ports Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 394/877] net/mlx5: Bridge, dont fail unlink of untracked/unsupported peer ports Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 395/877] sctp: hold asoc or transport before mod_timer() in timer handlers Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 396/877] net: stmmac: selftests: Support running selftests on DSA conduits Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 397/877] net: stmmac: selftests: Check the dev->features for S-TAG offload testing Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 398/877] net: stmmac: selftests: Capture all packets for vlan checks Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 399/877] net: stmmac: dwmac4: Use the correct bufzise when the len is exactly 8K Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 400/877] bpf: Reject dev-bound-only programs on other devices Greg Kroah-Hartman
2026-10-01 20:09   ` Harshit Mogalapalli
2026-10-02 20:59     ` Harshit Mogalapalli
2026-10-03  1:30       ` Sasha Levin
2026-10-02 21:10     ` Sasha Levin
2026-09-30 15:21 ` [PATCH 6.12 401/877] nfc: nfcmrvl: validate helper command length before pull Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 402/877] nfc: st21nfca: validate received frame size Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 403/877] nfc: llcp: Fix list corruption / refcount desync in nfc_llcp_recv_dm() Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 404/877] selftests: nci: Correct pthread_create return value check Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 405/877] nfc: llcp: Fix race condition in accept_queue lifecycle Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 406/877] selftests: nci: Fix uninitialized family ID on missing attribute Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 407/877] selftests/nci: Fix out-of-bounds store on thread join Greg Kroah-Hartman
2026-09-30 15:21 ` [PATCH 6.12 408/877] nfc: virtual_ncidev: Add missing ioctl compat handler Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 409/877] nfc: llcp: fix sdreq TLV list leak on parse/alloc/send failure Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 410/877] nfc: st21nfca: validate ISO15693 inventory length Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 411/877] nfc: llcp: fix -ENOMEM on connect with zero-length service name Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 412/877] nfc: llcp: fix WKS SAP hijacking via prefix match in nfc_llcp_wks_sap() Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 413/877] nfc: llcp: fix slab-out-of-bounds reads when logging service names Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 414/877] nfc: pn533: fix OOB read in pn533_acr122_is_rx_frame_valid() Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 415/877] net/sched: act_gate: budget the per-entry list in get_fill_size Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 416/877] veth: manage XDP program pointers during channel resize Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 417/877] net: skbuff: fix pull-bound underflow in skb_checksum_setup_ipv6() Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 418/877] vrf: Stop corrupting skb->csum when capturing CHECKSUM_COMPLETE packets Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 419/877] bpf: Fix immediate JMP JEQ/JNE on MIPS32 Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 420/877] bpf: Fix BSWAP 32 and 16 on MIPS64 Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 421/877] driver core: Add device probe log helper dev_warn_probe() Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 422/877] tg3: use random MAC address when tg3_get_device_address fails Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 423/877] net: bcmgenet: fix 64-bit RTNL stats reading in ethtool on 32-bit systems Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 424/877] net: bcmgenet: initialize u64 stats seq counter for all queues Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 425/877] net: bcmgenet: move bcmgenet_power_up into resume_noirq Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 426/877] net: bcmgenet: allow return of power up status Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 427/877] net: bcmgenet: do not skip WoL power up on GENET V1 Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 428/877] net: bcmgenet: validate Ethernet address in bcmgenet_set_mac_addr Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 429/877] net: bcmgenet: mask DMA_TIMEOUT_MASK when reading DMA_RING0_TIMEOUT Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 430/877] ip_gre: Reject enabling collect metadata through changelink Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 431/877] vxlan: use one headroom snapshot for neighbour replies Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 432/877] net: xps: reject an out of range traffic class Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 433/877] drm/imagination: clamp freelist reconstruction requests Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 434/877] bonding: crypto offload enabled, non-offload slave failover, rekey failed Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 435/877] macsec: add some of the lower devices features when offloading Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 436/877] macsec: inherit lower devices TSO limits " Greg Kroah-Hartman
2026-10-01  5:27   ` Karl Mehltretter
2026-10-01 11:31     ` Sasha Levin
2026-10-01 20:12   ` Harshit Mogalapalli
2026-10-02 12:10     ` Greg Kroah-Hartman
2026-10-02 20:43       ` Harshit Mogalapalli
2026-09-30 15:22 ` [PATCH 6.12 437/877] macsec: initialize SecY before registering the netdevice Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 438/877] net: dsa: mt7530: fix NULL dereference on unbind of MT7531 and MT7621 Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 439/877] tcp: fix use-after-free of retransmit_skb_hint in tcp_send_synack() Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 440/877] nfp: hold IPsec RX state under the XArray lock Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 441/877] net/smc: fix UAF on lgr list traversal in smcr_port_err() Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 442/877] tipc: Fix a data race on mon->peer_cnt in mon_timeout() Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 443/877] net: ethernet: stmmac: dwmac-rk: fix bulk clock leak when the PHY clock fails Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 444/877] llc: fix skb UAF and leaks on llc_mac_hdr_init() failure Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 445/877] bridge: check llc_mac_hdr_init() return value in br_send_bpdu() Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 446/877] net/sched: sch_teql: fix shadowed err in __teql_resolve() Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 447/877] vlan: ensure sufficient headroom in vlan_dev_hard_header() Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 448/877] autofs: fix sbi->pipe file reference leak in autofs_kill_sb() Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 449/877] perf/x86/intel: Ensure KVM guest PEBS path doesnt set unwanted PERF_GLOBAL_CTRL bits Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 450/877] perf/x86/intel: Dont write PEBS_ENABLED on host<=>guest xfers if CPU has PEBS isolation, to fix stuck PEBS_ENABLED Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 451/877] perf/x86/intel: Dont pointlessly context switch DS_AREA (and PEBS config) if PEBS is unused Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 452/877] perf/x86/intel: Make @data a mandatory param for intel_guest_get_msrs() Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 453/877] mptcp: return sk_wait_data() errors from recvmsg() Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 454/877] rculist: add list_splice_rcu() for private lists Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 455/877] netfilter: nf_tables: join hook list via splice_list_rcu() in commit phase Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 456/877] x86/mce: Fix hardware debug register corruption on task migration Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 457/877] x86/PCI: Disable enhanced atomics on AMD NBIO 7.7 and 7.11 Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 458/877] virtio_net: copy zerocopy frags in start_xmit without NAPI Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 459/877] tipc: reject invalid and unexpected GRP_ACK_MSG to prevent bc_ackers underflow Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 460/877] tcp: prevent collapsing skbs across boundary in rtx queue Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 461/877] sctp: discard the rest of the packet on a stale-cookie error Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 462/877] af_packet: fix integer overflow in prb_calc_retire_blk_tmo() Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 463/877] ata: libata-scsi: bound the ATA passthru sense descriptor writes Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 464/877] cgroup/pids: Restore pids.events notifications in local mode Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 465/877] fou: reject omitted FOU_ATTR_IPPROTO on FOU_ENCAP_DIRECT Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 466/877] fs/ntfs3: use d_instantiate_new() in ntfs_create_inode() and murder syzbots "WARNING in do_new_mount" saga Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 467/877] writeback: bound cleanup_offline_cgwb() rescans by rotating scanned inodes Greg Kroah-Hartman
2026-09-30 15:22 ` [PATCH 6.12 468/877] workqueue: Fix NULL current_pwq deref in flush dependency check Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 469/877] writeback: report a Tasks-RCU quiescent state per cgwb drain pass Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 470/877] fsl/fman: Fix clk reference leak in read_dts_node() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 471/877] ipe: protect the dm-verity root hash with RCU Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 472/877] ipv6: do not let ipv6_find_hdr() return an offset past the packet end Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 473/877] ipv6: sr: enforce exact attribute length for SEG6_ATTR_DST Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 474/877] gpio: arizona: Fix runtime PM leak in arizona_gpio_direction_out() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 475/877] gpio: zynq: fix runtime PM leak on request error path Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 476/877] llc: reserve device headroom for allocated frames Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 477/877] mctp: route: iterate socket tag list in mctp_lookup_prealloc_tag() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 478/877] rds: ib: Clear the sg list when mapping an MR fails Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 479/877] drm/imagination: Propagate map failures correctly from pvr_mmu_map_sgl() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 480/877] drm/imagination: Fix page count for page table for map() interface Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 481/877] drm/i915: fix incorrect RCU teardown order Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 482/877] drm/amd/display: Fix dc stream excess put in dm_update_crtc_state() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 483/877] drm/amd/display: Bump frame warning limit for clang builds of dml Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 484/877] drm/amdgpu: Fix last_update fence leak in amdgpu_vm_init() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 485/877] drm/amdgpu: Fix runtime PM leak in amdgpu_debugfs_test_ib_show() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 486/877] drm/amdgpu: Fix vmid_wait fence leak in amdgpu_ring_init() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 487/877] drm/nouveau/uvmm: fix UAF in nouveau_uvmm_sm when BO is in TTM_PL_SYSTEM Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 488/877] drm/nouveau: fix autosuspend cleanup during teardown Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 489/877] drm/nouveau: Fix bridge reference leak in nv1a_ram_new() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 490/877] drm/nouveau: fix double-free in nvif_vmm_dtor Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 491/877] drm/nouveau: Fix gem reference leak in validate_init() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 492/877] drm/nouveau: Fix runtime PM leak in nouveau_connector_detect() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 493/877] drm/nouveau: RCU-free the scheduler-containing nouveau_sched Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 494/877] drm/nouveau: dont bump pin count on failed re-pin in nouveau_bo_pin_locked() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 495/877] drm/xe: Limit sg segment size to PAGE_SIZE on Xen PV Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 496/877] drm/virtio: fix memory leak of fence event on execbuffer failure Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 497/877] drm/virtio: fix NULL pointer dereference on fence allocation failure Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 498/877] gpio: tps65219: Fix GPIO input value reads Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 499/877] mm/hugetlb: preserve mremap address delta when skipping page tables Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 500/877] PCI: of_property: Omit bus properties without a subordinate bus Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 501/877] HID: alps: fix use-after-free on input2 registration failure Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 502/877] HID: quirks: add ALWAYS_POLL quirk for SDINNOVATION gaming keyboard Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 503/877] HID: wacom: fix OOB read in wacom_wac_pen_serial_enforce() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 504/877] net/mlx5: Fix rev_entry reference leak in mlx5_tc_ct_shared_counter_get() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 505/877] net/mlx5e: advertise MACsec offload only when supported Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 506/877] net/sched: reject IDR error pointers when deleting actions Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 507/877] net: arp: terminate device name before lookup Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 508/877] net: atl1: fix soft lockup on out-of-range cmb_tpd_next_to_clean read Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 509/877] net: hisilicon: hns_dsaf_mac: fix mdio device leak in hns_mac_register_phy() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 510/877] net: openvswitch: conntrack: avoid modifying shared unconfirmed ct entry Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 511/877] net: openvswitch: conntrack: remove add_helper dead code Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 512/877] net: openvswitch: conntrack: fix helper UAF due to extensions realloc Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 513/877] net: atl1c: fix soft lockup on out-of-range tpd_cons read Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 514/877] net: atl1e: fix soft lockup on out-of-range hw_next_to_clean read Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 515/877] net: bridge: mdb: restart port group walk after deletion Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 516/877] net: usb: cdc_mbim: add MeiG Smart SRM821 to ZLP whitelist Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 517/877] net: usb: lan78xx: Fix URB reference leak in lan78xx_submit_deferred_urbs() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 518/877] netfilter: ip6t_rpfilter: reject routes without inet6_dev Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 519/877] netfilter: ip6t_rt: fix zero-address non-strict match out-of-bounds read Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 520/877] netfilter: nf_tables: skip expired catchall elements on insert and delete Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 521/877] nfc: fix use-after-free in nfc_get_local_general_bytes Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 522/877] nfc: llcp: drop truncated I/RR/RNR PDUs in nfc_llcp_recv_hdlc() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 523/877] nfc: port100: reject frames whose declared length exceeds the received data Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 524/877] scsi: libiscsi_tcp: Check the data direction of a Data-In PDU Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 525/877] perf/core: Fix NULL pmu_ctx passed to pmu->sched_task() Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 526/877] perf/core: Run sched_task() for PMUs with only CPU-wide events Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 527/877] pinctrl: single: free the IRQ on domain creation failure Greg Kroah-Hartman
2026-09-30 15:23 ` [PATCH 6.12 528/877] pinctrl: sunxi: keep a shadow copy of the data register output latches Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 529/877] s390/cio: Fix NULL pointer dereference in ccw_device_get_util_str() Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 530/877] s390/cmf: Fix virtual vs physical address confusion Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 531/877] s390/vfio-ap: fix KVM GISC and page leak when queue removed from host config Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 532/877] KVM: Ensure memory attributes xarray nodes are accounted to the callers memcg Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 533/877] KVM: Dont treat reserved xarray entries as having memory attributes Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 534/877] KVM: arm64: Fix spurious warning for benign stage 2 teardown race Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 535/877] RISC-V: KVM: Synchronize hrtimer callback during teardown Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 536/877] RISC-V: KVM: Fix HSM hart status error propagation Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 537/877] Bluetooth: hci_conn: fix CIS hold ownership on reuse Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 538/877] Bluetooth: hci_sock: validate event length before filtering Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 539/877] Bluetooth: hci_sock: reject out-of-range OCF values Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 540/877] Bluetooth: ISO: balance the parent hold in hci_bind_bis() Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 541/877] Bluetooth: L2CAP: validate frame length before control and FCS access Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 542/877] Bluetooth: mgmt: fix race in read_unconf_index_list() Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 543/877] Bluetooth: RFCOMM: fix NULL dereference of dlc->session in RFCOMM_CONNINFO Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 544/877] smb: client: fix create context out-of-bounds reads Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 545/877] smb: client: clean up failed cached directory opens Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 546/877] smb: client: validate POSIX create context length Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 547/877] xfs: dont assert when XFS_SCRUB_TYPE_HEALTHY scans return corruption Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 548/877] xfs: fix attr fork block count checks in xrep_inode_blockcounts Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 549/877] xfs: release orphanage dir inode if chown fails Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 550/877] xfs: use correct jiffies comparison function in xchk_maybe_relax Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 551/877] xfs: check padding field in xfs_ioc_commit_range Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 552/877] xfs: dont call xfs_exchange_range_finish for a dry run Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 553/877] xfs: check di_forkoff correctly in scrub Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 554/877] xfs: drop dquot flush lock when we cant find a buffer to flush Greg Kroah-Hartman
2026-10-01 20:21   ` Harshit Mogalapalli
2026-10-02  6:24     ` Greg Kroah-Hartman
2026-10-03  1:30     ` Sasha Levin
2026-09-30 15:24 ` [PATCH 6.12 555/877] xfs: fix blockgc group quota scanning when usrquota isnt enforced Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 556/877] net: tls: fix silent data drop under pipe back-pressure Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 557/877] perf test: Change all remaining #!/bin/sh to #!/bin/bash Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 558/877] ring-buffer: Add helper functions for allocations Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 559/877] ring-buffer: Fix subbuf resize race with ring_buffer_alloc_read_page() Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 560/877] sched: Rework prev_balance() to avoid stale prev references Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 561/877] sched/core: Make core-sched flips wait for in-flight selections Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 562/877] ASoC: codecs: aw88261: reduce log spam Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 563/877] ASoC: codecs: aw88261: only check PLL and clock state at power-up Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 564/877] ring-buffer: Make cpu_buffer::free_page a buffer_data_read_page Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 565/877] dmaengine: Add devm_dma_request_chan() Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 566/877] i2c: mxs: fix DMA channel leak on probe error Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 567/877] lockd: fix swapped arguments in nlmsvc_match_ip() Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 568/877] firmware: qcom_scm: Rename peripheral as pas_id Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 569/877] remoteproc: pas: Replace metadata context with PAS context structure Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 570/877] remoteproc: qcom: pas: Guard dtb metadata release with dtb_pas_id check Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 571/877] power: supply: ab8500_fg: Remove redundant dev_err()/dev_err_probe() Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 572/877] power: supply: ab8500_fg: fix use-after-free on remove Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 573/877] PCI: starfive: Use regulator APIs to control the 3v3 power supply of PCIe slots Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 574/877] PCI: starfive: Fix resource leaks on error paths in host_init() Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 575/877] iommu/msm: Use helper function devm_clk_get_prepared() Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 576/877] iommu/msm: Unwind probe state on registration failure Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 577/877] iommufd: Pass @pasid through the device attach/replace path Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 578/877] iommufd: Fix UAF in selftest IOPF reporting Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 579/877] platform/x86: ISST: Check for admin capability for write commands Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 580/877] platform/x86: ISST: Validate max level for set feature Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 581/877] mmc: via-sdmmc: cancel card-detect work on remove Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 582/877] PCI: Introduce PCI_SLOT_PLACEHOLDER constant for slot_nr placeholder value Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 583/877] PCI: Allow per function PCI slots to fix slot reset on s390 Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 584/877] platform/x86: think-lmi: Fix current password length check Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 585/877] platform/x86: think-lmi: improve check if BIOS account security enabled Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 586/877] platform/x86: think-lmi: Fix certificate thumbprint sysfs output Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 587/877] platform/x86: intel_sar: Check ACPI_HANDLE() against NULL Greg Kroah-Hartman
2026-09-30 15:24 ` [PATCH 6.12 588/877] platform/x86: int1092: Fix potential memory leak in sar_probe() Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 589/877] platform/x86/amd/pmc: Move STB block into amd_pmc_s2d_init() Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 590/877] platform/x86/amd/pmc: Move STB functionality to a new file for better code organization Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 591/877] platform/x86/amd/pmc: Define enum for S2D/PMC msg_port and add helper function Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 592/877] platform/x86/amd/pmc: Restore msg_port on amd_stb_s2d_init() error paths Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 593/877] platform/x86/amd/pmc: Propagate SMU errors and validate S2D address Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 594/877] io_uring/waitid: have io_waitid_complete() remove wait queue entry Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 595/877] io_uring/waitid: avoid siginfo copy during ring teardown Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 596/877] power: supply: qcom_battmgr: fix use-after-free Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 597/877] net/smc: Address spelling errors Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 598/877] net/smc: stop killed, freed and out_of_sync sharing a byte Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 599/877] net/mlx5e: SHAMPO, Always calculate page size Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 600/877] net/mlx5e: do not HW-GRO coalesce small frames Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 601/877] ALSA: hda/ext: preserve PPLCCTL bits when clearing reset Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 602/877] hwrng: drivers - Switch back to struct platform_driver::remove() Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 603/877] hwrng: stm32 - Fix runtime PM cleanup on registration failure Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 604/877] i3c: master: Do not treat master device as a duplicate target Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 605/877] wifi: mt76: mt7915: set correct background radar capability Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 606/877] wifi: mt76: mt7915: bound the device EEPROM address before the EFUSE copy Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 607/877] i3c: master: Fix use-after-free of master->this Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 608/877] udf: Move udf_map_block() up Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 609/877] udf: Fix data loss when converting inline inodes to out of line Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 610/877] usb: dwc3: gadget: Reinitiate stream for all host NoStream behavior Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 611/877] usb: dwc3: clear forceRM when issuing EndTransfer Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 612/877] wifi: rtw89: cleanup unused rtwdev::roc_work Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 613/877] wifi: rtw89: Hide some errors when the device is unplugged Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 614/877] wifi: rtw89: pci: add .shutdown callback to stop rfkill polling on reboot Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 615/877] usb: typec: tcpm: fix debug accessory mode detection for sink ports Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 616/877] usb: typec: tcpm: constrain TCPM_SOURCING_VBUS event handling Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 617/877] wifi: mt76: mt7996: bound the device EEPROM address before the EFUSE copy Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 618/877] xhci: Cleanup Candence controller PCI device and vendor ID usage Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 619/877] usb: cdns3: rename hibernated argument of role->resume() to lost_power Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 620/877] usb: cdnsp: fix wakeup from S3 after controller context loss Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 621/877] usb: storage: realtek_cr: fix use-after-free on disconnect Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 622/877] usb: gadget: f_mass_storage: fix null pointer dereference in fsg_common_set_num_buffers() Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 623/877] staging: rtl8723bs: fix spacing around operators Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 624/877] staging: rtl8723bs: fix OOB read in rtw_restruct_wmm_ie() Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 625/877] staging: sm750fb: fix mono image source stride mismatch in lynxfb_ops_imageblit() Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 626/877] tracing/probes: Fix anon_stack check for unnamed bitfields in btf_find_struct_member Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 627/877] Documentation: tracing: Add documentation about eprobes Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 628/877] tracing/probes: Fix BTF kflag check for anonymous struct member access Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 629/877] mm/secretmem: properly account locked pages Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 630/877] tracing: Clean up use of trace_create_maxlat_file() Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 631/877] tracing: Take trace_array reference when opening options file Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 632/877] ftrace: Take trace_array reference before accessing its ftrace_ops Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 633/877] dma-buf: dma-heap: dont publish fd before copy_to_user() succeeds Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 634/877] compiler_types: Move lock checking attributes to compiler-context-analysis.h Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 635/877] futex: Provide rt_mutex_.*_schedule() equivalents for futex scheduling Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 636/877] rtc: rzn1: Handle unset alarm weekday in rzn1_rtc_read_alarm Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 637/877] perf/aux: Allocate non-contiguous AUX pages by default Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 638/877] perf/x86/intel: Remove anythread_deprecated bit from perf_capabilities Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 639/877] ring-buffer: Show persistent buffer dropped events in trace_pipe file Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 640/877] ring-buffer: Allow splice reads on static buffers Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 641/877] nvme: add missing SRCU grace period in error path Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 642/877] nvme: all namespaces in a subsystem must adhere to a common atomic write size Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 643/877] nvme: refactor the atomic write unit detection Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 644/877] nvme: fix atomic write size validation Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 645/877] nvme: skip the zoned limits update if the zone info query failed Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 646/877] s390/vfio-ap: Fix missing lock required to access list of ap_matrix_mdev objects Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 647/877] mm: fix incorrect vm_flags usage when checking allowable orders for tmpfs Greg Kroah-Hartman
2026-09-30 15:25 ` [PATCH 6.12 648/877] nvdimm: preserve flush callback -ENOMEM Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 649/877] nvdimm: pmem: keep PREFLUSH before data writes Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 650/877] nvdimm: virtio_pmem: stop allocating child flush bio Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 651/877] nvdimm: virtio_pmem: always wake -ENOSPC waiters Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 652/877] nvdimm: virtio_pmem: use READ_ONCE()/WRITE_ONCE() for wait flags Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 653/877] nvdimm: virtio_pmem: refcount requests for token lifetime Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 654/877] mtd: rawnand: pl353: Add message about ECC mode Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 655/877] mtd: rawnand: pl353: Make sure we use the monolithic helpers for raw accesses Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 656/877] clk: qcom: Fix test_ctl_hi field for DEFAULT_EVO PLLs Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 657/877] ASoC: tegra210_mixer: sort the register default table Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 658/877] ASoC: tegra: Fix the MIXER enable default value Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 659/877] mm/mremap: reset unfaulted VMA page offset for MREMAP_DONTUNMAP Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 660/877] KVM: x86/mmu: Dynamically allocate shadow MMUs hashed page list Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 661/877] KVM: x86/mmu: Split kvm_mmu_zap_all_fast() into "front" and "back" halves Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 662/877] KVM: x86: Extract REGS and SREGS runtime sync code to helpers Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 663/877] KVM: x86: Rename __{g,s}et_sregs2() => kvm_vcpu_ioctl_x86_{g,s}et_sregs2() Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 664/877] KVM: x86: Move the bulk of register specific code from x86.c to regs.c Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 665/877] KVM: x86: Check EFER validity on KVM_SET_SREGS* Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 666/877] media: i2c: imx355: Replace client->dev usage Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 667/877] media: imx355: Avoid calling imx355_power_off twice in error path Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 668/877] media: rkvdec: Propagate platform_get_irq() errors Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 669/877] KVM: s390: Zero initialize data structures for inject_pfault_token Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 670/877] KVM: x86: Disallow EFER.LME and EFER.LMA if long mode is not supported Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 671/877] scsi: qla2xxx: Zero dport diagnostics buffer to avoid info leak Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 672/877] scsi: qla2xxx: Fix queue teardown NULL dma_free and bitmap locking Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 673/877] scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 674/877] scsi: qla2xxx: Null out freed pointers in qla2x00_mem_alloc() error path Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 675/877] scsi: qla2xxx: Bound VP index against VP_CTRL IOCB bitmap size Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 676/877] media: chips-media: wave5: Add timeout while stop_streaming Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 677/877] scsi: qla2xxx: Use ring-slot helpers in __qla2x00_alloc_iocbs Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 678/877] scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 679/877] scsi: qla2xxx: Fix 64G link speed reporting in get_data_rate Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 680/877] scsi: qla2xxx: Skip vport under deletion in report ID acquisition Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 681/877] scsi: qla2xxx: Fix soft lockup polling continuation IOCB signature Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 682/877] scsi: qla2xxx: Clamp max_npiv_vports to VP_CTRL bitmap capacity Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 683/877] scsi: qla2xxx: Unlink NVMe unsol ctx before freeing on LS reject error Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 684/877] scsi: qla2xxx: Serialize NVMe unsol ctx list with a per-fcport lock Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 685/877] scsi: qla2xxx: Validate BSG request_len before reading vendor_cmd[] Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 686/877] f2fs: validate MOVE_RANGE destination size Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 687/877] f2fs: convert F2FS_I_SB to sbi in f2fs_setattr() Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 688/877] f2fs: dont allow unaligned truncation to smaller/equal size on pinned file Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 689/877] f2fs: fix to avoid potential section-unaligned pinfile Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 690/877] f2fs: dirty directory inodes on mtime/ctime update Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 691/877] f2fs: limit recovery filename logging to stored length Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 692/877] f2fs: fix dentry folio leak in find_in_level Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 693/877] f2fs: embed f2fs_gc_kthread in f2fs_sb_info Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 694/877] f2fs: Convert clear_node_page_dirty() to clear_node_folio_dirty() Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 695/877] f2fs: fix to clear dirty flag on folio in error path Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 696/877] f2fs: accurately adjust free_sections during free_segment_range Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 697/877] drm/amdgpu: Fix missing unwind in amdgpu_ib_schedule() error path Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 698/877] drm/amdgpu: add a helper to calculate ring distance Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 699/877] drm/amdgpu: plumb timedout fence through to force completion Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 700/877] drm/amdgpu: avoid force-completing uninitialized UVD rings Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 701/877] drm/nouveau/disp/r535: Add scanline position support + head state support Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 702/877] drm/amd/display: Set gpuvm min page size to 4K on dcn35/36 Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 703/877] drm/sysfb: simpledrm: Improve panel-size validation Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 704/877] drm/sysfb: simpledrm: Improve stride validation Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 705/877] firmware: sysfb: Move bpp-depth calculation into screen_info helper Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 706/877] drm/sysfb: simpledrm: Improve framebuffer-size validation Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 707/877] drm/sysfb: ofdrm: Fix integer overflow in fb_size calculation Greg Kroah-Hartman
2026-09-30 15:26 ` [PATCH 6.12 708/877] drm/sysfb: ofdrm: Fix is_avivo() constant comparison bug Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 709/877] configfs:get_target() - release path as soon as we grab configfs_item reference Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 710/877] configfs: pin the symlink targets dirent instead of chasing ->ci_dentry Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 711/877] tracing: Fix memory corruption from a "STACKTRACE" histogram key Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 712/877] ipmr: account multicast table and route memory Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 713/877] sysctl: move the "cad_pid" entry from pid_table[] to kern_reboot_table[] Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 714/877] reboot: fix cad_pid use-after-free race Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 715/877] configfs: unhash the dentry before dropping the item in rmdir Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 716/877] tracing: Constify struct event_trigger_ops Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 717/877] tracing: Remove get_trigger_ops() and add count_func() from trigger ops Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 718/877] tracing: Merge struct event_trigger_ops into struct event_command Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 719/877] tracing: Set the trace clock before registering the histogram trigger Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 720/877] virtio-mmio: Remove virtqueue list from mmio device Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 721/877] virtio_mmio: disable IRQ wake before free_irq Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 722/877] tools/bootconfig: Cleanup bootconfig footer size calculations Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 723/877] tools/bootconfig: Fix integer overflow and truncation in size checks Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 724/877] tracing: Take trace_array reference when opening a tracer options file Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 725/877] tracing: Take the reference before publishing the named histogram trigger Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 726/877] tracing: Undo the registration when enabling the histogram trigger fails Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 727/877] EDAC/altera: Use ECC manager compatible to select A10/S10 IRQ layout Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 728/877] EDAC/altera: Use parent device for devres in altr_portb_setup() Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 729/877] genetlink: pin family module during policy dump Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 730/877] drm/bridge: tc358768: Enforce input bus flags via atomic_check Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 731/877] io_uring/rw: end write accounting from ->ki_complete Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 732/877] io_uring/net: dont overconsume buffers when using MSG_TRUNC Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 733/877] bootconfig: Fix integer overflow in initrd size check Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 734/877] net: bridge: use option bits for CFM/MRP frame handlers Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 735/877] drm/xe: Flush LSC untyped L1 dataport cache after rcs/ccs batches Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 736/877] netfilter: cttimeout: detach dataplane timeout policy and repurpose refcount Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 737/877] netfilter: cttimeout: prevent UAF during module unload Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 738/877] net: macb: Replace open-coded implementation with napi_schedule() Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 739/877] net: macb: Use netif_napi_add_tx() instead of netif_napi_add() for TX NAPI Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 740/877] net: macb: unify device pointer naming convention Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 741/877] net: macb: initialize PTP state before registering clock Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 742/877] erofs: add sysfs feature entry for xattr prefixes Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 743/877] idpf: Fix kernel-doc descriptions to avoid warnings Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 744/877] idpf: introduce idpf_q_vec_rsrc struct and move vector resources to it Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 745/877] idpf: disable DIM work before freeing q_vectors Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 746/877] ipv4: remove fib_devindex_hashfn() Greg Kroah-Hartman
2026-10-01 20:24   ` Harshit Mogalapalli
2026-10-02 21:04     ` Harshit Mogalapalli
2026-10-03  1:30       ` Sasha Levin
2026-10-02 21:10     ` Sasha Levin
2026-10-02 21:17       ` Harshit Mogalapalli
2026-09-30 15:27 ` [PATCH 6.12 747/877] ipv4: use rcu in ip_fib_check_default() Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 748/877] ipv4: remove fib_info_devhash[] Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 749/877] ipv6: make ipv6_pinfo.saddr_cache a boolean Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 750/877] ipv6: reorganise struct ipv6_pinfo Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 751/877] ipv6: Move ipv6_fl_list from ipv6_pinfo to inet_sock Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 752/877] ipv6: flowlabel: cap duplicate leases per socket Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 753/877] landlock: Clarify documentation for the IOCTL access right Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 754/877] landlock: Fix use-after-free of the sources parent directory Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 755/877] netmem: add a couple of page helper wrappers Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 756/877] net: page_pool: rename page_pool_alloc_netmem to *_netmems Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 757/877] page_pool: disable sync for cpu for dmabuf memory provider Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 758/877] bnxt_en: Propagate TPA buffer allocation failures in bnxt_queue_mem_alloc() Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 759/877] mptcp: pm: drop match in userspace_pm_append_new_local_addr Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 760/877] sock: add sock_kmemdup helper Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 761/877] mptcp: use sock_kmemdup for address entry Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 762/877] mptcp: pm: userspace: fix address ID overflow Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 763/877] bnxt_en: Do not set EOP on RX AGG BDs on 5760X chips Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 764/877] eth: bnxt: store rx buffer size per queue Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 765/877] bnxt: fix memory leak in bnxt_queue_mem_alloc error cases Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 766/877] bnxt_en: Dont free the live rings TPA state on queue restart failure Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 767/877] mptcp: pm: reset retrans_time when ADD_ADDR entry is reused Greg Kroah-Hartman
2026-09-30 15:27 ` [PATCH 6.12 768/877] mptcp: pm: use for_each_subflow helper Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 769/877] mptcp: pm: rename add_entry structure to add_addr Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 770/877] mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0 Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 771/877] tcp: introduce icsk->icsk_keepalive_timer Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 772/877] mptcp: do not reschedule the RTX timer for fallback sockets Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 773/877] mptcp: prevent race between disconnect() and rtx Greg Kroah-Hartman
2026-10-01 20:30   ` Harshit Mogalapalli
2026-10-02 12:11     ` Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 774/877] smb: client: refactor ACL setting control flow in id_mode_to_cifs_acl() Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 775/877] smb/client: fix security flag calculation when setting security descriptors Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 776/877] smb: client: fail DACL rewrite when the new DACL exceeds 64K Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 777/877] xfs: report healthy filesystem events in scrub stats Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 778/877] xfs: fix short ifork reaping computation in xreap_bmapi_binval Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 779/877] xfs: strengthen the "is cow staging" helpers in scrub Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 780/877] xfs: remove the i_ino field in struct xfs_inode Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 781/877] xfs: fix under-reservation of blocks when repairing sf directories Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 782/877] xfs: fix backwards mergeability logic in refcount scrubber Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 783/877] cifs: Fix specification of function pointers Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 784/877] 9p: Fix v9fs_issue_write() to update i_size and remote_i_size Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 785/877] phy: renesas: rcar-gen3-usb2: Avoid long delay in atomic context Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 786/877] ALSA: usb-audio: Optimize the copy of packet sizes for implicit fb handling Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 787/877] ALSA: usb-audio: Clamp implicit feedback packet count to URB capacity Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 788/877] swiotlb: use the adjusted address for the highmem page lookup Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 789/877] net: phy: mediatek: do not report link and per-speed LED rules together Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 790/877] btrfs: take commit root semaphore when iterating in mark_block_group_to_copy() Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 791/877] arm64: Use load LSE atomics for the non-return per-CPU atomic operations Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 792/877] arm64: percpu: Fix LSE operations on {8,16}-bit types Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 793/877] i2c: qcom-cci: Stop complaining about DT set clock rate Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 794/877] i2c: qcom-cci: Remove the unused variable cci_clk_rate Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 795/877] i2c: qcom-cci: fix device_node refcount leak in cci_probe()/cci_remove() Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 796/877] scsi: fnic: Fix missed link-up when critical IRQ targets offline CPU Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 797/877] Input: hp_sdc - shut down kicker timer on module exit Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 798/877] wifi: wcn36xx: Fix potential use-after-free in TX ack timer teardown Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 799/877] hwmon: (pwm-fan) Stop RPM timer before freeing tach data Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 800/877] drm/msm/dpu: clear pending peripheral flush state Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 801/877] wifi: libipw: reject TKIP frames without a full MIC Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 802/877] wifi: mac80211: track MU-MIMO configuration on disabled interfaces Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 803/877] wifi: mac80211: refuse to make a monitor active when it has no queue Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 804/877] smb: mark the new channel addition log as informational log with cifs_info Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 805/877] smb: client: fix use-after-free of iface in cifs_try_adding_channels() Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 806/877] drm/amdgpu: Failed to check various return code Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 807/877] drm/amdgpu: set the VM pointer to NULL in amdgpu_job_prepare Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 808/877] drm/amdgpu/umsch: remove vpe test from umsch Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 809/877] drm/amdgpu: use GFP_NOWAIT for memory allocations Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 810/877] drm/amdgpu: fix rmmio iounmap skipped on device removal Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 811/877] smb: client: fix OOB struct field reads in move_smb2_ea_to_cifs() Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 812/877] drm: add drm_memory_stats_is_zero Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 813/877] drm/amdgpu: hold a runtime PM reference for P2P dma-buf attachments Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 814/877] smb: client: fix reparse buffer bounds in cifs_query_reparse_point() Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 815/877] smb/client: send lease break ACKs thru correct session for multiuser mounts Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 816/877] arm64/boot: Disable trapping of PMZR_EL0 writes to EL2 Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 817/877] vlan: require the MAC header to be present in __vlan_insert_inner_tag() Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 818/877] gpio: cdev: fix kernel stack leak to user-space in error path Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 819/877] ipe: fix use-after-free when auditing a newly loaded policy Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 820/877] bna: prevent IOC timer rearm during teardown Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 821/877] i2c: qcom-geni: Fix hardcoded clock index in SE_GENI_CLK_SEL Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 822/877] drm/amdgpu: Fix acpi device leak in amdgpu_acpi_enumerate_xcc() Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 823/877] drm/client: Pass force parameter to client restore Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 824/877] drm/client: fix restore of partially initialized client Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 825/877] drm/i915/mst: add mst sub-struct to struct intel_dp Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 826/877] drm/i915/dp_mst: Fix configuring FEC for a disconnected stream Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 827/877] mm/rmap: allocate anon_vma_chain objects unlocked when possible Greg Kroah-Hartman
2026-09-30 15:28 ` [PATCH 6.12 828/877] mm/rmap: fix missing barrier between anon_vma init and vma->anon_vma publish Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 829/877] drm/xe/vm: nuke PTs only after unlinking contested VMAs Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 830/877] mm/damon/vaddr: avoid hw-driven pte updates during damon_hugetlb_mkold() Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 831/877] mm/hugetlb: fix surplus pages in dissolve_free_huge_page() Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 832/877] mm/hugetlb: create hstate_is_gigantic_no_runtime helper Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 833/877] mm/hugetlb: do not dissolve gigantic pages without runtime support Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 834/877] super: make iterate_supers_type() deletion-safe Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 835/877] PCI: Fix Resizable BAR restore order Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 836/877] PCI: Fix BAR resize for devices on a root bus Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 837/877] packet: use ubuf_info completion for TX_RING packets Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 838/877] HID: hid-alps: Use pm_ptr instead of #ifdef CONFIG_PM Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 839/877] HID: alps: unregister DualPoint Stick input device on remove Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 840/877] net/sched: act_ct: fix helper UAF due to extensions realloc Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 841/877] net/sched: act_ct: avoid modifying shared unconfirmed ct entry Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 842/877] net: ipconfig: Remove outdated comment and indent code block Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 843/877] net: ipconfig: bound DHCP option construction Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 844/877] net: ena: Remove autopolling mode Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 845/877] net: ena: fix MMIO read buffer leak on probe failure Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 846/877] KVM: SVM: Flush cache only on CPUs running SEV guest Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 847/877] KVM: SEV: Do cache maintenance on the source VM during intra-host migration Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 848/877] perf/x86/intel: Update event constraints and cache_extra_regsfor LNL Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 849/877] perf/x86/intel: Remove incorrect LionCove PEBS data-source constraints Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 850/877] perf/x86/intel: Update event constraints and cache_extra_regsfor ADL Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 851/877] perf/x86/intel: Fix GRT PEBS load/store direction for latency events, to fix sample classification Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 852/877] RISC-V: KVM: Fix null pointer dereference in kvm_riscv_aia_imsic_rw_attr() Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 853/877] RISC-V: KVM: Serialize IMSIC attributes with vCPU migration Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 854/877] rose: fix dev_put() leak in rose_loopback_timer() Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 855/877] rose: hold loopback neighbour reference across timer callback Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 856/877] rose: fix race between loopback timer and module removal Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 857/877] rose: clear neighbour pointer after rose_neigh_put() in state machines Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 858/877] rose: guard rose_neigh_put() against NULL in timer expiry Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 859/877] rose: fix netdev double-hold in rose_rx_call_request() Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 860/877] rose: fix notifier unregistered too early in rose_exit() Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 861/877] rose: set SOCK_DESTROY in rose_kill_by_device() for prompt cleanup Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 862/877] rose: disconnect orphaned STATE_2 sockets when device is gone Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 863/877] rose: fix netdev double-hold in rose_make_new() Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 864/877] rose: release netdev ref and destroy orphaned incoming sockets Greg Kroah-Hartman
2026-10-01  9:42   ` Bernard Pidoux
2026-10-01 11:31     ` Sasha Levin
2026-09-30 15:29 ` [PATCH 6.12 865/877] rose: drop CALL_REQUEST in loopback timer when device is not running Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 866/877] rose: cancel neighbour timers in rose_neigh_put() before freeing Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 867/877] rose: clear neighbour pointer in rose_kill_by_device() Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 868/877] rose: dont free fd-owned sockets when reaping in the heartbeat Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 869/877] drm/amdgpu: fix ring timeout issue in gfx10 sr-iov environment Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 870/877] nvme: revert the cross-controller atomic write size validation Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 871/877] bootconfig: Fix negative seeks on 32-bit with LFS enabled Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 872/877] tracing: Move d_max_latency out of CONFIG_FSNOTIFY protection Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 873/877] mtd: rawnand: pl353: Fix debug prints Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 874/877] platform/x86/amd/pmc: Fix LPS0 and debugfs leaks when STB init fails Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 875/877] usb: dwc3: gadget: Fix use-after-free in dwc3_gadget_free_endpoints due to race condition Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 876/877] bpf: Reject key-less BTF for hash maps Greg Kroah-Hartman
2026-09-30 15:29 ` [PATCH 6.12 877/877] mm/hugetlb: keep max_huge_pages when dissolving surplus folios Greg Kroah-Hartman
2026-09-30 19:08 ` [PATCH 6.12 000/877] 6.12.112-rc1 review Florian Fainelli
2026-09-30 22:35 ` Peter Schneider
2026-10-01  5:25 ` Barry K. Nathan
2026-10-01  9:17 ` Pavel Machek
2026-10-01 10:06 ` Ron Economos
2026-10-01 12:01 ` Miguel Ojeda
2026-10-01 16:44 ` Brett A C Sheffield
2026-10-01 22:24 ` Richard Narron

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.