Skip to contentSkip to conversation

6.12.91-rc1 review

PATCH In review Greg Kroah-Hartman 14 participants 691 messages May 20 – May 27 Page 1 of 6

Subsystems (7)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 6.12.91-rc1 review

This is the start of the stable review cycle for the 6.12.91 release. There are 666 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, 22 May 2026 16:20:16 +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.91-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 <[email protected]>

    Linux 6.12.91-rc1

Matthieu Baerts (NGI0) <[email protected]>
mptcp: pm: ADD_ADDR rtx: resched blocked ADD_ADDR quicker

Matthieu Baerts (NGI0) <[email protected]>
mptcp: pm: ADD_ADDR rtx: fix potential data-race

Matthieu Baerts (NGI0) <[email protected]>
mptcp: pm: kernel: correctly retransmit ADD_ADDR ID 0

Johan Hovold <[email protected]>
spi: sifive: fix controller deregistration

Pei Xiao <[email protected]>
spi: sifive: Simplify clock handling with devm_clk_get_enabled()

Chao Yu <[email protected]>
f2fs: fix false alarm of lockdep on cp_global_sem lock

Yongpeng Yang <[email protected]>
f2fs: fix incorrect file address mapping when inline inode is unwritten

Paolo Abeni <[email protected]>
mptcp: fix rx timestamp corruption on fastopen

Paolo Abeni <[email protected]>
mptcp: drop __mptcp_fastopen_gen_msk_ackseq()

Matthieu Baerts (NGI0) <[email protected]>
mptcp: pm: prio: skip closed subflows

Tejun Heo <[email protected]>

    sched_ext: Guard scx_dsq_move() against NULL kit->dsq after failed iter_new

Jason Gunthorpe <[email protected]>
RDMA/mana: Remove user triggerable WARN_ON() in mana_ib_create_qp_rss()

Qu Wenruo <[email protected]>
btrfs: do not mark inode incompressible after inline attempt fails

Piyush Sachdeva <[email protected]>
smb: client: Use FullSessionKey for AES-256 encryption key derivation

Filipe Manana <[email protected]>
btrfs: fix missing last_unlink_trans update when removing a directory

Filipe Manana <[email protected]>
btrfs: use btrfs inodes in btrfs_rmdir() to avoid so much usage of BTRFS_I()

Filipe Manana <[email protected]>
btrfs: use inode already stored in local variable at btrfs_rmdir()

Ashutosh Desai <[email protected]>
drm/v3d: Reject empty multisync extension to prevent infinite loop

David Carlier <[email protected]>
eventfs: Use list_add_tail_rcu() for SRCU-protected children list

Zhenzhong Duan <[email protected]>
iommufd: Fix return value of iommufd_fault_fops_write()

Johan Hovold <[email protected]>
drm/gma500/oaktrail_lvds: fix i2c adapter leaks on init

Johan Hovold <[email protected]>
drm/gma500/oaktrail_lvds: fix hang on init failure

Johan Hovold <[email protected]>
drm/gma500/oaktrail_hdmi: fix i2c adapter leak on setup

Matthew Auld <[email protected]>
drm/xe/dma-buf: handle empty bo and UAF races

Gyeyoung Baek <[email protected]>
drm/panfrost: Fix wait_bo ioctl leaking positive return from dma_resv_wait_timeout()

Sebastian Brzezinka <[email protected]>
drm/i915: skip __i915_request_skip() for already signaled requests

Naval Alcalá <[email protected]>
iommu/vt-d: Disable DMAR for Intel Q35 IGFX

Raphael Zimmer <[email protected]>
libceph: handle rbtree insertion error in decode_choose_args()

Raphael Zimmer <[email protected]>
libceph: Fix potential out-of-bounds access in crush_decode()

Raphael Zimmer <[email protected]>
libceph: Fix potential null-ptr-deref in decode_choose_args()

Raphael Zimmer <[email protected]>
libceph: Fix potential out-of-bounds access in osdmap_decode()

Yong-Xuan Wang <[email protected]>
irqchip/riscv-imsic: Clear interrupt move state during CPU offlining

Paulo Alcantara <[email protected]>
netfs: fix error handling in netfs_extract_user_iter()

Ma Ke <[email protected]>
powerpc/warp: Fix error handling in pika_dtm_thread

Nicholas Carlini <[email protected]>
io-wq: check that the predecessor is hashed in io_wq_remove_pending()

Viacheslav Dubeyko <[email protected]>
ceph: fix BUG_ON in __ceph_build_xattrs_blob() due to stale blob size

Viacheslav Dubeyko <[email protected]>
ceph: fix a buffer leak in __ceph_setxattr()

Cássio Gabriel <[email protected]>
ALSA: usb-audio: Bound MIDI endpoint descriptor scans

Cássio Gabriel <[email protected]>
ALSA: usb-audio: Bound MIDI 2.0 endpoint descriptor scans

Chaitanya Kumar Borah <[email protected]>
drm/i915/dp: Fix VSC dynamic range signaling for RGB formats

Myeonghun Pak <[email protected]>
drm/loongson: Use managed KMS polling

Ye Bin <[email protected]>
smb/client: fix possible infinite loop and oob read in symlink_data()

Pauli Virtanen <[email protected]>
Bluetooth: btmtk: accept too short WMT FUNC_CTRL events

Igor Pylypiv <[email protected]>
ata: libata-scsi: fix requeue of deferred ATA PASS-THROUGH commands

Pablo Neira Ayuso <[email protected]>

    netfilter: nf_tables: unconditionally bump set->nelems before insertion

Qiang Ma <[email protected]>
KVM: x86: Fix Xen hypercall tracepoint argument assignment

Junrui Luo <[email protected]>
KVM: s390: pci: fix GAIT table indexing due to double-scaling pointer arithmetic

Aaron Sacks <[email protected]>
KVM: Reject wrapped offset in kvm_reset_dirty_gfn()

Sergio Correia <[email protected]>
audit: enforce AUDIT_LOCKED for AUDIT_TRIM and AUDIT_MAKE_EQUIV

Zoran Ilievski <[email protected]>
net: atlantic: preserve PCI wake-from-D3 on shutdown when WOL enabled

Li Xiasong <[email protected]>
netfilter: nft_ct: fix missing expect put in obj eval

Mario Limonciello <[email protected]>
Revert "ACPI: CPPC: Adjust debug messages in amd_set_max_freq_ratio() to warn"

Sergio Correia <[email protected]>
audit: fix incorrect inheritable capability in CAPSET records

Li Xiasong <[email protected]>
netfilter: nf_conntrack_sip: get helper before allocating expectation

Breno Leitao <[email protected]>

    workqueue: Fix wq->cpu_pwq leak in alloc_and_link_pwqs() WQ_UNBOUND path

Matt Vollrath <[email protected]>
i40e: Cleanup PTP pins on probe failure

Herbert Xu <[email protected]>

    crypto: af_alg - Cap AEAD AD length to 0x80000000

Mina Almasry <[email protected]>
page_pool: fix incorrect mp_ops error handling

Breno Leitao <[email protected]>
netpoll: pass buffer size to egress_dev() to avoid MAC truncation

Breno Leitao <[email protected]>
netpoll: Extract IPv6 address retrieval function

Eric Dumazet <[email protected]>
net/sched: sch_pie: annotate more data-races in pie_dump_stats()

Ian Rogers <[email protected]>
perf tool_pmu: Fix aggregation on duration_time

Jason Gunthorpe <[email protected]>

    iommu/amd: Put list_add/del(dev_data) back under the domain->lock

Vasant Hegde <[email protected]>
iommu/amd: Reorder attach device code

Justin Chen <[email protected]>
net: bcmgenet: fix leaking free_bds

Ryo Takakura <[email protected]>
net: bcmgenet: Initialize u64 stats seq counter

Gao Xiang <[email protected]>
erofs: fix offset truncation when shifting pgoff on 32-bit platforms

Samiullah Khawaja <[email protected]>
PCI: Initialize temporary device in new_id_store()

Al Viro <[email protected]>

    ntfs: ->d_compare() must not block

Xianglai Li <[email protected]>
LoongArch: KVM: Compile switch.S directly into the kernel

Greg Kroah-Hartman <[email protected]>
smb: client: fix OOB reads parsing symlink error response

Liang Jie <[email protected]>
smb: client: correctly handle ErrorContextData as a flexible array

Zhaoyang Huang <[email protected]>
arm64: Reserve an extra page for early kernel mapping

Paolo Abeni <[email protected]>
net/sched: cls_flower: revert unintended changes

Dan Carpenter <[email protected]>
sfc: fix error code in efx_devlink_info_running_versions()

Jakub Kicinski <[email protected]>
net: tls: fix strparser anchor skb leak on offload RX setup failure

Petr Oros <[email protected]>
ice: fix NULL pointer dereference in ice_reset_all_vfs()

Petr Oros <[email protected]>
iavf: add VIRTCHNL_OP_ADD_VLAN to success completion handler

Petr Oros <[email protected]>
iavf: wait for PF confirmation before removing VLAN filters

Petr Oros <[email protected]>
iavf: stop removing VLAN filters from PF on interface down

Petr Oros <[email protected]>
iavf: rename IAVF_VLAN_IS_NEW to IAVF_VLAN_ADDING

Hasan Basbunar <[email protected]>
page_pool: fix memory-provider leak in page_pool_create_percpu() error path

Pavel Begunkov <[email protected]>
net: page_pool: create hooks for custom memory providers

Samiullah Khawaja <[email protected]>
page_pool: Set dma_sync to false for devmem memory provider

Shuicheng Lin <[email protected]>
drm/xe/gsc: Fix BO leak on error in query_compatibility_version()

Shuicheng Lin <[email protected]>
drm/xe: Fix error cleanup in xe_exec_queue_create_ioctl()

Matt Roper <[email protected]>
drm/xe/debugfs: Correct printing of register whitelist ranges

Timur Kristóf <[email protected]>
drm/amd/display: Read EDID from VBIOS embedded panel info

Timur Kristóf <[email protected]>
drm/amd/display: Allow DCE link encoder without AUX registers

Sebastian Andrzej Siewior <[email protected]>
futex: Prevent lockup in requeue-PI during signal/ timeout wakeup

Richard Fitzgerald <[email protected]>
ALSA: hda: cs35l56: Fix uninitialized value in cs35l56_hda_read_acpi()

wangdicheng <[email protected]>
ALSA: hda/conexant: Fix missing error check for jack detection

wangdicheng <[email protected]>

    ALSA: hda/conexant: Renaming the codec with device ID 0x1f86 and 0x1f87

Breno Leitao <[email protected]>
netconsole: propagate device name truncation in dev_name_store()

Eric Dumazet <[email protected]>
net/sched: sch_cake: annotate data-races in cake_dump_stats() (V)

Weiming Shi <[email protected]>
bareudp: fix NULL pointer dereference in bareudp_fill_metadata_dst()

Xin Long <[email protected]>
sctp: discard stale INIT after handshake completion

Xin Long <[email protected]>
netfilter: skip recording stale or retransmitted INIT

Christian A. Ehrhardt <[email protected]>
ASoC: codecs: ab8500: Fix casting of private data

Yinjie Yao <[email protected]>
drm/amdgpu/jpeg: set no_user_fence for JPEG v5.0.0 ring

Yinjie Yao <[email protected]>
drm/amdgpu/jpeg: set no_user_fence for JPEG v4.0.5 ring

Yinjie Yao <[email protected]>
drm/amdgpu/jpeg: set no_user_fence for JPEG v4.0.3 ring

Yinjie Yao <[email protected]>
drm/amdgpu/jpeg: set no_user_fence for JPEG v4.0 ring

Yinjie Yao <[email protected]>
drm/amdgpu/jpeg: set no_user_fence for JPEG v3.0 ring

Yinjie Yao <[email protected]>
drm/amdgpu/jpeg: set no_user_fence for JPEG v2.5 ring

Yinjie Yao <[email protected]>
drm/amdgpu/jpeg: set no_user_fence for JPEG v2.0 ring

Yinjie Yao <[email protected]>
drm/amdgpu/vcn: set no_user_fence for VCN v5.0.0 enc ring

Yinjie Yao <[email protected]>
drm/amdgpu/vcn: set no_user_fence for VCN v4.0.5 enc ring

Yinjie Yao <[email protected]>
drm/amdgpu/vcn: set no_user_fence for VCN v4.0.3 enc ring

Yinjie Yao <[email protected]>
drm/amdgpu/vcn: set no_user_fence for VCN v3.0 enc/dec rings

Yinjie Yao <[email protected]>
drm/amdgpu/vcn: set no_user_fence for VCN v2.5 enc/dec rings

Yinjie Yao <[email protected]>
drm/amdgpu/vcn: set no_user_fence for VCN v2.0 enc/dec rings

Heiko Schocher <[email protected]>
net: phy: dp83869: fix setting CLK_O_SEL field.

William A. Kennington III <[email protected]>
net: mctp i2c: check length before marking flow active

Zicheng Qu <[email protected]>
sched/fair: Clear rel_deadline when initializing forked entities

Takashi Iwai <[email protected]>
ALSA: usb-audio: Fix potential leak of pd at parsing UAC3 streams

Breno Leitao <[email protected]>
netpoll: fix IPv6 local-address corruption

Breno Leitao <[email protected]>
netpoll: extract IPv4 address retrieval into helper function

Breno Leitao <[email protected]>
netpoll: Extract carrier wait function

Uday Shankar <[email protected]>
netconsole: allow selection of egress interface via MAC address

Uday Shankar <[email protected]>
net, treewide: define and use MAC_ADDR_STR_LEN

Altan Hacigumus <[email protected]>
tcp: make probe0 timer handle expired user timeout

Florian Westphal <[email protected]>
neigh: let neigh_xmit take skb ownership

Weiming Shi <[email protected]>
net/sched: taprio: fix NULL pointer dereference in class dump

Paul Geurts <[email protected]>
NFC: trf7970a: Ignore antenna noise when checking for RF field

Morduan Zang <[email protected]>
net: usb: rtl8150: free skb on usb_submit_urb() failure in xmit

Zhan Jun <[email protected]>

    net: usb: rtl8150: fix use-after-free in rtl8150_start_xmit()

Ido Schimmel <[email protected]>
vrf: Fix a potential NPD when removing a port from a VRF

Eric Dumazet <[email protected]>
net/sched: sch_fq_pie: annotate data-races in fq_pie_dump_stats()

Eric Dumazet <[email protected]>
net/sched: sch_choke: annotate data-races in choke_dump_stats()

Stephen Hemminger <[email protected]>
net/sched: netem: check for negative latency and jitter

Stephen Hemminger <[email protected]>
net/sched: netem: fix slot delay calculation overflow

Stephen Hemminger <[email protected]>
net/sched: netem: validate slot configuration

Stephen Hemminger <[email protected]>
net/sched: netem: only reseed PRNG when seed is explicitly provided

Stephen Hemminger <[email protected]>
net/sched: netem: fix queue limit check to include reordered packets

Stephen Hemminger <[email protected]>
net/sched: netem: fix probability gaps in 4-state loss model

Nikola Z. Ivanov <[email protected]>
netdevsim: zero initialize struct iphdr in dummy sk_buff

Daan De Meyer <[email protected]>
cdrom, scsi: sr: propagate read-only status to block layer via set_disk_ro()

Wentao Guan <[email protected]>
arm64/scs: Fix potential sign extension issue of advance_loc4

Yuho Choi <[email protected]>
drm/sysfb: ofdrm: fix PCI device reference leaks

John Madieu <[email protected]>
spi: rockchip: Read ISR, not IMR, to detect cs-inactive IRQ

Guilherme G. Piccoli <[email protected]>
ASoC: amd: acp: Add DMI quirk for Valve Steam Deck OLED

Florian Westphal <[email protected]>
netfilter: nf_conntrack_sip: don't use simple_strtoul

Jiexun Wang <[email protected]>
netfilter: xt_policy: fix strict mode inbound policy matching

Timur Kristóf <[email protected]>
drm/amdgpu/gfx6: Support harvested SI chips with disabled TCCs (v2)

Timur Kristóf <[email protected]>
drm/amdgpu/uvd3.1: Don't validate the firmware when already validated

Alexandre Demers <[email protected]>
drm/amdgpu: fix spelling typos

Christian König <[email protected]>
drm/amdgpu: fix AMDGPU_INFO_READ_MMR_REG

Timur Kristóf <[email protected]>
drm/amdgpu/gmc: Fix AMDGPU_GART_PLACEMENT_LOW to not overlap with VRAM

Keith Busch <[email protected]>
nvme-pci: fix missed admin queue sq doorbell write

Pablo Neira Ayuso <[email protected]>
netfilter: arp_tables: fix IEEE1394 ARP payload parsing

Maurizio Lombardi <[email protected]>
nvmet-tcp: propagate nvmet_tcp_build_pdu_iovec() errors to its callers

Breno Leitao <[email protected]>
tracing: branch: Fix inverted check on stat tracer registration

Petr Malat <[email protected]>
cgroup: Increment nr_dying_subsys_* from rmdir context

Mark Harmstone <[email protected]>
btrfs: fix double-decrement of bytes_may_use in submit_one_async_extent()

Amir Goldstein <[email protected]>
fsnotify: fix inode reference leak in fsnotify_recalc_mask()

Wolfram Sang <[email protected]>
mailbox: mailbox-test: make data_ready a per-instance variable

Wolfram Sang <[email protected]>
mailbox: mailbox-test: initialize struct earlier

Wolfram Sang <[email protected]>
mailbox: mailbox-test: don't free the reused channel

Wolfram Sang <[email protected]>
mailbox: add sanity check for channel array

cuitao <[email protected]>
cgroup/rdma: fix integer overflow in rdmacg_try_charge()

Edward Adam Davis <[email protected]>
sched/psi: fix race between file release and pressure write

Wolfram Sang <[email protected]>
mailbox: mailbox-test: free channels on probe error

Jason-JH Lin <[email protected]>
mailbox: mtk-cmdq: Fix CURR and END addr for task insert case

Yuho Choi <[email protected]>
fbdev: offb: fix PCI device reference leak on probe failure

Mathias Krause <[email protected]>
kbuild: builddeb - avoid recompiles for non-cross-compiles

Anthony Pighin (Nokia) <[email protected]>

    rtc: abx80x: Disable alarm feature if no interrupt attached

Bae Yeonju <[email protected]>
fs/adfs: validate nzones in adfs_validate_bblk()

Kohei Enju <[email protected]>
vhost_net: fix sleeping with preempt-disabled in vhost_net_busy_poll()

Lee Jones <[email protected]>
tipc: fix double-free in tipc_buf_append()

Alexey Kodanev <[email protected]>
nfp: fix swapped arguments in nfp_encode_basic_qdr() calls

Brett Creeley <[email protected]>
virtio_net: sync rss_trailer.max_tx_vq on queue_pairs change via VQ_PAIRS_SET

Akihiko Odaki <[email protected]>
virtio_net: Use new RSS config structs

Akihiko Odaki <[email protected]>
virtio_net: Fix endian with virtio_net_ctrl_rss

Akihiko Odaki <[email protected]>
virtio_net: Split struct virtio_net_rss_config

Lorenzo Bianconi <[email protected]>
net: airoha: Move ndesc initialization at end of airoha_qdma_init_rx_queue()

Mieczyslaw Nalewaj <[email protected]>
net: dsa: realtek: rtl8365mb: fix mode mask calculation

Eric Dumazet <[email protected]>
net/sched: sch_sfb: annotate data-races in sfb_dump_stats()

Eric Dumazet <[email protected]>
net/sched: sch_red: annotate data-races in red_dump_stats()

Eric Dumazet <[email protected]>
net/sched: sch_fq_codel: remove data-races from fq_codel_dump_stats()

Eric Dumazet <[email protected]>
net/sched: sch_pie: annotate data-races in pie_dump_stats()

Eric Dumazet <[email protected]>
net_sched: sch_hhf: annotate data-races in hhf_dump_stats()

Jacob Keller <[email protected]>
ice: fix ice_ptp_read_tx_hwtstamp_status_eth56g

Grzegorz Nitka <[email protected]>
ice: fix timestamp interrupt configuration for E825C

Michael Bommarito <[email protected]>
net/rds: zero per-item info buffer before handing it to visitors

Hyunwoo Kim <[email protected]>

    ksmbd: scope conn->binding slowpath to bound sessions only

DaeMyung Kang <[email protected]>
ksmbd: fix durable fd leak on ClientGUID mismatch in durable v2 open

DaeMyung Kang <[email protected]>
ksmbd: destroy async_ida in ksmbd_conn_free()

DaeMyung Kang <[email protected]>
ksmbd: destroy tree_conn_ida in ksmbd_session_destroy()

Sangyun Kim <[email protected]>
pwm: atmel-tcb: Cache clock rates and mark chip as atomic

Jun Yan <[email protected]>
arm64: dts: meson-gxl-p230: fix ethernet PHY interrupt number

Weiming Shi <[email protected]>
slip: bound decode() reads against the compressed packet length

Weiming Shi <[email protected]>
slip: reject VJ receive packets on instances with no rstate array

Fernando Fernandez Mancera <[email protected]>
netfilter: nfnetlink_osf: fix potential NULL dereference in ttl check

Fernando Fernandez Mancera <[email protected]>
netfilter: nfnetlink_osf: fix out-of-bounds read on option matching

Yingnan Zhang <[email protected]>
ipvs: fix MTU check for GSO packets in tunnel mode

Pablo Neira Ayuso <[email protected]>
netfilter: xtables: restrict several matches to inet family

Florian Westphal <[email protected]>
netfilter: conntrack: remove sprintf usage

Xiang Mei <[email protected]>
netfilter: nfnetlink_osf: fix divide-by-zero in OSF_WSS_MODULO

Pablo Neira Ayuso <[email protected]>
netfilter: nft_osf: restrict it to ipv4

Weiming Shi <[email protected]>
openvswitch: cap upcall PID array size and pre-size vport replies

Prathamesh Deshpande <[email protected]>
net/mlx5: Fix HCA caps leak on notifier init failure

Qingfang Deng <[email protected]>
pppoe: drop PFC frames

Michael Bommarito <[email protected]>
sctp: fix OOB write to userspace in sctp_getsockopt_peer_auth_chunks

Eric Dumazet <[email protected]>
ipv6: fix possible UAF in icmpv6_rcv()

Matt Vollrath <[email protected]>
e1000e: Unroll PTP in probe error handling

Kohei Enju <[email protected]>
i40e: don't advertise IFF_SUPP_NOFCS

Paul Greenwalt <[email protected]>
ice: fix ICE_AQ_LINK_SPEED_M for 200G

Michal Schmidt <[email protected]>
ice: fix double-free of tx_buf skb

Alice Mikityanska <[email protected]>
ice: Remove jumbo_remove step from TX path

Grzegorz Nitka <[email protected]>
ice: update PCS latency settings for E825 10G/25Gb modes

Eric Dumazet <[email protected]>

    tcp: annotate data-races around tp->plb_rehash

Eric Dumazet <[email protected]>

    tcp: annotate data-races around (tp->write_seq - tp->snd_nxt)

Eric Dumazet <[email protected]>

    tcp: annotate data-races around tp->dsack_dups

Eric Dumazet <[email protected]>

    tcp: annotate data-races around tp->bytes_retrans

Eric Dumazet <[email protected]>

    tcp: annotate data-races around tp->bytes_sent

Eric Dumazet <[email protected]>
tcp: add data-race annotations for TCP_NLA_SNDQ_SIZE

Eric Dumazet <[email protected]>

    tcp: add data-race annotations around tp->data_segs_out and tp->total_retrans

Vinicius Costa Gomes <[email protected]>
net/sched: taprio: fix use-after-free in advance_sched() on schedule switch

Jiayuan Chen <[email protected]>
nexthop: fix IPv6 route referencing IPv4 nexthop

Dudu Lu <[email protected]>
net/sched: sch_cake: fix NAT destination port not being updated in cake_update_flowkeys

Dudu Lu <[email protected]>
macvlan: fix macvlan_get_size() not reserving space for IFLA_MACVLAN_BC_CUTOFF

Dudu Lu <[email protected]>
net/sched: act_mirred: fix wrong device for mac_header_xmit check in tcf_blockcast_redir

Gabor Juhos <[email protected]>
arm64: dts: marvell: armada-37xx: use 'usb2-phy' in USB3 controller's phy-names

Peng Fan <[email protected]>
arm64: dts: imx8mm-tqma8mqml: Correct PAD settings for PMIC_nINT

Peng Fan <[email protected]>
arm64: dts: imx8mn-tqma8mqnl: Correct PAD settings for PMIC_nINT

Peng Fan <[email protected]>
arm64: dts: imx8mm-emtop-som: Correct PAD settings for PMIC_nINT

René Rebe <[email protected]>
PCMCIA: Fix garbled log messages for KERN_CONT

Peng Fan <[email protected]>
arm64: dts: imx8mp-data-modul-edm-sbc: Correct PAD settings for PMIC_nINT

Peng Fan <[email protected]>
arm64: dts: imx8mp-dhcom-som: Correct PAD settings for PMIC_nINT

Peng Fan <[email protected]>
arm64: dts: imx8mp-icore-mx8mp: Correct PAD settings for PMIC_nINT

Peng Fan <[email protected]>
arm64: dts: imx8mp-navqp: Correct PAD settings for PMIC_nINT

Peng Fan <[email protected]>
arm64: dts: imx8mp-debix-som-a: Correct PAD settings for PMIC_nINT

Peng Fan <[email protected]>
arm64: dts: imx8mp-debix-model-a: Correct PAD settings for PMIC_nINT

Gao Xiang <[email protected]>
erofs: unify lcn as u64 for 32-bit platforms

Gao Xiang <[email protected]>
erofs: avoid infinite loops due to corrupted subpage compact indexes

Chao Yu <[email protected]>

    erofs: do sanity check on m->type in z_erofs_load_compact_lcluster()

Gao Xiang <[email protected]>
erofs: add encoded extent on-disk definition

Paul Moses <[email protected]>
crypto: ccp - copy IV using skcipher ivsize

T Pratham <[email protected]>
crypto: sa2ul - Fix AEAD fallback algorithm names

Ville Syrjälä <[email protected]>
drm/i915/wm: Verify the correct plane DDB entry

Ville Syrjälä <[email protected]>
drm/i915: Relocate the SKL wm sanitation code

Yongpeng Yang <[email protected]>
f2fs: protect extension_list reading with sb_lock in f2fs_sbi_show()

Brian Masney <[email protected]>
clk: visconti: pll: initialize clk_init_data to zero

Jagadeesh Kona <[email protected]>
clk: qcom: gcc-x1e80100: Keep GCC USB QTB clock always ON

Geert Uytterhoeven <[email protected]>
lib/hexdump: print_hex_dump_bytes() calls print_hex_dump_debug()

Konrad Dybcio <[email protected]>
clk: qcom: dispcc-sc7180: Add missing MDSS resets

Konrad Dybcio <[email protected]>
dt-bindings: clock: qcom,dispcc-sc7180: Define MDSS resets

Geert Uytterhoeven <[email protected]>
clk: xgene: Fix mapping leak in xgene_pllclk_init()

Arnd Bergmann <[email protected]>
clk: qoriq: avoid format string warning

Thomas Weißschuh <[email protected]>
x86/um: fix vDSO installation

Thomas Weißschuh <[email protected]>
x86/um/vdso: Drop VDSO64-y from Makefile

Sebastian Krzyszkowiak <[email protected]>
clk: imx8mq: Correct the CSI PHY sels

Felix Gu <[email protected]>
clk: imx: imx6q: Fix device node reference leak in of_assigned_ldb_sels()

Felix Gu <[email protected]>
clk: imx: imx6q: Fix device node reference leak in pll6_bypassed()

Val Packett <[email protected]>
clk: qcom: dispcc-sm8250: Enable parents for pixel clocks

Val Packett <[email protected]>
clk: qcom: dispcc-sm8250: Use shared ops on the mdss vsync clk

Val Packett <[email protected]>

    clk: qcom: gcc-sc8180x: Use retention for PCIe power domains

Val Packett <[email protected]>

    clk: qcom: gcc-sc8180x: Use retention for USB power domains

Val Packett <[email protected]>

    clk: qcom: gcc-sc8180x: Add missing GDSCs

Val Packett <[email protected]>

    dt-bindings: clock: qcom,gcc-sc8180x: Add missing GDSCs

Junrui Luo <[email protected]>
scsi: target: core: Fix integer overflow in UNMAP bounds check

Konrad Dybcio <[email protected]>
clk: qcom: dispcc-sm4450: Fix DSI byte clock rate setting

White Lewis <[email protected]>

    clk: qcom: dispcc-sc8280xp: remove CLK_SET_RATE_PARENT from byte_div_clk_src dividers

Yang Erkun <[email protected]>
scsi: sg: Resolve soft lockup issue when opening /dev/sgX

Yang Erkun <[email protected]>
scsi: sg: Fix sysctl sg-big-buff register during sg_init()

Dmitry Baryshkov <[email protected]>
clk: qcom: dispcc-sm8450: use RCG2 ops for DPTX1 AUX clock source

Florian Westphal <[email protected]>
RDMA/core: Prefer NLA_NUL_STRING

Pengpeng Hou <[email protected]>
platform/x86: dell-wmi-sysman: bound enumeration string aggregation

Fedor Pchelkin <[email protected]>
platform/x86: dell_rbu: avoid uninit value usage in packet_size_write()

Pengpeng Hou <[email protected]>
fs/ntfs3: terminate the cached volume label after UTF-8 conversion

Thomas Bogendoerfer <[email protected]>
tty: serial: ip22zilog: Fix section mispatch warning

Denis Benato <[email protected]>
platform/x86: asus-wmi: fix screenpad brightness range

Denis Benato <[email protected]>
platform/x86: asus-wmi: adjust screenpad power/brightness handling

Andy Shevchenko <[email protected]>
nfs/blocklayout: Fix compilation error (make W=1) in bl_write_pagelist()

Abdun Nihaal <[email protected]>
mfd: mc13xxx-core: Fix memory leak in mc13xxx_add_subdevice_pdata()

Rafael J. Wysocki <[email protected]>
platform/x86: panasonic-laptop: Fix OPTD notifier registration and cleanup

Randy Dunlap <[email protected]>
tty: hvc_iucv: fix off-by-one in number of supported devices

Chen Ni <[email protected]>

    leds: lgm-sso: Remove duplicate assignments for priv->mmap

Rafael J. Wysocki <[email protected]>
platform/surface: surfacepro3_button: Drop wakeup source on remove

Chen Ni <[email protected]>
backlight: sky81452-backlight: Check return value of devm_gpiod_get_optional() in sky81452_bl_parse_dt()

Billy Tsai <[email protected]>
i3c: mipi-i3c-hci: fix IBI payload length calculation for final status

Jorge Marques <[email protected]>
i3c: master: Fix error codes at send_ccc_cmd

Felix Gu <[email protected]>
i3c: dw: Fix memory leak in dw_i3c_master_i3c_xfers()

Felix Gu <[email protected]>
i3c: master: dw-i3c: Fix missing reset assertion in remove() callback

Philipp Zabel <[email protected]>
reset: Add devres helpers to request pre-deasserted reset controls

Philipp Zabel <[email protected]>
reset: replace boolean parameters with flags parameter

Arnaldo Carvalho de Melo <[email protected]>
perf util: Kill die() prototype, dead for a long time

Ian Rogers <[email protected]>
perf maps: Fix copy_from that can break sorted by name order

Ian Rogers <[email protected]>
perf cgroup: Update metric leader in evlist__expand_cgroup

Ian Rogers <[email protected]>
perf python: Add parse_events function

Ian Rogers <[email protected]>
perf tool_pmu: Factor tool events into their own PMU

Ian Rogers <[email protected]>
perf evsel: Add alternate_hw_config and use in evsel__match

Jian Zhang <[email protected]>
ipmi: ssif_bmc: change log level to dbg in irq callback

Jian Zhang <[email protected]>
ipmi: ssif_bmc: fix message desynchronization after truncated response

Jian Zhang <[email protected]>
ipmi: ssif_bmc: fix missing check for copy_to_user() partial failure

Leo Yan <[email protected]>
perf expr: Return -EINVAL for syntax error in expr__find_ids()

Chuck Lever <[email protected]>
perf tools: Fix module symbol resolution for non-zero .text sh_addr

Ian Rogers <[email protected]>

    perf stat: Fix opt->value type for parse_cache_level

Ian Rogers <[email protected]>
perf lock: Fix option value type in parse_max_stack

Biju Das <[email protected]>
pinctrl: renesas: rzg2l: Fix save/restore of {IOLH,IEN,PUPD,SMT} registers

Yu-Chun Lin <[email protected]>
pinctrl: abx500: Fix type of 'argument' variable

Yu-Chun Lin <[email protected]>
pinctrl: realtek: Fix function signature for config argument

Mike Leach <[email protected]>
perf: tools: cs-etm: Fix print issue for Coresight debug in ETE/TRBE trace

Ian Rogers <[email protected]>
perf branch: Avoid incrementing NULL

Andy Shevchenko <[email protected]>
pinctrl: cy8c95x0: Avoid returning positive values to user space

Andy Shevchenko <[email protected]>
pinctrl: cy8c95x0: Unify messages with help of dev_err_probe()

Andy Shevchenko <[email protected]>
pinctrl: cy8c95x0: remove duplicate error message

Ethan Tidmore <[email protected]>
pinctrl: pinctrl-pic32: Fix resource leak

Puranjay Mohan <[email protected]>
bpf, arm32: Reject BPF-to-BPF calls and callbacks in the JIT

Puranjay Mohan <[email protected]>
bpf: Validate node_id in arena_alloc_pages()

Jiri Olsa <[email protected]>
libbpf: Prevent double close and leak of btf objects

Mykyta Yatsenko <[email protected]>
libbpf: Stringify errno in log messages in libbpf.c

Ihor Solodrai <[email protected]>
libbpf: Change log level of BTF loading error message

Yihan Ding <[email protected]>
bpf: allow UTF-8 literals in bpf_bprintf_prepare()

Mykyta Yatsenko <[email protected]>
bpf: Fix NULL deref in map_kptr_match_type for scalar regs

Daniel Borkmann <[email protected]>
bpf: Fix precedence bug in convert_bpf_ld_abs alignment check

Michal Luczaj <[email protected]>
bpf, sockmap: Take state lock for af_unix iter

Michal Luczaj <[email protected]>
bpf, sockmap: Fix af_unix null-ptr-deref in proto update

Michal Luczaj <[email protected]>
bpf, sockmap: Fix af_unix iter deadlock

Puranjay Mohan <[email protected]>
bpf, riscv: Remove redundant bpf_flush_icache() after pack allocator finalize

Daniel Borkmann <[email protected]>
bpf, arm64: Fix off-by-one in check_imm signed range check

Ye Bin <[email protected]>
ext4: fix possible null-ptr-deref in mbt_kunit_exit()

Oliver Neukum <[email protected]>
HID: usbhid: fix deadlock in hid_post_reset()

Richard Genoud <[email protected]>
mtd: rawnand: sunxi: fix sunxi_nfc_hw_ecc_read_extra_oob

Li Ming <[email protected]>
cxl/pci: Check memdev driver binding status in cxl_reset_done()

Cosmin Tanislav <[email protected]>
mtd: parsers: ofpart: call of_node_get() for dedicated subpartitions

Cosmin Tanislav <[email protected]>
mtd: parsers: ofpart: call of_node_put() only in ofpart_fail path

Shiji Yang <[email protected]>
mtd: spi-nor: swp: check SR_TB flag when getting tb_mask

Jonas Gorski <[email protected]>
mtd: spi-nor: update spi_nor_fixups::post_sfdp() documentation

Takahiro Kuwano <[email protected]>
mtd: spi-nor: sfdp: introduce smpt_map_id fixup hook

Takahiro Kuwano <[email protected]>
mtd: spi-nor: sfdp: introduce smpt_read_dummy fixup hook

Haibo Chen <[email protected]>
mtd: spi-nor: core: correct the op.dummy.nbytes when check read operations

Geert Uytterhoeven <[email protected]>
dt-bindings: interrupt-controller: arm,gic-v3: Fix EPPI range

Dmitry Safonov <[email protected]>
ima_fs: Correctly create securityfs files for unsupported hash algos

Al Viro <[email protected]>
ima_fs: get rid of lookup-by-dentry stuff

Al Viro <[email protected]>
ima_fs: don't bother with removal of files in directory we'll be removing

Chen Ni <[email protected]>
mtd: physmap_of_gemini: Fix disabled pinctrl state check

Denis Benato <[email protected]>
HID: asus: do not abort probe when not necessary

Denis Benato <[email protected]>
HID: asus: make asus_resume adhere to linux kernel coding standards

Daniel Hodges <[email protected]>
ima: check return value of crypto_shash_final() in boot aggregate

Tim Michals <[email protected]>
remoteproc: xlnx: Fix sram property parsing

Francesco Lavra <[email protected]>
hte: tegra194: remove Kconfig dependency on Tegra194 SoC

Pengpeng Hou <[email protected]>
tracing: Rebuild full_name on each hist_field_name() call

Richard Fitzgerald <[email protected]>
soundwire: cadence: Clear message complete before signaling waiting thread

Frank Li <[email protected]>
dmaengine: mxs-dma: Fix missing return value from of_dma_controller_register()

Cole Leavitt <[email protected]>
soundwire: bus: demote UNATTACHED state warnings to dev_dbg()

Khairul Anuar Romli <[email protected]>
dmaengine: dw-axi-dmac: Remove unnecessary return statement from void function

ZhengYuan Huang <[email protected]>
ocfs2: validate group add input before caching

ZhengYuan Huang <[email protected]>
ocfs2: validate bg_bits during freefrag scan

ZhengYuan Huang <[email protected]>
ocfs2: fix listxattr handling when the buffer is full

Sebastian Ene <[email protected]>
firmware: arm_ffa: Use the correct buffer size during RXTX_MAP

Frank Li <[email protected]>
ARM: dts: imx27-eukrea: replace interrupts with interrupts-extended

Christoph Hellwig <[email protected]>
arm64/xor: fix conflicting attributes for xor_block_template

Aaro Koskinen <[email protected]>
ARM: OMAP1: Fix DEBUG_LL and earlyprintk on OMAP16XX

Alexander Koskovich <[email protected]>

    arm64: dts: qcom: sm8250: Add missing CPU7 3.09GHz OPP

Alok Tiwari <[email protected]>
soc: qcom: aoss: compare against normalized cooling state

Alok Tiwari <[email protected]>
soc: qcom: llcc: fix v1 SB syndrome register offset

Junrui Luo <[email protected]>
ocfs2/dlm: fix off-by-one in dlm_match_regions() region comparison

Junrui Luo <[email protected]>
ocfs2/dlm: validate qr_numregions in dlm_match_regions()

Michal Grzedzicki <[email protected]>
unshare: fix nsproxy leak in ksys_unshare() on set_cred_ucounts() failure

Sumit Gupta <[email protected]>
soc/tegra: cbb: Set ERD on resume for err interrupt

Xu Yang <[email protected]>
arm64: dts: imx8qxp-mek: switch Type-C connector power-role to dual

Xu Yang <[email protected]>
arm64: dts: imx8qm-mek: switch Type-C connector power-role to dual

Josua Mayer <[email protected]>
arm64: dts: lx2160a: complete pinmux for rcwsr12 configuration word

Josua Mayer <[email protected]>
arm64: dts: lx2160a: change zeros to hexadecimal in pinmux nodes

Josua Mayer <[email protected]>
arm64: dts: lx2160a: add sda gpio references for i2c bus recovery

Josua Mayer <[email protected]>
arm64: dts: lx2160a: rename pinmux nodes for readability

Josua Mayer <[email protected]>
arm64: dts: lx2160a: remove duplicate pinmux nodes

Josua Mayer <[email protected]>
arm64: dts: lx2160a: change i2c0 (iic1) pinmux mask to one bit

Nora Schiffer <[email protected]>
arm64: dts: freescale: imx8mp-tqma8mpql-mba8mp-ras314: fix UART1 RTS/CTS muxing

Francesco Dolcini <[email protected]>
arm64: dts: ti: k3-am62-verdin: Fix SPI_1 GPIO CS pinctrl label

Judith Mendez <[email protected]>
arm64: dts: ti: k3-am62-lp-sk: Enable internal pulls for MMC0 data pins

Judith Mendez <[email protected]>
arm64: dts: ti: k3-am62p5-sk: Disable MMC1 internal pulls on data pins

David Heidelberg <[email protected]>
arm64: dts: qcom: sdm845-xiaomi-beryllium: Mark l1a regulator as powered during boot

Luca Weiss <[email protected]>
arm64: dts: qcom: sm7225-fairphone-fp4: Fix conflicting bias pinctrl

Vladimir Zapolskiy <[email protected]>
arm64: dts: qcom: sm8650: Enable UHS-I SDR50 and SDR104 SD card modes

Vladimir Zapolskiy <[email protected]>
arm64: dts: qcom: sm8550: Enable UHS-I SDR50 and SDR104 SD card modes

Vladimir Zapolskiy <[email protected]>
arm64: dts: qcom: sm8450: Enable UHS-I SDR50 and SDR104 SD card modes

Vladimir Zapolskiy <[email protected]>
arm64: dts: qcom: sm8650: Fix xo clock supply of SD host controller

Vladimir Zapolskiy <[email protected]>
arm64: dts: qcom: sm8550: Fix xo clock supply of platform SD host controller

Konrad Dybcio <[email protected]>
arm64: dts: qcom: sm8650: Fix GIC_ITS range length

Konrad Dybcio <[email protected]>
arm64: dts: qcom: sm8550: Fix GIC_ITS range length

Konrad Dybcio <[email protected]>
arm64: dts: qcom: sm8450: Fix GIC_ITS range length

Gatien Chevallier <[email protected]>
bus: rifsc: fix RIF configuration check for peripherals

Dmitry Baryshkov <[email protected]>
soc: qcom: ocmem: return -EPROBE_DEFER is ocmem is not available

Dmitry Baryshkov <[email protected]>
soc: qcom: ocmem: register reasons for probe deferrals

Dmitry Baryshkov <[email protected]>
soc: qcom: ocmem: make the core clock optional

Chris Morgan <[email protected]>
arm64: dts: rockchip: Correct Joystick Axes on Gameforce Ace

Chris Morgan <[email protected]>
arm64: dts: rockchip: Correct Fan Supply for Gameforce Ace

Ming Wang <[email protected]>
arm64: dts: rockchip: Fix Bluetooth stability on LCKFB TaiShan Pi

Barnabás Czémán <[email protected]>
arm64: dts: qcom: msm8953-xiaomi-daisy: fix backlight

Barnabás Czémán <[email protected]>
arm64: dts: qcom: msm8953-xiaomi-vince: correct wled ovp value

Akari Tsuyukusa <[email protected]>
arm64: dts: mediatek: mt7986a: Fix gpio-ranges pin count

Akari Tsuyukusa <[email protected]>
arm64: dts: mediatek: mt7981b: Fix gpio-ranges pin count

Akari Tsuyukusa <[email protected]>
arm64: dts: mediatek: mt6795: Fix gpio-ranges pin count

Jacob Pan <[email protected]>
iommufd: vfio compatibility extension check for noiommu mode

Sherry Sun <[email protected]>
arm64: dts: imx8mp-evk: Enable pull select bit for PCIe regulator GPIO (M.2 W_DISABLE1)

Heiko Stuebner <[email protected]>
arm64: dts: rockchip: Make Jaguar PCIe-refclk pin use pull-up config

Francesco Dolcini <[email protected]>
arm64: dts: imx8-apalis: Fix LEDs name collision

Mikko Perttunen <[email protected]>
memory: tegra30-emc: Fix dll_change check

Mikko Perttunen <[email protected]>
memory: tegra124-emc: Fix dll_change check

Rafał Miłecki <[email protected]>
ARM: dts: mediatek: mt7623: fix efuse fallback compatible

Nícolas F. R. A. Prado <[email protected]>
arm64: dts: mediatek: mt8365: Describe infracfg-nao as a pure syscon

Joshua Klinesmith <[email protected]>
ksmbd: fix use-after-free from async crypto on Qualcomm crypto engine

Thomas Huth <[email protected]>
efi/capsule-loader: fix incorrect sizeof in phys array reallocation

Andreas Gruenbacher <[email protected]>
gfs2: prevent NULL pointer dereference during unmount

Andreas Gruenbacher <[email protected]>
gfs2: add some missing log locking

Jan Kara <[email protected]>
quota: Fix race of dquot_scan_active() with quota deactivation

Ricardo B. Marlière <[email protected]>
ktest: Run POST_KTEST hooks on failure and cancellation

Ricardo B. Marlière <[email protected]>
ktest: Honor empty per-test option overrides

Ricardo B. Marlière <[email protected]>
ktest: Avoid undef warning when WARNINGS_FILE is unset

Ondrej Mosnacek <[email protected]>
fanotify: call fanotify_events_supported() before path_permission() and security_path_notify()

Al Viro <[email protected]>
fdget(), trivial conversions

Al Viro <[email protected]>
net/socket.c: switch to CLASS(fd)

Andreas Gruenbacher <[email protected]>
gfs2: Call unlock_new_inode before d_instantiate

Kailang Yang <[email protected]>
ALSA: hda/realtek - fixed speaker no sound update

Haixin Xu <[email protected]>
crypto: jitterentropy - replace long-held spinlock with mutex

Ming-Hung Tsai <[email protected]>
dm cache: fix missing return in invalidate_committed's error path

Cássio Gabriel <[email protected]>
ALSA: sc6000: Keep the programmed board state in card-private data

Pei Xiao <[email protected]>
spi: mtk-snfi: unregister ECC engine on probe failure and remove() callback

Manikanta Maddireddy <[email protected]>
PCI: tegra194: Fix CBB timeout caused by DBI access before core power-on

Manikanta Maddireddy <[email protected]>
PCI: dwc: Apply ECRC workaround to DesignWare 5.00a as well

Manikanta Maddireddy <[email protected]>
PCI: tegra194: Use DWC IP core version

Vidya Sagar <[email protected]>
PCI: tegra194: Free up Endpoint resources during remove()

Vidya Sagar <[email protected]>
PCI: tegra194: Allow system suspend when the Endpoint link is not up

Vidya Sagar <[email protected]>
PCI: tegra194: Set LTR message request before PCIe link up in Endpoint mode

Vidya Sagar <[email protected]>
PCI: tegra194: Disable direct speed change for Endpoint mode

Vidya Sagar <[email protected]>
PCI: tegra194: Use devm_gpiod_get_optional() to parse "nvidia,refclk-select"

Manikanta Maddireddy <[email protected]>
PCI: tegra194: Disable PERST# IRQ only in Endpoint mode

Vidya Sagar <[email protected]>
PCI: tegra194: Don't force the device into the D0 state before L2

Manivannan Sadhasivam <[email protected]>
PCI: tegra194: Rename 'root_bus' to 'root_port_bus' in tegra_pcie_downstream_dev_to_D0()

Manikanta Maddireddy <[email protected]>
PCI: tegra194: Disable LTSSM after transition to Detect on surprise link down

Manikanta Maddireddy <[email protected]>
PCI: tegra194: Increase LTSSM poll time on surprise link down

Vidya Sagar <[email protected]>
PCI: tegra194: Fix polling delay for L2 state

Richard Cheng <[email protected]>
PCI/NPEM: Set LED_HW_PLUGGABLE for hotplug-capable ports

Cássio Gabriel <[email protected]>
ASoC: SOF: compress: return the configured codec from get_params

Panagiotis Petrakopoulos <[email protected]>
ALSA: scarlett2: Add missing sentinel initializer field

Waiman Long <[email protected]>
selftest: memcg: skip memcg_sock test if address family not supported

Jane Chu <[email protected]>
Documentation: fix a hugetlbfs reservation statement

AnishMulay <[email protected]>
selftests/mm: skip migration tests if NUMA is unavailable

Chen-Yu Tsai <[email protected]>
PCI: mediatek-gen3: Prevent leaking IRQ domains when IRQ not found

Gerd Bayer <[email protected]>
PCI: Enable AtomicOps only if Root Port supports them

Denis Rastyogin <[email protected]>

    ASoC: rsnd: Fix potential out-of-bounds access of component_dais[]

Giovanni Cabiddu <[email protected]>
crypto: qat - use swab32 macro

Giovanni Cabiddu <[email protected]>
crypto: qat - fix type mismatch in RAS sysfs show functions

Ahsan Atta <[email protected]>

    crypto: qat - disable 420xx AE cluster when lead engine is fused off

Ahsan Atta <[email protected]>
crypto: qat - disable 4xxx AE cluster when lead engine is fused off

Suman Kumar Chakraborty <[email protected]>
crypto: qat - introduce fuse array

Srinivas Kandagatla <[email protected]>
ASoC: qcom: qdsp6: topology: check widget type before accessing data

Vasant Hegde <[email protected]>
iommu/amd: Fix clone_alias() to use the original device's devid

Suravee Suthikulpanit <[email protected]>
iommu/amd: Introduce helper function get_dte256()

Suravee Suthikulpanit <[email protected]>
iommu/amd: Introduce helper function to update 256-bit DTE

Vasant Hegde <[email protected]>
iommu/amd: Convert dev_data lock from spinlock to mutex

Vasant Hegde <[email protected]>
iommu/amd: Rearrange attach device code

Vasant Hegde <[email protected]>
iommu/amd: Reduce domain lock scope in attach device path

Vasant Hegde <[email protected]>
iommu/amd: Do not detach devices in domain free path

Vasant Hegde <[email protected]>

    iommu/amd: xarray to track protection_domain->iommu list

Vasant Hegde <[email protected]>
iommu/amd: Remove protection_domain.dev_cnt variable

Shengjiu Wang <[email protected]>
ASoC: fsl_easrc: Change the type for iec958 channel status controls

Shengjiu Wang <[email protected]>
ASoC: fsl_easrc: Fix value type in fsl_easrc_iec958_get_bits()

Shengjiu Wang <[email protected]>
ASoC: fsl_easrc: Check the variable range in fsl_easrc_iec958_put_bits()

Shengjiu Wang <[email protected]>
ASoC: fsl_xcvr: Fix event generation in fsl_xcvr_mode_put()

Shengjiu Wang <[email protected]>
ASoC: fsl_xcvr: Fix event generation in fsl_xcvr_arc_mode_put()

Shengjiu Wang <[email protected]>
ASoC: fsl_micfil: Fix event generation in micfil_quality_set()

Shengjiu Wang <[email protected]>
ASoC: fsl_micfil: Fix event generation in micfil_put_dc_remover_state()

Shengjiu Wang <[email protected]>
ASoC: fsl_micfil: Fix event generation in hwvad_put_init_mode()

Shengjiu Wang <[email protected]>
ASoC: fsl_micfil: Fix event generation in hwvad_put_enable()

Shengjiu Wang <[email protected]>
ASoC: fsl_micfil: Add access property for "VAD Detected"

Dmitry Baryshkov <[email protected]>
PM: domains: De-constify fields in struct dev_pm_domain_attach_data

Felix Gu <[email protected]>

    pmdomain: imx: scu-pd: Fix device_node reference leak during ->probe()

Felix Gu <[email protected]>
pmdomain: ti: omap_prm: Fix a reference leak on device node

Akhil P Oommen <[email protected]>
drm/msm/a6xx: Use barriers while updating HFI Q headers

Connor Abbott <[email protected]>
drm/msm/a6xx: Fix dumping A650+ debugbus blocks

Rob Clark <[email protected]>
drm/msm/shrinker: Fix can_block() logic

Rob Clark <[email protected]>
drm/msm/a6xx: Fix HLSQ register dumping

Ethan Tidmore <[email protected]>
ASoC: SOF: Intel: hda: Place check before dereference

Lei Huang <[email protected]>
ALSA: hda/realtek: fix code style (ERROR: else should follow close brace '}')

Billy Tsai <[email protected]>
hwmon: (aspeed-g6-pwm-tach): remove redundant driver remove callback

Uwe Kleine-König <[email protected]>
hwmon: Switch back to struct platform_driver::remove()

Timur Kristóf <[email protected]>
drm/amdgpu/uvd4.2: Don't initialize UVD 4.2 when DPM is disabled

Sunil Khatri <[email protected]>
drm/amdgpu: update the handle ptr in early_init

Sunil Khatri <[email protected]>
drm/amdgpu: update the handle ptr in dump_ip_state

Sunil Khatri <[email protected]>
drm/amdgpu: add amdgpu_device reference in ip block

Timur Kristóf <[email protected]>
drm/amd/pm/smu7: Add SCLK cap for quirky Hawaii board

Timur Kristóf <[email protected]>
drm/amd/pm/ci: Fill DW8 fields from SMC

Timur Kristóf <[email protected]>
drm/amd/pm/ci: Clear EnabledForActivity field for memory levels

Timur Kristóf <[email protected]>

    drm/amd/pm/ci: Fix powertune defaults for Hawaii 0x67B0

Timur Kristóf <[email protected]>
drm/amd/pm/smu7: Fix SMU7 voltage dependency on display clock

Timur Kristóf <[email protected]>
drm/amd/pm/ci: Disable MCLK DPM on problematic CI ASICs

Timur Kristóf <[email protected]>
drm/amd/pm/ci: Use highest MCLK on CI when MCLK DPM is disabled

Cássio Gabriel <[email protected]>
ALSA: core: Validate compress device numbers without dynamic minors

Krishna Chaitanya Chundru <[email protected]>
PCI: qcom: Advertise Hotplug Slot Capability with no Command Completion support

Sebastian Reichel <[email protected]>
drm/panel: simple: Correct G190EAN01 prepare timing

Dmitry Baryshkov <[email protected]>
drm/panel: sharp-ls043t1le01: make use of prepare_prev_first

Alexander Koskovich <[email protected]>

    drm/msm/dsi: rename MSM8998 DSI version from V2_2_0 to V2_0_0

Pengyu Luo <[email protected]>
drm/msm/dsi: fix hdisplay calculation for CMD mode panel

Pengyu Luo <[email protected]>
drm/msm/dsi: fix bits_per_pclk

Pengyu Luo <[email protected]>
drm/msm/dsi: add the missing parameter description

Yuanjie Yang <[email protected]>
drm/msm/dpu: fix mismatch between power and frequency

Nicolin Chen <[email protected]>
iommu/tegra241-cmdqv: Set supports_cmd op in tegra241_vcmdq_hw_init()

Alexandru Dadu <[email protected]>
drm/imagination: Switch reset_reason fields from enum to u32

Pei Xiao <[email protected]>
spi: hisi-kunpeng: prevent infinite while() loop in hisi_spi_flush_fifo

Alex Deucher <[email protected]>
drm/amdgpu/gfx11: look at the right prop for gfx queue priority

Alex Deucher <[email protected]>
drm/amdgpu/gfx10: look at the right prop for gfx queue priority

Koichiro Den <[email protected]>
PCI: dwc: rcar-gen4: Change EPC BAR alignment to 4K as per the documentation

Daniel Jordan <[email protected]>
padata: Put CPU offline callback in ONLINE section to allow failure

Chuyi Zhou <[email protected]>
padata: Remove cpu online check from cpu add and removal

Thorsten Blum <[email protected]>
crypto: atmel-aes - guard unregister on error in atmel_aes_register_algs

Thorsten Blum <[email protected]>

    crypto: atmel - Use unregister_{aeads,ahashes,skciphers}

Herbert Xu <[email protected]>
crypto: tegra - Disable softirqs before finalizing request

Akhil R <[email protected]>
crypto: tegra - Reserve keyslots to allocate dynamically

Akhil R <[email protected]>
crypto: tegra - Transfer HASH init function to crypto engine

Akhil R <[email protected]>
crypto: tegra - finalize crypto req on error

Andy Shevchenko <[email protected]>
fbdev: matroxfb: Mark variable with __maybe_unused to avoid W=1 build break

Guillaume Gonnet <[email protected]>
dm init: ensure device probing has finished in dm-mod.waitfor=

Srinivasan Shanmugam <[email protected]>
drm/amdgpu: Add default case in DVI mode validation

Ethan Tidmore <[email protected]>
drm/sun4i: Fix resource leaks

Maíra Canal <[email protected]>
drm/v3d: Handle error from drm_sched_entity_init()

David Carlier <[email protected]>
selftests/sched_ext: Add missing error check for exit__load()

Vladimir Zapolskiy <[email protected]>
media: i2c: og01a1b: Fix V4L2 subdevice data initialization on probe

Laurent Pinchart <[email protected]>

    media: i2c: og01a1b: Replace client->dev usage

Felix Gu <[email protected]>
spi: fsl-qspi: Use reinit_completion() for repeated operations

Felix Gu <[email protected]>
spi: nxp-fspi: Use reinit_completion() for repeated operations

Haibo Chen <[email protected]>
spi: spi-nxp-fspi: enable runtime pm for fspi

Harikrishna Shenoy <[email protected]>
drm/bridge: cadence: cdns-mhdp8546-core: Handle HDCP state in bridge atomic check

Jayesh Choudhary <[email protected]>
drm/bridge: cadence: cdns-mhdp8546-core: Add mode_valid hook to drm_bridge_funcs

Jayesh Choudhary <[email protected]>
drm/bridge: cadence: cdns-mhdp8546-core: Set the mhdp connector earlier in atomic_enable()

Junrui Luo <[email protected]>
dm log: fix out-of-bounds write due to region_count overflow

Ming-Hung Tsai <[email protected]>
dm cache metadata: fix memory leak on metadata abort retry

Manivannan Sadhasivam <[email protected]>
PCI: dwc: Perform cleanup in the error path of dw_pcie_resume_noirq()

Richard Zhu <[email protected]>
PCI: dwc: Invoke post_init in dw_pcie_resume_noirq()

Aksh Garg <[email protected]>
PCI: dwc: ep: Fix MSI-X Table Size configuration in dw_pcie_ep_set_msix()

Niklas Cassel <[email protected]>
PCI: endpoint: Align pci_epc_set_msix(), pci_epc_ops::set_msix() nr_irqs encoding

Rafael J. Wysocki <[email protected]>
platform/chrome: chromeos_tbmc: Drop wakeup source on remove

Ming-Hung Tsai <[email protected]>
dm cache: fix dirty mapping checking in passthrough mode switching

Ming-Hung Tsai <[email protected]>
dm cache: support shrinking the origin device

Ming-Hung Tsai <[email protected]>
dm cache: fix concurrent write failure in passthrough mode

Ming-Hung Tsai <[email protected]>
dm cache policy smq: fix missing locks in invalidating cache blocks

Ming-Hung Tsai <[email protected]>
dm cache: fix write hang in passthrough mode

Ming-Hung Tsai <[email protected]>
dm cache: fix write path cache coherency in passthrough mode

Ming-Hung Tsai <[email protected]>
dm cache: fix null-deref with concurrent writes in passthrough mode

Sander Vanheule <[email protected]>
ASoC: sti: use managed regmap_field allocations

Sander Vanheule <[email protected]>
ASoC: sti: Return errors from regmap_field_alloc()

Ethan Tidmore <[email protected]>
drm/sun4i: backend: fix error pointer dereference

Kuninori Morimoto <[email protected]>
ASoC: soc-compress: use function to clear symmetric params

Kuninori Morimoto <[email protected]>

    ASoC: add symmetric_ prefix for dai->rate/channels/sample_bits

Daniel Baluta <[email protected]>
ASoC: SOF: ipc3: Use standard dev_dbg API

Alexander Konyukhov <[email protected]>
drm/komeda: fix integer overflow in AFBC framebuffer size check

Jiayuan Chen <[email protected]>
net, bpf: fix null-ptr-deref in xdp_master_redirect() for down master

Xin Long <[email protected]>
sctp: fix missing encap_port propagation for GSO fragments

Kuniyuki Iwashima <[email protected]>

    tcp: Don't set treq->req_usec_ts in cookie_tcp_reqsk_init().

Gabriel Krisman Bertazi <[email protected]>
udp: Force compute_score to always inline

Alok Tiwari <[email protected]>
ipv6: udp: fix typos in comments

Alok Tiwari <[email protected]>
ipv4: udp: fix typos in comments

Maxime Chevallier <[email protected]>
net: phy: qcom: at803x: Use the correct bit to disable extended next page

Stefan Metzmacher <[email protected]>

    Bluetooth: SCO: check for codecs->num_codecs == 1 before assigning to sco_pi(sk)->codec

Dudu Lu <[email protected]>
Bluetooth: l2cap: Add missing chan lock in l2cap_ecred_reconf_rsp

Pauli Virtanen <[email protected]>
Bluetooth: fix locking in hci_conn_request_evt() with HCI_PROTO_DEFER

Jonathan Rissanen <[email protected]>
Bluetooth: hci_ldisc: Clear HCI_UART_PROTO_INIT on error

Luiz Augusto von Dentz <[email protected]>
Bluetooth: L2CAP: Fix printing wrong information if SDU length exceeds MTU

Sun Jian <[email protected]>
bpf: reject short IPv4/IPv6 inputs in bpf_prog_test_run_skb

Gal Pressman <[email protected]>
net/mlx5e: IPsec, fix ASO poll timeout with read_poll_timeout_atomic()

Gal Pressman <[email protected]>
net/mlx5e: Fix features not applied during netdev registration

Charles Perry <[email protected]>
net: phy: fix a return path in get_phy_c45_ids()

Josua Mayer <[email protected]>
dt-bindings: net: dsa: nxp,sja1105: make spi-cpol optional for sja1110

Luca Weiss <[email protected]>
net: ipa: Fix decoding EV_PER_EE for IPA v5.0+

Luca Weiss <[email protected]>
net: ipa: Fix programming of QTIME_TIMESTAMP_CFG

Taegu Ha <[email protected]>
ppp: require CAP_NET_ADMIN in target netns for unattached ioctls

Lang Xu <[email protected]>
bpf: Fix OOB in pcpu_init_value

Greg Jumper <[email protected]>
net/rds: Restrict use of RDS/IB to the initial network namespace

Håkon Bugge <[email protected]>
net/rds: Optimize rds_ib_laddr_check

Emil Tsalapatis <[email protected]>
bpf: Allow instructions with arena source and non-arena dest registers

Lorenzo Bianconi <[email protected]>
net: airoha: Add missing RX_CPU_IDX() configuration in airoha_qdma_cleanup_rx_queue()

Lorenzo Bianconi <[email protected]>
net: airoha: Implement BQL support

Florian Westphal <[email protected]>
selftests: netfilter: nft_tproxy.sh: adjust to socat changes

Jamal Hadi Salim <[email protected]>
net/sched: act_ct: Only release RCU read lock after ct_ft

Eduard Zingerman <[email protected]>
selftests/bpf: fix __jited_unpriv tag name

Daniel Borkmann <[email protected]>
bpf: Enforce regsafe base id consistency for BPF_ADD_CONST scalars

Puranjay Mohan <[email protected]>
bpf: Relax scalar id equivalence for state pruning

Mashiro Chen <[email protected]>
net: hamradio: 6pack: fix uninit-value in sixpack_receive_buf

Sechang Lim <[email protected]>
bpf: Fix RCU stall in bpf_fd_array_map_clear()

Puranjay Mohan <[email protected]>
bpf: return VMA snapshot from task_vma iterator

Puranjay Mohan <[email protected]>
bpf: switch task_vma iterator from mmap_lock to per-VMA locks

Puranjay Mohan <[email protected]>
bpf: fix mm lifecycle in open-coded task_vma iterator

Florian Westphal <[email protected]>
netfilter: nft_fwd_netdev: check ttl/hl before forwarding

Florian Westphal <[email protected]>
netfilter: xt_socket: enable defrag after all other checks

Mohsin Bashir <[email protected]>
eth: fbnic: Use wake instead of start

Justin Chen <[email protected]>
net: bcmgenet: fix racing timeout handler

Zak Kemble <[email protected]>
net: bcmgenet: switch to use 64bit statistics

Doug Berger <[email protected]>
net: bcmgenet: support reclaiming unsent Tx packets

Doug Berger <[email protected]>
net: bcmgenet: move DESC_INDEX flow to ring 0

Doug Berger <[email protected]>
net: bcmgenet: add bcmgenet_has_* helpers

Justin Chen <[email protected]>
net: bcmgenet: fix off-by-one in bcmgenet_put_txcb

Wang Wensheng <[email protected]>
arm64: kexec: Remove duplicate allocation for trans_pgd

Haoyu Lu <[email protected]>
ACPI: AGDI: fix missing newline in error message

Baochen Qiang <[email protected]>
wifi: ath10k: fix station lookup failure during disconnect

Weiming Shi <[email protected]>
bpf: reject negative CO-RE accessor indices in bpf_core_parse_spec()

Jiayuan Chen <[email protected]>
bpf: Drop task_to_inode and inet_conn_established from lsm sleepable hooks

Nicolas Escande <[email protected]>
wifi: mac80211: handle VHT EXT NSS in ieee80211_determine_our_sta_mode()

Ethan Tidmore <[email protected]>
wifi: brcmfmac: Fix error pointer dereference

MingTao Huang <[email protected]>

    bpf: Fix stale offload->prog pointer after constant blinding

Weiming Shi <[email protected]>
bpf: fix end-of-list detection in cgroup_storage_get_next_key()

Eric Dumazet <[email protected]>

    macvlan: annotate data-races around port->bc_queue_len_used

Amit Machhiwal <[email protected]>
selftests/powerpc: Suppress -Wmaybe-uninitialized with GCC 15

Sourabh Jain <[email protected]>
powerpc/crash: Update backup region offset in elfcorehdr on memory hotplug

Sourabh Jain <[email protected]>
powerpc/crash: fix backup region offset update to elfcorehdr

Chih Kai Hsu <[email protected]>
r8152: fix incorrect register write to USB_UPHY_XTAL

Alexey Velichayshiy <[email protected]>
wifi: rtw89: phy: fix uninitialized variable access in rtw89_phy_cfo_set_crystal_cap()

haoyu.lu <[email protected]>
bpf,arc_jit: Fix missing newline in pr_err messages

Alexei Starovoitov <[email protected]>
bpf: Fix variable length stack write over spilled pointers

David Carlier <[email protected]>
bpf: Use RCU-safe iteration in dev_map_redirect_multi() SKB path

Michael Lo <[email protected]>
wifi: mt76: mt7921: fix 6GHz regulatory update on connection

Duoming Zhou <[email protected]>

    wifi: mt76: mt7996: fix use-after-free bugs in mt7996_mac_dump_work()

Duoming Zhou <[email protected]>

    wifi: mt76: mt7915: fix use-after-free bugs in mt7915_mac_dump_work()

StanleyYP Wang <[email protected]>

    wifi: mt76: mt7996: fix struct mt7996_mcu_uni_event

James Clark <[email protected]>
arm64: cpufeature: Make PMUVer and PerfMon unsigned

Rory Little <[email protected]>
wifi: mt76: mt7921: Place upper limit on station AID

Alok Tiwari <[email protected]>
wifi: mt76: mt7996: fix FCS error flag check in RX descriptor

Ming Yen Hsieh <[email protected]>
wifi: mt76: mt7925: prevent NULL vif dereference in mt7925_mac_write_txwi

Ming Yen Hsieh <[email protected]>
wifi: mt76: mt7925: prevent NULL pointer dereference in mt7925_tx_check_aggr()

Ryder Lee <[email protected]>
wifi: mt76: mt7915: fix use_cts_prot support

Ryder Lee <[email protected]>
wifi: mt76: mt7615: fix use_cts_prot support

Leon Yen <[email protected]>
wifi: mt76: mt7925: Fix incorrect MLO mode in firmware control

Sean Wang <[email protected]>
wifi: mt76: mt7921: Reset ampdu_state state in case of failure in mt76_connac2_tx_check_aggr()

Petr Pavlu <[email protected]>
module: Fix freeing of charp module parameters when CONFIG_SYSFS=n

Petr Pavlu <[email protected]>
params: Replace __modinit with __init_or_module

Ilya Leoshkevich <[email protected]>
s390/bpf: Zero-extend bpf prog return values and kfunc arguments

Cai Xinchen <[email protected]>
dpaa2: compile dpaa2 even CONFIG_FSL_DPAA2_ETH=n

Cai Xinchen <[email protected]>
dpaa2: add independent dependencies for FSL_DPAA2_SWITCH

Feng Yang <[email protected]>
bpf: test_run: Fix the null pointer dereference issue in bpf_lwt_xmit_push_encap

Duoming Zhou <[email protected]>
wifi: rtlwifi: pci: fix possible use-after-free caused by unfinished irq_prepare_bcn_tasklet

Zilin Guan <[email protected]>
wifi: mwifiex: Fix memory leak in mwifiex_11n_aggregate_pkt()

Mario Limonciello (AMD) <[email protected]>
firmware: dmi: Correct an indexing error in dmi.h

Bart Van Assche <[email protected]>
locking: Fix rwlock support in <linux/spinlock_up.h>

Thomas Weißschuh <[email protected]>
sparc64: vdso: Link with -z noexecstack

Thomas Weißschuh <[email protected]>
sparc/vdso: Always reject undefined references during linking

Thomas Gleixner <[email protected]>
hrtimer: Reduce trace noise in hrtimer_start()

Peter Zijlstra <[email protected]>
hrtimer: Avoid pointless reprogramming in __hrtimer_start_range_ns()

Richard Clark <[email protected]>
hrtimers: Update the return type of enqueue_hrtimer()

Brian Masney <[email protected]>
irqchip/irq-pic32-evic: Address warning related to wrong printf() formatter

Danilo Krummrich <[email protected]>
bus: fsl-mc: use generic driver_override infrastructure

Danilo Krummrich <[email protected]>
s390/cio: use generic driver_override infrastructure

Danilo Krummrich <[email protected]>
platform/wmi: use generic driver_override infrastructure

Danilo Krummrich <[email protected]>
PCI: use generic driver_override infrastructure

Gui-Dong Han <[email protected]>
soundwire: debugfs: initialize firmware_file to empty string

Gui-Dong Han <[email protected]>
debugfs: fix placement of EXPORT_SYMBOL_GPL for debugfs_create_str()

Gui-Dong Han <[email protected]>
debugfs: check for NULL pointer in debugfs_create_str()

Gopi Krishna Menon <[email protected]>
thermal/drivers/spear: Fix error condition for reading st,thermal-flags

Danilo Krummrich <[email protected]>
devres: fix missing node debug info in devm_krealloc()

Rafael J. Wysocki <[email protected]>
ACPI: x86: cmos_rtc: Improve coordination with ACPI TAD driver

Rafael J. Wysocki <[email protected]>
ACPI: x86: cmos_rtc: Clean up address space handler driver

Filipe Manana <[email protected]>
btrfs: fix deadlock between reflink and transaction commit when using flushoncommit

David Sterba <[email protected]>
btrfs: pass struct btrfs_inode to clone_copy_inline_extent()

Yu Kuai <[email protected]>
md: wake raid456 reshape waiters before suspend

Gao Xiang <[email protected]>
erofs: verify metadata accesses for file-backed mounts

Cole Leavitt <[email protected]>
pstore/ram: fix resource leak when ioremap() fails

Jackie Liu <[email protected]>
blk-cgroup: fix disk reference leak in blkcg_maybe_throttle_current()

Deepanshu Kartikey <[email protected]>
nilfs2: reject zero bd_oblocknr in nilfs_ioctl_mark_blocks_dirty()

Daan De Meyer <[email protected]>
loop: fix partition scan race between udev and loop_reread_partitions()

Bart Van Assche <[email protected]>
drbd: Balance RCU calls in drbd_adm_dump_devices()

Xiao Ni <[email protected]>
md/raid1: fix the comparing region of interval tree

HyungJung Joo <[email protected]>
fs/mbcache: cancel shrink work before destroying the cache

HyungJung Joo <[email protected]>
fs/omfs: reject s_sys_blocksize smaller than OMFS_DIR_START

Ming Lei <[email protected]>
blk-cgroup: wait for blkcg cleanup before initializing new disk

Pavel Begunkov <[email protected]>
io_uring/kbuf: use mem_is_zero()

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

Diffstat:

 .../bindings/interrupt-controller/arm,gic-v3.yaml  |   2 +-
 .../devicetree/bindings/net/dsa/nxp,sja1105.yaml   |   2 -
 Documentation/mm/hugetlbfs_reserv.rst              |   2 +-
 Documentation/networking/netconsole.rst            |   6 +-
 Makefile                                           |   4 +-
 arch/arc/net/bpf_jit_arcv2.c                       |   8 +-
 arch/arm/boot/dts/mediatek/mt7623.dtsi             |   2 +-
 .../boot/dts/nxp/imx/imx27-eukrea-cpuimx27.dtsi    |   8 +-
 .../nxp/imx/imx27-eukrea-mbimxsd27-baseboard.dts   |   2 +-
 arch/arm/mach-omap1/clock_data.c                   |   4 +-
 arch/arm/net/bpf_jit_32.c                          |   6 +
 .../boot/dts/amlogic/meson-gxl-s905d-p230.dts      |   3 +-
 arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi     | 161 +++--
 .../boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi |   4 +
 .../boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi |   4 +
 .../arm64/boot/dts/freescale/imx8mm-emtop-som.dtsi |   4 +-
 .../arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi |   2 +-
 .../arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi |   2 +-
 .../dts/freescale/imx8mp-data-modul-edm-sbc.dts    |   2 +-
 .../boot/dts/freescale/imx8mp-debix-model-a.dts    |   2 +-
 .../dts/freescale/imx8mp-debix-som-a-bmb-08.dts    |   2 +-
 .../boot/dts/freescale/imx8mp-debix-som-a.dtsi     |   2 +-
 .../arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi |   2 +-
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts       |   2 +-
 .../boot/dts/freescale/imx8mp-icore-mx8mp.dtsi     |   2 +-
 arch/arm64/boot/dts/freescale/imx8mp-navqp.dts     |   2 +-
 .../freescale/imx8mp-tqma8mpql-mba8mp-ras314.dts   |   4 +-
 arch/arm64/boot/dts/freescale/imx8qm-mek.dts       |  10 +-
 arch/arm64/boot/dts/freescale/imx8qxp-mek.dts      |  10 +-
 arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi  |   2 +-
 arch/arm64/boot/dts/marvell/armada-37xx.dtsi       |   2 +-
 arch/arm64/boot/dts/mediatek/mt6795.dtsi           |   2 +-
 arch/arm64/boot/dts/mediatek/mt7981b.dtsi          |   2 +-
 arch/arm64/boot/dts/mediatek/mt7986a.dtsi          |   2 +-
 arch/arm64/boot/dts/mediatek/mt8365.dtsi           |   5 +-
 arch/arm64/boot/dts/qcom/msm8953-xiaomi-daisy.dts  |   2 +-
 arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts  |   2 +-
 .../dts/qcom/sdm845-xiaomi-beryllium-common.dtsi   |   1 +
 arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts  |   4 +
 arch/arm64/boot/dts/qcom/sm8250.dtsi               |   5 +
 arch/arm64/boot/dts/qcom/sm8450.dtsi               |   5 +-
 arch/arm64/boot/dts/qcom/sm8550.dtsi               |   7 +-
 arch/arm64/boot/dts/qcom/sm8650.dtsi               |   7 +-
 arch/arm64/boot/dts/rockchip/rk3566-lckfb-tspi.dts |   4 +-
 arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts     |   2 +-
 .../boot/dts/rockchip/rk3588s-gameforce-ace.dts    |  12 +-
 arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts           |  14 +-
 arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi         |   2 +-
 arch/arm64/boot/dts/ti/k3-am62p5-sk.dts            |   6 +-
 arch/arm64/include/asm/kernel-pgtable.h            |   7 +-
 arch/arm64/include/asm/xor.h                       |   2 +-
 arch/arm64/kernel/cpufeature.c                     |   4 +-
 arch/arm64/kernel/machine_kexec.c                  |   3 -
 arch/arm64/kernel/pi/patch-scs.c                   |   4 +-
 arch/arm64/net/bpf_jit_comp.c                      |   4 +-
 arch/loongarch/Kbuild                              |   2 +-
 arch/loongarch/include/asm/asm-prototypes.h        |  20 +
 arch/loongarch/include/asm/kvm_host.h              |   3 -
 arch/loongarch/kvm/Makefile                        |   3 +-
 arch/loongarch/kvm/main.c                          |  35 +-
 arch/loongarch/kvm/switch.S                        |  19 +-
 arch/powerpc/include/asm/kexec.h                   |  14 +-
 arch/powerpc/kexec/crash.c                         |  64 ++
 arch/powerpc/kexec/file_load_64.c                  |  29 +-
 arch/powerpc/kvm/book3s_64_vio.c                   |  21 +-
 arch/powerpc/kvm/powerpc.c                         |  24 +-
 arch/powerpc/platforms/44x/warp.c                  |   2 +
 arch/powerpc/platforms/cell/spu_syscalls.c         |   6 +-
 arch/riscv/net/bpf_jit.h                           |   6 -
 arch/riscv/net/bpf_jit_core.c                      |   7 -
 arch/s390/kvm/interrupt.c                          |   3 +-
 arch/s390/kvm/pci.c                                |   6 +-
 arch/s390/net/bpf_jit_comp.c                       |  39 +-
 arch/sparc/vdso/Makefile                           |   7 +-
 arch/sparc/vdso/checkundef.sh                      |  10 -
 arch/x86/Makefile.um                               |   2 +
 arch/x86/kernel/acpi/cppc.c                        |   6 +-
 arch/x86/kernel/cpu/sgx/main.c                     |  10 +-
 arch/x86/kvm/svm/sev.c                             |  39 +-
 arch/x86/kvm/trace.h                               |   2 +-
 arch/x86/um/vdso/Makefile                          |   7 +-
 block/blk-cgroup.c                                 |  16 +
 block/disk-events.c                                |   3 +-
 crypto/af_alg.c                                    |   2 +
 crypto/jitterentropy-kcapi.c                       |  14 +-
 drivers/acpi/arm64/agdi.c                          |   2 +-
 drivers/acpi/x86/cmos_rtc.c                        |  79 ++-
 drivers/ata/libata-scsi.c                          |   4 +-
 drivers/base/devres.c                              |   2 +
 drivers/block/drbd/drbd_nl.c                       |   8 +-
 drivers/bluetooth/btmtk.c                          |   4 +-
 drivers/bluetooth/hci_ldisc.c                      |   3 +
 drivers/bus/fsl-mc/fsl-mc-bus.c                    |  43 +-
 drivers/bus/stm32_rifsc.c                          |  52 +-
 drivers/cdrom/cdrom.c                              |  73 ++-
 drivers/char/ipmi/ssif_bmc.c                       |  34 +-
 drivers/clk/clk-qoriq.c                            |  17 +-
 drivers/clk/clk-xgene.c                            |   2 +
 drivers/clk/imx/clk-imx6q.c                        |  12 +-
 drivers/clk/imx/clk-imx8mq.c                       |   4 +-
 drivers/clk/qcom/dispcc-sc7180.c                   |   8 +
 drivers/clk/qcom/dispcc-sc8280xp.c                 |   4 -
 drivers/clk/qcom/dispcc-sm4450.c                   |   1 -
 drivers/clk/qcom/dispcc-sm8250.c                   |   6 +-
 drivers/clk/qcom/dispcc-sm8450.c                   |   2 +-
 drivers/clk/qcom/gcc-sc8180x.c                     |  64 +-
 drivers/clk/qcom/gcc-x1e80100.c                    |   1 +
 drivers/clk/visconti/pll.c                         |   2 +-
 drivers/crypto/atmel-aes.c                         |  23 +-
 drivers/crypto/atmel-sha.c                         |  27 +-
 drivers/crypto/atmel-tdes.c                        |  25 +-
 drivers/crypto/ccp/ccp-crypto-aes.c                |   7 +-
 .../crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c |  20 +-
 drivers/crypto/intel/qat/qat_420xx/adf_drv.c       |   2 +-
 .../crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c   |  14 +-
 drivers/crypto/intel/qat/qat_4xxx/adf_drv.c        |   2 +-
 .../crypto/intel/qat/qat_c3xxx/adf_c3xxx_hw_data.c |   4 +-
 drivers/crypto/intel/qat/qat_c3xxx/adf_drv.c       |   2 +-
 .../crypto/intel/qat/qat_c62x/adf_c62x_hw_data.c   |   4 +-
 drivers/crypto/intel/qat/qat_c62x/adf_drv.c        |   4 +-
 .../intel/qat/qat_common/adf_accel_devices.h       |  12 +-
 .../crypto/intel/qat/qat_common/adf_gen2_hw_data.c |   2 +-
 .../intel/qat/qat_common/adf_sysfs_ras_counters.c  |  12 +-
 .../intel/qat/qat_common/icp_qat_hw_20_comp.h      |  10 +-
 .../intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c  |   6 +-
 drivers/crypto/intel/qat/qat_dh895xcc/adf_drv.c    |   2 +-
 drivers/crypto/sa2ul.c                             |   4 +-
 drivers/crypto/tegra/tegra-se-aes.c                | 257 ++++++--
 drivers/crypto/tegra/tegra-se-hash.c               | 104 +--
 drivers/crypto/tegra/tegra-se-key.c                |  19 +-
 drivers/crypto/tegra/tegra-se.h                    |  33 +-
 drivers/cxl/pci.c                                  |   3 +
 drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c     |   2 -
 drivers/dma/mxs-dma.c                              |   1 +
 drivers/firmware/arm_ffa/driver.c                  |   2 +-
 drivers/firmware/efi/capsule-loader.c              |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu.h                |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c            |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c     |   2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c         |  28 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c            |   7 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_isp.c            |   5 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_job.c            |   2 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c            |  57 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c            |   4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c          |  23 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_umsch_mm.c       |   4 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vpe.c            |   4 +-
 drivers/gpu/drm/amd/amdgpu/cik.c                   |   4 +-
 drivers/gpu/drm/amd/amdgpu/cik_ih.c                |   4 +-
 drivers/gpu/drm/amd/amdgpu/cik_sdma.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/cz_ih.c                 |   4 +-
 drivers/gpu/drm/amd/amdgpu/dce_v10_0.c             |   4 +-
 drivers/gpu/drm/amd/amdgpu/dce_v11_0.c             |   4 +-
 drivers/gpu/drm/amd/amdgpu/dce_v6_0.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/dce_v8_0.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c             |  10 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c             |  10 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c             |   8 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c              |  70 ++-
 drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c              |   8 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c            |   8 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c             |   4 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c             |   4 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c             |   4 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/iceland_ih.c            |   4 +-
 drivers/gpu/drm/amd/amdgpu/ih_v6_0.c               |   4 +-
 drivers/gpu/drm/amd/amdgpu/ih_v6_1.c               |   4 +-
 drivers/gpu/drm/amd/amdgpu/ih_v7_0.c               |   4 +-
 drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.c             |   4 +-
 drivers/gpu/drm/amd/amdgpu/jpeg_v1_0.h             |   2 +-
 drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c             |   5 +-
 drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c             |   6 +-
 drivers/gpu/drm/amd/amdgpu/jpeg_v3_0.c             |   5 +-
 drivers/gpu/drm/amd/amdgpu/jpeg_v4_0.c             |   5 +-
 drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_3.c           |   5 +-
 drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c           |   5 +-
 drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_0.c           |   5 +-
 drivers/gpu/drm/amd/amdgpu/mes_v11_0.c             |   4 +-
 drivers/gpu/drm/amd/amdgpu/mes_v12_0.c             |   4 +-
 drivers/gpu/drm/amd/amdgpu/navi10_ih.c             |   4 +-
 drivers/gpu/drm/amd/amdgpu/nv.c                    |   4 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c             |   4 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c             |   4 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c             |   8 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c           |   8 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c             |   8 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c             |   8 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c             |   8 +-
 drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c             |   8 +-
 drivers/gpu/drm/amd/amdgpu/si.c                    |   4 +-
 drivers/gpu/drm/amd/amdgpu/si_dma.c                |   4 +-
 drivers/gpu/drm/amd/amdgpu/si_ih.c                 |   4 +-
 drivers/gpu/drm/amd/amdgpu/soc15.c                 |   4 +-
 drivers/gpu/drm/amd/amdgpu/soc21.c                 |   4 +-
 drivers/gpu/drm/amd/amdgpu/soc24.c                 |   4 +-
 drivers/gpu/drm/amd/amdgpu/tonga_ih.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c              |  20 +-
 drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c              |  12 +-
 drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/vce_v2_0.c              |   6 +-
 drivers/gpu/drm/amd/amdgpu/vce_v3_0.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/vce_v4_0.c              |   4 +-
 drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c              |  10 +-
 drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c              |  10 +-
 drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c              |  10 +-
 drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c              |  11 +-
 drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c              |   8 +-
 drivers/gpu/drm/amd/amdgpu/vcn_v4_0_3.c            |   9 +-
 drivers/gpu/drm/amd/amdgpu/vcn_v4_0_5.c            |   9 +-
 drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c            |   9 +-
 drivers/gpu/drm/amd/amdgpu/vega10_ih.c             |   4 +-
 drivers/gpu/drm/amd/amdgpu/vega20_ih.c             |   4 +-
 drivers/gpu/drm/amd/amdgpu/vi.c                    |   4 +-
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |   6 +-
 drivers/gpu/drm/amd/display/dc/bios/bios_parser.c  |  62 ++
 .../gpu/drm/amd/display/dc/dce/dce_link_encoder.c  |   4 +-
 .../amd/display/include/grph_object_ctrl_defs.h    |   4 +
 drivers/gpu/drm/amd/include/amd_shared.h           |   6 +-
 drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c         |   4 +-
 drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c         |   4 +-
 drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c   |   5 +-
 drivers/gpu/drm/amd/pm/powerplay/hwmgr/hwmgr.c     |  15 +
 .../gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c    | 118 +++-
 .../gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.h    |   1 +
 drivers/gpu/drm/amd/pm/powerplay/inc/hwmgr.h       |   1 +
 .../gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c    |  15 +-
 drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c          |   4 +-
 .../drm/arm/display/komeda/komeda_framebuffer.c    |   6 +-
 .../gpu/drm/bridge/cadence/cdns-mhdp8546-core.c    |  72 ++-
 .../gpu/drm/bridge/cadence/cdns-mhdp8546-core.h    |   1 +
 .../gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c    |  18 +-
 drivers/gpu/drm/drm_syncobj.c                      |   9 +-
 drivers/gpu/drm/gma500/oaktrail_hdmi.c             |   1 +
 drivers/gpu/drm/gma500/oaktrail_lvds.c             |   9 +-
 drivers/gpu/drm/i915/display/intel_dp.c            |   9 +-
 drivers/gpu/drm/i915/display/skl_watermark.c       | 420 ++++++-------
 drivers/gpu/drm/i915/gt/intel_reset.c              |   3 +-
 drivers/gpu/drm/imagination/pvr_rogue_fwif.h       |   8 +-
 .../gpu/drm/imagination/pvr_rogue_fwif_shared.h    |   6 +-
 drivers/gpu/drm/loongson/lsdc_drv.c                |   2 +-
 drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c        |  14 +-
 drivers/gpu/drm/msm/adreno/a6xx_hfi.c              |  14 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c            |   2 -
 drivers/gpu/drm/msm/dsi/dsi_cfg.c                  |   4 +-
 drivers/gpu/drm/msm/dsi/dsi_cfg.h                  |   2 +-
 drivers/gpu/drm/msm/dsi/dsi_host.c                 |  16 +-
 drivers/gpu/drm/msm/msm_gem_shrinker.c             |   5 +-
 drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c    |   1 +
 drivers/gpu/drm/panel/panel-simple.c               |   2 +-
 drivers/gpu/drm/panfrost/panfrost_drv.c            |   2 +
 drivers/gpu/drm/sun4i/sun4i_backend.c              |   6 +-
 drivers/gpu/drm/tiny/ofdrm.c                       |   2 +
 drivers/gpu/drm/v3d/v3d_drv.c                      |  16 +-
 drivers/gpu/drm/v3d/v3d_submit.c                   |   5 +
 drivers/gpu/drm/xe/xe_dma_buf.c                    |  31 +-
 drivers/gpu/drm/xe/xe_exec_queue.c                 |   7 +-
 drivers/gpu/drm/xe/xe_gsc.c                        |   2 +-
 drivers/gpu/drm/xe/xe_reg_whitelist.c              |   2 +-
 drivers/hid/hid-asus.c                             |  28 +-
 drivers/hid/usbhid/hid-core.c                      |   2 +-
 drivers/hte/Kconfig                                |   6 +-
 drivers/hwmon/abituguru.c                          |   2 +-
 drivers/hwmon/abituguru3.c                         |   4 +-
 drivers/hwmon/aspeed-g6-pwm-tach.c                 |   8 -
 drivers/hwmon/da9052-hwmon.c                       |   2 +-
 drivers/hwmon/dme1737.c                            |   2 +-
 drivers/hwmon/f71805f.c                            |   2 +-
 drivers/hwmon/f71882fg.c                           |   2 +-
 drivers/hwmon/i5k_amb.c                            |   2 +-
 drivers/hwmon/max197.c                             |   2 +-
 drivers/hwmon/mc13783-adc.c                        |   2 +-
 drivers/hwmon/occ/p9_sbe.c                         |   4 +-
 drivers/hwmon/pc87360.c                            |   2 +-
 drivers/hwmon/pc87427.c                            |   2 +-
 drivers/hwmon/sch5636.c                            |   2 +-
 drivers/hwmon/sht15.c                              |   2 +-
 drivers/hwmon/sis5595.c                            |   2 +-
 drivers/hwmon/smsc47m1.c                           |   2 +-
 drivers/hwmon/ultra45_env.c                        |   2 +-
 drivers/hwmon/via-cputemp.c                        |   2 +-
 drivers/hwmon/via686a.c                            |   2 +-
 drivers/hwmon/vt1211.c                             |   2 +-
 drivers/hwmon/vt8231.c                             |   4 +-
 drivers/hwmon/w83627hf.c                           |   2 +-
 drivers/hwmon/w83781d.c                            |   2 +-
 drivers/hwmon/xgene-hwmon.c                        |   2 +-
 drivers/i3c/master.c                               |  32 +-
 drivers/i3c/master/dw-i3c-master.c                 |  16 +-
 drivers/i3c/master/mipi-i3c-hci/dma.c              |   5 +-
 drivers/infiniband/core/iwpm_msg.c                 |   6 +-
 drivers/infiniband/hw/mana/cq.c                    |   5 +-
 drivers/iommu/amd/amd_iommu_types.h                |  21 +-
 drivers/iommu/amd/iommu.c                          | 463 +++++++++-----
 drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c     |   7 +-
 drivers/iommu/intel/iommu.c                        |   3 +
 drivers/iommu/iommufd/fault.c                      |   5 +-
 drivers/iommu/iommufd/vfio_compat.c                |   2 +-
 drivers/irqchip/irq-pic32-evic.c                   |   2 +-
 drivers/irqchip/irq-riscv-imsic-early.c            |   2 +
 drivers/leds/blink/leds-lgm-sso.c                  |   2 -
 drivers/mailbox/mailbox-test.c                     |  39 +-
 drivers/mailbox/mailbox.c                          |   3 +-
 drivers/mailbox/mtk-cmdq-mailbox.c                 |   8 +-
 drivers/md/dm-cache-metadata.c                     |  24 +-
 drivers/md/dm-cache-metadata.h                     |   5 -
 drivers/md/dm-cache-policy-smq.c                   |   4 +
 drivers/md/dm-cache-target.c                       | 143 ++++-
 drivers/md/dm-init.c                               |   4 +-
 drivers/md/dm-log.c                                |   6 +-
 drivers/md/md.c                                    |  11 +
 drivers/md/raid1.c                                 |   4 +-
 drivers/media/i2c/og01a1b.c                        |  93 +--
 drivers/media/rc/lirc_dev.c                        |  13 +-
 drivers/memory/tegra/tegra124-emc.c                |   2 +-
 drivers/memory/tegra/tegra30-emc.c                 |   6 +-
 drivers/mfd/mc13xxx-core.c                         |   2 +-
 drivers/mtd/maps/physmap-gemini.c                  |   2 +-
 drivers/mtd/nand/raw/sunxi_nand.c                  |   6 +-
 drivers/mtd/parsers/ofpart_core.c                  |   4 +-
 drivers/mtd/spi-nor/core.c                         |   2 +-
 drivers/mtd/spi-nor/core.h                         |   8 +-
 drivers/mtd/spi-nor/sfdp.c                         |  30 +-
 drivers/mtd/spi-nor/swp.c                          |   4 +-
 drivers/net/bareudp.c                              |   3 +
 drivers/net/dsa/realtek/rtl8365mb.c                |   2 +-
 .../net/ethernet/aquantia/atlantic/aq_pci_func.c   |   2 +-
 drivers/net/ethernet/broadcom/genet/bcmgenet.c     | 698 ++++++++++-----------
 drivers/net/ethernet/broadcom/genet/bcmgenet.h     |  68 +-
 drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c |   4 +-
 drivers/net/ethernet/broadcom/genet/bcmmii.c       |   6 +-
 drivers/net/ethernet/freescale/Makefile            |   3 +-
 drivers/net/ethernet/freescale/dpaa2/Kconfig       |   4 +
 drivers/net/ethernet/intel/e1000e/netdev.c         |   1 +
 drivers/net/ethernet/intel/i40e/i40e.h             |   1 +
 drivers/net/ethernet/intel/i40e/i40e_main.c        |   2 +-
 drivers/net/ethernet/intel/i40e/i40e_ptp.c         |   3 +-
 drivers/net/ethernet/intel/iavf/iavf.h             |   9 +-
 drivers/net/ethernet/intel/iavf/iavf_main.c        |  52 +-
 drivers/net/ethernet/intel/iavf/iavf_virtchnl.c    |  76 ++-
 drivers/net/ethernet/intel/ice/ice_adminq_cmd.h    |   2 +-
 drivers/net/ethernet/intel/ice/ice_ptp_consts.h    |  12 +-
 drivers/net/ethernet/intel/ice/ice_ptp_hw.c        |  46 +-
 drivers/net/ethernet/intel/ice/ice_txrx.c          |   7 +-
 drivers/net/ethernet/intel/ice/ice_vf_lib.c        |   7 +-
 drivers/net/ethernet/mediatek/airoha_eth.c         |  27 +-
 .../mellanox/mlx5/core/en_accel/ipsec_offload.c    |  12 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c  |   8 +
 drivers/net/ethernet/mellanox/mlx5/core/main.c     |   4 +-
 drivers/net/ethernet/meta/fbnic/fbnic_pci.c        |   2 +-
 .../ethernet/netronome/nfp/nfpcore/nfp_target.c    |  17 +-
 drivers/net/ethernet/sfc/efx_devlink.c             |   2 +-
 drivers/net/hamradio/6pack.c                       |   9 +-
 drivers/net/ipa/gsi.c                              |   1 +
 drivers/net/ipa/ipa_main.c                         |   6 +-
 drivers/net/macvlan.c                              |   9 +-
 drivers/net/mctp/mctp-i2c.c                        |   4 +-
 drivers/net/netconsole.c                           |   9 +-
 drivers/net/netdevsim/dev.c                        |   2 +-
 drivers/net/phy/dp83869.c                          |  13 +-
 drivers/net/phy/phy_device.c                       |   4 +-
 drivers/net/phy/qcom/at803x.c                      |   2 +-
 drivers/net/ppp/ppp_generic.c                      |   5 +-
 drivers/net/ppp/pppoe.c                            |   8 +-
 drivers/net/slip/slhc.c                            |  49 +-
 drivers/net/usb/r8152.c                            |   2 +-
 drivers/net/usb/rtl8150.c                          |  12 +-
 drivers/net/virtio_net.c                           | 125 ++--
 drivers/net/vrf.c                                  |  15 +-
 drivers/net/wireless/ath/ath10k/wmi-tlv.c          |  26 +-
 .../wireless/broadcom/brcm80211/brcmfmac/chip.c    |  15 +
 drivers/net/wireless/marvell/mwifiex/11n_aggr.c    |   1 +
 drivers/net/wireless/mediatek/mt76/mt7615/mac.c    |  15 -
 drivers/net/wireless/mediatek/mt76/mt7615/main.c   |   7 +-
 drivers/net/wireless/mediatek/mt76/mt7615/mcu.c    |  47 ++
 drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h |   5 +-
 drivers/net/wireless/mediatek/mt76/mt7615/regs.h   |   2 -
 .../net/wireless/mediatek/mt76/mt76_connac_mac.c   |   6 +-
 drivers/net/wireless/mediatek/mt76/mt7915/init.c   |   1 +
 drivers/net/wireless/mediatek/mt76/mt7915/mac.c    |  13 -
 drivers/net/wireless/mediatek/mt76/mt7915/main.c   |   7 +-
 drivers/net/wireless/mediatek/mt76/mt7915/mcu.c    |  62 ++
 drivers/net/wireless/mediatek/mt76/mt7915/mcu.h    |  11 +
 drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h |   4 +
 drivers/net/wireless/mediatek/mt76/mt7921/main.c   |   9 +-
 drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h |   2 +
 drivers/net/wireless/mediatek/mt76/mt7925/mac.c    |   9 +-
 drivers/net/wireless/mediatek/mt76/mt7925/main.c   |   2 +-
 drivers/net/wireless/mediatek/mt76/mt7925/mcu.c    |   9 +-
 drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h |   4 +-
 drivers/net/wireless/mediatek/mt76/mt7996/init.c   |   1 +
 drivers/net/wireless/mediatek/mt76/mt7996/mac.c    |   2 +-
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c    |   2 +-
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.h    |   4 +-
 drivers/net/wireless/realtek/rtlwifi/pci.c         |   1 +
 drivers/net/wireless/realtek/rtw89/phy.c           |   2 +-
 drivers/nfc/trf7970a.c                             |   3 +-
 drivers/nvme/host/pci.c                            |   1 +
 drivers/nvme/target/tcp.c                          |  51 +-
 drivers/nvmem/brcm_nvram.c                         |   2 +-
 drivers/nvmem/layouts/u-boot-env.c                 |   2 +-
 drivers/pci/controller/cadence/pcie-cadence-ep.c   |   8 +-
 drivers/pci/controller/dwc/pcie-designware-ep.c    |   9 +-
 drivers/pci/controller/dwc/pcie-designware-host.c  |  18 +-
 drivers/pci/controller/dwc/pcie-designware.c       |  16 +-
 drivers/pci/controller/dwc/pcie-designware.h       |   2 +
 drivers/pci/controller/dwc/pcie-qcom.c             |  17 +-
 drivers/pci/controller/dwc/pcie-rcar-gen4.c        |   2 +-
 drivers/pci/controller/dwc/pcie-tegra194.c         | 183 +++---
 drivers/pci/controller/pcie-mediatek-gen3.c        |   8 +-
 drivers/pci/endpoint/pci-epc-core.c                |  11 +-
 drivers/pci/npem.c                                 |   2 +-
 drivers/pci/pci-driver.c                           |  20 +-
 drivers/pci/pci-sysfs.c                            |  28 -
 drivers/pci/pci.c                                  |  41 +-
 drivers/pci/probe.c                                |   1 -
 drivers/pcmcia/rsrc_nonstatic.c                    |   6 +-
 drivers/pinctrl/nomadik/pinctrl-abx500.c           |   2 +-
 drivers/pinctrl/pinctrl-cy8c95x0.c                 |  27 +-
 drivers/pinctrl/pinctrl-pic32.c                    |  20 +-
 drivers/pinctrl/realtek/pinctrl-rtd.c              |   2 +-
 drivers/pinctrl/renesas/pinctrl-rzg2l.c            |   7 +
 drivers/platform/chrome/chromeos_tbmc.c            |   6 +
 drivers/platform/surface/surfacepro3_button.c      |   1 +
 drivers/platform/x86/asus-wmi.c                    |  50 +-
 .../x86/dell/dell-wmi-sysman/enum-attributes.c     |  34 +-
 drivers/platform/x86/dell/dell_rbu.c               |   6 +-
 drivers/platform/x86/panasonic-laptop.c            |   5 +-
 drivers/platform/x86/wmi.c                         |  36 +-
 drivers/pmdomain/imx/scu-pd.c                      |   1 +
 drivers/pmdomain/ti/omap_prm.c                     |   1 +
 drivers/pwm/pwm-atmel-tcb.c                        |  38 +-
 drivers/remoteproc/xlnx_r5_remoteproc.c            |   2 +-
 drivers/reset/core.c                               | 119 +++-
 drivers/rtc/rtc-abx80x.c                           |   2 +
 drivers/s390/cio/cio.h                             |   5 -
 drivers/s390/cio/css.c                             |  34 +-
 drivers/scsi/sg.c                                  |  31 +-
 drivers/scsi/sr.c                                  |  11 +-
 drivers/scsi/sr.h                                  |   1 -
 drivers/soc/qcom/llcc-qcom.c                       |   2 +-
 drivers/soc/qcom/ocmem.c                           |  17 +-
 drivers/soc/qcom/qcom_aoss.c                       |   2 +-
 drivers/soc/tegra/cbb/tegra234-cbb.c               |   4 +
 drivers/soundwire/bus.c                            |   8 +-
 drivers/soundwire/cadence_master.c                 |   8 +
 drivers/soundwire/debugfs.c                        |   9 +-
 drivers/spi/spi-fsl-qspi.c                         |   3 +-
 drivers/spi/spi-hisi-kunpeng.c                     |  12 +-
 drivers/spi/spi-mtk-snfi.c                         |  14 +
 drivers/spi/spi-nxp-fspi.c                         | 102 ++-
 drivers/spi/spi-rockchip.c                         |   3 +-
 drivers/spi/spi-sifive.c                           |  29 +-
 drivers/target/target_core_sbc.c                   |   3 +-
 drivers/thermal/spear_thermal.c                    |   2 +-
 drivers/tty/hvc/hvc_iucv.c                         |   2 +-
 drivers/tty/serial/ip22zilog.c                     |   2 +-
 drivers/vfio/fsl-mc/vfio_fsl_mc.c                  |   4 +-
 drivers/vfio/pci/vfio_pci_core.c                   |   5 +-
 drivers/vhost/net.c                                |   4 +-
 drivers/video/backlight/sky81452-backlight.c       |   3 +
 drivers/video/fbdev/matrox/g450_pll.c              |   2 +-
 drivers/video/fbdev/offb.c                         |   7 +-
 drivers/xen/xen-pciback/pci_stub.c                 |   6 +-
 fs/adfs/super.c                                    |   3 +
 fs/btrfs/inode.c                                   |  42 +-
 fs/btrfs/ioctl.c                                   |   5 +-
 fs/btrfs/reflink.c                                 |  73 ++-
 fs/ceph/xattr.c                                    |  17 +
 fs/debugfs/file.c                                  |   7 +-
 fs/erofs/data.c                                    |  14 +
 fs/erofs/erofs_fs.h                                |  99 ++-
 fs/erofs/internal.h                                |   2 +-
 fs/erofs/zdata.c                                   |   2 +-
 fs/erofs/zmap.c                                    | 166 +++--
 fs/eventfd.c                                       |   9 +-
 fs/eventpoll.c                                     |  23 +-
 fs/ext4/mballoc-test.c                             |   6 +-
 fs/f2fs/f2fs.h                                     |   3 +
 fs/f2fs/inline.c                                   |  13 +-
 fs/f2fs/super.c                                    |  11 +
 fs/f2fs/sysfs.c                                    |   7 +-
 fs/fhandle.c                                       |   5 +-
 fs/gfs2/inode.c                                    |   3 +-
 fs/gfs2/log.c                                      |  33 +-
 fs/ioctl.c                                         |  23 +-
 fs/kernel_read_file.c                              |  12 +-
 fs/mbcache.c                                       |   1 +
 fs/netfs/iterator.c                                |  13 +-
 fs/nfs/blocklayout/blocklayout.c                   |   4 +-
 fs/nilfs2/ioctl.c                                  |   6 +
 fs/notify/fanotify/fanotify_user.c                 |  40 +-
 fs/notify/inotify/inotify_user.c                   |  17 +-
 fs/notify/mark.c                                   |  39 +-
 fs/ntfs3/dir.c                                     |   5 +-
 fs/ntfs3/fsntfs.c                                  |   4 +-
 fs/ntfs3/inode.c                                   |  13 +-
 fs/ntfs3/namei.c                                   |  17 +-
 fs/ntfs3/super.c                                   |   7 +-
 fs/ntfs3/xattr.c                                   |   5 +-
 fs/ocfs2/dlm/dlmdomain.c                           |  10 +-
 fs/ocfs2/ioctl.c                                   |  18 +-
 fs/ocfs2/resize.c                                  |  12 +-
 fs/ocfs2/xattr.c                                   |   4 +-
 fs/omfs/inode.c                                    |   6 +
 fs/open.c                                          |  36 +-
 fs/pstore/ram_core.c                               |   4 +
 fs/quota/dquot.c                                   |  38 +-
 fs/read_write.c                                    |  28 +-
 fs/signalfd.c                                      |   9 +-
 fs/smb/client/ioctl.c                              |   2 +-
 fs/smb/client/smb2file.c                           |  27 +-
 fs/smb/client/smb2pdu.h                            |   2 +-
 fs/smb/client/smb2transport.c                      |  32 +-
 fs/smb/server/auth.c                               |  11 +-
 fs/smb/server/connection.c                         |   9 +
 fs/smb/server/mgmt/user_session.c                  |  12 +-
 fs/smb/server/smb2pdu.c                            |   2 +
 fs/sync.c                                          |  29 +-
 fs/tracefs/event_inode.c                           |   2 +-
 include/dt-bindings/clock/qcom,dispcc-sc7180.h     |   7 +-
 include/dt-bindings/clock/qcom,gcc-sc8180x.h       |   5 +
 include/linux/cdrom.h                              |   1 +
 include/linux/cpuhotplug.h                         |   1 -
 include/linux/dmi.h                                |   5 +
 include/linux/file.h                               |   6 -
 include/linux/fsl/mc.h                             |   4 -
 include/linux/if_ether.h                           |   3 +
 include/linux/moduleparam.h                        |  11 +-
 include/linux/netpoll.h                            |   6 +
 include/linux/padata.h                             |   8 +-
 include/linux/pci-epc.h                            |   6 +-
 include/linux/pci.h                                |   6 -
 include/linux/pm_domain.h                          |   4 +-
 include/linux/ppp_defs.h                           |  16 +
 include/linux/printk.h                             |   5 +-
 include/linux/quotaops.h                           |   9 +-
 include/linux/reset.h                              | 274 ++++++--
 include/linux/spinlock_up.h                        |  20 +-
 include/linux/wmi.h                                |   4 -
 include/net/page_pool/memory_provider.h            |  15 +
 include/net/page_pool/types.h                      |   4 +
 include/net/pie.h                                  |   2 +-
 include/sound/soc-dai.h                            |   6 +-
 include/sound/soc.h                                |   3 +
 include/trace/events/timer.h                       |  11 +-
 include/uapi/linux/mii.h                           |   3 +-
 include/uapi/linux/virtio_net.h                    |  13 +
 io_uring/io-wq.c                                   |   3 +-
 io_uring/kbuf.c                                    |  14 +-
 io_uring/sqpoll.c                                  |  29 +-
 kernel/audit.c                                     |   4 +
 kernel/auditsc.c                                   |   2 +-
 kernel/bpf/arena.c                                 |   4 +
 kernel/bpf/arraymap.c                              |   4 +-
 kernel/bpf/bpf_lsm.c                               |   3 -
 kernel/bpf/core.c                                  |   2 +
 kernel/bpf/devmap.c                                |   5 +-
 kernel/bpf/hashtab.c                               |   2 +-
 kernel/bpf/helpers.c                               |  17 +-
 kernel/bpf/local_storage.c                         |   2 +-
 kernel/bpf/task_iter.c                             | 151 ++++-
 kernel/bpf/verifier.c                              | 127 +++-
 kernel/cgroup/cgroup.c                             |  46 +-
 kernel/cgroup/rdma.c                               |   2 +-
 kernel/events/core.c                               |  14 +-
 kernel/fork.c                                      |  11 +-
 kernel/futex/requeue.c                             |  13 +-
 kernel/module/main.c                               |   4 +-
 kernel/nsproxy.c                                   |   5 +-
 kernel/padata.c                                    | 130 ++--
 kernel/params.c                                    |  42 +-
 kernel/pid.c                                       |   7 +-
 kernel/sched/core.c                                |   1 +
 kernel/sched/ext.c                                 |   8 +
 kernel/sys.c                                       |  15 +-
 kernel/time/hrtimer.c                              |  56 +-
 kernel/trace/trace_branch.c                        |   8 +-
 kernel/trace/trace_events_hist.c                   |  12 +-
 kernel/watch_queue.c                               |   6 +-
 kernel/workqueue.c                                 |   4 +-
 lib/net_utils.c                                    |   4 +-
 mm/fadvise.c                                       |  10 +-
 mm/readahead.c                                     |  17 +-
 net/bluetooth/hci_event.c                          |   3 -
 net/bluetooth/l2cap_core.c                         |   8 +-
 net/bluetooth/sco.c                                |   3 +-
 net/bpf/test_run.c                                 |  35 +-
 net/ceph/crush/crush.c                             |   6 +-
 net/ceph/osdmap.c                                  |  14 +-
 net/core/devmem.c                                  |  24 +-
 net/core/filter.c                                  |   4 +-
 net/core/neighbour.c                               |  10 +-
 net/core/net_namespace.c                           |  10 +-
 net/core/netpoll.c                                 | 219 ++++---
 net/core/page_pool.c                               |  34 +-
 net/ipv4/netfilter/arp_tables.c                    |  18 +-
 net/ipv4/netfilter/arpt_mangle.c                   |   8 +
 net/ipv4/nexthop.c                                 |   4 +-
 net/ipv4/syncookies.c                              |   2 +-
 net/ipv4/tcp.c                                     |  22 +-
 net/ipv4/tcp_input.c                               |   6 +-
 net/ipv4/tcp_output.c                              |  15 +-
 net/ipv4/tcp_plb.c                                 |   2 +-
 net/ipv4/tcp_timer.c                               |   5 +-
 net/ipv4/udp.c                                     |  16 +-
 net/ipv6/icmp.c                                    |  10 +-
 net/ipv6/udp.c                                     |  17 +-
 net/mac80211/debugfs_sta.c                         |   7 +-
 net/mac80211/mlme.c                                |   3 +-
 net/mptcp/fastopen.c                               |  28 +-
 net/mptcp/pm_netlink.c                             |  26 +-
 net/mptcp/protocol.c                               |   4 +-
 net/mptcp/protocol.h                               |   5 +-
 net/mptcp/subflow.c                                |   3 -
 net/netfilter/ipvs/ip_vs_xmit.c                    |  19 +-
 net/netfilter/nf_conntrack_proto_sctp.c            |  10 +-
 net/netfilter/nf_conntrack_sip.c                   | 160 +++--
 net/netfilter/nf_nat_amanda.c                      |   2 +-
 net/netfilter/nf_nat_sip.c                         |  34 +-
 net/netfilter/nf_tables_api.c                      |  30 +-
 net/netfilter/nfnetlink_osf.c                      |  45 +-
 net/netfilter/nft_ct.c                             |   2 +
 net/netfilter/nft_fwd_netdev.c                     |  10 +
 net/netfilter/nft_osf.c                            |   6 +-
 net/netfilter/xt_mac.c                             |  34 +-
 net/netfilter/xt_owner.c                           |  37 +-
 net/netfilter/xt_physdev.c                         |  29 +-
 net/netfilter/xt_policy.c                          |   2 +-
 net/netfilter/xt_realm.c                           |   2 +-
 net/netfilter/xt_socket.c                          |  23 +-
 net/openvswitch/datapath.c                         |  35 +-
 net/openvswitch/vport.c                            |   3 +
 net/rds/af_rds.c                                   |  10 +-
 net/rds/connection.c                               |  14 +
 net/rds/ib.c                                       |  24 +-
 net/rds/ib.h                                       |   1 +
 net/rds/ib_rdma.c                                  |   2 +-
 net/sched/act_ct.c                                 |   8 +-
 net/sched/act_mirred.c                             |   2 +-
 net/sched/sch_cake.c                               |  15 +-
 net/sched/sch_choke.c                              |  26 +-
 net/sched/sch_fq_codel.c                           |   3 +-
 net/sched/sch_fq_pie.c                             |  19 +-
 net/sched/sch_hhf.c                                |  19 +-
 net/sched/sch_netem.c                              |  76 ++-
 net/sched/sch_pie.c                                |  52 +-
 net/sched/sch_red.c                                |  31 +-
 net/sched/sch_sfb.c                                |  54 +-
 net/sched/sch_taprio.c                             |  22 +-
 net/sctp/inqueue.c                                 |   1 +
 net/sctp/sm_statefuns.c                            |   6 +
 net/sctp/socket.c                                  |   2 +-
 net/socket.c                                       | 301 ++++-----
 net/tipc/msg.c                                     |  14 +-
 net/tls/tls.h                                      |   1 +
 net/tls/tls_strp.c                                 |   6 +
 net/tls/tls_sw.c                                   |   4 +
 net/unix/af_unix.c                                 |   9 +-
 net/unix/unix_bpf.c                                |   3 +
 scripts/package/builddeb                           |   8 +-
 security/integrity/ima/ima_crypto.c                |   2 +-
 security/integrity/ima/ima_fs.c                    | 153 ++---
 security/landlock/syscalls.c                       |  26 +-
 sound/core/compress_offload.c                      |   7 -
 sound/core/sound.c                                 |   7 +
 sound/isa/sc6000.c                                 | 152 +++--
 sound/pci/hda/cs35l56_hda.c                        |  12 +-
 sound/pci/hda/cs35l56_hda.h                        |   1 +
 sound/pci/hda/patch_conexant.c                     |  20 +-
 sound/pci/hda/patch_realtek.c                      |  20 +-
 sound/soc/amd/acp/acp-legacy-mach.c                |   2 +-
 sound/soc/amd/acp/acp-mach-common.c                |  22 +-
 sound/soc/amd/acp/acp-mach.h                       |   4 +
 sound/soc/amd/acp/acp-sof-mach.c                   |   2 +-
 sound/soc/codecs/ab8500-codec.c                    |   6 +-
 sound/soc/fsl/fsl_easrc.c                          | 123 ++--
 sound/soc/fsl/fsl_micfil.c                         |  60 +-
 sound/soc/fsl/fsl_xcvr.c                           |  22 +-
 sound/soc/mediatek/mt8188/mt8188-dai-pcm.c         |   2 +-
 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c         |   2 +-
 sound/soc/mediatek/mt8365/mt8365-dai-dmic.c        |   6 +-
 sound/soc/mediatek/mt8365/mt8365-dai-pcm.c         |   2 +-
 sound/soc/qcom/qdsp6/topology.c                    |   8 +-
 sound/soc/sh/rcar/core.c                           |   2 +-
 sound/soc/soc-compress.c                           |   4 +-
 sound/soc/soc-pcm.c                                |  33 +-
 sound/soc/sof/compress.c                           |   8 +-
 sound/soc/sof/intel/hda-stream.c                   |  10 +-
 sound/soc/sof/ipc3.c                               |   2 +-
 sound/soc/sof/sof-priv.h                           |   2 +
 sound/soc/sti/uniperif_player.c                    |   9 +-
 sound/usb/midi.c                                   |  12 +-
 sound/usb/midi2.c                                  |  12 +-
 sound/usb/mixer_scarlett2.c                        |   2 +-
 sound/usb/quirks.c                                 |   2 +-
 sound/usb/stream.c                                 |  58 +-
 sound/usb/stream.h                                 |   3 +-
 tools/lib/bpf/libbpf.c                             | 384 +++++-------
 tools/lib/bpf/relo_core.c                          |   2 +
 tools/perf/builtin-diff.c                          |   6 +-
 tools/perf/builtin-list.c                          |  13 +-
 tools/perf/builtin-lock.c                          |   2 +-
 tools/perf/builtin-stat.c                          |  44 +-
 tools/perf/util/Build                              |   1 +
 tools/perf/util/branch.h                           |   3 +
 tools/perf/util/cgroup.c                           |  30 +-
 tools/perf/util/cs-etm-decoder/cs-etm-decoder.c    |  51 +-
 tools/perf/util/evsel.c                            | 296 ++-------
 tools/perf/util/evsel.h                            |  49 +-
 tools/perf/util/expr.c                             |   3 +-
 tools/perf/util/maps.c                             |  13 +-
 tools/perf/util/metricgroup.c                      |   1 +
 tools/perf/util/parse-events.c                     |  94 ++-
 tools/perf/util/parse-events.h                     |  11 +-
 tools/perf/util/parse-events.l                     |  11 -
 tools/perf/util/parse-events.y                     |  18 +-
 tools/perf/util/pmu.c                              |  26 +-
 tools/perf/util/pmu.h                              |   4 +-
 tools/perf/util/pmus.c                             |   9 +
 tools/perf/util/print-events.c                     |  36 +-
 tools/perf/util/print-events.h                     |   1 -
 tools/perf/util/python.c                           |  61 ++
 tools/perf/util/stat-display.c                     |   6 +-
 tools/perf/util/stat-shadow.c                      |   1 +
 tools/perf/util/symbol-elf.c                       |   8 +-
 tools/perf/util/tool_pmu.c                         | 417 ++++++++++++
 tools/perf/util/tool_pmu.h                         |  51 ++
 tools/perf/util/util.h                             |   1 -
 tools/testing/ktest/ktest.pl                       |  35 +-
 tools/testing/selftests/bpf/prog_tests/snprintf.c  |   3 +-
 tools/testing/selftests/bpf/progs/bpf_misc.h       |   2 +-
 .../selftests/bpf/progs/verifier_scalar_ids.c      |   8 +-
 tools/testing/selftests/cgroup/test_memcontrol.c   |  11 +-
 tools/testing/selftests/mm/migration.c             |   3 +-
 .../selftests/net/netfilter/nft_tproxy_udp.sh      |  14 +-
 tools/testing/selftests/powerpc/vphn/Makefile      |   2 +-
 tools/testing/selftests/sched_ext/exit.c           |   2 +-
 virt/kvm/dirty_ring.c                              |   3 +-
 virt/kvm/vfio.c                                    |   8 +-
 748 files changed, 8358 insertions(+), 5520 deletions(-)
author maintainer
#1 lore raw

PATCH 1/666 io_uring/kbuf: use mem_is_zero()

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

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

From: Pavel Begunkov <[email protected]>

commit 1724849072854a66861d461b298b04612702d685 upstream.

Make use of mem_is_zero() for reserved fields checking.

---
 io_uring/kbuf.c |   14 ++++----------
 1 file changed, 4 insertions(+), 10 deletions(-)
io_uring/kbuf.c +4 -10
@@ -705,8 +705,7 @@ int io_register_pbuf_ring(struct io_ring
 
 	if (copy_from_user(&reg, arg, sizeof(reg)))
 		return -EFAULT;
-
-	if (reg.resv[0] || reg.resv[1] || reg.resv[2])
+	if (!mem_is_zero(reg.resv, sizeof(reg.resv)))
 		return -EINVAL;
 	if (reg.flags & ~(IOU_PBUF_RING_MMAP | IOU_PBUF_RING_INC))
 		return -EINVAL;
@@ -773,9 +772,7 @@ int io_unregister_pbuf_ring(struct io_ri
 
 	if (copy_from_user(&reg, arg, sizeof(reg)))
 		return -EFAULT;
-	if (reg.resv[0] || reg.resv[1] || reg.resv[2])
-		return -EINVAL;
-	if (reg.flags)
+	if (!mem_is_zero(reg.resv, sizeof(reg.resv)) || reg.flags)
 		return -EINVAL;
 
 	bl = io_buffer_get_list(ctx, reg.bgid);
@@ -793,14 +790,11 @@ int io_register_pbuf_status(struct io_ri
 {
 	struct io_uring_buf_status buf_status;
 	struct io_buffer_list *bl;
-	int i;
 
 	if (copy_from_user(&buf_status, arg, sizeof(buf_status)))
 		return -EFAULT;
-
-	for (i = 0; i < ARRAY_SIZE(buf_status.resv); i++)
-		if (buf_status.resv[i])
-			return -EINVAL;
+	if (!mem_is_zero(buf_status.resv, sizeof(buf_status.resv)))
+		return -EINVAL;
 
 	bl = io_buffer_get_list(ctx, buf_status.buf_group);
 	if (!bl)
author maintainer
#2 lore raw

PATCH 2/666 blk-cgroup: wait for blkcg cleanup before initializing new disk

In reply to Greg Kroah-Hartman

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

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

From: Ming Lei <[email protected]>

[ Upstream commit 3dbaacf6ab68f81e3375fe769a2ecdbd3ce386fd ]

When a queue is shared across disk rebind (e.g., SCSI unbind/bind), the previous disk's blkcg state is cleaned up asynchronously via disk_release() -> blkcg_exit_disk(). If the new disk's blkcg_init_disk() runs before that cleanup finishes, we may overwrite q->root_blkg while the old one is still alive, and radix_tree_insert() in blkg_create() fails with -EEXIST because the old blkg entries still occupy the same queue id slot in blkcg->blkg_tree. This causes the sd probe to fail with -ENOMEM.

Fix it by waiting in blkcg_init_disk() for root_blkg to become NULL, which indicates the previous disk's blkcg cleanup has completed.

Fixes 1059699f87eb ("block: move blkcg initialization/destroy into disk allocation/release handler")
Cc Yi Zhang <[email protected]>
---
 block/blk-cgroup.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
block/blk-cgroup.c +15 -0
index 3f7cb9d891aa3..9a198001cfa56 100644
@@ -24,6 +24,7 @@
 #include <linux/backing-dev.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/wait_bit.h>
 #include <linux/atomic.h>
 #include <linux/ctype.h>
 #include <linux/resume_user_mode.h>
@@ -611,6 +612,8 @@ static void blkg_destroy_all(struct gendisk *disk)
 
 	q->root_blkg = NULL;
 	spin_unlock_irq(&q->queue_lock);
+
+	wake_up_var(&q->root_blkg);
 }
 
 static void blkg_iostat_set(struct blkg_iostat *dst, struct blkg_iostat *src)
@@ -1451,6 +1454,18 @@ int blkcg_init_disk(struct gendisk *disk)
 	struct blkcg_gq *new_blkg, *blkg;
 	bool preloaded;
 
+	/*
+	 * If the queue is shared across disk rebind (e.g., SCSI), the
+	 * previous disk's blkcg state is cleaned up asynchronously via
+	 * disk_release() -> blkcg_exit_disk(). Wait for that cleanup to
+	 * finish (indicated by root_blkg becoming NULL) before setting up
+	 * new blkcg state. Otherwise, we may overwrite q->root_blkg while
+	 * the old one is still alive, and radix_tree_insert() in
+	 * blkg_create() will fail with -EEXIST because the old entries
+	 * still occupy the same queue id slot in blkcg->blkg_tree.
+	 */
+	wait_var_event(&q->root_blkg, !READ_ONCE(q->root_blkg));
+
 	new_blkg = blkg_alloc(&blkcg_root, disk, GFP_KERNEL);
 	if (!new_blkg)
 		return -ENOMEM;
Signature · 1 line
2.53.0
author maintainer
#3 lore raw

PATCH 3/666 fs/omfs: reject s_sys_blocksize smaller than OMFS_DIR_START

In reply to Greg Kroah-Hartman

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

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

From: HyungJung Joo <[email protected]>

[ Upstream commit 0621c385fda1376e967f37ccd534c26c3e511d14 ]

omfs_fill_super() rejects oversized s_sys_blocksize values (> PAGE_SIZE), but it does not reject values smaller than OMFS_DIR_START (0x1b8 = 440).

Later, omfs_make_empty() uses

    sbi->s_sys_blocksize - OMFS_DIR_START

as the length argument to memset(). Since s_sys_blocksize is u32, a crafted filesystem image with s_sys_blocksize < OMFS_DIR_START causes an unsigned underflow there, wrapping to a value near 2^32. That drives a ~4 GiB memset() from bh->b_data + OMFS_DIR_START and overwrites kernel memory far beyond the backing block buffer.

Add the corresponding lower-bound check alongside the existing upper-bound check in omfs_fill_super(), so that malformed images are rejected during superblock validation before any filesystem data is processed.

---
 fs/omfs/inode.c | 6 ++++++
 1 file changed, 6 insertions(+)
fs/omfs/inode.c +6 -0
index d6cd811630309..eb5a5fb26a791 100644
@@ -512,6 +512,12 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent)
 		goto out_brelse_bh;
 	}
 
+	if (sbi->s_sys_blocksize < OMFS_DIR_START) {
+		printk(KERN_ERR "omfs: sysblock size (%d) is too small\n",
+			sbi->s_sys_blocksize);
+		goto out_brelse_bh;
+	}
+
 	if (sbi->s_blocksize < sbi->s_sys_blocksize ||
 	    sbi->s_blocksize > OMFS_MAX_BLOCK_SIZE) {
 		printk(KERN_ERR "omfs: block size (%d) is out of range\n",
Signature · 1 line
2.53.0
author maintainer
#4 lore raw

PATCH 4/666 fs/mbcache: cancel shrink work before destroying the cache

In reply to Greg Kroah-Hartman

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

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

From: HyungJung Joo <[email protected]>

[ Upstream commit d227786ab1119669df4dc333a61510c52047cce4 ]

mb_cache_destroy() calls shrinker_free() and then frees all cache entries and the cache itself, but it does not cancel the pending c_shrink_work work item first.

If mb_cache_entry_create() schedules c_shrink_work via schedule_work() and the work item is still pending or running when mb_cache_destroy() runs, mb_cache_shrink_worker() will access the cache after its memory has been freed, causing a use-after-free.

This is only reachable by a privileged user (root or CAP_SYS_ADMIN) who can trigger the last put of a mounted ext2/ext4/ocfs2 filesystem.

Cancel the work item with cancel_work_sync() before calling shrinker_free(), ensuring the worker has finished and will not be rescheduled before the cache is torn down.

---
 fs/mbcache.c | 1 +
 1 file changed, 1 insertion(+)
fs/mbcache.c +1 -0
index e60a840999aa9..90b0564c62d0b 100644
@@ -408,6 +408,7 @@ void mb_cache_destroy(struct mb_cache *cache)
 {
 	struct mb_cache_entry *entry, *next;
 
+	cancel_work_sync(&cache->c_shrink_work);
 	shrinker_free(cache->c_shrink);
 
 	/*
Signature · 1 line
2.53.0
author maintainer
#5 lore raw

PATCH 5/666 md/raid1: fix the comparing region of interval tree

In reply to Greg Kroah-Hartman

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

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

From: Xiao Ni <[email protected]>

[ Upstream commit de3544d2e5ea99064498de3c21ba490155864657 ]

Interval tree uses [start, end] as a region which stores in the tree. In raid1, it uses the wrong end value. For example:
bio(A,B) is too big and needs to be split to bio1(A,C-1), bio2(C,B). The region of bio1 is [A,C] and the region of bio2 is [C,B]. So bio1 and bio2 overlap which is not right.

Fix this problem by using right end value of the region.

Fixes d0d2d8ba0494 ("md/raid1: introduce wait_for_serialization")
---
 drivers/md/raid1.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/md/raid1.c +2 -2
index 093b04e6be675..eb583df45ecbc 100644
@@ -61,7 +61,7 @@ static int check_and_add_serial(struct md_rdev *rdev, struct r1bio *r1_bio,
 	unsigned long flags;
 	int ret = 0;
 	sector_t lo = r1_bio->sector;
-	sector_t hi = lo + r1_bio->sectors;
+	sector_t hi = lo + r1_bio->sectors - 1;
 	struct serial_in_rdev *serial = &rdev->serial[idx];
 
 	spin_lock_irqsave(&serial->serial_lock, flags);
@@ -453,7 +453,7 @@ static void raid1_end_write_request(struct bio *bio)
 	int mirror = find_bio_disk(r1_bio, bio);
 	struct md_rdev *rdev = conf->mirrors[mirror].rdev;
 	sector_t lo = r1_bio->sector;
-	sector_t hi = r1_bio->sector + r1_bio->sectors;
+	sector_t hi = r1_bio->sector + r1_bio->sectors - 1;
 	bool ignore_error = !raid1_should_handle_error(bio) ||
 		(bio->bi_status && bio_op(bio) == REQ_OP_DISCARD);
 
Signature · 1 line
2.53.0
author maintainer
#6 lore raw

PATCH 6/666 drbd: Balance RCU calls in drbd_adm_dump_devices()

In reply to Greg Kroah-Hartman

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

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

From: Bart Van Assche <[email protected]>

[ Upstream commit 2b31e86387e60b3689339f0f0fbb4d3623d9d494 ]

Make drbd_adm_dump_devices() call rcu_read_lock() before rcu_read_unlock() is called. This has been detected by the Clang thread-safety analyzer.

---
 drivers/block/drbd/drbd_nl.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/block/drbd/drbd_nl.c +6 -2
index 8c12bf1b2a0d2..2e985101963e6 100644
@@ -3377,8 +3377,10 @@ int drbd_adm_dump_devices(struct sk_buff *skb, struct netlink_callback *cb)
 		if (resource_filter) {
 			retcode = ERR_RES_NOT_KNOWN;
 			resource = drbd_find_resource(nla_data(resource_filter));
-			if (!resource)
+			if (!resource) {
+				rcu_read_lock();
 				goto put_result;
+			}
 			cb->args[0] = (long)resource;
 		}
 	}
@@ -3627,8 +3629,10 @@ int drbd_adm_dump_peer_devices(struct sk_buff *skb, struct netlink_callback *cb)
 		if (resource_filter) {
 			retcode = ERR_RES_NOT_KNOWN;
 			resource = drbd_find_resource(nla_data(resource_filter));
-			if (!resource)
+			if (!resource) {
+				rcu_read_lock();
 				goto put_result;
+			}
 		}
 		cb->args[0] = (long)resource;
 	}
Signature · 1 line
2.53.0
author maintainer
#7 lore raw

PATCH 7/666 loop: fix partition scan race between udev and loop_reread_partitions()

In reply to Greg Kroah-Hartman

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

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

From: Daan De Meyer <[email protected]>

[ Upstream commit 267ec4d7223a783f029a980f41b93c39b17996da ]

When LOOP_CONFIGURE is called with LO_FLAGS_PARTSCAN, the following sequence occurs:

1. disk_force_media_change() sets GD_NEED_PART_SCAN
2. Uevent suppression is lifted and a KOBJ_CHANGE uevent is sent
3. loop_global_unlock() releases the lock
4. loop_reread_partitions() calls bdev_disk_changed() to scan

There is a race between steps 2 and 4: when udev receives the uevent and opens the device before loop_reread_partitions() runs, blkdev_get_whole() in bdev.c sees GD_NEED_PART_SCAN set and calls bdev_disk_changed() for a first scan. Then loop_reread_partitions() does a second scan. The open_mutex serializes these two scans, but does not prevent both from running.

The second scan in bdev_disk_changed() drops all partition devices from the first scan (via blk_drop_partitions()) before re-adding them, causing partition block devices to briefly disappear. This breaks any systemd unit with BindsTo= on the partition device: systemd observes the device going dead, fails the dependent units, and does not retry them when the device reappears.

Fix this by removing the GD_NEED_PART_SCAN set from disk_force_media_change() entirely. None of the current callers need the lazy on-open partition scan triggered by this flag:

- floppy: sets GENHD_FL_NO_PART, so disk_has_partscan() is always false and GD_NEED_PART_SCAN has no effect.
- loop (loop_configure, loop_change_fd): when LO_FLAGS_PARTSCAN is set, loop_reread_partitions() performs an explicit scan. When not set, GD_SUPPRESS_PART_SCAN prevents the lazy scan path.
- loop (__loop_clr_fd): calls bdev_disk_changed() explicitly if LO_FLAGS_PARTSCAN is set.
- nbd (nbd_clear_sock_ioctl): capacity is set to zero immediately after; nbd manages GD_NEED_PART_SCAN explicitly elsewhere.

With GD_NEED_PART_SCAN no longer set by disk_force_media_change(), udev opening the loop device after the uevent no longer triggers a redundant scan in blkdev_get_whole(), and only the single explicit scan from loop_reread_partitions() runs.

A regression test for this bug has been submitted to blktests:
https://github.com/linux-blktests/blktests/pull/240.

---
 block/disk-events.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
block/disk-events.c +2 -1
index 2f697224386aa..868823915bdc6 100644
@@ -290,13 +290,14 @@ EXPORT_SYMBOL(disk_check_media_change);
  * Should be called when the media changes for @disk.  Generates a uevent
  * and attempts to free all dentries and inodes and invalidates all block
  * device page cache entries in that case.
+ *
+ * Callers that need a partition re-scan should arrange for one explicitly.
  */
 void disk_force_media_change(struct gendisk *disk)
 {
 	disk_event_uevent(disk, DISK_EVENT_MEDIA_CHANGE);
 	inc_diskseq(disk);
 	bdev_mark_dead(disk->part0, true);
-	set_bit(GD_NEED_PART_SCAN, &disk->state);
 }
 EXPORT_SYMBOL_GPL(disk_force_media_change);
 
Signature · 1 line
2.53.0
author maintainer
#8 lore raw

PATCH 8/666 nilfs2: reject zero bd_oblocknr in nilfs_ioctl_mark_blocks_dirty()

In reply to Greg Kroah-Hartman

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

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

From: Deepanshu Kartikey <[email protected]>

[ Upstream commit be3e5d10643d3be1cbac9d9939f220a99253f980 ]

nilfs_ioctl_mark_blocks_dirty() uses bd_oblocknr to detect dead blocks by comparing it with the current block number bd_blocknr. If they differ, the block is considered dead and skipped.

However, bd_oblocknr should never be 0 since block 0 typically stores the primary superblock and is never a valid GC target block. A corrupted ioctl request with bd_oblocknr set to 0 causes the comparison to incorrectly match when the lookup returns -ENOENT and sets bd_blocknr to 0, bypassing the dead block check and calling nilfs_bmap_mark() on a non-existent block. This causes nilfs_btree_do_lookup() to return -ENOENT, triggering the WARN_ON(ret == -ENOENT).

Fix this by rejecting ioctl requests with bd_oblocknr set to 0 at the beginning of each iteration.

[ryusuke: slightly modified the commit message and comments for accuracy]

---
 fs/nilfs2/ioctl.c | 6 ++++++
 1 file changed, 6 insertions(+)
fs/nilfs2/ioctl.c +6 -0
index fa77f78df6817..4c66f6f99b2b2 100644
@@ -765,6 +765,12 @@ static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
 	int ret, i;
 
 	for (i = 0; i < nmembs; i++) {
+		/*
+		 * bd_oblocknr must never be 0 as block 0
+		 * is never a valid GC target block
+		 */
+		if (unlikely(!bdescs[i].bd_oblocknr))
+			return -EINVAL;
 		/* XXX: use macro or inline func to check liveness */
 		ret = nilfs_bmap_lookup_at_level(bmap,
 						 bdescs[i].bd_offset,
Signature · 1 line
2.53.0
author maintainer
#9 lore raw

PATCH 9/666 blk-cgroup: fix disk reference leak in blkcg_maybe_throttle_current()

In reply to Greg Kroah-Hartman

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

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

From: Jackie Liu <[email protected]>

[ Upstream commit 23308af722fefed00af5f238024c11710938fba3 ]

Add the missing put_disk() on the error path in blkcg_maybe_throttle_current(). When blkcg lookup, blkg lookup, or blkg_tryget() fails, the function jumps to the out label which only calls rcu_read_unlock() but does not release the disk reference acquired by blkcg_schedule_throttle() via get_device(). Since current->throttle_disk is already set to NULL before the lookup, blkcg_exit() cannot release this reference either, causing the disk to never be freed.

Restore the reference release that was present as blk_put_queue() in the original code but was inadvertently dropped during the conversion from request_queue to gendisk.

Fixes f05837ed73d0 ("blk-cgroup: store a gendisk to throttle in struct task_struct")
---
 block/blk-cgroup.c | 1 +
 1 file changed, 1 insertion(+)
block/blk-cgroup.c +1 -0
index 9a198001cfa56..a0fbb427a7a62 100644
@@ -1985,6 +1985,7 @@ void blkcg_maybe_throttle_current(void)
 	return;
 out:
 	rcu_read_unlock();
+	put_disk(disk);
 }
 
 /**
Signature · 1 line
2.53.0
author maintainer
#10 lore raw

PATCH 10/666 pstore/ram: fix resource leak when ioremap() fails

In reply to Greg Kroah-Hartman

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

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

From: Cole Leavitt <[email protected]>

[ Upstream commit 2ddb69f686ef7a621645e97fc7329c50edf5d0e5 ]

In persistent_ram_iomap(), ioremap() or ioremap_wc() may return NULL on failure. Currently, if this happens, the function returns NULL without releasing the memory region acquired by request_mem_region().

This leads to a resource leak where the memory region remains reserved but unusable.

Additionally, the caller persistent_ram_buffer_map() handles NULL correctly by returning -ENOMEM, but without this check, a NULL return combined with request_mem_region() succeeding leaves resources in an inconsistent state.

This is the ioremap() counterpart to commit 05363abc7625 ("pstore:
ram_core: fix incorrect success return when vmap() fails") which fixed a similar issue in the vmap() path.

Fixes 404a6043385d ("staging: android: persistent_ram: handle reserving and mapping memory")
---
 fs/pstore/ram_core.c | 4 ++++
 1 file changed, 4 insertions(+)
fs/pstore/ram_core.c +4 -0
index 7b6d6378a3b87..95675d4bab141 100644
@@ -489,6 +489,10 @@ static void *persistent_ram_iomap(phys_addr_t start, size_t size,
 	else
 		va = ioremap_wc(start, size);
 
+	/* We must release the mem region if ioremap fails. */
+	if (!va)
+		release_mem_region(start, size);
+
 	/*
 	 * Since request_mem_region() and ioremap() are byte-granularity
 	 * there is no need handle anything special like we do when the
Signature · 1 line
2.53.0
author maintainer
#11 lore raw

PATCH 11/666 erofs: verify metadata accesses for file-backed mounts

In reply to Greg Kroah-Hartman

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

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

From: Gao Xiang <[email protected]>

[ Upstream commit 307210c262a29f41d7177851295ea1703bd04175 ]

For file-backed mounts, metadata is fetched via the page cache of backing inodes to avoid double caching and redundant copy ops out of RO uptodate folios, which is used by Android APEXes, ComposeFS, containerd. However, rw_verify_area() was missing prior to metadata accesses.

Similar to vfs_iocb_iter_read(), fix this by:
- Enabling fanotify pre-content hooks on metadata accesses;
- security_file_permission() for security modules.

Verified that fanotify pre-content hooks now works correctly.

Fixes fb176750266a ("erofs: add file-backed mount support")
---
 fs/erofs/data.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
fs/erofs/data.c +14 -0
index 91182d5e3a66c..192c7ed885acd 100644
@@ -30,6 +30,20 @@ void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset,
 {
 	pgoff_t index = offset >> PAGE_SHIFT;
 	struct folio *folio = NULL;
+	loff_t fpos;
+	int err;
+
+	/*
+	 * Metadata access for file-backed mounts reuses page cache of backing
+	 * fs inodes (only folio data will be needed) to prevent double caching.
+	 * However, the data access range must be verified here in advance.
+	 */
+	if (buf->file) {
+		fpos = index << PAGE_SHIFT;
+		err = rw_verify_area(READ, buf->file, &fpos, PAGE_SIZE);
+		if (err < 0)
+			return ERR_PTR(err);
+	}
 
 	if (buf->page) {
 		folio = page_folio(buf->page);
Signature · 1 line
2.53.0
#12 lore raw

Re: [PATCH 6.12 011/666] erofs: verify metadata accesses for file-backed mounts

Hi Greg,

Quoted 2 lines · Greg Kroah-Hartman

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

Could you please help drop this too, the same reason as:
https://lore.kernel.org/r/ag3qlMOcTYM2FBUQ@debian

I will address this backport manually later.

Thanks,
Gao Xiang

Quoted 57 lines

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

From: Gao Xiang <[email protected]>

[ Upstream commit 307210c262a29f41d7177851295ea1703bd04175 ]

For file-backed mounts, metadata is fetched via the page cache of backing inodes to avoid double caching and redundant copy ops out of RO uptodate folios, which is used by Android APEXes, ComposeFS, containerd. However, rw_verify_area() was missing prior to metadata accesses.

Similar to vfs_iocb_iter_read(), fix this by:
- Enabling fanotify pre-content hooks on metadata accesses;
- security_file_permission() for security modules.

Verified that fanotify pre-content hooks now works correctly.

Fixes fb176750266a ("erofs: add file-backed mount support")
---
 fs/erofs/data.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
fs/erofs/data.c +14 -0
index 91182d5e3a66c..192c7ed885acd 100644
@@ -30,6 +30,20 @@ void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset,
 {
 	pgoff_t index = offset >> PAGE_SHIFT;
 	struct folio *folio = NULL;
+	loff_t fpos;
+	int err;
+
+	/*
+	 * Metadata access for file-backed mounts reuses page cache of backing
+	 * fs inodes (only folio data will be needed) to prevent double caching.
+	 * However, the data access range must be verified here in advance.
+	 */
+	if (buf->file) {
+		fpos = index << PAGE_SHIFT;
+		err = rw_verify_area(READ, buf->file, &fpos, PAGE_SIZE);
+		if (err < 0)
+			return ERR_PTR(err);
+	}
 
 	if (buf->page) {
 		folio = page_folio(buf->page);
Signature · 1 line
2.53.0
maintainer
#13 lore raw

Re: [PATCH 6.12 011/666] erofs: verify metadata accesses for file-backed mounts

Quoted 4 lines · Gao Xiang

Could you please help drop this too, the same reason as:
https://lore.kernel.org/r/ag3qlMOcTYM2FBUQ@debian

I will address this backport manually later.

Dropped from the 6.12 queue (along with the 7.0 and 6.18 counterparts). Thanks.

--
Thanks,
Sasha

author maintainer
#14 lore raw

PATCH 12/666 md: wake raid456 reshape waiters before suspend

In reply to Greg Kroah-Hartman

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

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

From: Yu Kuai <[email protected]>

[ Upstream commit cf86bb53b9c92354904a328e947a05ffbfdd1840 ]

During raid456 reshape, direct IO across the reshape position can sleep in raid5_make_request() waiting for reshape progress while still holding an active_io reference. If userspace then freezes reshape and writes md/suspend_lo or md/suspend_hi, mddev_suspend() kills active_io and waits for all in-flight IO to drain.

This can deadlock: the IO needs reshape progress to continue, but the reshape thread is already frozen, so the active_io reference is never dropped and suspend never completes.

raid5_prepare_suspend() already wakes wait_for_reshape for dm-raid. Do the same for normal md suspend when reshape is already interrupted, so waiting raid456 IO can abort, drop its reference, and let suspend finish.

The mdadm test tests/25raid456-reshape-deadlock reproduces the hang.

Fixes 714d20150ed8 ("md: add new helpers to suspend/resume array")
---
 drivers/md/md.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/md/md.c +11 -0
index 526390acd39e0..1aff3e541ceb5 100644
@@ -470,6 +470,17 @@ int mddev_suspend(struct mddev *mddev, bool interruptible)
 	}
 
 	percpu_ref_kill(&mddev->active_io);
+
+	/*
+	 * RAID456 IO can sleep in wait_for_reshape while still holding an
+	 * active_io reference. If reshape is already interrupted or frozen,
+	 * wake those waiters so they can abort and drop the reference instead
+	 * of deadlocking suspend.
+	 */
+	if (mddev->pers && mddev->pers->prepare_suspend &&
+	    reshape_interrupted(mddev))
+		mddev->pers->prepare_suspend(mddev);
+
 	if (interruptible)
 		err = wait_event_interruptible(mddev->sb_wait,
 				percpu_ref_is_zero(&mddev->active_io));
Signature · 1 line
2.53.0
author maintainer
#15 lore raw

PATCH 13/666 btrfs: pass struct btrfs_inode to clone_copy_inline_extent()

In reply to Greg Kroah-Hartman

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

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

From: David Sterba <[email protected]>

[ Upstream commit 65a66afd1ee5b2770fde296663baa0f79af56bc7 ]

Pass a struct btrfs_inode to clone_copy_inline_extent() as it's an internal interface, allowing to remove some use of BTRFS_I.

Stable-dep-of: b48c980b6a7e ("btrfs: fix deadlock between reflink and transaction commit when using flushoncommit")

---
 fs/btrfs/reflink.c | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)
fs/btrfs/reflink.c +14 -14
index f0824c948cb70..8640dbf1aefa4 100644
@@ -165,7 +165,7 @@ static int copy_inline_to_page(struct btrfs_inode *inode,
  * the source inode to destination inode when possible. When not possible we
  * copy the inline extent's data into the respective page of the inode.
  */
-static int clone_copy_inline_extent(struct inode *dst,
+static int clone_copy_inline_extent(struct btrfs_inode *inode,
 				    struct btrfs_path *path,
 				    struct btrfs_key *new_key,
 				    const u64 drop_start,
@@ -175,8 +175,8 @@ static int clone_copy_inline_extent(struct inode *dst,
 				    char *inline_data,
 				    struct btrfs_trans_handle **trans_out)
 {
-	struct btrfs_fs_info *fs_info = inode_to_fs_info(dst);
-	struct btrfs_root *root = BTRFS_I(dst)->root;
+	struct btrfs_root *root = inode->root;
+	struct btrfs_fs_info *fs_info = root->fs_info;
 	const u64 aligned_end = ALIGN(new_key->offset + datal,
 				      fs_info->sectorsize);
 	struct btrfs_trans_handle *trans = NULL;
@@ -185,12 +185,12 @@ static int clone_copy_inline_extent(struct inode *dst,
 	struct btrfs_key key;
 
 	if (new_key->offset > 0) {
-		ret = copy_inline_to_page(BTRFS_I(dst), new_key->offset,
+		ret = copy_inline_to_page(inode, new_key->offset,
 					  inline_data, size, datal, comp_type);
 		goto out;
 	}
 
-	key.objectid = btrfs_ino(BTRFS_I(dst));
+	key.objectid = btrfs_ino(inode);
 	key.type = BTRFS_EXTENT_DATA_KEY;
 	key.offset = 0;
 	ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
@@ -205,7 +205,7 @@ static int clone_copy_inline_extent(struct inode *dst,
 				goto copy_inline_extent;
 		}
 		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
-		if (key.objectid == btrfs_ino(BTRFS_I(dst)) &&
+		if (key.objectid == btrfs_ino(inode) &&
 		    key.type == BTRFS_EXTENT_DATA_KEY) {
 			/*
 			 * There's an implicit hole at file offset 0, copy the
@@ -214,7 +214,7 @@ static int clone_copy_inline_extent(struct inode *dst,
 			ASSERT(key.offset > 0);
 			goto copy_to_page;
 		}
-	} else if (i_size_read(dst) <= datal) {
+	} else if (i_size_read(&inode->vfs_inode) <= datal) {
 		struct btrfs_file_extent_item *ei;
 
 		ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
@@ -236,7 +236,7 @@ static int clone_copy_inline_extent(struct inode *dst,
 	 * We have no extent items, or we have an extent at offset 0 which may
 	 * or may not be inlined. All these cases are dealt the same way.
 	 */
-	if (i_size_read(dst) > datal) {
+	if (i_size_read(&inode->vfs_inode) > datal) {
 		/*
 		 * At the destination offset 0 we have either a hole, a regular
 		 * extent or an inline extent larger then the one we want to
@@ -270,7 +270,7 @@ static int clone_copy_inline_extent(struct inode *dst,
 	drop_args.start = drop_start;
 	drop_args.end = aligned_end;
 	drop_args.drop_cache = true;
-	ret = btrfs_drop_extents(trans, root, BTRFS_I(dst), &drop_args);
+	ret = btrfs_drop_extents(trans, root, inode, &drop_args);
 	if (ret)
 		goto out;
 	ret = btrfs_insert_empty_item(trans, root, path, new_key, size);
@@ -281,9 +281,9 @@ static int clone_copy_inline_extent(struct inode *dst,
 			    btrfs_item_ptr_offset(path->nodes[0],
 						  path->slots[0]),
 			    size);
-	btrfs_update_inode_bytes(BTRFS_I(dst), datal, drop_args.bytes_found);
-	btrfs_set_inode_full_sync(BTRFS_I(dst));
-	ret = btrfs_inode_set_file_extent_range(BTRFS_I(dst), 0, aligned_end);
+	btrfs_update_inode_bytes(inode, datal, drop_args.bytes_found);
+	btrfs_set_inode_full_sync(inode);
+	ret = btrfs_inode_set_file_extent_range(inode, 0, aligned_end);
 out:
 	if (!ret && !trans) {
 		/*
@@ -318,7 +318,7 @@ static int clone_copy_inline_extent(struct inode *dst,
 	 */
 	btrfs_release_path(path);
 
-	ret = copy_inline_to_page(BTRFS_I(dst), new_key->offset,
+	ret = copy_inline_to_page(inode, new_key->offset,
 				  inline_data, size, datal, comp_type);
 	goto out;
 }
@@ -526,7 +526,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
 				goto out;
 			}
 
-			ret = clone_copy_inline_extent(inode, path, &new_key,
+			ret = clone_copy_inline_extent(BTRFS_I(inode), path, &new_key,
 						       drop_start, datal, size,
 						       comp, buf, &trans);
 			if (ret)
Signature · 1 line
2.53.0
author maintainer
#16 lore raw

PATCH 14/666 btrfs: fix deadlock between reflink and transaction commit when using flushoncommit

In reply to Greg Kroah-Hartman

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

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

From: Filipe Manana <[email protected]>

[ Upstream commit b48c980b6a7e409050bb3067165db31cc6205e3e ]

When using the flushoncommit mount option, we can have a deadlock between a transaction commit and a reflink operation that copied an inline extent to an offset beyond the current i_size of the destination node.

The deadlock happens like this:

1) Task A clones an inline extent from inode X to an offset of inode Y that is beyond Y's current i_size. This means we copied the inline extent's data to a folio of inode Y that is beyond its EOF, using a call to copy_inline_to_page();

2) Task B starts a transaction commit and calls btrfs_start_delalloc_flush() to flush delalloc;

3) The delalloc flushing sees the new dirty folio of inode Y and when it attempts to flush it, it ends up at extent_writepage() and sees that the offset of the folio is beyond the i_size of inode Y, so it attempts to invalidate the folio by calling folio_invalidate(), which ends up at btrfs' folio invalidate callback - btrfs_invalidate_folio(). There it tries to lock the folio's range in inode Y's extent io tree, but it blocks since it's currently locked by task A - during a reflink we lock the inodes and the source and destination ranges after flushing all delalloc and waiting for ordered extent completion - after that we don't expect to have dirty folios in the ranges, the exception is if we have to copy an inline extent's data (because the destination offset is not zero);

4) Task A then attempts to start a transaction to update the inode item, and then it's blocked since the current transaction is in the TRANS_STATE_COMMIT_START state. Therefore task A has to wait for the current transaction to become unblocked (its state >= TRANS_STATE_UNBLOCKED).

So task A is waiting for the transaction commit done by task B, and the later waiting on the extent lock of inode Y that is currently held by task A.

Syzbot recently reported this with the following stack traces:

  INFO: task kworker/u8:7:1053 blocked for more than 143 seconds.
        Not tainted syzkaller #0
  "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
  task:kworker/u8:7    state:D stack:23520 pid:1053  tgid:1053  ppid:2      task_flags:0x4208060 flags:0x00080000
  Workqueue: writeback wb_workfn (flush-btrfs-46)
  Call Trace:
   <TASK>
   context_switch kernel/sched/core.c:5298 [inline]
   __schedule+0x1553/0x5240 kernel/sched/core.c:6911
   __schedule_loop kernel/sched/core.c:6993 [inline]
   schedule+0x164/0x360 kernel/sched/core.c:7008
   wait_extent_bit fs/btrfs/extent-io-tree.c:811 [inline]
   btrfs_lock_extent_bits+0x59c/0x700 fs/btrfs/extent-io-tree.c:1914
   btrfs_lock_extent fs/btrfs/extent-io-tree.h:152 [inline]
   btrfs_invalidate_folio+0x43d/0xc40 fs/btrfs/inode.c:7704
   extent_writepage fs/btrfs/extent_io.c:1852 [inline]
   extent_write_cache_pages fs/btrfs/extent_io.c:2580 [inline]
   btrfs_writepages+0x12ff/0x2440 fs/btrfs/extent_io.c:2713
   do_writepages+0x32e/0x550 mm/page-writeback.c:2554
   __writeback_single_inode+0x133/0x11a0 fs/fs-writeback.c:1750
   writeback_sb_inodes+0x995/0x19d0 fs/fs-writeback.c:2042
   wb_writeback+0x456/0xb70 fs/fs-writeback.c:2227
   wb_do_writeback fs/fs-writeback.c:2374 [inline]
   wb_workfn+0x41a/0xf60 fs/fs-writeback.c:2414
   process_one_work kernel/workqueue.c:3276 [inline]
   process_scheduled_works+0xb6e/0x18c0 kernel/workqueue.c:3359
   worker_thread+0xa53/0xfc0 kernel/workqueue.c:3440
   kthread+0x388/0x470 kernel/kthread.c:436
   ret_from_fork+0x51e/0xb90 arch/x86/kernel/process.c:158
   ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
   </TASK>
  INFO: task syz.4.64:6910 blocked for more than 143 seconds.
        Not tainted syzkaller #0
  "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
  task:syz.4.64        state:D stack:22752 pid:6910  tgid:6905  ppid:5944   task_flags:0x400140 flags:0x00080002
  Call Trace:
   <TASK>
   context_switch kernel/sched/core.c:5298 [inline]
   __schedule+0x1553/0x5240 kernel/sched/core.c:6911
   __schedule_loop kernel/sched/core.c:6993 [inline]
   schedule+0x164/0x360 kernel/sched/core.c:7008
   wait_current_trans+0x39f/0x590 fs/btrfs/transaction.c:535
   start_transaction+0x6a7/0x1650 fs/btrfs/transaction.c:705
   clone_copy_inline_extent fs/btrfs/reflink.c:299 [inline]
   btrfs_clone+0x128a/0x24d0 fs/btrfs/reflink.c:529
   btrfs_clone_files+0x271/0x3f0 fs/btrfs/reflink.c:750
   btrfs_remap_file_range+0x76b/0x1320 fs/btrfs/reflink.c:903
   vfs_copy_file_range+0xda7/0x1390 fs/read_write.c:1600
   __do_sys_copy_file_range fs/read_write.c:1683 [inline]
   __se_sys_copy_file_range+0x2fb/0x480 fs/read_write.c:1650
   do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
   do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
   entry_SYSCALL_64_after_hwframe+0x77/0x7f
  RIP: 0033:0x7f5f73afc799
  RSP: 002b:00007f5f7315e028 EFLAGS: 00000246 ORIG_RAX: 0000000000000146
  RAX: ffffffffffffffda RBX: 00007f5f73d75fa0 RCX: 00007f5f73afc799
  RDX: 0000000000000005 RSI: 0000000000000000 RDI: 0000000000000005
  RBP: 00007f5f73b92c99 R08: 0000000000000863 R09: 0000000000000000
  R10: 00002000000000c0 R11: 0000000000000246 R12: 0000000000000000
  R13: 00007f5f73d76038 R14: 00007f5f73d75fa0 R15: 00007fff138a5068
   </TASK>
  INFO: task syz.4.64:6975 blocked for more than 143 seconds.
        Not tainted syzkaller #0
  "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
  task:syz.4.64        state:D stack:24736 pid:6975  tgid:6905  ppid:5944   task_flags:0x400040 flags:0x00080002
  Call Trace:
   <TASK>
   context_switch kernel/sched/core.c:5298 [inline]
   __schedule+0x1553/0x5240 kernel/sched/core.c:6911
   __schedule_loop kernel/sched/core.c:6993 [inline]
   schedule+0x164/0x360 kernel/sched/core.c:7008
   wb_wait_for_completion+0x3e8/0x790 fs/fs-writeback.c:227
   __writeback_inodes_sb_nr+0x24c/0x2d0 fs/fs-writeback.c:2838
   try_to_writeback_inodes_sb+0x9a/0xc0 fs/fs-writeback.c:2886
   btrfs_start_delalloc_flush fs/btrfs/transaction.c:2175 [inline]
   btrfs_commit_transaction+0x82e/0x31a0 fs/btrfs/transaction.c:2364
   btrfs_ioctl+0xca7/0xd00 fs/btrfs/ioctl.c:5206
   vfs_ioctl fs/ioctl.c:51 [inline]
   __do_sys_ioctl fs/ioctl.c:597 [inline]
   __se_sys_ioctl+0xff/0x170 fs/ioctl.c:583
   do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
   do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
   entry_SYSCALL_64_after_hwframe+0x77/0x7f
  RIP: 0033:0x7f5f73afc799
  RSP: 002b:00007f5f7313d028 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
  RAX: ffffffffffffffda RBX: 00007f5f73d76090 RCX: 00007f5f73afc799
  RDX: 0000000000000000 RSI: 0000000000009408 RDI: 0000000000000004
  RBP: 00007f5f73b92c99 R08: 0000000000000000 R09: 0000000000000000
  R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
  R13: 00007f5f73d76128 R14: 00007f5f73d76090 R15: 00007fff138a5068
   </TASK>

Fix this by updating the i_size of the destination inode of a reflink operation after we copy an inline extent's data to an offset beyond the i_size and before attempting to start a transaction to update the inode's item.

Reported-by [email protected]
Fixes 05a5a7621ce6 ("Btrfs: implement full reflink support for inline extents")
---
 fs/btrfs/reflink.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)
fs/btrfs/reflink.c +45 -0
index 8640dbf1aefa4..e86df9c83aba5 100644
@@ -320,6 +320,51 @@ static int clone_copy_inline_extent(struct btrfs_inode *inode,
 
 	ret = copy_inline_to_page(inode, new_key->offset,
 				  inline_data, size, datal, comp_type);
+
+	/*
+	 * If we copied the inline extent data to a page/folio beyond the i_size
+	 * of the destination inode, then we need to increase the i_size before
+	 * we start a transaction to update the inode item. This is to prevent a
+	 * deadlock when the flushoncommit mount option is used, which happens
+	 * like this:
+	 *
+	 * 1) Task A clones an inline extent from inode X to an offset of inode
+	 *    Y that is beyond Y's current i_size. This means we copied the
+	 *    inline extent's data to a folio of inode Y that is beyond its EOF,
+	 *    using the call above to copy_inline_to_page();
+	 *
+	 * 2) Task B starts a transaction commit and calls
+	 *    btrfs_start_delalloc_flush() to flush delalloc;
+	 *
+	 * 3) The delalloc flushing sees the new dirty folio of inode Y and when
+	 *    it attempts to flush it, it ends up at extent_writepage() and sees
+	 *    that the offset of the folio is beyond the i_size of inode Y, so
+	 *    it attempts to invalidate the folio by calling folio_invalidate(),
+	 *    which ends up at btrfs' folio invalidate callback -
+	 *    btrfs_invalidate_folio(). There it tries to lock the folio's range
+	 *    in inode Y's extent io tree, but it blocks since it's currently
+	 *    locked by task A - during reflink we lock the inodes and the
+	 *    source and destination ranges after flushing all delalloc and
+	 *    waiting for ordered extent completion - after that we don't expect
+	 *    to have dirty folios in the ranges, the exception is if we have to
+	 *    copy an inline extent's data (because the destination offset is
+	 *    not zero);
+	 *
+	 * 4) Task A then does the 'goto out' below and attempts to start a
+	 *    transaction to update the inode item, and then it's blocked since
+	 *    the current transaction is in the TRANS_STATE_COMMIT_START state.
+	 *    Therefore task A has to wait for the current transaction to become
+	 *    unblocked (its state >= TRANS_STATE_UNBLOCKED).
+	 *
+	 * This leads to a deadlock - the task committing the transaction
+	 * waiting for the delalloc flushing which is blocked during folio
+	 * invalidation on the inode's extent lock and the reflink task waiting
+	 * for the current transaction to be unblocked so that it can start a
+	 * a new one to update the inode item (while holding the extent lock).
+	 */
+	if (ret == 0 && new_key->offset + datal > i_size_read(&inode->vfs_inode))
+		i_size_write(&inode->vfs_inode, new_key->offset + datal);
+
 	goto out;
 }
 
Signature · 1 line
2.53.0
author maintainer
#17 lore raw

PATCH 15/666 ACPI: x86: cmos_rtc: Clean up address space handler driver

In reply to Greg Kroah-Hartman

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

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

From: Rafael J. Wysocki <[email protected]>

[ Upstream commit ba0b236736dde4059bdcb8e99beaa50d6e5b6e7e ]

Make multiple changes that do not alter functionality to the CMOS RTC ACPI address space handler driver, including the following:

- Drop the unused .detach() callback from cmos_rtc_handler.

- Rename acpi_cmos_rtc_attach_handler() to acpi_cmos_rtc_attach().

- Rearrange acpi_cmos_rtc_space_handler() to reduce the number of redundant checks and make white space follow the coding style.

- Adjust an error message in acpi_install_cmos_rtc_space_handler() and make the white space follow the coding style.

- Rearrange acpi_remove_cmos_rtc_space_handler() and adjust an error message in it.

No intentional functional impact.

Stable-dep-of: 6cee29ad9d7e ("ACPI: x86: cmos_rtc: Improve coordination with ACPI TAD driver")

---
 drivers/acpi/x86/cmos_rtc.c | 61 +++++++++++++++++++------------------
 1 file changed, 32 insertions(+), 29 deletions(-)
drivers/acpi/x86/cmos_rtc.c +32 -29
index 51643ff6fe5fc..977234da9fc11 100644
@@ -24,31 +24,35 @@ static const struct acpi_device_id acpi_cmos_rtc_ids[] = {
 	{}
 };
 
-static acpi_status
-acpi_cmos_rtc_space_handler(u32 function, acpi_physical_address address,
-		      u32 bits, u64 *value64,
-		      void *handler_context, void *region_context)
+static acpi_status acpi_cmos_rtc_space_handler(u32 function,
+					       acpi_physical_address address,
+					       u32 bits, u64 *value64,
+					       void *handler_context,
+					       void *region_context)
 {
-	int i;
+	unsigned int i, bytes = DIV_ROUND_UP(bits, 8);
 	u8 *value = (u8 *)value64;
 
 	if (address > 0xff || !value64)
 		return AE_BAD_PARAMETER;
 
-	if (function != ACPI_WRITE && function != ACPI_READ)
-		return AE_BAD_PARAMETER;
+	guard(spinlock_irq)(&rtc_lock);
+
+	if (function == ACPI_WRITE) {
+		for (i = 0; i < bytes; i++, address++, value++)
+			CMOS_WRITE(*value, address);
 
-	spin_lock_irq(&rtc_lock);
+		return AE_OK;
+	}
 
-	for (i = 0; i < DIV_ROUND_UP(bits, 8); ++i, ++address, ++value)
-		if (function == ACPI_READ)
+	if (function == ACPI_READ) {
+		for (i = 0; i < bytes; i++, address++, value++)
 			*value = CMOS_READ(address);
-		else
-			CMOS_WRITE(*value, address);
 
-	spin_unlock_irq(&rtc_lock);
+		return AE_OK;
+	}
 
-	return AE_OK;
+	return AE_BAD_PARAMETER;
 }
 
 int acpi_install_cmos_rtc_space_handler(acpi_handle handle)
@@ -56,11 +60,11 @@ int acpi_install_cmos_rtc_space_handler(acpi_handle handle)
 	acpi_status status;
 
 	status = acpi_install_address_space_handler(handle,
-			ACPI_ADR_SPACE_CMOS,
-			&acpi_cmos_rtc_space_handler,
-			NULL, NULL);
+						    ACPI_ADR_SPACE_CMOS,
+						    acpi_cmos_rtc_space_handler,
+						    NULL, NULL);
 	if (ACPI_FAILURE(status)) {
-		pr_err("Error installing CMOS-RTC region handler\n");
+		pr_err("Failed to install CMOS-RTC address space handler\n");
 		return -ENODEV;
 	}
 
@@ -70,26 +74,25 @@ EXPORT_SYMBOL_GPL(acpi_install_cmos_rtc_space_handler);
 
 void acpi_remove_cmos_rtc_space_handler(acpi_handle handle)
 {
-	if (ACPI_FAILURE(acpi_remove_address_space_handler(handle,
-			ACPI_ADR_SPACE_CMOS, &acpi_cmos_rtc_space_handler)))
-		pr_err("Error removing CMOS-RTC region handler\n");
+	acpi_status status;
+
+	status = acpi_remove_address_space_handler(handle,
+						   ACPI_ADR_SPACE_CMOS,
+						   acpi_cmos_rtc_space_handler);
+	if (ACPI_FAILURE(status))
+		pr_err("Failed to remove CMOS-RTC address space handler\n");
 }
 EXPORT_SYMBOL_GPL(acpi_remove_cmos_rtc_space_handler);
 
-static int acpi_cmos_rtc_attach_handler(struct acpi_device *adev, const struct acpi_device_id *id)
+static int acpi_cmos_rtc_attach(struct acpi_device *adev,
+				const struct acpi_device_id *id)
 {
 	return acpi_install_cmos_rtc_space_handler(adev->handle);
 }
 
-static void acpi_cmos_rtc_detach_handler(struct acpi_device *adev)
-{
-	acpi_remove_cmos_rtc_space_handler(adev->handle);
-}
-
 static struct acpi_scan_handler cmos_rtc_handler = {
 	.ids = acpi_cmos_rtc_ids,
-	.attach = acpi_cmos_rtc_attach_handler,
-	.detach = acpi_cmos_rtc_detach_handler,
+	.attach = acpi_cmos_rtc_attach,
 };
 
 void __init acpi_cmos_rtc_init(void)
Signature · 1 line
2.53.0
author maintainer
#18 lore raw

PATCH 16/666 ACPI: x86: cmos_rtc: Improve coordination with ACPI TAD driver

In reply to Greg Kroah-Hartman

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

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

From: Rafael J. Wysocki <[email protected]>

[ Upstream commit 6cee29ad9d7e400d39ae0b1a54447fedcb62eecd ]

If a CMOS RTC (PNP0B00/PNP0B01/PNP0B02) device coexists with an ACPI TAD (timer and event alarm device, ACPI000E), the ACPI TAD driver will attempt to install the CMOS RTC address space hanlder that has been installed already and the TAD probing will fail.

Avoid that by changing acpi_install_cmos_rtc_space_handler() to return zero and acpi_remove_cmos_rtc_space_handler() to do nothing if the CMOS RTC address space handler has been installed already.

Fixes 596ca52a56da ("ACPI: TAD: Install SystemCMOS address space handler for ACPI000E")
---
 drivers/acpi/x86/cmos_rtc.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)
drivers/acpi/x86/cmos_rtc.c +17 -1
index 977234da9fc11..45db7e51cbe60 100644
@@ -24,6 +24,8 @@ static const struct acpi_device_id acpi_cmos_rtc_ids[] = {
 	{}
 };
 
+static bool cmos_rtc_space_handler_present __read_mostly;
+
 static acpi_status acpi_cmos_rtc_space_handler(u32 function,
 					       acpi_physical_address address,
 					       u32 bits, u64 *value64,
@@ -59,6 +61,9 @@ int acpi_install_cmos_rtc_space_handler(acpi_handle handle)
 {
 	acpi_status status;
 
+	if (cmos_rtc_space_handler_present)
+		return 0;
+
 	status = acpi_install_address_space_handler(handle,
 						    ACPI_ADR_SPACE_CMOS,
 						    acpi_cmos_rtc_space_handler,
@@ -68,6 +73,8 @@ int acpi_install_cmos_rtc_space_handler(acpi_handle handle)
 		return -ENODEV;
 	}
 
+	cmos_rtc_space_handler_present = true;
+
 	return 1;
 }
 EXPORT_SYMBOL_GPL(acpi_install_cmos_rtc_space_handler);
@@ -76,6 +83,9 @@ void acpi_remove_cmos_rtc_space_handler(acpi_handle handle)
 {
 	acpi_status status;
 
+	if (cmos_rtc_space_handler_present)
+		return;
+
 	status = acpi_remove_address_space_handler(handle,
 						   ACPI_ADR_SPACE_CMOS,
 						   acpi_cmos_rtc_space_handler);
@@ -87,7 +97,13 @@ EXPORT_SYMBOL_GPL(acpi_remove_cmos_rtc_space_handler);
 static int acpi_cmos_rtc_attach(struct acpi_device *adev,
 				const struct acpi_device_id *id)
 {
-	return acpi_install_cmos_rtc_space_handler(adev->handle);
+	int ret;
+
+	ret = acpi_install_cmos_rtc_space_handler(adev->handle);
+	if (ret < 0)
+		return ret;
+
+	return 1;
 }
 
 static struct acpi_scan_handler cmos_rtc_handler = {
Signature · 1 line
2.53.0
author maintainer
#19 lore raw

PATCH 17/666 devres: fix missing node debug info in devm_krealloc()

In reply to Greg Kroah-Hartman

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

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

From: Danilo Krummrich <[email protected]>

[ Upstream commit f813ec9e84b4d0ca81ec1da94ab07bfb4a29266c ]

Fix missing call to set_node_dbginfo() for new devres nodes created by devm_krealloc().

---
 drivers/base/devres.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/base/devres.c +2 -0
index 68224f2f83fff..f229c5b3e7850 100644
@@ -913,6 +913,8 @@ void *devm_krealloc(struct device *dev, void *ptr, size_t new_size, gfp_t gfp)
 	if (!new_dr)
 		return NULL;
 
+	set_node_dbginfo(&new_dr->node, "devm_krealloc_release", new_size);
+
 	/*
 	 * The spinlock protects the linked list against concurrent
 	 * modifications but not the resource itself.
Signature · 1 line
2.53.0
author maintainer
#20 lore raw

PATCH 18/666 thermal/drivers/spear: Fix error condition for reading st,thermal-flags

In reply to Greg Kroah-Hartman

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

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

From: Gopi Krishna Menon <[email protected]>

[ Upstream commit da2c4f332a0504d9c284e7626a561d343c8d6f57 ]

of_property_read_u32 returns 0 on success. The current check returns -EINVAL if the property is read successfully.

Fix the check by removing ! from of_property_read_u32

Fixes b9c7aff481f1 ("drivers/thermal/spear_thermal.c: add Device Tree probing capability")
---
 drivers/thermal/spear_thermal.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/thermal/spear_thermal.c +1 -1
index 60a871998b07e..19b37f9b093f9 100644
@@ -93,7 +93,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	int ret = 0, val;
 
-	if (!np || !of_property_read_u32(np, "st,thermal-flags", &val)) {
+	if (!np || of_property_read_u32(np, "st,thermal-flags", &val)) {
 		dev_err(&pdev->dev, "Failed: DT Pdata not passed\n");
 		return -EINVAL;
 	}
Signature · 1 line
2.53.0
author maintainer
#21 lore raw

PATCH 19/666 debugfs: check for NULL pointer in debugfs_create_str()

In reply to Greg Kroah-Hartman

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

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

From: Gui-Dong Han <[email protected]>

[ Upstream commit 31de83980d3764d784f79ff1bc93c42b324f4013 ]

Passing a NULL pointer to debugfs_create_str() leads to a NULL pointer dereference when the debugfs file is read. Following upstream discussions, forbid the creation of debugfs string files with NULL pointers. Add a WARN_ON() to expose offending callers and return early.

---
 fs/debugfs/file.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
fs/debugfs/file.c +4 -1
index 67299e8b734ed..d3ffd954d6f94 100644
@@ -1071,7 +1071,7 @@ static const struct file_operations fops_str_wo = {
  *          directory dentry if set.  If this parameter is %NULL, then the
  *          file will be created in the root of the debugfs filesystem.
  * @value: a pointer to the variable that the file should read to and write
- *         from.
+ *         from. This pointer and the string it points to must not be %NULL.
  *
  * This function creates a file in debugfs with the given name that
  * contains the value of the variable @value.  If the @mode variable is so
@@ -1080,6 +1080,9 @@ static const struct file_operations fops_str_wo = {
 void debugfs_create_str(const char *name, umode_t mode,
 			struct dentry *parent, char **value)
 {
+	if (WARN_ON(!value || !*value))
+		return;
+
 	debugfs_create_mode_unsafe(name, mode, parent, value, &fops_str,
 				   &fops_str_ro, &fops_str_wo);
 }
Signature · 1 line
2.53.0
author maintainer
#22 lore raw

PATCH 20/666 debugfs: fix placement of EXPORT_SYMBOL_GPL for debugfs_create_str()

In reply to Greg Kroah-Hartman

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

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

From: Gui-Dong Han <[email protected]>

[ Upstream commit 4afc929c0f74c4f22b055a82b371d50586da58ca ]

The EXPORT_SYMBOL_GPL() for debugfs_create_str was placed incorrectly away from the function definition. Move it immediately below the debugfs_create_str() function where it belongs.

Fixes d60b59b96795 ("debugfs: Export debugfs_create_str symbol")
---
 fs/debugfs/file.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/debugfs/file.c +1 -1
index d3ffd954d6f94..cc9587a1c9a9f 100644
@@ -991,7 +991,6 @@ ssize_t debugfs_read_file_str(struct file *file, char __user *user_buf,
 
 	return ret;
 }
-EXPORT_SYMBOL_GPL(debugfs_create_str);
 
 static ssize_t debugfs_write_file_str(struct file *file, const char __user *user_buf,
 				      size_t count, loff_t *ppos)
@@ -1086,6 +1085,7 @@ void debugfs_create_str(const char *name, umode_t mode,
 	debugfs_create_mode_unsafe(name, mode, parent, value, &fops_str,
 				   &fops_str_ro, &fops_str_wo);
 }
+EXPORT_SYMBOL_GPL(debugfs_create_str);
 
 static ssize_t read_file_blob(struct file *file, char __user *user_buf,
 			      size_t count, loff_t *ppos)
Signature · 1 line
2.53.0
author maintainer
#23 lore raw

PATCH 21/666 soundwire: debugfs: initialize firmware_file to empty string

In reply to Greg Kroah-Hartman

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

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

From: Gui-Dong Han <[email protected]>

[ Upstream commit 7215e4552f31e53595eae56a834f7e286beecccc ]

Passing NULL to debugfs_create_str() causes a NULL pointer dereference, and creating debugfs nodes with NULL string pointers is no longer permitted.

Additionally, firmware_file is a global pointer. Previously, adding every new slave blindly overwrote it with NULL.

Fix these issues by initializing firmware_file to an allocated empty string once in the subsystem init path (sdw_debugfs_init), and freeing it in the exit path. Existing driver code handles empty strings correctly.

---
 drivers/soundwire/debugfs.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/soundwire/debugfs.c +7 -2
index c30f571934ee2..93c93a128fb23 100644
@@ -295,8 +295,8 @@ void sdw_slave_debugfs_init(struct sdw_slave *slave)
 	debugfs_create_file("go", 0200, d, slave, &cmd_go_fops);
 
 	debugfs_create_file("read_buffer", 0400, d, slave, &read_buffer_fops);
-	firmware_file = NULL;
-	debugfs_create_str("firmware_file", 0200, d, &firmware_file);
+	if (firmware_file)
+		debugfs_create_str("firmware_file", 0200, d, &firmware_file);
 
 	slave->debugfs = d;
 }
@@ -308,10 +308,15 @@ void sdw_slave_debugfs_exit(struct sdw_slave *slave)
 
 void sdw_debugfs_init(void)
 {
+	if (!firmware_file)
+		firmware_file = kstrdup("", GFP_KERNEL);
+
 	sdw_debugfs_root = debugfs_create_dir("soundwire", NULL);
 }
 
 void sdw_debugfs_exit(void)
 {
 	debugfs_remove_recursive(sdw_debugfs_root);
+	kfree(firmware_file);
+	firmware_file = NULL;
 }
Signature · 1 line
2.53.0
author maintainer
#24 lore raw

PATCH 22/666 PCI: use generic driver_override infrastructure

In reply to Greg Kroah-Hartman

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

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

From: Danilo Krummrich <[email protected]>

[ Upstream commit 10a4206a24013be4d558d476010cbf2eb4c9fa64 ]

When a driver is probed through __driver_attach(), the bus' match() callback is called without the device lock held, thus accessing the driver_override field without a lock, which can cause a UAF.

Fix this by using the driver-core driver_override infrastructure taking care of proper locking internally.

Note that calling match() from __driver_attach() without the device lock held is intentional. [1]

---
 drivers/pci/pci-driver.c           | 11 +++++++----
 drivers/pci/pci-sysfs.c            | 28 ----------------------------
 drivers/pci/probe.c                |  1 -
 drivers/vfio/pci/vfio_pci_core.c   |  5 ++---
 drivers/xen/xen-pciback/pci_stub.c |  6 ++++--
 include/linux/pci.h                |  6 ------
 6 files changed, 13 insertions(+), 44 deletions(-)
drivers/pci/pci-driver.c +7 -4
index a00a2ce01045f..860d80787d9b1 100644
@@ -138,9 +138,11 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
 {
 	struct pci_dynid *dynid;
 	const struct pci_device_id *found_id = NULL, *ids;
+	int ret;
 
 	/* When driver_override is set, only bind to the matching driver */
-	if (dev->driver_override && strcmp(dev->driver_override, drv->name))
+	ret = device_match_driver_override(&dev->dev, &drv->driver);
+	if (ret == 0)
 		return NULL;
 
 	/* Look at the dynamic ids first, before the static ones */
@@ -164,7 +166,7 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
 		 * matching.
 		 */
 		if (found_id->override_only) {
-			if (dev->driver_override)
+			if (ret > 0)
 				return found_id;
 		} else {
 			return found_id;
@@ -172,7 +174,7 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
 	}
 
 	/* driver_override will always match, send a dummy id */
-	if (dev->driver_override)
+	if (ret > 0)
 		return &pci_device_id_any;
 	return NULL;
 }
@@ -423,7 +425,7 @@ static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
 static inline bool pci_device_can_probe(struct pci_dev *pdev)
 {
 	return (!pdev->is_virtfn || pdev->physfn->sriov->drivers_autoprobe ||
-		pdev->driver_override);
+		device_has_driver_override(&pdev->dev));
 }
 #else
 static inline bool pci_device_can_probe(struct pci_dev *pdev)
@@ -1677,6 +1679,7 @@ static void pci_dma_cleanup(struct device *dev)
 
 const struct bus_type pci_bus_type = {
 	.name		= "pci",
+	.driver_override = true,
 	.match		= pci_bus_match,
 	.uevent		= pci_uevent,
 	.probe		= pci_device_probe,
drivers/pci/pci-sysfs.c +0 -28
index 96f9cf9f8d643..122c182229b33 100644
@@ -606,33 +606,6 @@ static ssize_t devspec_show(struct device *dev,
 static DEVICE_ATTR_RO(devspec);
 #endif
 
-static ssize_t driver_override_store(struct device *dev,
-				     struct device_attribute *attr,
-				     const char *buf, size_t count)
-{
-	struct pci_dev *pdev = to_pci_dev(dev);
-	int ret;
-
-	ret = driver_set_override(dev, &pdev->driver_override, buf, count);
-	if (ret)
-		return ret;
-
-	return count;
-}
-
-static ssize_t driver_override_show(struct device *dev,
-				    struct device_attribute *attr, char *buf)
-{
-	struct pci_dev *pdev = to_pci_dev(dev);
-	ssize_t len;
-
-	device_lock(dev);
-	len = sysfs_emit(buf, "%s\n", pdev->driver_override);
-	device_unlock(dev);
-	return len;
-}
-static DEVICE_ATTR_RW(driver_override);
-
 static struct attribute *pci_dev_attrs[] = {
 	&dev_attr_power_state.attr,
 	&dev_attr_resource.attr,
@@ -660,7 +633,6 @@ static struct attribute *pci_dev_attrs[] = {
 #ifdef CONFIG_OF
 	&dev_attr_devspec.attr,
 #endif
-	&dev_attr_driver_override.attr,
 	&dev_attr_ari_enabled.attr,
 	NULL,
 };
drivers/pci/probe.c +0 -1
index 9e71eb4d1010e..d8c5a957b70e5 100644
@@ -2373,7 +2373,6 @@ static void pci_release_dev(struct device *dev)
 	pci_release_of_node(pci_dev);
 	pcibios_release_device(pci_dev);
 	pci_bus_put(pci_dev->bus);
-	kfree(pci_dev->driver_override);
 	bitmap_free(pci_dev->dma_alias_mask);
 	dev_dbg(dev, "device released\n");
 	kfree(pci_dev);
drivers/vfio/pci/vfio_pci_core.c +2 -3
index 5f545b45078f8..dd6e73de2e2a0 100644
@@ -2014,9 +2014,8 @@ static int vfio_pci_bus_notifier(struct notifier_block *nb,
 	    pdev->is_virtfn && physfn == vdev->pdev) {
 		pci_info(vdev->pdev, "Captured SR-IOV VF %s driver_override\n",
 			 pci_name(pdev));
-		pdev->driver_override = kasprintf(GFP_KERNEL, "%s",
-						  vdev->vdev.ops->name);
-		WARN_ON(!pdev->driver_override);
+		WARN_ON(device_set_driver_override(&pdev->dev,
+						   vdev->vdev.ops->name));
 	} else if (action == BUS_NOTIFY_BOUND_DRIVER &&
 		   pdev->is_virtfn && physfn == vdev->pdev) {
 		struct pci_driver *drv = pci_dev_driver(pdev);
drivers/xen/xen-pciback/pci_stub.c +4 -2
index b616b7768c3b9..8b3006078d003 100644
@@ -618,6 +618,8 @@ static int pcistub_seize(struct pci_dev *dev,
 	return err;
 }
 
+static struct pci_driver xen_pcibk_pci_driver;
+
 /* Called when 'bind'. This means we must _NOT_ call pci_reset_function or
  * other functions that take the sysfs lock. */
 static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id)
@@ -629,8 +631,8 @@ static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id)
 
 	match = pcistub_match(dev);
 
-	if ((dev->driver_override &&
-	     !strcmp(dev->driver_override, PCISTUB_DRIVER_NAME)) ||
+	if (device_match_driver_override(&dev->dev,
+					 &xen_pcibk_pci_driver.driver) > 0 ||
 	    match) {
 
 		if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL
include/linux/pci.h +0 -6
index 242ee3843e10e..825e6b3056f15 100644
@@ -540,12 +540,6 @@ struct pci_dev {
 	u8		supported_speeds; /* Supported Link Speeds Vector */
 	phys_addr_t	rom;		/* Physical address if not from BAR */
 	size_t		romlen;		/* Length if not from BAR */
-	/*
-	 * Driver name to force a match.  Do not set directly, because core
-	 * frees it.  Use driver_set_override() to set or clear it.
-	 */
-	const char	*driver_override;
-
 	unsigned long	priv_flags;	/* Private flags for the PCI driver */
 
 	/* These methods index pci_reset_fn_methods[] */
Signature · 1 line
2.53.0
author maintainer
#25 lore raw

PATCH 23/666 platform/wmi: use generic driver_override infrastructure

In reply to Greg Kroah-Hartman

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

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

From: Danilo Krummrich <[email protected]>

[ Upstream commit 8a700b1fc94df4d847a04f14ebc7f8532592b367 ]

When a driver is probed through __driver_attach(), the bus' match() callback is called without the device lock held, thus accessing the driver_override field without a lock, which can cause a UAF.

Fix this by using the driver-core driver_override infrastructure taking care of proper locking internally.

Note that calling match() from __driver_attach() without the device lock held is intentional. [1]

---
 drivers/platform/x86/wmi.c | 36 +++++-------------------------------
 include/linux/wmi.h        |  4 ----
 2 files changed, 5 insertions(+), 35 deletions(-)
drivers/platform/x86/wmi.c +5 -31
index 3cbe180c3fc0a..f13173eb070e6 100644
@@ -696,39 +696,11 @@ static ssize_t expensive_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(expensive);
 
-static ssize_t driver_override_show(struct device *dev, struct device_attribute *attr,
-				    char *buf)
-{
-	struct wmi_device *wdev = to_wmi_device(dev);
-	ssize_t ret;
-
-	device_lock(dev);
-	ret = sysfs_emit(buf, "%s\n", wdev->driver_override);
-	device_unlock(dev);
-
-	return ret;
-}
-
-static ssize_t driver_override_store(struct device *dev, struct device_attribute *attr,
-				     const char *buf, size_t count)
-{
-	struct wmi_device *wdev = to_wmi_device(dev);
-	int ret;
-
-	ret = driver_set_override(dev, &wdev->driver_override, buf, count);
-	if (ret < 0)
-		return ret;
-
-	return count;
-}
-static DEVICE_ATTR_RW(driver_override);
-
 static struct attribute *wmi_attrs[] = {
 	&dev_attr_modalias.attr,
 	&dev_attr_guid.attr,
 	&dev_attr_instance_count.attr,
 	&dev_attr_expensive.attr,
-	&dev_attr_driver_override.attr,
 	NULL
 };
 ATTRIBUTE_GROUPS(wmi);
@@ -797,7 +769,6 @@ static void wmi_dev_release(struct device *dev)
 {
 	struct wmi_block *wblock = dev_to_wblock(dev);
 
-	kfree(wblock->dev.driver_override);
 	kfree(wblock);
 }
 
@@ -806,10 +777,12 @@ static int wmi_dev_match(struct device *dev, const struct device_driver *driver)
 	const struct wmi_driver *wmi_driver = drv_to_wdrv(driver);
 	struct wmi_block *wblock = dev_to_wblock(dev);
 	const struct wmi_device_id *id = wmi_driver->id_table;
+	int ret;
 
 	/* When driver_override is set, only bind to the matching driver */
-	if (wblock->dev.driver_override)
-		return !strcmp(wblock->dev.driver_override, driver->name);
+	ret = device_match_driver_override(dev, driver);
+	if (ret >= 0)
+		return ret;
 
 	if (id == NULL)
 		return 0;
@@ -891,6 +864,7 @@ static struct class wmi_bus_class = {
 static const struct bus_type wmi_bus_type = {
 	.name = "wmi",
 	.dev_groups = wmi_groups,
+	.driver_override = true,
 	.match = wmi_dev_match,
 	.uevent = wmi_dev_uevent,
 	.probe = wmi_dev_probe,
include/linux/wmi.h +0 -4
index 3275470b5531e..63cca3b58d6df 100644
@@ -16,16 +16,12 @@
  * struct wmi_device - WMI device structure
  * @dev: Device associated with this WMI device
  * @setable: True for devices implementing the Set Control Method
- * @driver_override: Driver name to force a match; do not set directly,
- *		     because core frees it; use driver_set_override() to
- *		     set or clear it.
  *
  * This represents WMI devices discovered by the WMI driver core.
  */
 struct wmi_device {
 	struct device dev;
 	bool setable;
-	const char *driver_override;
 };
 
 /**
Signature · 1 line
2.53.0
author maintainer
#26 lore raw

PATCH 24/666 s390/cio: use generic driver_override infrastructure

In reply to Greg Kroah-Hartman

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

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

From: Danilo Krummrich <[email protected]>

[ Upstream commit ac4d8bb6e2e13e8684a76ea48d13ebaaaf5c24c4 ]

When a driver is probed through __driver_attach(), the bus' match() callback is called without the device lock held, thus accessing the driver_override field without a lock, which can cause a UAF.

Fix this by using the driver-core driver_override infrastructure taking care of proper locking internally.

Note that calling match() from __driver_attach() without the device lock held is intentional. [1]

---
 drivers/s390/cio/cio.h |  5 -----
 drivers/s390/cio/css.c | 34 ++++------------------------------
 2 files changed, 4 insertions(+), 35 deletions(-)
drivers/s390/cio/cio.h +0 -5
index a9057a5b670a6..23374604c6b01 100644
@@ -103,11 +103,6 @@ struct subchannel {
 	struct work_struct todo_work;
 	struct schib_config config;
 	u64 dma_mask;
-	/*
-	 * Driver name to force a match.  Do not set directly, because core
-	 * frees it.  Use driver_set_override() to set or clear it.
-	 */
-	const char *driver_override;
 } __attribute__ ((aligned(8)));
 
 DECLARE_PER_CPU_ALIGNED(struct irb, cio_irb);
drivers/s390/cio/css.c +4 -30
index 61be7c0550bc4..b0ddbad1ebf37 100644
@@ -160,7 +160,6 @@ static void css_subchannel_release(struct device *dev)
 
 	sch->config.intparm = 0;
 	cio_commit_config(sch);
-	kfree(sch->driver_override);
 	kfree(sch);
 }
 
@@ -324,37 +323,9 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 
 static DEVICE_ATTR_RO(modalias);
 
-static ssize_t driver_override_store(struct device *dev,
-				     struct device_attribute *attr,
-				     const char *buf, size_t count)
-{
-	struct subchannel *sch = to_subchannel(dev);
-	int ret;
-
-	ret = driver_set_override(dev, &sch->driver_override, buf, count);
-	if (ret)
-		return ret;
-
-	return count;
-}
-
-static ssize_t driver_override_show(struct device *dev,
-				    struct device_attribute *attr, char *buf)
-{
-	struct subchannel *sch = to_subchannel(dev);
-	ssize_t len;
-
-	device_lock(dev);
-	len = sysfs_emit(buf, "%s\n", sch->driver_override);
-	device_unlock(dev);
-	return len;
-}
-static DEVICE_ATTR_RW(driver_override);
-
 static struct attribute *subch_attrs[] = {
 	&dev_attr_type.attr,
 	&dev_attr_modalias.attr,
-	&dev_attr_driver_override.attr,
 	NULL,
 };
 
@@ -1358,9 +1329,11 @@ static int css_bus_match(struct device *dev, const struct device_driver *drv)
 	struct subchannel *sch = to_subchannel(dev);
 	const struct css_driver *driver = to_cssdriver(drv);
 	struct css_device_id *id;
+	int ret;
 
 	/* When driver_override is set, only bind to the matching driver */
-	if (sch->driver_override && strcmp(sch->driver_override, drv->name))
+	ret = device_match_driver_override(dev, drv);
+	if (ret == 0)
 		return 0;
 
 	for (id = driver->subchannel_type; id->match_flags; id++) {
@@ -1417,6 +1390,7 @@ static int css_uevent(const struct device *dev, struct kobj_uevent_env *env)
 
 static const struct bus_type css_bus_type = {
 	.name     = "css",
+	.driver_override = true,
 	.match    = css_bus_match,
 	.probe    = css_probe,
 	.remove   = css_remove,
Signature · 1 line
2.53.0
author maintainer
#27 lore raw

PATCH 25/666 bus: fsl-mc: use generic driver_override infrastructure

In reply to Greg Kroah-Hartman

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

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

From: Danilo Krummrich <[email protected]>

[ Upstream commit 6c8dfb0362732bf1e4829867a2a5239fedc592d0 ]

When a driver is probed through __driver_attach(), the bus' match() callback is called without the device lock held, thus accessing the driver_override field without a lock, which can cause a UAF.

Fix this by using the driver-core driver_override infrastructure taking care of proper locking internally.

Note that calling match() from __driver_attach() without the device lock held is intentional. [1]

---
 drivers/bus/fsl-mc/fsl-mc-bus.c   | 43 +++++--------------------------
 drivers/vfio/fsl-mc/vfio_fsl_mc.c |  4 +--
 include/linux/fsl/mc.h            |  4 ---
 3 files changed, 8 insertions(+), 43 deletions(-)
drivers/bus/fsl-mc/fsl-mc-bus.c +7 -36
index 5543ba93e5017..2810f3b6e2f6c 100644
@@ -86,12 +86,16 @@ static int fsl_mc_bus_match(struct device *dev, const struct device_driver *drv)
 	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
 	const struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv);
 	bool found = false;
+	int ret;
 
 	/* When driver_override is set, only bind to the matching driver */
-	if (mc_dev->driver_override) {
-		found = !strcmp(mc_dev->driver_override, mc_drv->driver.name);
+	ret = device_match_driver_override(dev, drv);
+	if (ret > 0) {
+		found = true;
 		goto out;
 	}
+	if (ret == 0)
+		goto out;
 
 	if (!mc_drv->match_id_table)
 		goto out;
@@ -180,39 +184,8 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR_RO(modalias);
 
-static ssize_t driver_override_store(struct device *dev,
-				     struct device_attribute *attr,
-				     const char *buf, size_t count)
-{
-	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
-	int ret;
-
-	if (WARN_ON(dev->bus != &fsl_mc_bus_type))
-		return -EINVAL;
-
-	ret = driver_set_override(dev, &mc_dev->driver_override, buf, count);
-	if (ret)
-		return ret;
-
-	return count;
-}
-
-static ssize_t driver_override_show(struct device *dev,
-				    struct device_attribute *attr, char *buf)
-{
-	struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
-	ssize_t len;
-
-	device_lock(dev);
-	len = sysfs_emit(buf, "%s\n", mc_dev->driver_override);
-	device_unlock(dev);
-	return len;
-}
-static DEVICE_ATTR_RW(driver_override);
-
 static struct attribute *fsl_mc_dev_attrs[] = {
 	&dev_attr_modalias.attr,
-	&dev_attr_driver_override.attr,
 	NULL,
 };
 
@@ -315,6 +288,7 @@ ATTRIBUTE_GROUPS(fsl_mc_bus);
 
 const struct bus_type fsl_mc_bus_type = {
 	.name = "fsl-mc",
+	.driver_override = true,
 	.match = fsl_mc_bus_match,
 	.uevent = fsl_mc_bus_uevent,
 	.dma_configure  = fsl_mc_dma_configure,
@@ -924,9 +898,6 @@ static struct notifier_block fsl_mc_nb;
  */
 void fsl_mc_device_remove(struct fsl_mc_device *mc_dev)
 {
-	kfree(mc_dev->driver_override);
-	mc_dev->driver_override = NULL;
-
 	/*
 	 * The device-specific remove callback will get invoked by device_del()
 	 */
drivers/vfio/fsl-mc/vfio_fsl_mc.c +1 -3
index f65d91c01f2ec..03600872c4809 100644
@@ -430,9 +430,7 @@ static int vfio_fsl_mc_bus_notifier(struct notifier_block *nb,
 
 	if (action == BUS_NOTIFY_ADD_DEVICE &&
 	    vdev->mc_dev == mc_cont) {
-		mc_dev->driver_override = kasprintf(GFP_KERNEL, "%s",
-						    vfio_fsl_mc_ops.name);
-		if (!mc_dev->driver_override)
+		if (device_set_driver_override(dev, vfio_fsl_mc_ops.name))
 			dev_warn(dev, "VFIO_FSL_MC: Setting driver override for device in dprc %s failed\n",
 				 dev_name(&mc_cont->dev));
 		else
include/linux/fsl/mc.h +0 -4
index c90ec889bfc26..b5f64a9046891 100644
@@ -178,9 +178,6 @@ struct fsl_mc_obj_desc {
  * @regions: pointer to array of MMIO region entries
  * @irqs: pointer to array of pointers to interrupts allocated to this device
  * @resource: generic resource associated with this MC object device, if any.
- * @driver_override: driver name to force a match; do not set directly,
- *                   because core frees it; use driver_set_override() to
- *                   set or clear it.
  *
  * Generic device object for MC object devices that are "attached" to a
  * MC bus.
@@ -214,7 +211,6 @@ struct fsl_mc_device {
 	struct fsl_mc_device_irq **irqs;
 	struct fsl_mc_resource *resource;
 	struct device_link *consumer_link;
-	const char *driver_override;
 };
 
 #define to_fsl_mc_device(_dev) \
Signature · 1 line
2.53.0
author maintainer
#28 lore raw

PATCH 26/666 irqchip/irq-pic32-evic: Address warning related to wrong printf() formatter

In reply to Greg Kroah-Hartman

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

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

From: Brian Masney <[email protected]>

[ Upstream commit 86be659415b0ddefebc3120e309091aa215a9064 ]

This driver is currently only build on 32 bit MIPS systems. When building it on x86_64, the following warning occurs:

drivers/irqchip/irq-pic32-evic.c: In function ‘pic32_ext_irq_of_init’:
./include/linux/kern_levels.h:5:25: error: format ‘%d’ expects argument of type
‘int’, but argument 2 has type ‘long unsigned int’ [-Werror=format=]

Update the printf() formatter in preparation for allowing this driver to be compiled on all architectures.

Fixes aaa8666ada780 ("IRQCHIP: irq-pic32-evic: Add support for PIC32 interrupt controller")
---
 drivers/irqchip/irq-pic32-evic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/irqchip/irq-pic32-evic.c +1 -1
index eb6ca516a1664..9b309d8ec20c3 100644
@@ -196,7 +196,7 @@ static void __init pic32_ext_irq_of_init(struct irq_domain *domain)
 
 	of_property_for_each_u32(node, pname, hwirq) {
 		if (i >= ARRAY_SIZE(priv->ext_irqs)) {
-			pr_warn("More than %d external irq, skip rest\n",
+			pr_warn("More than %zu external irq, skip rest\n",
 				ARRAY_SIZE(priv->ext_irqs));
 			break;
 		}
Signature · 1 line
2.53.0
author maintainer
#29 lore raw

PATCH 27/666 hrtimers: Update the return type of enqueue_hrtimer()

In reply to Greg Kroah-Hartman

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

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

From: Richard Clark <[email protected]>

[ Upstream commit da7100d3bf7d6f5c49ef493ea963766898e9b069 ]

The return type should be 'bool' instead of 'int' according to the calling context in the kernel, and its internal implementation, i.e. :

	return timerqueue_add();

which is a bool-return function.

[ tglx: Adjust function arguments ]

Stable-dep-of: f2e388a019e4 ("hrtimer: Reduce trace noise in hrtimer_start()")

---
 kernel/time/hrtimer.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
kernel/time/hrtimer.c +3 -4
index 640d2ea4bd1fa..6abd0d2807f5d 100644
@@ -1091,11 +1091,10 @@ EXPORT_SYMBOL_GPL(hrtimer_forward);
  * The timer is inserted in expiry order. Insertion into the
  * red black tree is O(log(n)). Must hold the base lock.
  *
- * Returns 1 when the new timer is the leftmost timer in the tree.
+ * Returns true when the new timer is the leftmost timer in the tree.
  */
-static int enqueue_hrtimer(struct hrtimer *timer,
-			   struct hrtimer_clock_base *base,
-			   enum hrtimer_mode mode)
+static bool enqueue_hrtimer(struct hrtimer *timer, struct hrtimer_clock_base *base,
+			    enum hrtimer_mode mode)
 {
 	debug_activate(timer, mode);
 	WARN_ON_ONCE(!base->cpu_base->online);
Signature · 1 line
2.53.0
author maintainer
#30 lore raw

PATCH 28/666 hrtimer: Avoid pointless reprogramming in __hrtimer_start_range_ns()

In reply to Greg Kroah-Hartman

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

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

From: Peter Zijlstra <[email protected]>

[ Upstream commit d19ff16c11db38f3ee179d72751fb9b340174330 ]

Much like hrtimer_reprogram(), skip programming if the cpu_base is running the hrtimer interrupt.

Stable-dep-of: f2e388a019e4 ("hrtimer: Reduce trace noise in hrtimer_start()")

---
 kernel/time/hrtimer.c | 8 ++++++++
 1 file changed, 8 insertions(+)
kernel/time/hrtimer.c +8 -0
index 6abd0d2807f5d..343c7e4008aba 100644
@@ -1279,6 +1279,14 @@ static int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
 	}
 
 	first = enqueue_hrtimer(timer, new_base, mode);
+
+	/*
+	 * If the hrtimer interrupt is running, then it will reevaluate the
+	 * clock bases and reprogram the clock event device.
+	 */
+	if (new_base->cpu_base->in_hrtirq)
+		return false;
+
 	if (!force_local) {
 		/*
 		 * If the current CPU base is online, then the timer is
Signature · 1 line
2.53.0
author maintainer
#31 lore raw

PATCH 29/666 hrtimer: Reduce trace noise in hrtimer_start()

In reply to Greg Kroah-Hartman

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

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

From: Thomas Gleixner <[email protected]>

[ Upstream commit f2e388a019e4cf83a15883a3d1f1384298e9a6aa ]

hrtimer_start() when invoked with an already armed timer traces like:

<comm>-.. [032] d.h2. 5.002263: hrtimer_cancel: hrtimer= ....
<comm>-.. [032] d.h1. 5.002263: hrtimer_start: hrtimer= ....

Which is incorrect as the timer doesn't get canceled. Just the expiry time changes. The internal dequeue operation which is required for that is not really interesting for trace analysis. But it makes it tedious to keep real cancellations and the above case apart.

Remove the cancel tracing in hrtimer_start() and add a 'was_armed' indicator to the hrtimer start tracepoint, which clearly indicates what the state of the hrtimer is when hrtimer_start() is invoked:

<comm>-.. [032] d.h1. 6.200103: hrtimer_start: hrtimer= .... was_armed=0
<comm>-.. [032] d.h1. 6.200558: hrtimer_start: hrtimer= .... was_armed=1

---
 include/trace/events/timer.h | 11 +++++----
 kernel/time/hrtimer.c        | 43 +++++++++++++++++-------------------
 2 files changed, 27 insertions(+), 27 deletions(-)
include/trace/events/timer.h +7 -4
index 1ef58a04fc579..19c975ffea176 100644
@@ -218,12 +218,13 @@ TRACE_EVENT(hrtimer_init,
  * hrtimer_start - called when the hrtimer is started
  * @hrtimer:	pointer to struct hrtimer
  * @mode:	the hrtimers mode
+ * @was_armed:	Was armed when hrtimer_start*() was invoked
  */
 TRACE_EVENT(hrtimer_start,
 
-	TP_PROTO(struct hrtimer *hrtimer, enum hrtimer_mode mode),
+	TP_PROTO(struct hrtimer *hrtimer, enum hrtimer_mode mode, bool was_armed),
 
-	TP_ARGS(hrtimer, mode),
+	TP_ARGS(hrtimer, mode, was_armed),
 
 	TP_STRUCT__entry(
 		__field( void *,	hrtimer		)
@@ -231,6 +232,7 @@ TRACE_EVENT(hrtimer_start,
 		__field( s64,		expires		)
 		__field( s64,		softexpires	)
 		__field( enum hrtimer_mode,	mode	)
+		__field( bool,		was_armed	)
 	),
 
 	TP_fast_assign(
@@ -239,13 +241,14 @@ TRACE_EVENT(hrtimer_start,
 		__entry->expires	= hrtimer_get_expires(hrtimer);
 		__entry->softexpires	= hrtimer_get_softexpires(hrtimer);
 		__entry->mode		= mode;
+		__entry->was_armed	= was_armed;
 	),
 
 	TP_printk("hrtimer=%p function=%ps expires=%llu softexpires=%llu "
-		  "mode=%s", __entry->hrtimer, __entry->function,
+		  "mode=%s was_armed=%d", __entry->hrtimer, __entry->function,
 		  (unsigned long long) __entry->expires,
 		  (unsigned long long) __entry->softexpires,
-		  decode_hrtimer_mode(__entry->mode))
+		  decode_hrtimer_mode(__entry->mode), __entry->was_armed)
 );
 
 /**
kernel/time/hrtimer.c +20 -23

117 lines not on this page · raw message

Signature · 1 line
2.53.0
author maintainer
#32 lore raw

PATCH 30/666 sparc/vdso: Always reject undefined references during linking

In reply to Greg Kroah-Hartman

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

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

From: Thomas Weißschuh <[email protected]>

[ Upstream commit 652262975db421767ada3f05b926854bbb357759 ]

Instead of using a custom script to detect and fail on undefined references, use --no-undefined for all VDSO linker invocations.

Drop the now unused checkundef.sh script.

Stable-dep-of: acc4f131d5d5 ("sparc64: vdso: Link with -z noexecstack")

---
 arch/sparc/vdso/Makefile      |  7 +++----
 arch/sparc/vdso/checkundef.sh | 10 ----------
 2 files changed, 3 insertions(+), 14 deletions(-)
 delete mode 100644 arch/sparc/vdso/checkundef.sh
arch/sparc/vdso/Makefile +3 -4
index 243dbfc4609d8..c7697884975ea 100644
@@ -22,7 +22,7 @@ targets += $(foreach x, 32 64, vdso-image-$(x).c vdso$(x).so vdso$(x).so.dbg)
 
 CPPFLAGS_vdso.lds += -P -C
 
-VDSO_LDFLAGS_vdso.lds = -m elf64_sparc -soname linux-vdso.so.1 --no-undefined \
+VDSO_LDFLAGS_vdso.lds = -m elf64_sparc -soname linux-vdso.so.1 \
 			-z max-page-size=8192
 
 $(obj)/vdso64.so.dbg: $(obj)/vdso.lds $(vobjs) FORCE
@@ -101,7 +101,6 @@ $(obj)/vdso32.so.dbg: FORCE \
 quiet_cmd_vdso = VDSO    $@
       cmd_vdso = $(LD) -nostdlib -o $@ \
 		       $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
-		       -T $(filter %.lds,$^) $(filter %.o,$^) && \
-		sh $(src)/checkundef.sh '$(OBJDUMP)' '$@'
+		       -T $(filter %.lds,$^) $(filter %.o,$^)
 
-VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 -Bsymbolic
+VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 -Bsymbolic --no-undefined
arch/sparc/vdso/checkundef.sh deleted +0 -10
deleted file mode 100644
index 2d85876ffc325..0000000000000
@@ -1,10 +0,0 @@
-#!/bin/sh
-objdump="$1"
-file="$2"
-$objdump -t "$file" | grep '*UUND*' | grep -v '#scratch' > /dev/null 2>&1
-if [ $? -eq 1 ]; then
-    exit 0
-else
-    echo "$file: undefined symbols found" >&2
-    exit 1
-fi
Signature · 1 line
2.53.0
author maintainer
#33 lore raw

PATCH 31/666 sparc64: vdso: Link with -z noexecstack

In reply to Greg Kroah-Hartman

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

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

From: Thomas Weißschuh <[email protected]>

[ Upstream commit acc4f131d5d57c2aa89db914aeb6f7bb0ab4eb4a ]

The vDSO stack does not need to be executable. Prevent the linker from creating executable. For more background see commit ffcf9c5700e4 ("x86:
link vdso and boot with -z noexecstack --no-warn-rwx-segments").

Also prevent the following warning from the linker:
sparc64-linux-ld: warning: arch/sparc/vdso/vdso-note.o: missing .note.GNU-stack section implies executable stack
sparc64-linux-ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker

---
 arch/sparc/vdso/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/sparc/vdso/Makefile +1 -1
index c7697884975ea..fc3ada4269f1a 100644
@@ -103,4 +103,4 @@ quiet_cmd_vdso = VDSO    $@
 		       $(VDSO_LDFLAGS) $(VDSO_LDFLAGS_$(filter %.lds,$(^F))) \
 		       -T $(filter %.lds,$^) $(filter %.o,$^)
 
-VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 -Bsymbolic --no-undefined
+VDSO_LDFLAGS = -shared --hash-style=both --build-id=sha1 -Bsymbolic --no-undefined -z noexecstack
Signature · 1 line
2.53.0
author maintainer
#34 lore raw

PATCH 32/666 locking: Fix rwlock support in <linux/spinlock_up.h>

In reply to Greg Kroah-Hartman

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

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

From: Bart Van Assche <[email protected]>

[ Upstream commit 756a0e011cfca0b45a48464aa25b05d9a9c2fb0b ]

Architecture support for rwlocks must be available whether or not CONFIG_DEBUG_SPINLOCK has been defined. Move the definitions of the arch_{read,write}_{lock,trylock,unlock}() macros such that these become visbile if CONFIG_DEBUG_SPINLOCK=n.

This patch prepares for converting do_raw_{read,write}_trylock() into inline functions. Without this patch that conversion triggers a build failure for UP architectures, e.g. arm-ep93xx. I used the following kernel configuration to build the kernel for that architecture:

CONFIG_ARCH_MULTIPLATFORM=y
CONFIG_ARCH_MULTI_V7=n
CONFIG_ATAGS=y
CONFIG_MMU=y
CONFIG_ARCH_MULTI_V4T=y
CONFIG_CPU_LITTLE_ENDIAN=y
CONFIG_ARCH_EP93XX=y

---
 include/linux/spinlock_up.h | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)
include/linux/spinlock_up.h +10 -10
index c87204247592f..a132fc562297a 100644
@@ -48,16 +48,6 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 	lock->slock = 1;
 }
 
-/*
- * Read-write spinlocks. No debug version.
- */
-#define arch_read_lock(lock)		do { barrier(); (void)(lock); } while (0)
-#define arch_write_lock(lock)		do { barrier(); (void)(lock); } while (0)
-#define arch_read_trylock(lock)	({ barrier(); (void)(lock); 1; })
-#define arch_write_trylock(lock)	({ barrier(); (void)(lock); 1; })
-#define arch_read_unlock(lock)		do { barrier(); (void)(lock); } while (0)
-#define arch_write_unlock(lock)	do { barrier(); (void)(lock); } while (0)
-
 #else /* DEBUG_SPINLOCK */
 #define arch_spin_is_locked(lock)	((void)(lock), 0)
 /* for sched/core.c and kernel_lock.c: */
@@ -68,4 +58,14 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
 
 #define arch_spin_is_contended(lock)	(((void)(lock), 0))
 
+/*
+ * Read-write spinlocks. No debug version.
+ */
+#define arch_read_lock(lock)		do { barrier(); (void)(lock); } while (0)
+#define arch_write_lock(lock)		do { barrier(); (void)(lock); } while (0)
+#define arch_read_trylock(lock)	({ barrier(); (void)(lock); 1; })
+#define arch_write_trylock(lock)	({ barrier(); (void)(lock); 1; })
+#define arch_read_unlock(lock)		do { barrier(); (void)(lock); } while (0)
+#define arch_write_unlock(lock)	do { barrier(); (void)(lock); } while (0)
+
 #endif /* __LINUX_SPINLOCK_UP_H */
Signature · 1 line
2.53.0
author maintainer
#35 lore raw

PATCH 33/666 firmware: dmi: Correct an indexing error in dmi.h

In reply to Greg Kroah-Hartman

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

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

From: Mario Limonciello (AMD) <[email protected]>

[ Upstream commit c064abc68e009d2cc18416e7132d9c25e03125b6 ]

The entries later in enum dmi_entry_type don't match the SMBIOS specification¹.

The entry for type 33: 64-Bit Memory Error Information is not present and thus the index for all later entries is incorrect.

Add it.

Also, add missing entry types 43-46, while at it.

¹ Search for "System Management BIOS (SMBIOS) Reference Specification"

[ bp: Drop the flaky SMBIOS spec URL. ]

---
 include/linux/dmi.h | 5 +++++
 1 file changed, 5 insertions(+)
include/linux/dmi.h +5 -0
index 927f8a8b7a1dd..2eedf44e68012 100644
@@ -60,6 +60,7 @@ enum dmi_entry_type {
 	DMI_ENTRY_OOB_REMOTE_ACCESS,
 	DMI_ENTRY_BIS_ENTRY,
 	DMI_ENTRY_SYSTEM_BOOT,
+	DMI_ENTRY_64_MEM_ERROR,
 	DMI_ENTRY_MGMT_DEV,
 	DMI_ENTRY_MGMT_DEV_COMPONENT,
 	DMI_ENTRY_MGMT_DEV_THRES,
@@ -69,6 +70,10 @@ enum dmi_entry_type {
 	DMI_ENTRY_ADDITIONAL,
 	DMI_ENTRY_ONBOARD_DEV_EXT,
 	DMI_ENTRY_MGMT_CONTROLLER_HOST,
+	DMI_ENTRY_TPM_DEVICE,
+	DMI_ENTRY_PROCESSOR_ADDITIONAL,
+	DMI_ENTRY_FIRMWARE_INVENTORY,
+	DMI_ENTRY_STRING_PROPERTY,
 	DMI_ENTRY_INACTIVE = 126,
 	DMI_ENTRY_END_OF_TABLE = 127,
 };
Signature · 1 line
2.53.0
author maintainer
#36 lore raw

PATCH 34/666 wifi: mwifiex: Fix memory leak in mwifiex_11n_aggregate_pkt()

In reply to Greg Kroah-Hartman

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

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

From: Zilin Guan <[email protected]>

[ Upstream commit 990a73dec3fdc145fef6c827c29205437d533ece ]

In mwifiex_11n_aggregate_pkt(), skb_aggr is allocated via mwifiex_alloc_dma_align_buf(). If mwifiex_is_ralist_valid() returns false, the function currently returns -1 immediately without freeing the previously allocated skb_aggr, causing a memory leak.

Since skb_aggr has not yet been queued via skb_queue_tail(), no other references to this memory exist. Therefore, it has to be freed locally before returning the error.

Fix this by calling mwifiex_write_data_complete() to free skb_aggr before returning the error status.

Compile tested only. Issue found using a prototype static analysis tool and code review.

Fixes 5e6e3a92b9a4 ("wireless: mwifiex: initial commit for Marvell mwifiex driver")
---
 drivers/net/wireless/marvell/mwifiex/11n_aggr.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/marvell/mwifiex/11n_aggr.c +1 -0
index 34b4b34276d6d..042b1fe5f0d67 100644
@@ -203,6 +203,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
 
 		if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
 			spin_unlock_bh(&priv->wmm.ra_list_spinlock);
+			mwifiex_write_data_complete(adapter, skb_aggr, 1, -1);
 			return -1;
 		}
 
Signature · 1 line
2.53.0
author maintainer
#37 lore raw

PATCH 35/666 wifi: rtlwifi: pci: fix possible use-after-free caused by unfinished irq_prepare_bcn_tasklet

In reply to Greg Kroah-Hartman

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

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

From: Duoming Zhou <[email protected]>

[ Upstream commit 039cd522dc70151da13329a5e3ae19b1736f468a ]

The irq_prepare_bcn_tasklet is initialized in rtl_pci_init() and scheduled when RTL_IMR_BCNINT interrupt is triggered by hardware. But it is never killed in rtl_pci_deinit(). When the rtlwifi card probe fails or is being detached, the ieee80211_hw is deallocated. However, irq_prepare_bcn_tasklet may still be running or pending, leading to use-after-free when the freed ieee80211_hw is accessed in _rtl_pci_prepare_bcn_tasklet().

Similar to irq_tasklet, add tasklet_kill() in rtl_pci_deinit() to ensure that irq_prepare_bcn_tasklet is properly terminated before the ieee80211_hw is released.

The issue was identified through static analysis.

---
 drivers/net/wireless/realtek/rtlwifi/pci.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/realtek/rtlwifi/pci.c +1 -0
index d080469264cf8..f0010336e78c1 100644
@@ -1674,6 +1674,7 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw)
 
 	synchronize_irq(rtlpci->pdev->irq);
 	tasklet_kill(&rtlpriv->works.irq_tasklet);
+	tasklet_kill(&rtlpriv->works.irq_prepare_bcn_tasklet);
 	cancel_work_sync(&rtlpriv->works.lps_change_work);
 }
 
Signature · 1 line
2.53.0
author maintainer
#38 lore raw

PATCH 36/666 bpf: test_run: Fix the null pointer dereference issue in bpf_lwt_xmit_push_encap

In reply to Greg Kroah-Hartman

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

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

From: Feng Yang <[email protected]>

[ Upstream commit 972787479ee73006fddb5e59ab5c8e733810ff42 ]

The bpf_lwt_xmit_push_encap helper needs to access skb_dst(skb)->dev to calculate the needed headroom:

	err = skb_cow_head(skb,
			   len + LL_RESERVED_SPACE(skb_dst(skb)->dev));

But skb->_skb_refdst may not be initialized when the skb is set up by bpf_prog_test_run_skb function. Executing bpf_lwt_push_ip_encap function in this scenario will trigger null pointer dereference, causing a kernel crash as Yinhao reported:

[  105.186365] BUG: kernel NULL pointer dereference, address: 0000000000000000
[  105.186382] #PF: supervisor read access in kernel mode
[  105.186388] #PF: error_code(0x0000) - not-present page
[  105.186393] PGD 121d3d067 P4D 121d3d067 PUD 106c83067 PMD 0
[  105.186404] Oops: 0000 [#1] PREEMPT SMP NOPTI
[  105.186412] CPU: 3 PID: 3250 Comm: poc Kdump: loaded Not tainted 6.19.0-rc5 #1
[  105.186423] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[  105.186427] RIP: 0010:bpf_lwt_push_ip_encap+0x1eb/0x520
[  105.186443] Code: 0f 84 de 01 00 00 0f b7 4a 04 66 85 c9 0f 85 47 01 00 00 31 c0 5b 5d 41 5c 41 5d 41 5e c3 cc cc cc cc 48 8b 73 58 48 83 e6 fe <48> 8b 36 0f b7 be ec 00 00 00 0f b7 b6 e6 00 00 00 01 fe 83 e6 f0
[  105.186449] RSP: 0018:ffffbb0e0387bc50 EFLAGS: 00010246
[  105.186455] RAX: 000000000000004e RBX: ffff94c74e036500 RCX: ffff94c74874da00
[  105.186460] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff94c74e036500
[  105.186463] RBP: 0000000000000001 R08: 0000000000000002 R09: 0000000000000000
[  105.186467] R10: ffffbb0e0387bd50 R11: 0000000000000000 R12: ffffbb0e0387bc98
[  105.186471] R13: 0000000000000014 R14: 0000000000000000 R15: 0000000000000002
[  105.186484] FS:  00007f166aa4d680(0000) GS:ffff94c8b7780000(0000) knlGS:0000000000000000
[  105.186490] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  105.186494] CR2: 0000000000000000 CR3: 000000015eade001 CR4: 0000000000770ee0
[  105.186499] PKRU: 55555554
[  105.186502] Call Trace:
[  105.186507]  <TASK>
[  105.186513]  bpf_lwt_xmit_push_encap+0x2b/0x40
[  105.186522]  bpf_prog_a75eaad51e517912+0x41/0x49
[  105.186536]  ? kvm_clock_get_cycles+0x18/0x30
[  105.186547]  ? ktime_get+0x3c/0xa0
[  105.186554]  bpf_test_run+0x195/0x320
[  105.186563]  ? bpf_test_run+0x10f/0x320
[  105.186579]  bpf_prog_test_run_skb+0x2f5/0x4f0
[  105.186590]  __sys_bpf+0x69c/0xa40
[  105.186603]  __x64_sys_bpf+0x1e/0x30
[  105.186611]  do_syscall_64+0x59/0x110
[  105.186620]  entry_SYSCALL_64_after_hwframe+0x76/0xe0
[  105.186649] RIP: 0033:0x7f166a97455d

Temporarily add the setting of skb->_skb_refdst before bpf_test_run to resolve the issue.

---
 net/bpf/test_run.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
net/bpf/test_run.c +15 -0
index c885a3942a161..18257cf6bb488 100644
@@ -1097,6 +1097,21 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
 		skb->ip_summed = CHECKSUM_COMPLETE;
 	}
 
+	if (prog->type == BPF_PROG_TYPE_LWT_XMIT) {
+		if (!ipv6_bpf_stub) {
+			pr_warn_once("Please test this program with the IPv6 module loaded\n");
+			ret = -EOPNOTSUPP;
+			goto out;
+		}
+#if IS_ENABLED(CONFIG_IPV6)
+		/* For CONFIG_IPV6=n, ipv6_bpf_stub is NULL which is
+		 * handled by the above if statement.
+		 */
+		dst_hold(&net->ipv6.ip6_null_entry->dst);
+		skb_dst_set(skb, &net->ipv6.ip6_null_entry->dst);
+#endif
+	}
+
 	ret = bpf_test_run(prog, skb, repeat, &retval, &duration, false);
 	if (ret)
 		goto out;
Signature · 1 line
2.53.0
author maintainer
#39 lore raw

PATCH 37/666 dpaa2: add independent dependencies for FSL_DPAA2_SWITCH

In reply to Greg Kroah-Hartman

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

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

From: Cai Xinchen <[email protected]>

[ Upstream commit 12589892f41c4c645c80ef9f036f7451a6045624 ]

Since the commit 84cba72956fd ("dpaa2-switch: integrate the MAC endpoint support") included dpaa2-mac.o in the driver, but it didn't select PCS_LYNX, PHYLINK and FSL_XGMAC_MDIO. it will lead to link error, such as
undefined reference to phylink_ethtool_ksettings_set' undefined reference to lynx_pcs_create_fwnode'

And the same reason as the commit d2624e70a2f53 ("dpaa2-eth: select XGMAC_MDIO for MDIO bus support"), enable the FSL_XGMAC_MDIO Kconfig option in order to have MDIO access to internal and external PHYs.

Because dpaa2-switch uses fsl_mc_driver APIs, add depends on FSL_MC_BUS && FSL_MC_DPIO as FSL_DPAA2_SWITCH do.

FSL_XGMAC_MDIO and FSL_MC_BUS depend on OF, thus the dependence of FSL_MC_BUS can satisfy FSL_XGMAC_MDIO's OF requirement.

Fixes 84cba72956fd ("dpaa2-switch: integrate the MAC endpoint support")
---
 drivers/net/ethernet/freescale/dpaa2/Kconfig | 4 ++++
 1 file changed, 4 insertions(+)
drivers/net/ethernet/freescale/dpaa2/Kconfig +4 -0
index d029b69c3f183..36280e5d99e1f 100644
@@ -34,6 +34,10 @@ config FSL_DPAA2_SWITCH
 	tristate "Freescale DPAA2 Ethernet Switch"
 	depends on BRIDGE || BRIDGE=n
 	depends on NET_SWITCHDEV
+	depends on FSL_MC_BUS && FSL_MC_DPIO
+	select PHYLINK
+	select PCS_LYNX
+	select FSL_XGMAC_MDIO
 	help
 	  Driver for Freescale DPAA2 Ethernet Switch. This driver manages
 	  switch objects discovered on the Freeescale MC bus.
Signature · 1 line
2.53.0
author maintainer
#40 lore raw

PATCH 38/666 dpaa2: compile dpaa2 even CONFIG_FSL_DPAA2_ETH=n

In reply to Greg Kroah-Hartman

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

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

From: Cai Xinchen <[email protected]>

[ Upstream commit 97daf00745f7f9f261b0e91418de6e79d7826c36 ]

CONFIG_FSL_DPAA2_ETH and CONFIG_FSL_DPAA2_SWITCH are not associated, but the compilation of FSL_DPAA2_SWITCH depends on the compilation of the dpaa2 folder. The files controlled by CONFIG_FSL_DPAA2_SWITCH in the dpaa2 folder are not controlled by CONFIG_FSL_DPAA2_ETH, except for the files controlled by CONFIG_FSL_DPAA2_SWITCH. Therefore, removing the restriction will not affect the compilation of the files in the directory.

Fixes f48298d3fbfaa ("staging: dpaa2-switch: move the driver out of staging")
---
 drivers/net/ethernet/freescale/Makefile | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/net/ethernet/freescale/Makefile +1 -2
index de7b318422330..d0a259e47960f 100644
@@ -22,6 +22,5 @@ ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
 obj-$(CONFIG_FSL_FMAN) += fman/
 obj-$(CONFIG_FSL_DPAA_ETH) += dpaa/
 
-obj-$(CONFIG_FSL_DPAA2_ETH) += dpaa2/
-
+obj-y += dpaa2/
 obj-y += enetc/
Signature · 1 line
2.53.0
author maintainer
#41 lore raw

PATCH 39/666 s390/bpf: Zero-extend bpf prog return values and kfunc arguments

In reply to Greg Kroah-Hartman

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

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

From: Ilya Leoshkevich <[email protected]>

[ Upstream commit 202e42e4aa890172366354b233c42c73107a3f59 ]

s390x ABI requires callers to zero-extend unsigned arguments and sign-extend signed arguments, and callees to zero-extend unsigned return values and sign-extend signed return values.

s390 BPF JIT currently implements only sign extension. Fix this omission and implement zero extension too.

---
 arch/s390/net/bpf_jit_comp.c | 39 ++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 15 deletions(-)
arch/s390/net/bpf_jit_comp.c +24 -15
index f305cb42070df..c3ad3cf86ca64 100644
@@ -842,25 +842,34 @@ static int bpf_jit_probe_post(struct bpf_jit *jit, struct bpf_prog *fp,
 }
 
 /*
- * Sign-extend the register if necessary
+ * Sign- or zero-extend the register if necessary
  */
-static int sign_extend(struct bpf_jit *jit, int r, u8 size, u8 flags)
+static int sign_zero_extend(struct bpf_jit *jit, int r, u8 size, u8 flags)
 {
-	if (!(flags & BTF_FMODEL_SIGNED_ARG))
-		return 0;
-
 	switch (size) {
 	case 1:
-		/* lgbr %r,%r */
-		EMIT4(0xb9060000, r, r);
+		if (flags & BTF_FMODEL_SIGNED_ARG)
+			/* lgbr %r,%r */
+			EMIT4(0xb9060000, r, r);
+		else
+			/* llgcr %r,%r */
+			EMIT4(0xb9840000, r, r);
 		return 0;
 	case 2:
-		/* lghr %r,%r */
-		EMIT4(0xb9070000, r, r);
+		if (flags & BTF_FMODEL_SIGNED_ARG)
+			/* lghr %r,%r */
+			EMIT4(0xb9070000, r, r);
+		else
+			/* llghr %r,%r */
+			EMIT4(0xb9850000, r, r);
 		return 0;
 	case 4:
-		/* lgfr %r,%r */
-		EMIT4(0xb9140000, r, r);
+		if (flags & BTF_FMODEL_SIGNED_ARG)
+			/* lgfr %r,%r */
+			EMIT4(0xb9140000, r, r);
+		else
+			/* llgfr %r,%r */
+			EMIT4(0xb9160000, r, r);
 		return 0;
 	case 8:
 		return 0;
@@ -1802,9 +1811,9 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
 				return -1;
 
 			for (j = 0; j < m->nr_args; j++) {
-				if (sign_extend(jit, BPF_REG_1 + j,
-						m->arg_size[j],
-						m->arg_flags[j]))
+				if (sign_zero_extend(jit, BPF_REG_1 + j,
+						     m->arg_size[j],
+						     m->arg_flags[j]))
 					return -1;
 			}
 		}
@@ -2551,7 +2560,7 @@ static int invoke_bpf_prog(struct bpf_tramp_jit *tjit,
 	call_r1(jit);
 	/* stg %r2,retval_off(%r15) */
 	if (save_ret) {
-		if (sign_extend(jit, REG_2, m->ret_size, m->ret_flags))
+		if (sign_zero_extend(jit, REG_2, m->ret_size, m->ret_flags))
 			return -1;
 		EMIT6_DISP_LH(0xe3000000, 0x0024, REG_2, REG_0, REG_15,
 			      tjit->retval_off);
Signature · 1 line
2.53.0
author maintainer
#42 lore raw

PATCH 40/666 params: Replace __modinit with __init_or_module

In reply to Greg Kroah-Hartman

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

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

From: Petr Pavlu <[email protected]>

[ Upstream commit 3cb0c3bdea5388519bc1bf575dca6421b133302b ]

Remove the custom __modinit macro from kernel/params.c and instead use the common __init_or_module macro from include/linux/module.h. Both provide the same functionality.

Stable-dep-of: deffe1edba62 ("module: Fix freeing of charp module parameters when CONFIG_SYSFS=n")

---
 kernel/params.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)
kernel/params.c +5 -10
index 9935ff599356b..2be5a083f9399 100644
@@ -595,12 +595,6 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
 }
 #endif
 
-#ifdef CONFIG_MODULES
-#define __modinit
-#else
-#define __modinit __init
-#endif
-
 #ifdef CONFIG_SYSFS
 void kernel_param_lock(struct module *mod)
 {
@@ -625,9 +619,9 @@ EXPORT_SYMBOL(kernel_param_unlock);
  * create file in sysfs.  Returns an error on out of memory.  Always cleans up
  * if there's an error.
  */
-static __modinit int add_sysfs_param(struct module_kobject *mk,
-				     const struct kernel_param *kp,
-				     const char *name)
+static __init_or_module int add_sysfs_param(struct module_kobject *mk,
+					    const struct kernel_param *kp,
+					    const char *name)
 {
 	struct module_param_attrs *new_mp;
 	struct attribute **new_attrs;
@@ -763,7 +757,8 @@ void destroy_params(const struct kernel_param *params, unsigned num)
 			params[i].ops->free(params[i].arg);
 }
 
-struct module_kobject __modinit * lookup_or_create_module_kobject(const char *name)
+struct module_kobject * __init_or_module
+lookup_or_create_module_kobject(const char *name)
 {
 	struct module_kobject *mk;
 	struct kobject *kobj;
Signature · 1 line
2.53.0
author maintainer
#43 lore raw

PATCH 41/666 module: Fix freeing of charp module parameters when CONFIG_SYSFS=n

In reply to Greg Kroah-Hartman

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

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

From: Petr Pavlu <[email protected]>

[ Upstream commit deffe1edba626d474fef38007c03646ca5876a0e ]

When setting a charp module parameter, the param_set_charp() function allocates memory to store a copy of the input value. Later, when the module is potentially unloaded, the destroy_params() function is called to free this allocated memory.

However, destroy_params() is available only when CONFIG_SYSFS=y, otherwise only a dummy variant is present. In the unlikely case that the kernel is configured with CONFIG_MODULES=y and CONFIG_SYSFS=n, this results in a memory leak of charp values when a module is unloaded.

Fix this issue by making destroy_params() always available when CONFIG_MODULES=y. Rename the function to module_destroy_params() to clarify that it is intended for use by the module loader.

Fixes e180a6b7759a ("param: fix charp parameters set via sysfs")
---
 include/linux/moduleparam.h | 11 +++--------
 kernel/module/main.c        |  4 ++--
 kernel/params.c             | 27 ++++++++++++++++++---------
 3 files changed, 23 insertions(+), 19 deletions(-)
include/linux/moduleparam.h +3 -8
index 110e9d09de243..4c0b436f2092a 100644
@@ -396,14 +396,9 @@ extern char *parse_args(const char *name,
 		      void *arg, parse_unknown_fn unknown);
 
 /* Called by module remove. */
-#ifdef CONFIG_SYSFS
-extern void destroy_params(const struct kernel_param *params, unsigned num);
-#else
-static inline void destroy_params(const struct kernel_param *params,
-				  unsigned num)
-{
-}
-#endif /* !CONFIG_SYSFS */
+#ifdef CONFIG_MODULES
+void module_destroy_params(const struct kernel_param *params, unsigned int num);
+#endif
 
 /* All the helper functions */
 /* The macros to do compile-time type checking stolen from Jakub
kernel/module/main.c +2 -2
index 915a9cf33dd0d..ad58c44fb74fd 100644
@@ -1286,7 +1286,7 @@ static void free_module(struct module *mod)
 	module_unload_free(mod);
 
 	/* Free any allocated parameters. */
-	destroy_params(mod->kp, mod->num_kp);
+	module_destroy_params(mod->kp, mod->num_kp);
 
 	if (is_livepatch_module(mod))
 		free_module_elf(mod);
@@ -3022,7 +3022,7 @@ static int load_module(struct load_info *info, const char __user *uargs,
 	mod_sysfs_teardown(mod);
  coming_cleanup:
 	mod->state = MODULE_STATE_GOING;
-	destroy_params(mod->kp, mod->num_kp);
+	module_destroy_params(mod->kp, mod->num_kp);
 	blocking_notifier_call_chain(&module_notify_list,
 				     MODULE_STATE_GOING, mod);
 	klp_module_going(mod);
kernel/params.c +18 -9
index 2be5a083f9399..4495038fc2e7e 100644
@@ -748,15 +748,6 @@ void module_param_sysfs_remove(struct module *mod)
 }
 #endif
 
-void destroy_params(const struct kernel_param *params, unsigned num)
-{
-	unsigned int i;
-
-	for (i = 0; i < num; i++)
-		if (params[i].ops->free)
-			params[i].ops->free(params[i].arg);
-}
-
 struct module_kobject * __init_or_module
 lookup_or_create_module_kobject(const char *name)
 {
@@ -991,3 +982,21 @@ static int __init param_sysfs_builtin_init(void)
 late_initcall(param_sysfs_builtin_init);
 
 #endif /* CONFIG_SYSFS */
+
+#ifdef CONFIG_MODULES
+
+/*
+ * module_destroy_params - free all parameters for one module
+ * @params: module parameters (array)
+ * @num: number of module parameters
+ */
+void module_destroy_params(const struct kernel_param *params, unsigned int num)
+{
+	unsigned int i;
+
+	for (i = 0; i < num; i++)
+		if (params[i].ops->free)
+			params[i].ops->free(params[i].arg);
+}
+
+#endif /* CONFIG_MODULES */
Signature · 1 line
2.53.0
author maintainer
#44 lore raw

PATCH 42/666 wifi: mt76: mt7921: Reset ampdu_state state in case of failure in mt76_connac2_tx_check_aggr()

In reply to Greg Kroah-Hartman

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

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

From: Sean Wang <[email protected]>

[ Upstream commit 53ffffeb9624ffab6d9a3b1da8635a23f1172b5e ]

Reset ampdu_state if ieee80211_start_tx_ba_session() fails in mt76_connac2_tx_check_aggr(), otherwise the driver may incorrectly assume aggregation is active and skip future BA setup attempts.

Fixes 163f4d22c118 ("mt76: mt7921: add MAC support")
---
 drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +4 -2
index 268f414f0a023..05f2ff8e012b5 100644
@@ -1135,8 +1135,10 @@ void mt76_connac2_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
 		return;
 
 	wcid = (struct mt76_wcid *)sta->drv_priv;
-	if (!test_and_set_bit(tid, &wcid->ampdu_state))
-		ieee80211_start_tx_ba_session(sta, tid, 0);
+	if (!test_and_set_bit(tid, &wcid->ampdu_state)) {
+		if (ieee80211_start_tx_ba_session(sta, tid, 0))
+			clear_bit(tid, &wcid->ampdu_state);
+	}
 }
 EXPORT_SYMBOL_GPL(mt76_connac2_tx_check_aggr);
 
Signature · 1 line
2.53.0
author maintainer
#45 lore raw

PATCH 43/666 wifi: mt76: mt7925: Fix incorrect MLO mode in firmware control

In reply to Greg Kroah-Hartman

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

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

From: Leon Yen <[email protected]>

[ Upstream commit 1695f662329faa07c860c73453c097823852df28 ]

The selection of MLO mode should depend on the capabilities of the STA rather than those of the peer AP to avoid compatibility issues with certain APs, such as Xiaomi BE5000 WiFi7 router.

Fixes 69acd6d910b0c ("wifi: mt76: mt7925: add mt7925_change_vif_links")
---
 drivers/net/wireless/mediatek/mt76/mt7925/main.c   | 2 +-
 drivers/net/wireless/mediatek/mt76/mt7925/mcu.c    | 9 ++++++---
 drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h | 4 ++--
 3 files changed, 9 insertions(+), 6 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7925/main.c +1 -1
index 59d4357819eda..5fc95c8623647 100644
@@ -535,7 +535,7 @@ static int mt7925_set_mlo_roc(struct mt792x_phy *phy,
 
 	phy->roc_grant = false;
 
-	err = mt7925_mcu_set_mlo_roc(mconf, sel_links, 5, ++phy->roc_token_id);
+	err = mt7925_mcu_set_mlo_roc(phy, mconf, sel_links, 5, ++phy->roc_token_id);
 	if (err < 0) {
 		clear_bit(MT76_STATE_ROC, &phy->mt76->state);
 		goto out;
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +6 -3
index 0e7ea02574de0..1f113a618515e 100644
@@ -1245,8 +1245,8 @@ int mt7925_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
 	return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true);
 }
 
-int mt7925_mcu_set_mlo_roc(struct mt792x_bss_conf *mconf, u16 sel_links,
-			   int duration, u8 token_id)
+int mt7925_mcu_set_mlo_roc(struct mt792x_phy *phy, struct mt792x_bss_conf *mconf,
+			   u16 sel_links, int duration, u8 token_id)
 {
 	struct mt792x_vif *mvif = mconf->vif;
 	struct ieee80211_vif *vif = container_of((void *)mvif,
@@ -1281,6 +1281,8 @@ int mt7925_mcu_set_mlo_roc(struct mt792x_bss_conf *mconf, u16 sel_links,
 			.roc[1].len = cpu_to_le16(sizeof(struct roc_acquire_tlv))
 	};
 
+	struct wiphy *wiphy = phy->mt76->hw->wiphy;
+
 	if (!mconf || hweight16(vif->valid_links) < 2 ||
 	    hweight16(sel_links) != 2)
 		return -EPERM;
@@ -1303,7 +1305,8 @@ int mt7925_mcu_set_mlo_roc(struct mt792x_bss_conf *mconf, u16 sel_links,
 		is_AG_band |= links[i].chan->band == NL80211_BAND_2GHZ;
 	}
 
-	if (vif->cfg.eml_cap & IEEE80211_EML_CAP_EMLSR_SUPP)
+	if (!(wiphy->iftype_ext_capab[0].mld_capa_and_ops &
+	      IEEE80211_MLD_CAP_OP_MAX_SIMUL_LINKS))
 		type = is_AG_band ? MT7925_ROC_REQ_MLSR_AG :
 				    MT7925_ROC_REQ_MLSR_AA;
 	else
drivers/net/wireless/mediatek/mt76/mt7925/mt7925.h +2 -2
index 27680ad28b600..bc8d38782a81a 100644
@@ -324,8 +324,8 @@ int mt7925_set_tx_sar_pwr(struct ieee80211_hw *hw,
 int mt7925_mcu_regval(struct mt792x_dev *dev, u32 regidx, u32 *val, bool set);
 int mt7925_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,
 		       enum environment_cap env_cap);
-int mt7925_mcu_set_mlo_roc(struct mt792x_bss_conf *mconf, u16 sel_links,
-			   int duration, u8 token_id);
+int mt7925_mcu_set_mlo_roc(struct mt792x_phy *phy, struct mt792x_bss_conf *mconf,
+			   u16 sel_links, int duration, u8 token_id);
 int mt7925_mcu_set_roc(struct mt792x_phy *phy, struct mt792x_bss_conf *mconf,
 		       struct ieee80211_channel *chan, int duration,
 		       enum mt7925_roc_req type, u8 token_id);
Signature · 1 line
2.53.0
author maintainer
#46 lore raw

PATCH 44/666 wifi: mt76: mt7615: fix use_cts_prot support

In reply to Greg Kroah-Hartman

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

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

From: Ryder Lee <[email protected]>

[ Upstream commit 1974a67d9b65c29a0a9426e32e8cd8c056de48b7 ]

Driver should not directly write WTBL to prevent overwritten issues.

With this fix, when driver needs to adjust its behavior for compatibility, especially concerning older 11g/n devices, by enabling or disabling CTS protection frames, often for hidden SSIDs or to manage legacy clients.

---
 .../net/wireless/mediatek/mt76/mt7615/mac.c   | 15 ------
 .../net/wireless/mediatek/mt76/mt7615/main.c  |  7 +--
 .../net/wireless/mediatek/mt76/mt7615/mcu.c   | 47 +++++++++++++++++++
 .../wireless/mediatek/mt76/mt7615/mt7615.h    |  5 +-
 .../net/wireless/mediatek/mt76/mt7615/regs.h  |  2 -
 5 files changed, 53 insertions(+), 23 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7615/mac.c +0 -15
index 7ba789834e8df..1e473f490b4bd 100644
@@ -1174,21 +1174,6 @@ void mt7615_mac_set_rates(struct mt7615_phy *phy, struct mt7615_sta *sta,
 }
 EXPORT_SYMBOL_GPL(mt7615_mac_set_rates);
 
-void mt7615_mac_enable_rtscts(struct mt7615_dev *dev,
-			      struct ieee80211_vif *vif, bool enable)
-{
-	struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
-	u32 addr;
-
-	addr = mt7615_mac_wtbl_addr(dev, mvif->sta.wcid.idx) + 3 * 4;
-
-	if (enable)
-		mt76_set(dev, addr, MT_WTBL_W3_RTS);
-	else
-		mt76_clear(dev, addr, MT_WTBL_W3_RTS);
-}
-EXPORT_SYMBOL_GPL(mt7615_mac_enable_rtscts);
-
 static int
 mt7615_mac_wtbl_update_key(struct mt7615_dev *dev, struct mt76_wcid *wcid,
 			   struct ieee80211_key_conf *key,
drivers/net/wireless/mediatek/mt76/mt7615/main.c +4 -3
index 4f0c840ef93de..f747285a1a5dd 100644
@@ -584,9 +584,6 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
 		}
 	}
 
-	if (changed & BSS_CHANGED_ERP_CTS_PROT)
-		mt7615_mac_enable_rtscts(dev, vif, info->use_cts_prot);
-
 	if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) {
 		mt7615_mcu_add_bss_info(phy, vif, NULL, true);
 		mt7615_mcu_sta_add(phy, vif, NULL, true);
@@ -599,6 +596,10 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
 		       BSS_CHANGED_BEACON_ENABLED))
 		mt7615_mcu_add_beacon(dev, hw, vif, info->enable_beacon);
 
+	if (changed & BSS_CHANGED_HT || changed & BSS_CHANGED_ERP_CTS_PROT)
+		mt7615_mcu_set_protection(phy, vif, info->ht_operation_mode,
+					  info->use_cts_prot);
+
 	if (changed & BSS_CHANGED_PS)
 		mt76_connac_mcu_set_vif_ps(&dev->mt76, vif);
 
drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +47 -0

50 lines not on this page · raw message

drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +2 -3
index 530da48ce3ea9..aac748fee257f 100644
@@ -466,8 +466,6 @@ void mt7615_mac_reset_counters(struct mt7615_phy *phy);
 void mt7615_mac_cca_stats_reset(struct mt7615_phy *phy);
 void mt7615_mac_set_scs(struct mt7615_phy *phy, bool enable);
 void mt7615_mac_enable_nf(struct mt7615_dev *dev, bool ext_phy);
-void mt7615_mac_enable_rtscts(struct mt7615_dev *dev,
-			      struct ieee80211_vif *vif, bool enable);
 void mt7615_mac_sta_poll(struct mt7615_dev *dev);
 int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi,
 			  struct sk_buff *skb, struct mt76_wcid *wcid,
@@ -522,7 +520,8 @@ int mt7615_mcu_set_sku_en(struct mt7615_phy *phy, bool enable);
 int mt7615_mcu_apply_rx_dcoc(struct mt7615_phy *phy);
 int mt7615_mcu_apply_tx_dpd(struct mt7615_phy *phy);
 int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy);
-
+int mt7615_mcu_set_protection(struct mt7615_phy *phy, struct ieee80211_vif *vif,
+			      u8 ht_mode, bool use_cts_prot);
 int mt7615_mcu_set_roc(struct mt7615_phy *phy, struct ieee80211_vif *vif,
 		       struct ieee80211_channel *chan, int duration);
 
drivers/net/wireless/mediatek/mt76/mt7615/regs.h +0 -2
index 806b3887c541c..9e6d55c91b269 100644
@@ -455,8 +455,6 @@ enum mt7615_reg_base {
 #define MT_WTBL_RIUCR3_RATE6		GENMASK(19, 8)
 #define MT_WTBL_RIUCR3_RATE7		GENMASK(31, 20)
 
-#define MT_WTBL_W3_RTS			BIT(22)
-
 #define MT_WTBL_W5_CHANGE_BW_RATE	GENMASK(7, 5)
 #define MT_WTBL_W5_SHORT_GI_20		BIT(8)
 #define MT_WTBL_W5_SHORT_GI_40		BIT(9)
Signature · 1 line
2.53.0
author maintainer
#47 lore raw

PATCH 45/666 wifi: mt76: mt7915: fix use_cts_prot support

In reply to Greg Kroah-Hartman

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

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

From: Ryder Lee <[email protected]>

[ Upstream commit 8b2c26562b95c6397e132d21f2bd3d73aaee0c0a ]

With this fix, when driver needs to adjust its behavior for compatibility, especially concerning older 11g/n devices, by enabling or disabling CTS protection frames, often for hidden SSIDs or to manage legacy clients.

---
 .../net/wireless/mediatek/mt76/mt7915/mac.c   | 13 ----
 .../net/wireless/mediatek/mt76/mt7915/main.c  |  7 ++-
 .../net/wireless/mediatek/mt76/mt7915/mcu.c   | 62 +++++++++++++++++++
 .../net/wireless/mediatek/mt76/mt7915/mcu.h   | 11 ++++
 .../wireless/mediatek/mt76/mt7915/mt7915.h    |  4 ++
 5 files changed, 81 insertions(+), 16 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +0 -13
index 799e8d2cc7e6e..ab31a350ca735 100644
@@ -235,19 +235,6 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
 	rcu_read_unlock();
 }
 
-void mt7915_mac_enable_rtscts(struct mt7915_dev *dev,
-			      struct ieee80211_vif *vif, bool enable)
-{
-	struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
-	u32 addr;
-
-	addr = mt7915_mac_wtbl_lmac_addr(dev, mvif->sta.wcid.idx, 5);
-	if (enable)
-		mt76_set(dev, addr, BIT(5));
-	else
-		mt76_clear(dev, addr, BIT(5));
-}
-
 static void
 mt7915_wed_check_ppe(struct mt7915_dev *dev, struct mt76_queue *q,
 		     struct mt7915_sta *msta, struct sk_buff *skb,
drivers/net/wireless/mediatek/mt76/mt7915/main.c +4 -3
index 8c0d63cebf3e1..f49dcdde3f2c6 100644
@@ -68,7 +68,7 @@ int mt7915_run(struct ieee80211_hw *hw)
 	if (ret)
 		goto out;
 
-	ret = mt76_connac_mcu_set_rts_thresh(&dev->mt76, 0x92b,
+	ret = mt76_connac_mcu_set_rts_thresh(&dev->mt76, MT7915_RTS_LEN_THRES,
 					     phy->mt76->band_idx);
 	if (ret)
 		goto out;
@@ -630,8 +630,9 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
 	if (set_sta == 1)
 		mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, false);
 
-	if (changed & BSS_CHANGED_ERP_CTS_PROT)
-		mt7915_mac_enable_rtscts(dev, vif, info->use_cts_prot);
+	if (changed & BSS_CHANGED_HT || changed & BSS_CHANGED_ERP_CTS_PROT)
+		mt7915_mcu_set_protection(phy, vif, info->ht_operation_mode,
+					  info->use_cts_prot);
 
 	if (changed & BSS_CHANGED_ERP_SLOT) {
 		int slottime = info->use_short_slot ? 9 : 20;
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +62 -0

68 lines not on this page · raw message

drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +11 -0
index 49476a4182fd1..b7e26c2409444 100644
@@ -399,6 +399,17 @@ struct bss_info_inband_discovery {
 	__le16 prob_rsp_len;
 } __packed __aligned(4);
 
+struct bss_info_prot {
+	__le16 tag;
+	__le16 len;
+	__le32 prot_type;
+	__le32 prot_mode;
+	__le32 rts_len_thres;
+	__le16 he_rts_thres;
+	u8 rts_pkt_thres;
+	u8 rsv[5];
+} __packed;
+
 enum {
 	BSS_INFO_BCN_CSA,
 	BSS_INFO_BCN_BCC,
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +4 -0
index 5fe872ef2e939..f49d6b2f81e42 100644
@@ -83,6 +83,8 @@
 #define MT7915_CRIT_TEMP		110
 #define MT7915_MAX_TEMP			120
 
+#define MT7915_RTS_LEN_THRES		0x92b
+
 struct mt7915_vif;
 struct mt7915_sta;
 struct mt7915_dfs_pulse;
@@ -458,6 +460,8 @@ int mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *v
 				 u32 changed);
 int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 			  int enable, u32 changed);
+int mt7915_mcu_set_protection(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+			      u8 ht_mode, bool use_cts_prot);
 int mt7915_mcu_add_obss_spr(struct mt7915_phy *phy, struct ieee80211_vif *vif,
 			    struct ieee80211_he_obss_pd *he_obss_pd);
 int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
Signature · 1 line
2.53.0
author maintainer
#48 lore raw

PATCH 46/666 wifi: mt76: mt7925: prevent NULL pointer dereference in mt7925_tx_check_aggr()

In reply to Greg Kroah-Hartman

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

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

From: Ming Yen Hsieh <[email protected]>

[ Upstream commit 83ae3a18ba957257b4c406273d2da2caeea2b439 ]

Move the NULL check for 'sta' before dereferencing it to prevent a possible crash.

Fixes 44eb173bdd4f ("wifi: mt76: mt7925: add link handling in mt7925_txwi_free")
---
 drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7925/mac.c +4 -1
index 18b7479cee799..e308c97b574b8 100644
@@ -849,11 +849,14 @@ static void mt7925_tx_check_aggr(struct ieee80211_sta *sta, struct sk_buff *skb,
 	bool is_8023;
 	u16 fc, tid;
 
+	if (!sta)
+		return;
+
 	link_sta = rcu_dereference(sta->link[wcid->link_id]);
 	if (!link_sta)
 		return;
 
-	if (!sta || !(link_sta->ht_cap.ht_supported || link_sta->he_cap.has_he))
+	if (!(link_sta->ht_cap.ht_supported || link_sta->he_cap.has_he))
 		return;
 
 	tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
Signature · 1 line
2.53.0
author maintainer
#49 lore raw

PATCH 47/666 wifi: mt76: mt7925: prevent NULL vif dereference in mt7925_mac_write_txwi

In reply to Greg Kroah-Hartman

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

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

From: Ming Yen Hsieh <[email protected]>

[ Upstream commit 962eb04e67552be406c906c83099c1d736aae3b6 ]

Check for a NULL vif before accessing ieee80211_vif_is_mld(vif) to avoid a potential kernel panic in scenarios where vif might not be initialized.

Fixes ebb1406813c6 ("wifi: mt76: mt7925: add link handling to txwi")
---
 drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7925/mac.c +2 -2
index e308c97b574b8..e5de05a91aee7 100644
@@ -807,8 +807,8 @@ mt7925_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
 	txwi[5] = cpu_to_le32(val);
 
 	val = MT_TXD6_DAS | FIELD_PREP(MT_TXD6_MSDU_CNT, 1);
-	if (!ieee80211_vif_is_mld(vif) ||
-	    (q_idx >= MT_LMAC_ALTX0 && q_idx <= MT_LMAC_BCN0))
+	if (vif && (!ieee80211_vif_is_mld(vif) ||
+	    (q_idx >= MT_LMAC_ALTX0 && q_idx <= MT_LMAC_BCN0)))
 		val |= MT_TXD6_DIS_MAT;
 	txwi[6] = cpu_to_le32(val);
 	txwi[7] = 0;
Signature · 1 line
2.53.0
author maintainer
#50 lore raw

PATCH 48/666 wifi: mt76: mt7996: fix FCS error flag check in RX descriptor

In reply to Greg Kroah-Hartman

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

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

From: Alok Tiwari <[email protected]>

[ Upstream commit d8db56142e531f060c938fa0b5175ed6c8cabb11 ]

The mt7996 driver currently checks the MT_RXD3_NORMAL_FCS_ERR bit in rxd1 whereas other Connac3-based drivers(mt7925) correctly check this bit in rxd3.

Since the MT_RXD3_NORMAL_FCS_ERR bit is defined in the fourth RX descriptor word (rxd3), update mt7996 to use the proper descriptor field. This change aligns mt7996 with mt7925 and the rest of the Connac3 family.

Fixes 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
---
 drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7996/mac.c +1 -1
index b7a5426c933d0..6f8167bb86136 100644
@@ -501,7 +501,7 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, enum mt76_rxq_id q,
 	    !(csum_status & (BIT(0) | BIT(2) | BIT(3))))
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
-	if (rxd1 & MT_RXD3_NORMAL_FCS_ERR)
+	if (rxd3 & MT_RXD3_NORMAL_FCS_ERR)
 		status->flag |= RX_FLAG_FAILED_FCS_CRC;
 
 	if (rxd1 & MT_RXD1_NORMAL_TKIP_MIC_ERR)
Signature · 1 line
2.53.0
author maintainer
#51 lore raw

PATCH 49/666 wifi: mt76: mt7921: Place upper limit on station AID

In reply to Greg Kroah-Hartman

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

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

From: Rory Little <[email protected]>

[ Upstream commit 4d0bf21e3e20619d51d06c0c36207aabab8b712c ]

Any station configured with an AID over 20 causes a firmware crash. This situation occurred in our testing using an AP interface on 7922 hardware, with a modified hostapd, sourced from Mediatek's OpenWRT feeds.

In stock hostapd, station AIDs begin counting at 1, and this configuration is prevented with an upper limit on associated stations. However, the modified hostapd began allocation at 65, which caused the firmware to crash. This fix does not allow these AIDs to work, but will prevent the firmware crash.

This crash was only seen on IFTYPE_AP interfaces, and the fix does not appear to have an effect on IFTYPE_STATION behavior.

Fixes 5c14a5f944b9 ("mt76: mt7921: introduce mt7921e support")
---
 drivers/net/wireless/mediatek/mt76/mt7921/main.c   | 6 ++++++
 drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h | 2 ++
 2 files changed, 8 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7921/main.c +6 -0
index bc823a7c09bba..6ed2edd054b55 100644
@@ -802,6 +802,9 @@ int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
 	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
 	int ret, idx;
 
+	if (sta->aid > MT7921_MAX_AID)
+		return -ENOENT;
+
 	idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT792x_WTBL_STA - 1);
 	if (idx < 0)
 		return -ENOSPC;
@@ -845,6 +848,9 @@ int mt7921_mac_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif,
 	struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
 	struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
 
+	if (sta->aid > MT7921_MAX_AID)
+		return -ENOENT;
+
 	if (ev != MT76_STA_EVENT_ASSOC)
 	    return 0;
 
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +2 -0
index 16c89815c0b8a..7a7e09fcf4b5e 100644
@@ -7,6 +7,8 @@
 #include "../mt792x.h"
 #include "regs.h"
 
+#define MT7921_MAX_AID                  20
+
 #define MT7921_TX_RING_SIZE		2048
 #define MT7921_TX_MCU_RING_SIZE		256
 #define MT7921_TX_FWDL_RING_SIZE	128
Signature · 1 line
2.53.0
author maintainer
#52 lore raw

PATCH 50/666 arm64: cpufeature: Make PMUVer and PerfMon unsigned

In reply to Greg Kroah-Hartman

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

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

From: James Clark <[email protected]>

[ Upstream commit d1dcc20bcc40efe1f1c71639376c91dafa489222 ]

On the host, this change doesn't make a difference because the fields are defined as FTR_EXACT. However, KVM allows userspace to set these fields for a guest and overrides the type to be FTR_LOWER_SAFE. And while KVM used to do an unsigned comparison to validate that the new value is lower than what the hardware provides, since the linked commit it uses the generic sanitization framework which does a signed comparison.

Fix it by defining these fields as unsigned. In theory, without this fix, userspace could set a higher PMU version than the hardware supports by providing any value with the top bit set.

Fixes c118cead07a7 ("KVM: arm64: Use generic sanitisation for ID_(AA64)DFR0_EL1")
---
 arch/arm64/kernel/cpufeature.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/kernel/cpufeature.c +2 -2
index 5e68d65e675e5..8246015fd2d73 100644
@@ -533,7 +533,7 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = {
 	 * We can instantiate multiple PMU instances with different levels
 	 * of support.
 	 */
-	S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_AA64DFR0_EL1_PMUVer_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_AA64DFR0_EL1_PMUVer_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64DFR0_EL1_DebugVer_SHIFT, 4, 0x6),
 	ARM64_FTR_END,
 };
@@ -677,7 +677,7 @@ static const struct arm64_ftr_bits ftr_id_pfr2[] = {
 
 static const struct arm64_ftr_bits ftr_id_dfr0[] = {
 	/* [31:28] TraceFilt */
-	S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_DFR0_EL1_PerfMon_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_EXACT, ID_DFR0_EL1_PerfMon_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_EL1_MProfDbg_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_EL1_MMapTrc_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_EL1_CopTrc_SHIFT, 4, 0),
Signature · 1 line
2.53.0
author maintainer
#53 lore raw

PATCH 51/666 wifi: mt76: mt7996: fix struct mt7996_mcu_uni_event

In reply to Greg Kroah-Hartman

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

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

From: StanleyYP Wang <[email protected]>

[ Upstream commit efbd5bf395f4e6b45a87f3835d4c2e28170c77c5 ]

The cid field is defined as a two-byte value in the firmware.

Fixes 98686cd21624 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
---
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 2 +-
 drivers/net/wireless/mediatek/mt76/mt7996/mcu.h | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +1 -1
index 8738e4b645420..54567a5893449 100644
@@ -218,7 +218,7 @@ mt7996_mcu_parse_response(struct mt76_dev *mdev, int cmd,
 		event = (struct mt7996_mcu_uni_event *)skb->data;
 		ret = le32_to_cpu(event->status);
 		/* skip invalid event */
-		if (mcu_cmd != event->cid)
+		if (mcu_cmd != le16_to_cpu(event->cid))
 			ret = -EAGAIN;
 	} else {
 		skb_pull(skb, sizeof(struct mt7996_mcu_rxd));
drivers/net/wireless/mediatek/mt76/mt7996/mcu.h +2 -2
index a75e1c9435bb0..ded2fe7210680 100644
@@ -25,8 +25,8 @@ struct mt7996_mcu_rxd {
 };
 
 struct mt7996_mcu_uni_event {
-	u8 cid;
-	u8 __rsv[3];
+	__le16 cid;
+	u8 __rsv[2];
 	__le32 status; /* 0: success, others: fail */
 } __packed;
 
Signature · 1 line
2.53.0
author maintainer
#54 lore raw

PATCH 52/666 wifi: mt76: mt7915: fix use-after-free bugs in mt7915_mac_dump_work()

In reply to Greg Kroah-Hartman

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

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

From: Duoming Zhou <[email protected]>

[ Upstream commit 1146d0946b5358fad24812bd39d68f31cd40cc34 ]

When the mt7915 pci chip is detaching, the mt7915_crash_data is released in mt7915_coredump_unregister(). However, the work item dump_work may still be running or pending, leading to UAF bugs when the already freed crash_data is dereferenced again in mt7915_mac_dump_work().

The race condition can occur as follows:

CPU 0 (removal path)               | CPU 1 (workqueue)
mt7915_pci_remove()                | mt7915_sys_recovery_set()
 mt7915_unregister_device()        |  mt7915_reset()
  mt7915_coredump_unregister()     |   queue_work()
   vfree(dev->coredump.crash_data) | mt7915_mac_dump_work()
                                   |  crash_data-> // UAF

Fix this by ensuring dump_work is properly canceled before the crash_data is deallocated. Add cancel_work_sync() in mt7915_unregister_device() to synchronize with any pending or executing dump work.

Fixes 4dbcb9125cc3 ("wifi: mt76: mt7915: enable coredump support")
---
 drivers/net/wireless/mediatek/mt76/mt7915/init.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/mediatek/mt76/mt7915/init.c +1 -0
index 83f062fb95d5a..b2220ff7d6758 100644
@@ -1275,6 +1275,7 @@ int mt7915_register_device(struct mt7915_dev *dev)
 
 void mt7915_unregister_device(struct mt7915_dev *dev)
 {
+	cancel_work_sync(&dev->dump_work);
 	mt7915_unregister_ext_phy(dev);
 	mt7915_coredump_unregister(dev);
 	mt7915_unregister_thermal(&dev->phy);
Signature · 1 line
2.53.0
author maintainer
#55 lore raw

PATCH 53/666 wifi: mt76: mt7996: fix use-after-free bugs in mt7996_mac_dump_work()

In reply to Greg Kroah-Hartman

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

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

From: Duoming Zhou <[email protected]>

[ Upstream commit c8f62f73bbced3a79894655bdb0b625462d956fc ]

When the mt7996 pci chip is detaching, the mt7996_crash_data is released in mt7996_coredump_unregister(). However, the work item dump_work may still be running or pending, leading to UAF bugs when the already freed crash_data is dereferenced again in mt7996_mac_dump_work().

The race condition can occur as follows:

CPU 0 (removal path)               | CPU 1 (workqueue)
mt7996_pci_remove()                | mt7996_sys_recovery_set()
 mt7996_unregister_device()        |  mt7996_reset()
  mt7996_coredump_unregister()     |   queue_work()
   vfree(dev->coredump.crash_data) | mt7996_mac_dump_work()
                                   |  crash_data-> // UAF

Fix this by ensuring dump_work is properly canceled before the crash_data is deallocated. Add cancel_work_sync() in mt7996_unregister_device() to synchronize with any pending or executing dump work.

Fixes 878161d5d4a4 ("wifi: mt76: mt7996: enable coredump support")
---
 drivers/net/wireless/mediatek/mt76/mt7996/init.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/wireless/mediatek/mt76/mt7996/init.c +1 -0
index 5cd2fb7d9835c..fc2d46b10b720 100644
@@ -1399,6 +1399,7 @@ int mt7996_register_device(struct mt7996_dev *dev)
 
 void mt7996_unregister_device(struct mt7996_dev *dev)
 {
+	cancel_work_sync(&dev->dump_work);
 	cancel_work_sync(&dev->wed_rro.work);
 	mt7996_unregister_phy(mt7996_phy3(dev), MT_BAND2);
 	mt7996_unregister_phy(mt7996_phy2(dev), MT_BAND1);
Signature · 1 line
2.53.0
author maintainer
#56 lore raw

PATCH 54/666 wifi: mt76: mt7921: fix 6GHz regulatory update on connection

In reply to Greg Kroah-Hartman

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

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

From: Michael Lo <[email protected]>

[ Upstream commit 3dc0c40d7806c72cfe88cf4e1e2650c1673f9db4 ]

Call mt7921_regd_update() instead of mt7921_mcu_set_clc() when setting the 6GHz power type after connection, so that regulatory limits and SAR power are also applied.

Fixes 51ba0e3a15eb ("wifi: mt76: mt7921: add 6GHz power type support for clc")
---
 drivers/net/wireless/mediatek/mt76/mt7921/main.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7921/main.c +2 -1
index 6ed2edd054b55..a93ae4e44f16a 100644
@@ -791,7 +791,8 @@ mt7921_regd_set_6ghz_power_type(struct ieee80211_vif *vif, bool is_add)
 	}
 
 out:
-	mt7921_mcu_set_clc(dev, dev->mt76.alpha2, dev->country_ie_env);
+	if (vif->bss_conf.chanreq.oper.chan->band == NL80211_BAND_6GHZ)
+		mt7921_regd_update(dev);
 }
 
 int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
Signature · 1 line
2.53.0
author maintainer
#57 lore raw

PATCH 55/666 bpf: Use RCU-safe iteration in dev_map_redirect_multi() SKB path

In reply to Greg Kroah-Hartman

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

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

From: David Carlier <[email protected]>

[ Upstream commit 8ed82f807bb09d2c8455aaa665f2c6cb17bc6a19 ]

The DEVMAP_HASH branch in dev_map_redirect_multi() uses hlist_for_each_entry_safe() to iterate hash buckets, but this function runs under RCU protection (called from xdp_do_generic_redirect_map() in softirq context). Concurrent writers (__dev_map_hash_update_elem, dev_map_hash_delete_elem) modify the list using RCU primitives (hlist_add_head_rcu, hlist_del_rcu).

hlist_for_each_entry_safe() performs plain pointer dereferences without rcu_dereference(), missing the acquire barrier needed to pair with writers' rcu_assign_pointer(). On weakly-ordered architectures (ARM64, POWER), a reader can observe a partially-constructed node. It also defeats CONFIG_PROVE_RCU lockdep validation and KCSAN data-race detection.

Replace with hlist_for_each_entry_rcu() using rcu_read_lock_bh_held() as the lockdep condition, consistent with the rcu_dereference_check() used in the DEVMAP (non-hash) branch of the same functions. Also fix the same incorrect lockdep_is_held(&dtab->index_lock) condition in dev_map_enqueue_multi(), where the lock is not held either.

Fixes e624d4ed4aa8 ("xdp: Extend xdp_redirect_map with broadcast support")
---
 kernel/bpf/devmap.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
kernel/bpf/devmap.c +2 -3
index 39b7efa396b8e..17f8c9d6e95cc 100644
@@ -653,7 +653,7 @@ int dev_map_enqueue_multi(struct xdp_frame *xdpf, struct net_device *dev_rx,
 		for (i = 0; i < dtab->n_buckets; i++) {
 			head = dev_map_index_hash(dtab, i);
 			hlist_for_each_entry_rcu(dst, head, index_hlist,
-						 lockdep_is_held(&dtab->index_lock)) {
+						rcu_read_lock_bh_held()) {
 				if (!is_valid_dst(dst, xdpf))
 					continue;
 
@@ -735,7 +735,6 @@ int dev_map_redirect_multi(struct net_device *dev, struct sk_buff *skb,
 	struct bpf_dtab_netdev *dst, *last_dst = NULL;
 	int excluded_devices[1+MAX_NEST_DEV];
 	struct hlist_head *head;
-	struct hlist_node *next;
 	int num_excluded = 0;
 	unsigned int i;
 	int err;
@@ -775,7 +774,7 @@ int dev_map_redirect_multi(struct net_device *dev, struct sk_buff *skb,
 	} else { /* BPF_MAP_TYPE_DEVMAP_HASH */
 		for (i = 0; i < dtab->n_buckets; i++) {
 			head = dev_map_index_hash(dtab, i);
-			hlist_for_each_entry_safe(dst, next, head, index_hlist) {
+			hlist_for_each_entry_rcu(dst, head, index_hlist, rcu_read_lock_bh_held()) {
 				if (is_ifindex_excluded(excluded_devices, num_excluded,
 							dst->dev->ifindex))
 					continue;
Signature · 1 line
2.53.0
author maintainer
#58 lore raw

PATCH 56/666 bpf: Fix variable length stack write over spilled pointers

In reply to Greg Kroah-Hartman

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

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

From: Alexei Starovoitov <[email protected]>

[ Upstream commit 4639eb9e30ab10c7935c7c19e872facf9a94713f ]

Scrub slots if variable-offset stack write goes over spilled pointers. Otherwise is_spilled_reg() may == true && spilled_ptr.type == NOT_INIT and valid program is rejected by check_stack_read_fixed_off() with obscure "invalid size of register fill" message.

---
 kernel/bpf/verifier.c | 28 ++++++++++++++++++++--------
 1 file changed, 20 insertions(+), 8 deletions(-)
kernel/bpf/verifier.c +20 -8
index 96a04cd904a11..feb90c6e94620 100644
@@ -4724,6 +4724,18 @@ static void check_fastcall_stack_contract(struct bpf_verifier_env *env,
 	}
 }
 
+static void scrub_special_slot(struct bpf_func_state *state, int spi)
+{
+	int i;
+
+	/* regular write of data into stack destroys any spilled ptr */
+	state->stack[spi].spilled_ptr.type = NOT_INIT;
+	/* Mark slots as STACK_MISC if they belonged to spilled ptr/dynptr/iter. */
+	if (is_stack_slot_special(&state->stack[spi]))
+		for (i = 0; i < BPF_REG_SIZE; i++)
+			scrub_spilled_slot(&state->stack[spi].slot_type[i]);
+}
+
 /* check_stack_{read,write}_fixed_off functions track spill/fill of registers,
  * stack boundary and alignment are checked in check_mem_access()
  */
@@ -4809,12 +4821,7 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env,
 	} else {
 		u8 type = STACK_MISC;
 
-		/* regular write of data into stack destroys any spilled ptr */
-		state->stack[spi].spilled_ptr.type = NOT_INIT;
-		/* Mark slots as STACK_MISC if they belonged to spilled ptr/dynptr/iter. */
-		if (is_stack_slot_special(&state->stack[spi]))
-			for (i = 0; i < BPF_REG_SIZE; i++)
-				scrub_spilled_slot(&state->stack[spi].slot_type[i]);
+		scrub_special_slot(state, spi);
 
 		/* only mark the slot as written if all 8 bytes were written
 		 * otherwise read propagation may incorrectly stop too soon
@@ -4949,8 +4956,13 @@ static int check_stack_write_var_off(struct bpf_verifier_env *env,
 			}
 		}
 
-		/* Erase all other spilled pointers. */
-		state->stack[spi].spilled_ptr.type = NOT_INIT;
+		/*
+		 * Scrub slots if variable-offset stack write goes over spilled pointers.
+		 * Otherwise is_spilled_reg() may == true && spilled_ptr.type == NOT_INIT
+		 * and valid program is rejected by check_stack_read_fixed_off()
+		 * with obscure "invalid size of register fill" message.
+		 */
+		scrub_special_slot(state, spi);
 
 		/* Update the slot type. */
 		new_type = STACK_MISC;
Signature · 1 line
2.53.0
author maintainer
#59 lore raw

PATCH 57/666 bpf,arc_jit: Fix missing newline in pr_err messages

In reply to Greg Kroah-Hartman

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

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

From: haoyu.lu <[email protected]>

[ Upstream commit b6b5e0ebd429d66ce37ae5af649a74ea1f041d92 ]

Add missing newline to pr_err messages in ARC JIT.

---
 arch/arc/net/bpf_jit_arcv2.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arc/net/bpf_jit_arcv2.c +4 -4
index 6d989b6d88c69..7ee50aeae5a45 100644
@@ -2427,7 +2427,7 @@ u8 arc_prologue(u8 *buf, u32 usage, u16 frame_size)
 
 #ifdef ARC_BPF_JIT_DEBUG
 	if ((usage & BIT(ARC_R_FP)) && frame_size == 0) {
-		pr_err("FP is being saved while there is no frame.");
+		pr_err("FP is being saved while there is no frame.\n");
 		BUG();
 	}
 #endif
@@ -2454,7 +2454,7 @@ u8 arc_epilogue(u8 *buf, u32 usage, u16 frame_size)
 
 #ifdef ARC_BPF_JIT_DEBUG
 	if ((usage & BIT(ARC_R_FP)) && frame_size == 0) {
-		pr_err("FP is being saved while there is no frame.");
+		pr_err("FP is being saved while there is no frame.\n");
 		BUG();
 	}
 #endif
@@ -2868,7 +2868,7 @@ u8 gen_jmp_64(u8 *buf, u8 rd, u8 rs, u8 cond, u32 curr_off, u32 targ_off)
 		break;
 	default:
 #ifdef ARC_BPF_JIT_DEBUG
-		pr_err("64-bit jump condition is not known.");
+		pr_err("64-bit jump condition is not known.\n");
 		BUG();
 #endif
 	}
@@ -2948,7 +2948,7 @@ u8 gen_jmp_32(u8 *buf, u8 rd, u8 rs, u8 cond, u32 curr_off, u32 targ_off)
 	 */
 	if (cond >= ARC_CC_LAST) {
 #ifdef ARC_BPF_JIT_DEBUG
-		pr_err("32-bit jump condition is not known.");
+		pr_err("32-bit jump condition is not known.\n");
 		BUG();
 #endif
 		return 0;
Signature · 1 line
2.53.0
author maintainer
#60 lore raw

PATCH 58/666 wifi: rtw89: phy: fix uninitialized variable access in rtw89_phy_cfo_set_crystal_cap()

In reply to Greg Kroah-Hartman

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

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

From: Alexey Velichayshiy <[email protected]>

[ Upstream commit 047cddf88c611e616d49a00311d4722e46286234 ]

In the rtw89_phy_cfo_set_crystal_cap() function, for chips other than RTL8852A/RTL8851B, the values read by rtw89_mac_read_xtal_si() are stored into the local variables sc_xi_val and sc_xo_val. If either read fails, these variables remain uninitialized, they are later used to update cfo->crystal_cap and in debug print statements. This can lead to undefined behavior.

Fix the issue by initializing sc_xi_val and sc_xo_val to zero, like is implemented in vendor driver.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes 8379fa611536 ("rtw89: 8852c: add write/read crystal function in CFO tracking")
---
 drivers/net/wireless/realtek/rtw89/phy.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/realtek/rtw89/phy.c +1 -1
index b473e02ecd9e7..d544077ec2989 100644
@@ -3893,7 +3893,7 @@ static void rtw89_phy_cfo_set_crystal_cap(struct rtw89_dev *rtwdev,
 {
 	struct rtw89_cfo_tracking_info *cfo = &rtwdev->cfo_tracking;
 	const struct rtw89_chip_info *chip = rtwdev->chip;
-	u8 sc_xi_val, sc_xo_val;
+	u8 sc_xi_val = 0, sc_xo_val = 0;
 
 	if (!force && cfo->crystal_cap == crystal_cap)
 		return;
Signature · 1 line
2.53.0
author maintainer
#61 lore raw

PATCH 59/666 r8152: fix incorrect register write to USB_UPHY_XTAL

In reply to Greg Kroah-Hartman

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

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

From: Chih Kai Hsu <[email protected]>

[ Upstream commit 48afd5124fd6129c46fd12cb06155384b1c4a0c4 ]

The old code used ocp_write_byte() to clear the OOBS_POLLING bit (BIT(8)) in the USB_UPHY_XTAL register, but this doesn't correctly clear a bit in the upper byte of the 16-bit register.

Fix this by using ocp_write_word() instead.

---
 drivers/net/usb/r8152.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/usb/r8152.c +1 -1
index 6ce25673e4cc8..1c36816405f13 100644
@@ -3894,7 +3894,7 @@ static void r8156_ups_en(struct r8152 *tp, bool enable)
 		case RTL_VER_15:
 			ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPHY_XTAL);
 			ocp_data &= ~OOBS_POLLING;
-			ocp_write_byte(tp, MCU_TYPE_USB, USB_UPHY_XTAL, ocp_data);
+			ocp_write_word(tp, MCU_TYPE_USB, USB_UPHY_XTAL, ocp_data);
 			break;
 		default:
 			break;
Signature · 1 line
2.53.0
author maintainer
#62 lore raw

PATCH 60/666 powerpc/crash: fix backup region offset update to elfcorehdr

In reply to Greg Kroah-Hartman

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

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

From: Sourabh Jain <[email protected]>

[ Upstream commit 789335cacdf37da93bb7c70322dff8c7e82881df ]

update_backup_region_phdr() in file_load_64.c iterates over all the program headers in the kdump kernel’s elfcorehdr and updates the p_offset of the program header whose physical address starts at 0.

However, the loop logic is incorrect because the program header pointer is not updated during iteration. Since elfcorehdr typically contains PT_NOTE entries first, the PT_LOAD program header with physical address 0 is never reached. As a result, its p_offset is not updated to point to the backup region.

Because of this behavior, the capture kernel exports the first 64 KB of the crashed kernel’s memory at offset 0, even though that memory actually lives in the backup region. When a crash happens, purgatory copies the first 64 KB of the crashed kernel’s memory into the backup region so the capture kernel can safely use it.

This has not caused problems so far because the first 64 KB is usually identical in both the crashed and capture kernels. However, this is just an assumption and is not guaranteed to always hold true.

Fix update_backup_region_phdr() to correctly update the p_offset of the program header with a starting physical address of 0 by correcting the logic used to iterate over the program headers.

Fixes cb350c1f1f86 ("powerpc/kexec_file: Prepare elfcore header for crashing kernel")
---
 arch/powerpc/kexec/file_load_64.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kexec/file_load_64.c +1 -1
index 248a0f00a291f..cb09916b4056b 100644
@@ -574,7 +574,7 @@ static void update_backup_region_phdr(struct kimage *image, Elf64_Ehdr *ehdr)
 	unsigned int i;
 
 	phdr = (Elf64_Phdr *)(ehdr + 1);
-	for (i = 0; i < ehdr->e_phnum; i++) {
+	for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
 		if (phdr->p_paddr == BACKUP_SRC_START) {
 			phdr->p_offset = image->arch.backup_start;
 			kexec_dprintk("Backup region offset updated to 0x%lx\n",
Signature · 1 line
2.53.0
author maintainer
#63 lore raw

PATCH 61/666 powerpc/crash: Update backup region offset in elfcorehdr on memory hotplug

In reply to Greg Kroah-Hartman

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

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

From: Sourabh Jain <[email protected]>

[ Upstream commit f53b24d1fa263f56155213eabab734c18d884aff ]

When elfcorehdr is prepared for kdump, the program header representing the first 64 KB of memory is expected to have its offset point to the backup region. This is required because purgatory copies the first 64 KB of the crashed kernel memory to this backup region following a kernel crash. This allows the capture kernel to use the first 64 KB of memory to place the exception vectors and other required data.

When elfcorehdr is recreated due to memory hotplug, the offset of the program header representing the first 64 KB is not updated. As a result, the capture kernel exports the first 64 KB at offset 0, even though the data actually resides in the backup region.

Fix this by calling sync_backup_region_phdr() to update the program header offset in the elfcorehdr created during memory hotplug.

sync_backup_region_phdr() works for images loaded via the kexec_file_load syscall. However, it does not work for kexec_load, because image->arch.backup_start is not initialized in that case. So introduce machine_kexec_post_load() to process the elfcorehdr prepared by kexec-tools and initialize image->arch.backup_start for kdump images loaded via kexec_load syscall.

Rename update_backup_region_phdr() to sync_backup_region_phdr() and extend it to synchronize the backup region offset between the kdump image and the ELF core header. The helper now supports updating either the kdump image from the ELF program header or updating the ELF program header from the kdump image, avoiding code duplication.

Define ARCH_HAS_KIMAGE_ARCH and struct kimage_arch when CONFIG_KEXEC_FILE or CONFIG_CRASH_DUMP is enabled so that kimage->arch.backup_start is available with the kexec_load system call.

This patch depends on the patch titled "powerpc/crash: fix backup region offset update to elfcorehdr".

Fixes 849599b702ef ("powerpc/crash: add crash memory hotplug support")
---
 arch/powerpc/include/asm/kexec.h  | 14 +++++--
 arch/powerpc/kexec/crash.c        | 64 +++++++++++++++++++++++++++++++
 arch/powerpc/kexec/file_load_64.c | 29 +-------------
 3 files changed, 76 insertions(+), 31 deletions(-)
arch/powerpc/include/asm/kexec.h +11 -3
index 601e569303e1b..e6c0724109e39 100644
@@ -66,11 +66,9 @@ void relocate_new_kernel(unsigned long indirection_page, unsigned long reboot_co
 			 unsigned long start_address) __noreturn;
 void kexec_copy_flush(struct kimage *image);
 
-#ifdef CONFIG_KEXEC_FILE
-extern const struct kexec_file_ops kexec_elf64_ops;
 
+#if defined(CONFIG_KEXEC_FILE) || defined(CONFIG_CRASH_DUMP)
 #define ARCH_HAS_KIMAGE_ARCH
-
 struct kimage_arch {
 	struct crash_mem *exclude_ranges;
 
@@ -78,6 +76,10 @@ struct kimage_arch {
 	void *backup_buf;
 	void *fdt;
 };
+#endif
+
+#ifdef CONFIG_KEXEC_FILE
+extern const struct kexec_file_ops kexec_elf64_ops;
 
 char *setup_kdump_cmdline(struct kimage *image, char *cmdline,
 			  unsigned long cmdline_len);
@@ -141,6 +143,10 @@ int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags);
 
 unsigned int arch_crash_get_elfcorehdr_size(void);
 #define crash_get_elfcorehdr_size arch_crash_get_elfcorehdr_size
+
+int machine_kexec_post_load(struct kimage *image);
+#define machine_kexec_post_load machine_kexec_post_load
+
 #endif /* CONFIG_CRASH_HOTPLUG */
 
 extern int crashing_cpu;
@@ -155,6 +161,8 @@ extern void default_machine_crash_shutdown(struct pt_regs *regs);
 extern void crash_kexec_prepare(void);
 extern void crash_kexec_secondary(struct pt_regs *regs);
 
+extern void sync_backup_region_phdr(struct kimage *image, Elf64_Ehdr *ehdr,
+				    bool phdr_to_kimage);
 static inline bool kdump_in_progress(void)
 {
 	return crashing_cpu >= 0;
arch/powerpc/kexec/crash.c +64 -0

83 lines not on this page · raw message

arch/powerpc/kexec/file_load_64.c +1 -28
index cb09916b4056b..276233f73a533 100644
@@ -557,33 +557,6 @@ static int load_backup_segment(struct kimage *image, struct kexec_buf *kbuf)
 	return 0;
 }
 
-/**
- * update_backup_region_phdr - Update backup region's offset for the core to
- *                             export the region appropriately.
- * @image:                     Kexec image.
- * @ehdr:                      ELF core header.
- *
- * Assumes an exclusive program header is setup for the backup region
- * in the ELF headers
- *
- * Returns nothing.
- */
-static void update_backup_region_phdr(struct kimage *image, Elf64_Ehdr *ehdr)
-{
-	Elf64_Phdr *phdr;
-	unsigned int i;
-
-	phdr = (Elf64_Phdr *)(ehdr + 1);
-	for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
-		if (phdr->p_paddr == BACKUP_SRC_START) {
-			phdr->p_offset = image->arch.backup_start;
-			kexec_dprintk("Backup region offset updated to 0x%lx\n",
-				      image->arch.backup_start);
-			return;
-		}
-	}
-}
-
 static unsigned int kdump_extra_elfcorehdr_size(struct crash_mem *cmem)
 {
 #if defined(CONFIG_CRASH_HOTPLUG) && defined(CONFIG_MEMORY_HOTPLUG)
@@ -628,7 +601,7 @@ static int load_elfcorehdr_segment(struct kimage *image, struct kexec_buf *kbuf)
 	}
 
 	/* Fix the offset for backup region in the ELF header */
-	update_backup_region_phdr(image, headers);
+	sync_backup_region_phdr(image, headers, false);
 
 	kbuf->buffer = headers;
 	kbuf->mem = KEXEC_BUF_MEM_UNKNOWN;
Signature · 1 line
2.53.0
author maintainer
#64 lore raw

PATCH 62/666 selftests/powerpc: Suppress -Wmaybe-uninitialized with GCC 15

In reply to Greg Kroah-Hartman

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

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

From: Amit Machhiwal <[email protected]>

[ Upstream commit 6e65886fceb23605eff952d6b1975737b4c4b154 ]

GCC 15 reports the below false positive '-Wmaybe-uninitialized' warning in vphn_unpack_associativity() when building the powerpc selftests.

  # make -C tools/testing/selftests TARGETS="powerpc"
  [...]
    CC       test-vphn
  In file included from test-vphn.c:3:
  In function ‘vphn_unpack_associativity’,
      inlined from ‘test_one’ at test-vphn.c:371:2,
      inlined from ‘test_vphn’ at test-vphn.c:399:9:
  test-vphn.c:10:33: error: ‘be_packed’ may be used uninitialized [-Werror=maybe-uninitialized]
     10 | #define be16_to_cpup(x)         bswap_16(*x)
        |                                 ^~~~~~~~
  vphn.c:42:27: note: in expansion of macro ‘be16_to_cpup’
     42 |                 u16 new = be16_to_cpup(field++);
        |                           ^~~~~~~~~~~~
  In file included from test-vphn.c:19:
  vphn.c: In function ‘test_vphn’:
  vphn.c:27:16: note: ‘be_packed’ declared here
     27 |         __be64 be_packed[VPHN_REGISTER_COUNT];
        |                ^~~~~~~~~
  cc1: all warnings being treated as errors

When vphn_unpack_associativity() is called from hcall_vphn() in kernel the error is not seen while building vphn.c during kernel compilation. This is because the top level Makefile includes '-fno-strict-aliasing' flag always.

The issue here is that GCC 15 emits '-Wmaybe-uninitialized' due to type punning between __be64[] and __b16* when accessing the buffer via be16_to_cpup(). The underlying object is fully initialized but GCC 15 fails to track the aliasing due to the strict aliasing violation here. Please refer [1] and [2]. This results in a false positive warning which is promoted to an error under '-Werror'. This problem is not seen when the compilation is performed with GCC 13 and 14. An issue [1] has also been created on GCC bugzilla.

The selftest compiles fine with '-fno-strict-aliasing'. Since this GCC flag is used to compile vphn.c in kernel too, the same flag should be used to build vphn tests when compiling vphn.c in the selftest as well.

Fix this by including '-fno-strict-aliasing' during vphn.c compilation in the selftest. This keeps the build working while limiting the scope of the suppression to building vphn tests.

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124427
[2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99768

---
 tools/testing/selftests/powerpc/vphn/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/powerpc/vphn/Makefile +1 -1
index 61d519a076c6f..778fc396340db 100644
@@ -5,7 +5,7 @@ top_srcdir = ../../../../..
 include ../../lib.mk
 include ../flags.mk
 
-CFLAGS += -m64 -I$(CURDIR)
+CFLAGS += -m64 -I$(CURDIR) -fno-strict-aliasing
 
 $(TEST_GEN_PROGS): ../harness.c
 
Signature · 1 line
2.53.0
author maintainer
#65 lore raw

PATCH 63/666 macvlan: annotate data-races around port->bc_queue_len_used

In reply to Greg Kroah-Hartman

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

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

From: Eric Dumazet <[email protected]>

[ Upstream commit 1ef5789d9906df3771c99b7f413caaf2bf473ca5 ]

port->bc_queue_len_used is read and written locklessly, add READ_ONCE()/WRITE_ONCE() annotations.

While WRITE_ONCE() in macvlan_fill_info() is not yet needed, it is a prereq for future RTNL avoidance.

Fixes d4bff72c8401 ("macvlan: Support for high multicast packet rate")
---
 drivers/net/macvlan.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/net/macvlan.c +5 -3
index 3770bc84a9445..b43a1221a5908 100644
@@ -351,6 +351,7 @@ static void macvlan_broadcast_enqueue(struct macvlan_port *port,
 				      const struct macvlan_dev *src,
 				      struct sk_buff *skb)
 {
+	u32 bc_queue_len_used = READ_ONCE(port->bc_queue_len_used);
 	struct sk_buff *nskb;
 	int err = -ENOMEM;
 
@@ -361,7 +362,7 @@ static void macvlan_broadcast_enqueue(struct macvlan_port *port,
 	MACVLAN_SKB_CB(nskb)->src = src;
 
 	spin_lock(&port->bc_queue.lock);
-	if (skb_queue_len(&port->bc_queue) < port->bc_queue_len_used) {
+	if (skb_queue_len(&port->bc_queue) < bc_queue_len_used) {
 		if (src)
 			dev_hold(src->dev);
 		__skb_queue_tail(&port->bc_queue, nskb);
@@ -1723,7 +1724,8 @@ static int macvlan_fill_info(struct sk_buff *skb,
 	}
 	if (nla_put_u32(skb, IFLA_MACVLAN_BC_QUEUE_LEN, vlan->bc_queue_len_req))
 		goto nla_put_failure;
-	if (nla_put_u32(skb, IFLA_MACVLAN_BC_QUEUE_LEN_USED, port->bc_queue_len_used))
+	if (nla_put_u32(skb, IFLA_MACVLAN_BC_QUEUE_LEN_USED,
+			READ_ONCE(port->bc_queue_len_used)))
 		goto nla_put_failure;
 	if (port->bc_cutoff != 1 &&
 	    nla_put_s32(skb, IFLA_MACVLAN_BC_CUTOFF, port->bc_cutoff))
@@ -1783,7 +1785,7 @@ static void update_port_bc_queue_len(struct macvlan_port *port)
 		if (vlan->bc_queue_len_req > max_bc_queue_len_req)
 			max_bc_queue_len_req = vlan->bc_queue_len_req;
 	}
-	port->bc_queue_len_used = max_bc_queue_len_req;
+	WRITE_ONCE(port->bc_queue_len_used, max_bc_queue_len_req);
 }
 
 static int macvlan_device_event(struct notifier_block *unused,
Signature · 1 line
2.53.0
author maintainer
#66 lore raw

PATCH 64/666 bpf: fix end-of-list detection in cgroup_storage_get_next_key()

In reply to Greg Kroah-Hartman

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

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

From: Weiming Shi <[email protected]>

[ Upstream commit 5828b9e5b272ecff7cf5d345128d3de7324117f7 ]

list_next_entry() never returns NULL -- when the current element is the last entry it wraps to the list head via container_of(). The subsequent NULL check is therefore dead code and get_next_key() never returns -ENOENT for the last element, instead reading storage->key from a bogus pointer that aliases internal map fields and copying the result to userspace.

Replace it with list_entry_is_head() so the function correctly returns -ENOENT when there are no more entries.

---
 kernel/bpf/local_storage.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/local_storage.c +1 -1
index 3969eb0382afb..cfb4ff2610518 100644
@@ -259,7 +259,7 @@ static int cgroup_storage_get_next_key(struct bpf_map *_map, void *key,
 			goto enoent;
 
 		storage = list_next_entry(storage, list_map);
-		if (!storage)
+		if (list_entry_is_head(storage, &map->list, list_map))
 			goto enoent;
 	} else {
 		storage = list_first_entry(&map->list,
Signature · 1 line
2.53.0
author maintainer
#67 lore raw

PATCH 65/666 bpf: Fix stale offload->prog pointer after constant blinding

In reply to Greg Kroah-Hartman

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

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

From: MingTao Huang <[email protected]>

[ Upstream commit a1aa9ef47c299c5bbc30594d3c2f0589edf908e6 ]

When a dev-bound-only BPF program (BPF_F_XDP_DEV_BOUND_ONLY) undergoes JIT compilation with constant blinding enabled (bpf_jit_harden >= 2), bpf_jit_blind_constants() clones the program. The original prog is then freed in bpf_jit_prog_release_other(), which updates aux->prog to point to the surviving clone, but fails to update offload->prog.

This leaves offload->prog pointing to the freed original program. When the network namespace is subsequently destroyed, cleanup_net() triggers bpf_dev_bound_netdev_unregister(), which iterates ondev->progs and calls __bpf_prog_offload_destroy(offload->prog). Accessing the freed prog causes a page fault:

BUG: unable to handle page fault for address: ffffc900085f1038
Workqueue: netns cleanup_net
RIP: 0010:__bpf_prog_offload_destroy+0xc/0x80
Call Trace:
__bpf_offload_dev_netdev_unregister+0x257/0x350
bpf_dev_bound_netdev_unregister+0x4a/0x90
unregister_netdevice_many_notify+0x2a2/0x660

...
cleanup_net+0x21a/0x320

The test sequence that triggers this reliably is:

1. Set net.core.bpf_jit_harden=2 (echo 2 > /proc/sys/net/core/bpf_jit_harden)
2. Run xdp_metadata selftest, which creates a dev-bound-only XDP program on a veth inside a netns (./test_progs -t xdp_metadata)
3. cleanup_net -> page fault in __bpf_prog_offload_destroy

Dev-bound-only programs are unique in that they have an offload structure but go through the normal JIT path instead of bpf_prog_offload_compile(). This means they are subject to constant blinding's prog clone-and-replace, while also having offload->prog that must stay in sync.

Fix this by updating offload->prog in bpf_jit_prog_release_other(), alongside the existing aux->prog update. Both are back-pointers to the prog that must be kept in sync when the prog is replaced.

Fixes 2b3486bc2d23 ("bpf: Introduce device-bound XDP programs")
---
 kernel/bpf/core.c | 2 ++
 1 file changed, 2 insertions(+)
kernel/bpf/core.c +2 -0
index b58833e99969a..517710c89fa50 100644
@@ -1489,6 +1489,8 @@ void bpf_jit_prog_release_other(struct bpf_prog *fp, struct bpf_prog *fp_other)
 	 * know whether fp here is the clone or the original.
 	 */
 	fp->aux->prog = fp;
+	if (fp->aux->offload)
+		fp->aux->offload->prog = fp;
 	bpf_prog_clone_free(fp_other);
 }
 
Signature · 1 line
2.53.0
author maintainer
#68 lore raw

PATCH 66/666 wifi: brcmfmac: Fix error pointer dereference

In reply to Greg Kroah-Hartman

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

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

From: Ethan Tidmore <[email protected]>

[ Upstream commit dd8592fc6007a451c3e4b9025de365e39de8178a ]

The function brcmf_chip_add_core() can return an error pointer and is not checked. Add checks for error pointer.

Detected by Smatch:
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c:1010 brcmf_chip_recognition() error:
'core' dereferencing possible ERR_PTR()

drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c:1013 brcmf_chip_recognition() error:
'core' dereferencing possible ERR_PTR()

drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c:1016 brcmf_chip_recognition() error:
'core' dereferencing possible ERR_PTR()

drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c:1019 brcmf_chip_recognition() error:
'core' dereferencing possible ERR_PTR()

drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c:1022 brcmf_chip_recognition() error:
'core' dereferencing possible ERR_PTR()

Fixes cb7cf7be9eba7 ("brcmfmac: make chip related functions host interface independent")
[add missing wifi: prefix]
---
 .../wireless/broadcom/brcm80211/brcmfmac/chip.c   | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +15 -0
index 2ef92ef25517e..4dbb1898f3065 100644
@@ -1006,18 +1006,33 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
 
 		core = brcmf_chip_add_core(ci, BCMA_CORE_CHIPCOMMON,
 					   SI_ENUM_BASE_DEFAULT, 0);
+		if (IS_ERR(core))
+			return PTR_ERR(core);
+
 		brcmf_chip_sb_corerev(ci, core);
 		core = brcmf_chip_add_core(ci, BCMA_CORE_SDIO_DEV,
 					   BCM4329_CORE_BUS_BASE, 0);
+		if (IS_ERR(core))
+			return PTR_ERR(core);
+
 		brcmf_chip_sb_corerev(ci, core);
 		core = brcmf_chip_add_core(ci, BCMA_CORE_INTERNAL_MEM,
 					   BCM4329_CORE_SOCRAM_BASE, 0);
+		if (IS_ERR(core))
+			return PTR_ERR(core);
+
 		brcmf_chip_sb_corerev(ci, core);
 		core = brcmf_chip_add_core(ci, BCMA_CORE_ARM_CM3,
 					   BCM4329_CORE_ARM_BASE, 0);
+		if (IS_ERR(core))
+			return PTR_ERR(core);
+
 		brcmf_chip_sb_corerev(ci, core);
 
 		core = brcmf_chip_add_core(ci, BCMA_CORE_80211, 0x18001000, 0);
+		if (IS_ERR(core))
+			return PTR_ERR(core);
+
 		brcmf_chip_sb_corerev(ci, core);
 	} else if (socitype == SOCI_AI) {
 		ci->iscoreup = brcmf_chip_ai_iscoreup;
Signature · 1 line
2.53.0
author maintainer
#69 lore raw

PATCH 67/666 wifi: mac80211: handle VHT EXT NSS in ieee80211_determine_our_sta_mode()

In reply to Greg Kroah-Hartman

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

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

From: Nicolas Escande <[email protected]>

[ Upstream commit b5b8e295973083abf823fb66647a7c702a8db8a7 ]

A station which has a NSS ratio on the number of streams it is capable of in 160MHz VHT operation is supposed to use the 'Extended NSS BW Support' as defined by section '9.4.2.156.2 VHT Capabilities Information field'.

This was missing in ieee80211_determine_our_sta_mode() and so we would wrongfully downgrade our bandwidth when connecting to an AP that supported 160MHz with messages such as:

	[   37.638346] wlan1: AP XX:XX:XX:XX:XX:XX changed bandwidth in assoc response, new used config is 5280.000 MHz, width 3 (5290.000/0 MHz)
Fixes 310c8387c638 ("wifi: mac80211: clean up connection process")
---
 net/mac80211/mlme.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
net/mac80211/mlme.c +2 -1
index 835316fd3cd76..20e5f513a27a3 100644
@@ -5304,7 +5304,8 @@ ieee80211_determine_our_sta_mode(struct ieee80211_sub_if_data *sdata,
 
 	if (is_5ghz &&
 	    !(vht_cap.cap & (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
-			     IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))) {
+			     IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ |
+			     IEEE80211_VHT_CAP_EXT_NSS_BW_MASK))) {
 		conn->bw_limit = IEEE80211_CONN_BW_LIMIT_80;
 		mlme_link_id_dbg(sdata, link_id,
 				 "no VHT 160 MHz capability on 5 GHz, limiting to 80 MHz");
Signature · 1 line
2.53.0
author maintainer
#70 lore raw

PATCH 68/666 bpf: Drop task_to_inode and inet_conn_established from lsm sleepable hooks

In reply to Greg Kroah-Hartman

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

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

From: Jiayuan Chen <[email protected]>

[ Upstream commit beaf0e96b1da74549a6cabd040f9667d83b2e97e ]

bpf_lsm_task_to_inode() is called under rcu_read_lock() and bpf_lsm_inet_conn_established() is called from softirq context, so neither hook can be used by sleepable LSM programs.

---
 kernel/bpf/bpf_lsm.c | 3 ---
 1 file changed, 3 deletions(-)
kernel/bpf/bpf_lsm.c +0 -3
index 3bc61628ab251..0849453b36176 100644
@@ -355,8 +355,6 @@ BTF_ID(func, bpf_lsm_sb_umount)
 BTF_ID(func, bpf_lsm_settime)
 
 #ifdef CONFIG_SECURITY_NETWORK
-BTF_ID(func, bpf_lsm_inet_conn_established)
-
 BTF_ID(func, bpf_lsm_socket_accept)
 BTF_ID(func, bpf_lsm_socket_bind)
 BTF_ID(func, bpf_lsm_socket_connect)
@@ -379,7 +377,6 @@ BTF_ID(func, bpf_lsm_current_getsecid_subj)
 BTF_ID(func, bpf_lsm_task_getsecid_obj)
 BTF_ID(func, bpf_lsm_task_prctl)
 BTF_ID(func, bpf_lsm_task_setscheduler)
-BTF_ID(func, bpf_lsm_task_to_inode)
 BTF_ID(func, bpf_lsm_userns_create)
 BTF_SET_END(sleepable_lsm_hooks)
 
Signature · 1 line
2.53.0
author maintainer
#71 lore raw

PATCH 69/666 bpf: reject negative CO-RE accessor indices in bpf_core_parse_spec()

In reply to Greg Kroah-Hartman

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

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

From: Weiming Shi <[email protected]>

[ Upstream commit 1c22483a2c4bbf747787f328392ca3e68619c4dc ]

CO-RE accessor strings are colon-separated indices that describe a path from a root BTF type to a target field, e.g. "0:1:2" walks through nested struct members. bpf_core_parse_spec() parses each component with sscanf("%d"), so negative values like -1 are silently accepted. The subsequent bounds checks (access_idx >= btf_vlen(t)) only guard the upper bound and always pass for negative values because C integer promotion converts the __u16 btf_vlen result to int, making the comparison (int)(-1) >= (int)(N) false for any positive N.

When -1 reaches btf_member_bit_offset() it gets cast to u32 0xffffffff, producing an out-of-bounds read far past the members array. A crafted BPF program with a negative CO-RE accessor on any struct that exists in vmlinux BTF (e.g. task_struct) crashes the kernel deterministically during BPF_PROG_LOAD on any system with CONFIG_DEBUG_INFO_BTF=y (default on major distributions). The bug is reachable with CAP_BPF:

 BUG: unable to handle page fault for address: ffffed11818b6626
 #PF: supervisor read access in kernel mode
 #PF: error_code(0x0000) - not-present page
 Oops: Oops: 0000 [#1] SMP KASAN NOPTI
 CPU: 0 UID: 0 PID: 85 Comm: poc Not tainted 7.0.0-rc6 #18 PREEMPT(full)
 RIP: 0010:bpf_core_parse_spec (tools/lib/bpf/relo_core.c:354)
 RAX: 00000000ffffffff
 Call Trace:
  <TASK>
  bpf_core_calc_relo_insn (tools/lib/bpf/relo_core.c:1321)
  bpf_core_apply (kernel/bpf/btf.c:9507)
  check_core_relo (kernel/bpf/verifier.c:19475)
  bpf_check (kernel/bpf/verifier.c:26031)
  bpf_prog_load (kernel/bpf/syscall.c:3089)
  __sys_bpf (kernel/bpf/syscall.c:6228)
  </TASK>

CO-RE accessor indices are inherently non-negative (struct member index, array element index, or enumerator index), so reject them immediately after parsing.

---
 tools/lib/bpf/relo_core.c | 2 ++
 1 file changed, 2 insertions(+)
tools/lib/bpf/relo_core.c +2 -0
index 63a4d5ad12d1a..04c8febfc0aa7 100644
@@ -293,6 +293,8 @@ int bpf_core_parse_spec(const char *prog_name, const struct btf *btf,
 			++spec_str;
 		if (sscanf(spec_str, "%d%n", &access_idx, &parsed_len) != 1)
 			return -EINVAL;
+		if (access_idx < 0)
+			return -EINVAL;
 		if (spec->raw_len == BPF_CORE_SPEC_MAX_LEN)
 			return -E2BIG;
 		spec_str += parsed_len;
Signature · 1 line
2.53.0
author maintainer
#72 lore raw

PATCH 70/666 wifi: ath10k: fix station lookup failure during disconnect

In reply to Greg Kroah-Hartman

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

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

From: Baochen Qiang <[email protected]>

[ Upstream commit 9a34a59c6086ae731a06b3e61b0951feef758648 ]

Recent commit [1] moved station statistics collection to an earlier stage of the disconnect flow. With this change in place, ath10k fails to resolve the station entry when handling a peer stats event triggered during disconnect, resulting in log messages such as:

wlp58s0: deauthenticating from 74:1a:e0:e7:b4:c8 by local choice (Reason: 3=DEAUTH_LEAVING) ath10k_pci 0000:3a:00.0: not found station for peer stats
ath10k_pci 0000:3a:00.0: failed to parse stats info tlv: -22

The failure occurs because ath10k relies on ieee80211_find_sta_by_ifaddr() for station lookup. That function uses local->sta_hash, but by the time the peer stats request is triggered during disconnect, mac80211 has already removed the station from that hash table, leading to lookup failure.

Before commit [1], this issue was not visible because the transition from IEEE80211_STA_NONE to IEEE80211_STA_NOTEXIST prevented ath10k from sending a peer stats request at all: ath10k_mac_sta_get_peer_stats_info() would fail early to find the peer and skip requesting statistics.

Fix this by switching the lookup path to ath10k_peer_find(), which queries ath10k's internal peer table. At the point where the firmware emits the peer stats event, the peer entry is still present in the driver's list, ensuring lookup succeeds.

Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00309-QCARMSWPZ-1

---
 drivers/net/wireless/ath/ath10k/wmi-tlv.c | 26 +++++++++++++----------
 1 file changed, 15 insertions(+), 11 deletions(-)
drivers/net/wireless/ath/ath10k/wmi-tlv.c +15 -11
index 16d07d619b4df..ba1294c8ee39f 100644
@@ -3,7 +3,7 @@
  * Copyright (c) 2005-2011 Atheros Communications Inc.
  * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
  * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
- * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
  */
 #include "core.h"
 #include "debug.h"
@@ -14,6 +14,7 @@
 #include "wmi-tlv.h"
 #include "p2p.h"
 #include "testmode.h"
+#include "txrx.h"
 #include <linux/bitfield.h>
 
 /***************/
@@ -224,8 +225,9 @@ static int ath10k_wmi_tlv_parse_peer_stats_info(struct ath10k *ar, u16 tag, u16
 						const void *ptr, void *data)
 {
 	const struct wmi_tlv_peer_stats_info *stat = ptr;
-	struct ieee80211_sta *sta;
+	u32 vdev_id = *(u32 *)data;
 	struct ath10k_sta *arsta;
+	struct ath10k_peer *peer;
 
 	if (tag != WMI_TLV_TAG_STRUCT_PEER_STATS_INFO)
 		return -EPROTO;
@@ -241,20 +243,20 @@ static int ath10k_wmi_tlv_parse_peer_stats_info(struct ath10k *ar, u16 tag, u16
 		   __le32_to_cpu(stat->last_tx_rate_code),
 		   __le32_to_cpu(stat->last_tx_bitrate_kbps));
 
-	rcu_read_lock();
-	sta = ieee80211_find_sta_by_ifaddr(ar->hw, stat->peer_macaddr.addr, NULL);
-	if (!sta) {
-		rcu_read_unlock();
-		ath10k_warn(ar, "not found station for peer stats\n");
+	guard(spinlock_bh)(&ar->data_lock);
+
+	peer = ath10k_peer_find(ar, vdev_id, stat->peer_macaddr.addr);
+	if (!peer || !peer->sta) {
+		ath10k_warn(ar, "not found %s with vdev id %u mac addr %pM for peer stats\n",
+			    peer ? "sta" : "peer", vdev_id, stat->peer_macaddr.addr);
 		return -EINVAL;
 	}
 
-	arsta = (struct ath10k_sta *)sta->drv_priv;
+	arsta = (struct ath10k_sta *)peer->sta->drv_priv;
 	arsta->rx_rate_code = __le32_to_cpu(stat->last_rx_rate_code);
 	arsta->rx_bitrate_kbps = __le32_to_cpu(stat->last_rx_bitrate_kbps);
 	arsta->tx_rate_code = __le32_to_cpu(stat->last_tx_rate_code);
 	arsta->tx_bitrate_kbps = __le32_to_cpu(stat->last_tx_bitrate_kbps);
-	rcu_read_unlock();
 
 	return 0;
 }
@@ -266,6 +268,7 @@ static int ath10k_wmi_tlv_op_pull_peer_stats_info(struct ath10k *ar,
 	const struct wmi_tlv_peer_stats_info_ev *ev;
 	const void *data;
 	u32 num_peer_stats;
+	u32 vdev_id;
 	int ret;
 
 	tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
@@ -284,15 +287,16 @@ static int ath10k_wmi_tlv_op_pull_peer_stats_info(struct ath10k *ar,
 	}
 
 	num_peer_stats = __le32_to_cpu(ev->num_peers);
+	vdev_id = __le32_to_cpu(ev->vdev_id);
 
 	ath10k_dbg(ar, ATH10K_DBG_WMI,
 		   "wmi tlv peer stats info update peer vdev id %d peers %i more data %d\n",
-		   __le32_to_cpu(ev->vdev_id),
+		   vdev_id,
 		   num_peer_stats,
 		   __le32_to_cpu(ev->more_data));
 
 	ret = ath10k_wmi_tlv_iter(ar, data, ath10k_wmi_tlv_len(data),
-				  ath10k_wmi_tlv_parse_peer_stats_info, NULL);
+				  ath10k_wmi_tlv_parse_peer_stats_info, &vdev_id);
 	if (ret)
 		ath10k_warn(ar, "failed to parse stats info tlv: %d\n", ret);
 
Signature · 1 line
2.53.0
author maintainer
#73 lore raw

PATCH 71/666 ACPI: AGDI: fix missing newline in error message

In reply to Greg Kroah-Hartman

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

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

From: Haoyu Lu <[email protected]>

[ Upstream commit b178330b67abb7293b6de28b2a49d49c83962db5 ]

Add the missing trailing newline to the dev_err() message printed when SDEI event registration fails.

This keeps the error output as a properly terminated log line.

Fixes a2a591fb76e6 ("ACPI: AGDI: Add driver for Arm Generic Diagnostic Dump and Reset device")
---
 drivers/acpi/arm64/agdi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/acpi/arm64/agdi.c +1 -1
index f5f21dd0d277e..dccbd1c4dafcf 100644
@@ -32,7 +32,7 @@ static int agdi_sdei_probe(struct platform_device *pdev,
 
 	err = sdei_event_register(adata->sdei_event, agdi_sdei_handler, pdev);
 	if (err) {
-		dev_err(&pdev->dev, "Failed to register for SDEI event %d",
+		dev_err(&pdev->dev, "Failed to register for SDEI event %d\n",
 			adata->sdei_event);
 		return err;
 	}
Signature · 1 line
2.53.0
author maintainer
#74 lore raw

PATCH 72/666 arm64: kexec: Remove duplicate allocation for trans_pgd

In reply to Greg Kroah-Hartman

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

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

From: Wang Wensheng <[email protected]>

[ Upstream commit ee020bf6f14094c9ae434bb37e6957a1fdad513c ]

trans_pgd would be allocated in trans_pgd_create_copy(), so remove the duplicate allocation before calling trans_pgd_create_copy().

Fixes 3744b5280e67 ("arm64: kexec: install a copy of the linear-map")
---
 arch/arm64/kernel/machine_kexec.c | 3 ---
 1 file changed, 3 deletions(-)
arch/arm64/kernel/machine_kexec.c +0 -3
index 6f121a0164a48..28df62051cc97 100644
@@ -129,9 +129,6 @@ int machine_kexec_post_load(struct kimage *kimage)
 	}
 
 	/* Create a copy of the linear map */
-	trans_pgd = kexec_page_alloc(kimage);
-	if (!trans_pgd)
-		return -ENOMEM;
 	rc = trans_pgd_create_copy(&info, &trans_pgd, PAGE_OFFSET, PAGE_END);
 	if (rc)
 		return rc;
Signature · 1 line
2.53.0
author maintainer
#75 lore raw

PATCH 73/666 net: bcmgenet: fix off-by-one in bcmgenet_put_txcb

In reply to Greg Kroah-Hartman

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

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

From: Justin Chen <[email protected]>

[ Upstream commit 57f3f53d2c9c5a9e133596e2f7bc1c50688a6d38 ]

The write_ptr points to the next open tx_cb. We want to return the tx_cb that gets rewinded, so we must rewind the pointer first then return the tx_cb that it points to. That way the txcb can be correctly cleaned up.

Fixes 876dbadd53a7 ("net: bcmgenet: Fix unmapping of fragments in bcmgenet_xmit()")
---
 drivers/net/ethernet/broadcom/genet/bcmgenet.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +3 -3
index 49f6e83d60139..ac9bd34f3b3ce 100644
@@ -1740,15 +1740,15 @@ static struct enet_cb *bcmgenet_put_txcb(struct bcmgenet_priv *priv,
 {
 	struct enet_cb *tx_cb_ptr;
 
-	tx_cb_ptr = ring->cbs;
-	tx_cb_ptr += ring->write_ptr - ring->cb_ptr;
-
 	/* Rewinding local write pointer */
 	if (ring->write_ptr == ring->cb_ptr)
 		ring->write_ptr = ring->end_ptr;
 	else
 		ring->write_ptr--;
 
+	tx_cb_ptr = ring->cbs;
+	tx_cb_ptr += ring->write_ptr - ring->cb_ptr;
+
 	return tx_cb_ptr;
 }
 
Signature · 1 line
2.53.0
author maintainer
#76 lore raw

PATCH 74/666 net: bcmgenet: add bcmgenet_has_* helpers

In reply to Greg Kroah-Hartman

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

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

From: Doug Berger <[email protected]>

[ Upstream commit 07c1a756a50b1180a085ab61819a388bbb906a95 ]

Introduce helper functions to indicate whether the driver should make use of a particular feature that it supports. These helpers abstract the implementation of how the feature availability is encoded.

Stable-dep-of: 5393b2b5bee2 ("net: bcmgenet: fix racing timeout handler")

---
 .../net/ethernet/broadcom/genet/bcmgenet.c    | 20 +++++++-------
 .../net/ethernet/broadcom/genet/bcmgenet.h    | 27 ++++++++++++++++++-
 drivers/net/ethernet/broadcom/genet/bcmmii.c  |  6 ++---
 3 files changed, 39 insertions(+), 14 deletions(-)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +10 -10
index ac9bd34f3b3ce..1767d96dd6546 100644
@@ -104,7 +104,7 @@ static inline void dmadesc_set_addr(struct bcmgenet_priv *priv,
 	 * the platform is explicitly configured for 64-bits/LPAE.
 	 */
 #ifdef CONFIG_PHYS_ADDR_T_64BIT
-	if (priv->hw_params->flags & GENET_HAS_40BITS)
+	if (bcmgenet_has_40bits(priv))
 		bcmgenet_writel(upper_32_bits(addr), d + DMA_DESC_ADDRESS_HI);
 #endif
 }
@@ -1644,9 +1644,9 @@ static int bcmgenet_power_down(struct bcmgenet_priv *priv,
 
 	case GENET_POWER_PASSIVE:
 		/* Power down LED */
-		if (priv->hw_params->flags & GENET_HAS_EXT) {
+		if (bcmgenet_has_ext(priv)) {
 			reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
-			if (GENET_IS_V5(priv) && !priv->ephy_16nm)
+			if (GENET_IS_V5(priv) && !bcmgenet_has_ephy_16nm(priv))
 				reg |= EXT_PWR_DOWN_PHY_EN |
 				       EXT_PWR_DOWN_PHY_RD |
 				       EXT_PWR_DOWN_PHY_SD |
@@ -1674,7 +1674,7 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv,
 {
 	u32 reg;
 
-	if (!(priv->hw_params->flags & GENET_HAS_EXT))
+	if (!bcmgenet_has_ext(priv))
 		return;
 
 	reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
@@ -1683,7 +1683,7 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv,
 	case GENET_POWER_PASSIVE:
 		reg &= ~(EXT_PWR_DOWN_DLL | EXT_PWR_DOWN_BIAS |
 			 EXT_ENERGY_DET_MASK);
-		if (GENET_IS_V5(priv) && !priv->ephy_16nm) {
+		if (GENET_IS_V5(priv) && !bcmgenet_has_ephy_16nm(priv)) {
 			reg &= ~(EXT_PWR_DOWN_PHY_EN |
 				 EXT_PWR_DOWN_PHY_RD |
 				 EXT_PWR_DOWN_PHY_SD |
@@ -2516,7 +2516,7 @@ static void bcmgenet_link_intr_enable(struct bcmgenet_priv *priv)
 	} else if (priv->ext_phy) {
 		int0_enable |= UMAC_IRQ_LINK_EVENT;
 	} else if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
-		if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
+		if (bcmgenet_has_moca_link_det(priv))
 			int0_enable |= UMAC_IRQ_LINK_EVENT;
 	}
 	bcmgenet_intrl2_0_writel(priv, int0_enable, INTRL2_CPU_MASK_CLEAR);
@@ -2581,7 +2581,7 @@ static void init_umac(struct bcmgenet_priv *priv)
 	}
 
 	/* Enable MDIO interrupts on GENET v3+ */
-	if (priv->hw_params->flags & GENET_HAS_MDIO_INTR)
+	if (bcmgenet_has_mdio_intr(priv))
 		int0_enable |= (UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR);
 
 	bcmgenet_intrl2_0_writel(priv, int0_enable, INTRL2_CPU_MASK_CLEAR);
@@ -3221,7 +3221,7 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id)
 		}
 	}
 
-	if ((priv->hw_params->flags & GENET_HAS_MDIO_INTR) &&
+	if (bcmgenet_has_mdio_intr(priv) &&
 		status & (UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR)) {
 		wake_up(&priv->wq);
 	}
@@ -3891,7 +3891,7 @@ static void bcmgenet_set_hw_params(struct bcmgenet_priv *priv)
 	}
 
 #ifdef CONFIG_PHYS_ADDR_T_64BIT
-	if (!(params->flags & GENET_HAS_40BITS))
+	if (!bcmgenet_has_40bits(priv))
 		pr_warn("GENET does not support 40-bits PA\n");
 #endif
 
@@ -4070,7 +4070,7 @@ static int bcmgenet_probe(struct platform_device *pdev)
 	bcmgenet_set_hw_params(priv);
 
 	err = -EIO;
-	if (priv->hw_params->flags & GENET_HAS_40BITS)
+	if (bcmgenet_has_40bits(priv))
 		err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(40));
 	if (err)
 		err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
drivers/net/ethernet/broadcom/genet/bcmgenet.h +26 -1
index c0005a0fff567..ed7402fb7fdaa 100644
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2014-2024 Broadcom
+ * Copyright (c) 2014-2025 Broadcom
  */
 
 #ifndef __BCMGENET_H__
@@ -648,6 +648,31 @@ struct bcmgenet_priv {
 	struct bcmgenet_mib_counters mib;
 };
 
+static inline bool bcmgenet_has_40bits(struct bcmgenet_priv *priv)
+{
+	return !!(priv->hw_params->flags & GENET_HAS_40BITS);
+}
+
+static inline bool bcmgenet_has_ext(struct bcmgenet_priv *priv)
+{
+	return !!(priv->hw_params->flags & GENET_HAS_EXT);
+}
+
+static inline bool bcmgenet_has_mdio_intr(struct bcmgenet_priv *priv)
+{
+	return !!(priv->hw_params->flags & GENET_HAS_MDIO_INTR);
+}
+
+static inline bool bcmgenet_has_moca_link_det(struct bcmgenet_priv *priv)
+{
+	return !!(priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET);
+}
+
+static inline bool bcmgenet_has_ephy_16nm(struct bcmgenet_priv *priv)
+{
+	return priv->ephy_16nm;
+}
+
 #define GENET_IO_MACRO(name, offset)					\
 static inline u32 bcmgenet_##name##_readl(struct bcmgenet_priv *priv,	\
 					u32 off)			\
drivers/net/ethernet/broadcom/genet/bcmmii.c +3 -3
index 9beb65e6d0a96..eeb2aa75efdae 100644
@@ -2,7 +2,7 @@
 /*
  * Broadcom GENET MDIO routines
  *
- * Copyright (c) 2014-2024 Broadcom
+ * Copyright (c) 2014-2025 Broadcom
  */
 
 #include <linux/acpi.h>
@@ -151,7 +151,7 @@ void bcmgenet_phy_power_set(struct net_device *dev, bool enable)
 	u32 reg = 0;
 
 	/* EXT_GPHY_CTRL is only valid for GENETv4 and onward */
-	if (GENET_IS_V4(priv) || priv->ephy_16nm) {
+	if (GENET_IS_V4(priv) || bcmgenet_has_ephy_16nm(priv)) {
 		reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL);
 		if (enable) {
 			reg &= ~EXT_CK25_DIS;
@@ -181,7 +181,7 @@ void bcmgenet_phy_power_set(struct net_device *dev, bool enable)
 
 static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
 {
-	if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
+	if (bcmgenet_has_moca_link_det(priv))
 		fixed_phy_set_link_update(priv->dev->phydev,
 					  bcmgenet_fixed_phy_link_update);
 }
Signature · 1 line
2.53.0
author maintainer
#77 lore raw

PATCH 75/666 net: bcmgenet: move DESC_INDEX flow to ring 0

In reply to Greg Kroah-Hartman

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

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

From: Doug Berger <[email protected]>

[ Upstream commit 3b5d4f5a820d362dd46472542b2e961fb1f93515 ]

The default transmit and receive packet handling is moved from the DESC_INDEX (i.e. 16) descriptor rings to the Ring 0 queues. This saves a fair amount of special case code by unifying the handling.

A default dummy filter is enabled in the Hardware Filter Block to route default receive packets to Ring 0.

Stable-dep-of: 5393b2b5bee2 ("net: bcmgenet: fix racing timeout handler")

---
 .../net/ethernet/broadcom/genet/bcmgenet.c    | 369 +++++-------------
 .../net/ethernet/broadcom/genet/bcmgenet.h    |  12 +-
 .../ethernet/broadcom/genet/bcmgenet_wol.c    |   4 +-
 3 files changed, 110 insertions(+), 275 deletions(-)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +103 -266
index 1767d96dd6546..8b73f1ed97a4c 100644
@@ -41,15 +41,13 @@
 
 #include "bcmgenet.h"
 
-/* Maximum number of hardware queues, downsized if needed */
-#define GENET_MAX_MQ_CNT	4
-
 /* Default highest priority queue for multi queue support */
-#define GENET_Q0_PRIORITY	0
+#define GENET_Q1_PRIORITY	0
+#define GENET_Q0_PRIORITY	1
 
-#define GENET_Q16_RX_BD_CNT	\
+#define GENET_Q0_RX_BD_CNT	\
 	(TOTAL_DESC - priv->hw_params->rx_queues * priv->hw_params->rx_bds_per_q)
-#define GENET_Q16_TX_BD_CNT	\
+#define GENET_Q0_TX_BD_CNT	\
 	(TOTAL_DESC - priv->hw_params->tx_queues * priv->hw_params->tx_bds_per_q)
 
 #define RX_BUF_LENGTH		2048
@@ -585,7 +583,7 @@ static void bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv,
 	u16 mask_16;
 	size_t size;
 
-	f = fs->location;
+	f = fs->location + 1;
 	if (fs->flow_type & FLOW_MAC_EXT) {
 		bcmgenet_hfb_insert_data(priv, f, 0,
 					 &fs->h_ext.h_dest, &fs->m_ext.h_dest,
@@ -667,19 +665,14 @@ static void bcmgenet_hfb_create_rxnfc_filter(struct bcmgenet_priv *priv,
 	}
 
 	bcmgenet_hfb_set_filter_length(priv, f, 2 * f_length);
-	if (!fs->ring_cookie || fs->ring_cookie == RX_CLS_FLOW_WAKE) {
-		/* Ring 0 flows can be handled by the default Descriptor Ring
-		 * We'll map them to ring 0, but don't enable the filter
-		 */
+	if (fs->ring_cookie == RX_CLS_FLOW_WAKE)
 		bcmgenet_hfb_set_filter_rx_queue_mapping(priv, f, 0);
-		rule->state = BCMGENET_RXNFC_STATE_DISABLED;
-	} else {
+	else
 		/* Other Rx rings are direct mapped here */
 		bcmgenet_hfb_set_filter_rx_queue_mapping(priv, f,
 							 fs->ring_cookie);
-		bcmgenet_hfb_enable_filter(priv, f);
-		rule->state = BCMGENET_RXNFC_STATE_ENABLED;
-	}
+	bcmgenet_hfb_enable_filter(priv, f);
+	rule->state = BCMGENET_RXNFC_STATE_ENABLED;
 }
 
 /* bcmgenet_hfb_clear
@@ -715,6 +708,10 @@ static void bcmgenet_hfb_clear(struct bcmgenet_priv *priv)
 
 	for (i = 0; i < priv->hw_params->hfb_filter_cnt; i++)
 		bcmgenet_hfb_clear_filter(priv, i);
+
+	/* Enable filter 0 to send default flow to ring 0 */
+	bcmgenet_hfb_set_filter_length(priv, 0, 4);
+	bcmgenet_hfb_enable_filter(priv, 0);
 }
 
 static void bcmgenet_hfb_init(struct bcmgenet_priv *priv)
@@ -819,20 +816,16 @@ static int bcmgenet_get_coalesce(struct net_device *dev,
 	unsigned int i;
 
 	ec->tx_max_coalesced_frames =
-		bcmgenet_tdma_ring_readl(priv, DESC_INDEX,
-					 DMA_MBUF_DONE_THRESH);
+		bcmgenet_tdma_ring_readl(priv, 0, DMA_MBUF_DONE_THRESH);
 	ec->rx_max_coalesced_frames =
-		bcmgenet_rdma_ring_readl(priv, DESC_INDEX,
-					 DMA_MBUF_DONE_THRESH);
+		bcmgenet_rdma_ring_readl(priv, 0, DMA_MBUF_DONE_THRESH);
 	ec->rx_coalesce_usecs =
-		bcmgenet_rdma_readl(priv, DMA_RING16_TIMEOUT) * 8192 / 1000;
+		bcmgenet_rdma_readl(priv, DMA_RING0_TIMEOUT) * 8192 / 1000;
 
-	for (i = 0; i < priv->hw_params->rx_queues; i++) {
+	for (i = 0; i <= priv->hw_params->rx_queues; i++) {
 		ring = &priv->rx_rings[i];
 		ec->use_adaptive_rx_coalesce |= ring->dim.use_dim;
 	}
-	ring = &priv->rx_rings[DESC_INDEX];
-	ec->use_adaptive_rx_coalesce |= ring->dim.use_dim;
 
 	return 0;
 }
@@ -902,17 +895,13 @@ static int bcmgenet_set_coalesce(struct net_device *dev,
 	/* Program all TX queues with the same values, as there is no
 	 * ethtool knob to do coalescing on a per-queue basis
 	 */
-	for (i = 0; i < priv->hw_params->tx_queues; i++)
+	for (i = 0; i <= priv->hw_params->tx_queues; i++)
 		bcmgenet_tdma_ring_writel(priv, i,
 					  ec->tx_max_coalesced_frames,
 					  DMA_MBUF_DONE_THRESH);
-	bcmgenet_tdma_ring_writel(priv, DESC_INDEX,
-				  ec->tx_max_coalesced_frames,
-				  DMA_MBUF_DONE_THRESH);
 
-	for (i = 0; i < priv->hw_params->rx_queues; i++)
+	for (i = 0; i <= priv->hw_params->rx_queues; i++)
 		bcmgenet_set_ring_rx_coalesce(&priv->rx_rings[i], ec);
-	bcmgenet_set_ring_rx_coalesce(&priv->rx_rings[DESC_INDEX], ec);
 
 	return 0;
 }
@@ -1120,7 +1109,7 @@ static const struct bcmgenet_stats bcmgenet_gstrings_stats[] = {
 	STAT_GENET_Q(1),
 	STAT_GENET_Q(2),
 	STAT_GENET_Q(3),
-	STAT_GENET_Q(16),
+	STAT_GENET_Q(4),
 };
 
 #define BCMGENET_STATS_LEN	ARRAY_SIZE(bcmgenet_gstrings_stats)
@@ -1465,10 +1454,10 @@ static int bcmgenet_insert_flow(struct net_device *dev,
 		loc_rule = &priv->rxnfc_rules[cmd->fs.location];
 	}
 	if (loc_rule->state == BCMGENET_RXNFC_STATE_ENABLED)
-		bcmgenet_hfb_disable_filter(priv, cmd->fs.location);
+		bcmgenet_hfb_disable_filter(priv, cmd->fs.location + 1);
 	if (loc_rule->state != BCMGENET_RXNFC_STATE_UNUSED) {
 		list_del(&loc_rule->list);
-		bcmgenet_hfb_clear_filter(priv, cmd->fs.location);
+		bcmgenet_hfb_clear_filter(priv, cmd->fs.location + 1);
 	}
 	loc_rule->state = BCMGENET_RXNFC_STATE_UNUSED;
 	memcpy(&loc_rule->fs, &cmd->fs,
@@ -1498,10 +1487,10 @@ static int bcmgenet_delete_flow(struct net_device *dev,
 	}
 
 	if (rule->state == BCMGENET_RXNFC_STATE_ENABLED)
-		bcmgenet_hfb_disable_filter(priv, cmd->fs.location);
+		bcmgenet_hfb_disable_filter(priv, cmd->fs.location + 1);
 	if (rule->state != BCMGENET_RXNFC_STATE_UNUSED) {
 		list_del(&rule->list);
-		bcmgenet_hfb_clear_filter(priv, cmd->fs.location);
+		bcmgenet_hfb_clear_filter(priv, cmd->fs.location + 1);
 	}
 	rule->state = BCMGENET_RXNFC_STATE_UNUSED;
 	memset(&rule->fs, 0, sizeof(struct ethtool_rx_flow_spec));
@@ -1752,18 +1741,6 @@ static struct enet_cb *bcmgenet_put_txcb(struct bcmgenet_priv *priv,
 	return tx_cb_ptr;
 }
 
-static inline void bcmgenet_rx_ring16_int_disable(struct bcmgenet_rx_ring *ring)
-{
-	bcmgenet_intrl2_0_writel(ring->priv, UMAC_IRQ_RXDMA_DONE,
-				 INTRL2_CPU_MASK_SET);
-}
-
-static inline void bcmgenet_rx_ring16_int_enable(struct bcmgenet_rx_ring *ring)
-{
-	bcmgenet_intrl2_0_writel(ring->priv, UMAC_IRQ_RXDMA_DONE,
-				 INTRL2_CPU_MASK_CLEAR);
-}
-
 static inline void bcmgenet_rx_ring_int_disable(struct bcmgenet_rx_ring *ring)
 {
 	bcmgenet_intrl2_1_writel(ring->priv,
@@ -1778,18 +1755,6 @@ static inline void bcmgenet_rx_ring_int_enable(struct bcmgenet_rx_ring *ring)
 				 INTRL2_CPU_MASK_CLEAR);
 }
 
-static inline void bcmgenet_tx_ring16_int_disable(struct bcmgenet_tx_ring *ring)
-{
-	bcmgenet_intrl2_0_writel(ring->priv, UMAC_IRQ_TXDMA_DONE,
-				 INTRL2_CPU_MASK_SET);
-}
-
-static inline void bcmgenet_tx_ring16_int_enable(struct bcmgenet_tx_ring *ring)
-{
-	bcmgenet_intrl2_0_writel(ring->priv, UMAC_IRQ_TXDMA_DONE,
-				 INTRL2_CPU_MASK_CLEAR);
-}
-
 static inline void bcmgenet_tx_ring_int_enable(struct bcmgenet_tx_ring *ring)
 {
 	bcmgenet_intrl2_1_writel(ring->priv, 1 << ring->index,
@@ -1870,12 +1835,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
 	struct sk_buff *skb;
 
 	/* Clear status before servicing to reduce spurious interrupts */
-	if (ring->index == DESC_INDEX)
-		bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_TXDMA_DONE,
-					 INTRL2_CPU_CLEAR);
-	else
-		bcmgenet_intrl2_1_writel(priv, (1 << ring->index),
-					 INTRL2_CPU_CLEAR);
+	bcmgenet_intrl2_1_writel(priv, (1 << ring->index), INTRL2_CPU_CLEAR);
 
 	/* Compute how many buffers are transmitted since last xmit call */
 	c_index = bcmgenet_tdma_ring_readl(priv, ring->index, TDMA_CONS_INDEX)
@@ -1909,7 +1869,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
 	ring->packets += pkts_compl;
 	ring->bytes += bytes_compl;
 
-	netdev_tx_completed_queue(netdev_get_tx_queue(dev, ring->queue),
+	netdev_tx_completed_queue(netdev_get_tx_queue(dev, ring->index),
 				  pkts_compl, bytes_compl);
 
 	return txbds_processed;
@@ -1937,14 +1897,14 @@ static int bcmgenet_tx_poll(struct napi_struct *napi, int budget)
 	spin_lock(&ring->lock);
 	work_done = __bcmgenet_tx_reclaim(ring->priv->dev, ring);
 	if (ring->free_bds > (MAX_SKB_FRAGS + 1)) {
-		txq = netdev_get_tx_queue(ring->priv->dev, ring->queue);
+		txq = netdev_get_tx_queue(ring->priv->dev, ring->index);
 		netif_tx_wake_queue(txq);
 	}
 	spin_unlock(&ring->lock);
 
 	if (work_done == 0) {
 		napi_complete(napi);
-		ring->int_enable(ring);
+		bcmgenet_tx_ring_int_enable(ring);
 
 		return 0;
 	}
@@ -1955,14 +1915,11 @@ static int bcmgenet_tx_poll(struct napi_struct *napi, int budget)
 static void bcmgenet_tx_reclaim_all(struct net_device *dev)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
-	int i;
-
-	if (netif_is_multiqueue(dev)) {
-		for (i = 0; i < priv->hw_params->tx_queues; i++)
-			bcmgenet_tx_reclaim(dev, &priv->tx_rings[i]);
-	}
+	int i = 0;
 
-	bcmgenet_tx_reclaim(dev, &priv->tx_rings[DESC_INDEX]);
+	do {
+		bcmgenet_tx_reclaim(dev, &priv->tx_rings[i++]);
+	} while (i <= priv->hw_params->tx_queues && netif_is_multiqueue(dev));
 }
 
 /* Reallocate the SKB to put enough headroom in front of it and insert
@@ -2050,19 +2007,14 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	index = skb_get_queue_mapping(skb);
 	/* Mapping strategy:
-	 * queue_mapping = 0, unclassified, packet xmited through ring16
-	 * queue_mapping = 1, goes to ring 0. (highest priority queue
-	 * queue_mapping = 2, goes to ring 1.
-	 * queue_mapping = 3, goes to ring 2.
-	 * queue_mapping = 4, goes to ring 3.
+	 * queue_mapping = 0, unclassified, packet xmited through ring 0
+	 * queue_mapping = 1, goes to ring 1. (highest priority queue)
+	 * queue_mapping = 2, goes to ring 2.
+	 * queue_mapping = 3, goes to ring 3.
+	 * queue_mapping = 4, goes to ring 4.
 	 */
-	if (index == 0)
-		index = DESC_INDEX;
-	else
-		index -= 1;
-
 	ring = &priv->tx_rings[index];
-	txq = netdev_get_tx_queue(dev, ring->queue);
+	txq = netdev_get_tx_queue(dev, index);
 
 	nr_frags = skb_shinfo(skb)->nr_frags;
 
@@ -2235,15 +2187,8 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
 	unsigned int discards;
 
 	/* Clear status before servicing to reduce spurious interrupts */
-	if (ring->index == DESC_INDEX) {
-		bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_RXDMA_DONE,
-					 INTRL2_CPU_CLEAR);
-	} else {
-		mask = 1 << (UMAC_IRQ1_RX_INTR_SHIFT + ring->index);
-		bcmgenet_intrl2_1_writel(priv,
-					 mask,
-					 INTRL2_CPU_CLEAR);
-	}
+	mask = 1 << (UMAC_IRQ1_RX_INTR_SHIFT + ring->index);
+	bcmgenet_intrl2_1_writel(priv, mask, INTRL2_CPU_CLEAR);
 
 	p_index = bcmgenet_rdma_ring_readl(priv, ring->index, RDMA_PROD_INDEX);
 
@@ -2392,7 +2337,7 @@ static int bcmgenet_rx_poll(struct napi_struct *napi, int budget)
 
 	if (work_done < budget) {
 		napi_complete_done(napi, work_done);
-		ring->int_enable(ring);
+		bcmgenet_rx_ring_int_enable(ring);
 	}
 
 	if (ring->dim.use_dim) {
@@ -2632,15 +2577,6 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
 	spin_lock_init(&ring->lock);
 	ring->priv = priv;
 	ring->index = index;
-	if (index == DESC_INDEX) {
-		ring->queue = 0;
-		ring->int_enable = bcmgenet_tx_ring16_int_enable;
-		ring->int_disable = bcmgenet_tx_ring16_int_disable;
-	} else {
-		ring->queue = index + 1;
-		ring->int_enable = bcmgenet_tx_ring_int_enable;
-		ring->int_disable = bcmgenet_tx_ring_int_disable;
-	}
 	ring->cbs = priv->tx_cbs + start_ptr;
 	ring->size = size;
 	ring->clean_ptr = start_ptr;
@@ -2651,8 +2587,8 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
 	ring->end_ptr = end_ptr - 1;
 	ring->prod_index = 0;
 
-	/* Set flow period for ring != 16 */
-	if (index != DESC_INDEX)
+	/* Set flow period for ring != 0 */
+	if (index)
 		flow_period_val = ENET_MAX_MTU_SIZE << 16;
 
 	bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_PROD_INDEX);
@@ -2690,13 +2626,6 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv,
 
 	ring->priv = priv;
 	ring->index = index;
-	if (index == DESC_INDEX) {
-		ring->int_enable = bcmgenet_rx_ring16_int_enable;
-		ring->int_disable = bcmgenet_rx_ring16_int_disable;
-	} else {
-		ring->int_enable = bcmgenet_rx_ring_int_enable;
-		ring->int_disable = bcmgenet_rx_ring_int_disable;
-	}
 	ring->cbs = priv->rx_cbs + start_ptr;
 	ring->size = size;
 	ring->c_index = 0;
@@ -2742,15 +2671,11 @@ static void bcmgenet_enable_tx_napi(struct bcmgenet_priv *priv)
 	unsigned int i;
 	struct bcmgenet_tx_ring *ring;
 
-	for (i = 0; i < priv->hw_params->tx_queues; ++i) {
+	for (i = 0; i <= priv->hw_params->tx_queues; ++i) {
 		ring = &priv->tx_rings[i];
 		napi_enable(&ring->napi);
-		ring->int_enable(ring);
+		bcmgenet_tx_ring_int_enable(ring);
 	}
-
-	ring = &priv->tx_rings[DESC_INDEX];
-	napi_enable(&ring->napi);
-	ring->int_enable(ring);
 }
 
 static void bcmgenet_disable_tx_napi(struct bcmgenet_priv *priv)
@@ -2758,13 +2683,10 @@ static void bcmgenet_disable_tx_napi(struct bcmgenet_priv *priv)
 	unsigned int i;
 	struct bcmgenet_tx_ring *ring;
 
-	for (i = 0; i < priv->hw_params->tx_queues; ++i) {
+	for (i = 0; i <= priv->hw_params->tx_queues; ++i) {
 		ring = &priv->tx_rings[i];
 		napi_disable(&ring->napi);
 	}
-
-	ring = &priv->tx_rings[DESC_INDEX];
-	napi_disable(&ring->napi);
 }
 
 static void bcmgenet_fini_tx_napi(struct bcmgenet_priv *priv)
@@ -2772,33 +2694,31 @@ static void bcmgenet_fini_tx_napi(struct bcmgenet_priv *priv)
 	unsigned int i;
 	struct bcmgenet_tx_ring *ring;
 
-	for (i = 0; i < priv->hw_params->tx_queues; ++i) {
+	for (i = 0; i <= priv->hw_params->tx_queues; ++i) {
 		ring = &priv->tx_rings[i];
 		netif_napi_del(&ring->napi);
 	}
-
-	ring = &priv->tx_rings[DESC_INDEX];
-	netif_napi_del(&ring->napi);
 }
 
 /* Initialize Tx queues
  *
- * Queues 0-3 are priority-based, each one has 32 descriptors,
- * with queue 0 being the highest priority queue.
+ * Queues 1-4 are priority-based, each one has 32 descriptors,
+ * with queue 1 being the highest priority queue.
  *
- * Queue 16 is the default Tx queue with
- * GENET_Q16_TX_BD_CNT = 256 - 4 * 32 = 128 descriptors.
+ * Queue 0 is the default Tx queue with
+ * GENET_Q0_TX_BD_CNT = 256 - 4 * 32 = 128 descriptors.
  *
  * The transmit control block pool is then partitioned as follows:
- * - Tx queue 0 uses tx_cbs[0..31]
- * - Tx queue 1 uses tx_cbs[32..63]
- * - Tx queue 2 uses tx_cbs[64..95]
- * - Tx queue 3 uses tx_cbs[96..127]
- * - Tx queue 16 uses tx_cbs[128..255]
+ * - Tx queue 0 uses tx_cbs[0..127]
+ * - Tx queue 1 uses tx_cbs[128..159]
+ * - Tx queue 2 uses tx_cbs[160..191]
+ * - Tx queue 3 uses tx_cbs[192..223]
+ * - Tx queue 4 uses tx_cbs[224..255]
  */
 static void bcmgenet_init_tx_queues(struct net_device *dev)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
+	unsigned int start = 0, end = GENET_Q0_TX_BD_CNT;
 	u32 i, dma_enable;
 	u32 dma_ctrl, ring_cfg;
 	u32 dma_priority[3] = {0, 0, 0};
@@ -2815,27 +2735,17 @@ static void bcmgenet_init_tx_queues(struct net_device *dev)
 	bcmgenet_tdma_writel(priv, DMA_ARBITER_SP, DMA_ARB_CTRL);
 
 	/* Initialize Tx priority queues */
-	for (i = 0; i < priv->hw_params->tx_queues; i++) {
-		bcmgenet_init_tx_ring(priv, i, priv->hw_params->tx_bds_per_q,
-				      i * priv->hw_params->tx_bds_per_q,
-				      (i + 1) * priv->hw_params->tx_bds_per_q);
+	for (i = 0; i <= priv->hw_params->tx_queues; i++) {
+		bcmgenet_init_tx_ring(priv, i, end - start, start, end);
+		start = end;
+		end += priv->hw_params->tx_bds_per_q;
 		ring_cfg |= (1 << i);
 		dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT));
 		dma_priority[DMA_PRIO_REG_INDEX(i)] |=
-			((GENET_Q0_PRIORITY + i) << DMA_PRIO_REG_SHIFT(i));
+			(i ? GENET_Q1_PRIORITY : GENET_Q0_PRIORITY)
+			<< DMA_PRIO_REG_SHIFT(i);
 	}
 
-	/* Initialize Tx default queue 16 */
-	bcmgenet_init_tx_ring(priv, DESC_INDEX, GENET_Q16_TX_BD_CNT,
-			      priv->hw_params->tx_queues *
-			      priv->hw_params->tx_bds_per_q,
-			      TOTAL_DESC);
-	ring_cfg |= (1 << DESC_INDEX);
-	dma_ctrl |= (1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT));
-	dma_priority[DMA_PRIO_REG_INDEX(DESC_INDEX)] |=
-		((GENET_Q0_PRIORITY + priv->hw_params->tx_queues) <<
-		 DMA_PRIO_REG_SHIFT(DESC_INDEX));
-
 	/* Set Tx queue priorities */
 	bcmgenet_tdma_writel(priv, dma_priority[0], DMA_PRIORITY_0);
 	bcmgenet_tdma_writel(priv, dma_priority[1], DMA_PRIORITY_1);
@@ -2855,15 +2765,11 @@ static void bcmgenet_enable_rx_napi(struct bcmgenet_priv *priv)
 	unsigned int i;
 	struct bcmgenet_rx_ring *ring;
 
-	for (i = 0; i < priv->hw_params->rx_queues; ++i) {
+	for (i = 0; i <= priv->hw_params->rx_queues; ++i) {
 		ring = &priv->rx_rings[i];
 		napi_enable(&ring->napi);
-		ring->int_enable(ring);
+		bcmgenet_rx_ring_int_enable(ring);
 	}
-
-	ring = &priv->rx_rings[DESC_INDEX];
-	napi_enable(&ring->napi);
-	ring->int_enable(ring);
 }
 
 static void bcmgenet_disable_rx_napi(struct bcmgenet_priv *priv)
@@ -2871,15 +2777,11 @@ static void bcmgenet_disable_rx_napi(struct bcmgenet_priv *priv)
 	unsigned int i;
 	struct bcmgenet_rx_ring *ring;
 
-	for (i = 0; i < priv->hw_params->rx_queues; ++i) {
+	for (i = 0; i <= priv->hw_params->rx_queues; ++i) {
 		ring = &priv->rx_rings[i];
 		napi_disable(&ring->napi);
 		cancel_work_sync(&ring->dim.dim.work);
 	}
-
-	ring = &priv->rx_rings[DESC_INDEX];
-	napi_disable(&ring->napi);
-	cancel_work_sync(&ring->dim.dim.work);
 }
 
 static void bcmgenet_fini_rx_napi(struct bcmgenet_priv *priv)
@@ -2887,13 +2789,10 @@ static void bcmgenet_fini_rx_napi(struct bcmgenet_priv *priv)
 	unsigned int i;
 	struct bcmgenet_rx_ring *ring;
 
-	for (i = 0; i < priv->hw_params->rx_queues; ++i) {
+	for (i = 0; i <= priv->hw_params->rx_queues; ++i) {
 		ring = &priv->rx_rings[i];
 		netif_napi_del(&ring->napi);
 	}
-
-	ring = &priv->rx_rings[DESC_INDEX];
-	netif_napi_del(&ring->napi);
 }
 
 /* Initialize Rx queues
@@ -2901,15 +2800,13 @@ static void bcmgenet_fini_rx_napi(struct bcmgenet_priv *priv)
  * Queues 0-15 are priority queues. Hardware Filtering Block (HFB) can be
  * used to direct traffic to these queues.
  *
- * Queue 16 is the default Rx queue with GENET_Q16_RX_BD_CNT descriptors.
+ * Queue 0 is also the default Rx queue with GENET_Q0_RX_BD_CNT descriptors.
  */
 static int bcmgenet_init_rx_queues(struct net_device *dev)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
-	u32 i;
-	u32 dma_enable;
-	u32 dma_ctrl;
-	u32 ring_cfg;
+	unsigned int start = 0, end = GENET_Q0_RX_BD_CNT;
+	u32 i, dma_enable, dma_ctrl = 0, ring_cfg = 0;
 	int ret;
 
 	dma_ctrl = bcmgenet_rdma_readl(priv, DMA_CTRL);
@@ -2921,34 +2818,21 @@ static int bcmgenet_init_rx_queues(struct net_device *dev)
 	ring_cfg = 0;
 
 	/* Initialize Rx priority queues */
-	for (i = 0; i < priv->hw_params->rx_queues; i++) {
-		ret = bcmgenet_init_rx_ring(priv, i,
-					    priv->hw_params->rx_bds_per_q,
-					    i * priv->hw_params->rx_bds_per_q,
-					    (i + 1) *
-					    priv->hw_params->rx_bds_per_q);
+	for (i = 0; i <= priv->hw_params->rx_queues; i++) {
+		ret = bcmgenet_init_rx_ring(priv, i, end - start, start, end);
 		if (ret)
 			return ret;
 
+		start = end;
+		end += priv->hw_params->rx_bds_per_q;
 		ring_cfg |= (1 << i);
 		dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT));
 	}
 
-	/* Initialize Rx default queue 16 */
-	ret = bcmgenet_init_rx_ring(priv, DESC_INDEX, GENET_Q16_RX_BD_CNT,
-				    priv->hw_params->rx_queues *
-				    priv->hw_params->rx_bds_per_q,
-				    TOTAL_DESC);
-	if (ret)
-		return ret;
-
-	ring_cfg |= (1 << DESC_INDEX);
-	dma_ctrl |= (1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT));
-
-	/* Enable rings */
+	/* Configure Rx queues as descriptor rings */
 	bcmgenet_rdma_writel(priv, ring_cfg, DMA_RING_CFG);
 
-	/* Configure ring as descriptor ring and re-enable DMA if enabled */
+	/* Enable Rx rings */
 	if (dma_enable)
 		dma_ctrl |= DMA_EN;
 	bcmgenet_rdma_writel(priv, dma_ctrl, DMA_CTRL);
@@ -3007,14 +2891,14 @@ static int bcmgenet_dma_teardown(struct bcmgenet_priv *priv)
 	}
 
 	dma_ctrl = 0;
-	for (i = 0; i < priv->hw_params->rx_queues; i++)
+	for (i = 0; i <= priv->hw_params->rx_queues; i++)
 		dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT));
 	reg = bcmgenet_rdma_readl(priv, DMA_CTRL);
 	reg &= ~dma_ctrl;
 	bcmgenet_rdma_writel(priv, reg, DMA_CTRL);
 
 	dma_ctrl = 0;
-	for (i = 0; i < priv->hw_params->tx_queues; i++)
+	for (i = 0; i <= priv->hw_params->tx_queues; i++)
 		dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT));
 	reg = bcmgenet_tdma_readl(priv, DMA_CTRL);
 	reg &= ~dma_ctrl;
@@ -3035,14 +2919,11 @@ static void bcmgenet_fini_dma(struct bcmgenet_priv *priv)
 		dev_kfree_skb(bcmgenet_free_tx_cb(&priv->pdev->dev,
 						  priv->tx_cbs + i));
 
-	for (i = 0; i < priv->hw_params->tx_queues; i++) {
-		txq = netdev_get_tx_queue(priv->dev, priv->tx_rings[i].queue);
+	for (i = 0; i <= priv->hw_params->tx_queues; i++) {
+		txq = netdev_get_tx_queue(priv->dev, i);
 		netdev_tx_reset_queue(txq);
 	}
 
-	txq = netdev_get_tx_queue(priv->dev, priv->tx_rings[DESC_INDEX].queue);
-	netdev_tx_reset_queue(txq);
-
 	bcmgenet_free_rx_buffers(priv);
 	kfree(priv->rx_cbs);
 	kfree(priv->tx_cbs);
@@ -3135,7 +3016,7 @@ static void bcmgenet_irq_task(struct work_struct *work)
 
 }
 
-/* bcmgenet_isr1: handle Rx and Tx priority queues */
+/* bcmgenet_isr1: handle Rx and Tx queues */
 static irqreturn_t bcmgenet_isr1(int irq, void *dev_id)
 {
 	struct bcmgenet_priv *priv = dev_id;
@@ -3154,7 +3035,7 @@ static irqreturn_t bcmgenet_isr1(int irq, void *dev_id)
 		  "%s: IRQ=0x%x\n", __func__, status);
 
 	/* Check Rx priority queue interrupts */
-	for (index = 0; index < priv->hw_params->rx_queues; index++) {
+	for (index = 0; index <= priv->hw_params->rx_queues; index++) {
 		if (!(status & BIT(UMAC_IRQ1_RX_INTR_SHIFT + index)))
 			continue;
 
@@ -3162,20 +3043,20 @@ static irqreturn_t bcmgenet_isr1(int irq, void *dev_id)
 		rx_ring->dim.event_ctr++;
 
 		if (likely(napi_schedule_prep(&rx_ring->napi))) {
-			rx_ring->int_disable(rx_ring);
+			bcmgenet_rx_ring_int_disable(rx_ring);
 			__napi_schedule_irqoff(&rx_ring->napi);
 		}
 	}
 
 	/* Check Tx priority queue interrupts */
-	for (index = 0; index < priv->hw_params->tx_queues; index++) {
+	for (index = 0; index <= priv->hw_params->tx_queues; index++) {
 		if (!(status & BIT(index)))
 			continue;
 
 		tx_ring = &priv->tx_rings[index];
 
 		if (likely(napi_schedule_prep(&tx_ring->napi))) {
-			tx_ring->int_disable(tx_ring);
+			bcmgenet_tx_ring_int_disable(tx_ring);
 			__napi_schedule_irqoff(&tx_ring->napi);
 		}
 	}
@@ -3183,12 +3064,10 @@ static irqreturn_t bcmgenet_isr1(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-/* bcmgenet_isr0: handle Rx and Tx default queues + other stuff */
+/* bcmgenet_isr0: handle other stuff */
 static irqreturn_t bcmgenet_isr0(int irq, void *dev_id)
 {
 	struct bcmgenet_priv *priv = dev_id;
-	struct bcmgenet_rx_ring *rx_ring;
-	struct bcmgenet_tx_ring *tx_ring;
 	unsigned int status;
 	unsigned long flags;
 
@@ -3202,25 +3081,6 @@ static irqreturn_t bcmgenet_isr0(int irq, void *dev_id)
 	netif_dbg(priv, intr, priv->dev,
 		  "IRQ=0x%x\n", status);
 
-	if (status & UMAC_IRQ_RXDMA_DONE) {
-		rx_ring = &priv->rx_rings[DESC_INDEX];
-		rx_ring->dim.event_ctr++;
-
-		if (likely(napi_schedule_prep(&rx_ring->napi))) {
-			rx_ring->int_disable(rx_ring);
-			__napi_schedule_irqoff(&rx_ring->napi);
-		}
-	}
-
-	if (status & UMAC_IRQ_TXDMA_DONE) {
-		tx_ring = &priv->tx_rings[DESC_INDEX];
-
-		if (likely(napi_schedule_prep(&tx_ring->napi))) {
-			tx_ring->int_disable(tx_ring);
-			__napi_schedule_irqoff(&tx_ring->napi);
-		}
-	}
-
 	if (bcmgenet_has_mdio_intr(priv) &&
 		status & (UMAC_IRQ_MDIO_DONE | UMAC_IRQ_MDIO_ERROR)) {
 		wake_up(&priv->wq);
@@ -3286,15 +3146,15 @@ static u32 bcmgenet_dma_disable(struct bcmgenet_priv *priv, bool flush_rx)
 	u32 dma_ctrl;
 
 	/* disable DMA */
-	dma_ctrl = 1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT) | DMA_EN;
-	for (i = 0; i < priv->hw_params->tx_queues; i++)
+	dma_ctrl = DMA_EN;
+	for (i = 0; i <= priv->hw_params->tx_queues; i++)
 		dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT));
 	reg = bcmgenet_tdma_readl(priv, DMA_CTRL);
 	reg &= ~dma_ctrl;
 	bcmgenet_tdma_writel(priv, reg, DMA_CTRL);
 
-	dma_ctrl = 1 << (DESC_INDEX + DMA_RING_BUF_EN_SHIFT) | DMA_EN;
-	for (i = 0; i < priv->hw_params->rx_queues; i++)
+	dma_ctrl = DMA_EN;
+	for (i = 0; i <= priv->hw_params->rx_queues; i++)
 		dma_ctrl |= (1 << (i + DMA_RING_BUF_EN_SHIFT));
 	reg = bcmgenet_rdma_readl(priv, DMA_CTRL);
 	reg &= ~dma_ctrl;
@@ -3377,6 +3237,9 @@ static int bcmgenet_open(struct net_device *dev)
 
 	bcmgenet_set_hw_addr(priv, dev->dev_addr);
 
+	/* HFB init */
+	bcmgenet_hfb_init(priv);
+
 	/* Disable RX/TX DMA and flush TX and RX queues */
 	dma_ctrl = bcmgenet_dma_disable(priv, true);
 
@@ -3387,12 +3250,8 @@ static int bcmgenet_open(struct net_device *dev)
 		goto err_clk_disable;
 	}
 
-	/* Always enable ring 16 - descriptor ring */
 	bcmgenet_enable_dma(priv, dma_ctrl);
 
-	/* HFB init */
-	bcmgenet_hfb_init(priv);
-
 	ret = request_irq(priv->irq0, bcmgenet_isr0, IRQF_SHARED,
 			  dev->name, priv);
 	if (ret < 0) {
@@ -3499,16 +3358,11 @@ static void bcmgenet_dump_tx_queue(struct bcmgenet_tx_ring *ring)
 	if (!netif_msg_tx_err(priv))
 		return;
 
-	txq = netdev_get_tx_queue(priv->dev, ring->queue);
+	txq = netdev_get_tx_queue(priv->dev, ring->index);
 
 	spin_lock(&ring->lock);
-	if (ring->index == DESC_INDEX) {
-		intsts = ~bcmgenet_intrl2_0_readl(priv, INTRL2_CPU_MASK_STATUS);
-		intmsk = UMAC_IRQ_TXDMA_DONE | UMAC_IRQ_TXDMA_MBDONE;
-	} else {
-		intsts = ~bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_MASK_STATUS);
-		intmsk = 1 << ring->index;
-	}
+	intsts = ~bcmgenet_intrl2_1_readl(priv, INTRL2_CPU_MASK_STATUS);
+	intmsk = 1 << ring->index;
 	c_index = bcmgenet_tdma_ring_readl(priv, ring->index, TDMA_CONS_INDEX);
 	p_index = bcmgenet_tdma_ring_readl(priv, ring->index, TDMA_PROD_INDEX);
 	txq_stopped = netif_tx_queue_stopped(txq);
@@ -3522,7 +3376,7 @@ static void bcmgenet_dump_tx_queue(struct bcmgenet_tx_ring *ring)
 		  "(sw)c_index: %d (hw)c_index: %d\n"
 		  "(sw)clean_p: %d (sw)write_p: %d\n"
 		  "(sw)cb_ptr: %d (sw)end_ptr: %d\n",
-		  ring->index, ring->queue,
+		  ring->index, ring->index,
 		  txq_stopped ? "stopped" : "active",
 		  intsts & intmsk ? "enabled" : "disabled",
 		  free_bds, ring->size,
@@ -3535,25 +3389,20 @@ static void bcmgenet_dump_tx_queue(struct bcmgenet_tx_ring *ring)
 static void bcmgenet_timeout(struct net_device *dev, unsigned int txqueue)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
-	u32 int0_enable = 0;
 	u32 int1_enable = 0;
 	unsigned int q;
 
 	netif_dbg(priv, tx_err, dev, "bcmgenet_timeout\n");
 
-	for (q = 0; q < priv->hw_params->tx_queues; q++)
+	for (q = 0; q <= priv->hw_params->tx_queues; q++)
 		bcmgenet_dump_tx_queue(&priv->tx_rings[q]);
-	bcmgenet_dump_tx_queue(&priv->tx_rings[DESC_INDEX]);
 
 	bcmgenet_tx_reclaim_all(dev);
 
-	for (q = 0; q < priv->hw_params->tx_queues; q++)
+	for (q = 0; q <= priv->hw_params->tx_queues; q++)
 		int1_enable |= (1 << q);
 
-	int0_enable = UMAC_IRQ_TXDMA_DONE;
-
 	/* Re-enable TX interrupts if disabled */
-	bcmgenet_intrl2_0_writel(priv, int0_enable, INTRL2_CPU_MASK_CLEAR);
 	bcmgenet_intrl2_1_writel(priv, int1_enable, INTRL2_CPU_MASK_CLEAR);
 
 	netif_trans_update(dev);
@@ -3657,16 +3506,13 @@ static struct net_device_stats *bcmgenet_get_stats(struct net_device *dev)
 	struct bcmgenet_rx_ring *rx_ring;
 	unsigned int q;
 
-	for (q = 0; q < priv->hw_params->tx_queues; q++) {
+	for (q = 0; q <= priv->hw_params->tx_queues; q++) {
 		tx_ring = &priv->tx_rings[q];
 		tx_bytes += tx_ring->bytes;
 		tx_packets += tx_ring->packets;
 	}
-	tx_ring = &priv->tx_rings[DESC_INDEX];
-	tx_bytes += tx_ring->bytes;
-	tx_packets += tx_ring->packets;
 
-	for (q = 0; q < priv->hw_params->rx_queues; q++) {
+	for (q = 0; q <= priv->hw_params->rx_queues; q++) {
 		rx_ring = &priv->rx_rings[q];
 
 		rx_bytes += rx_ring->bytes;
@@ -3674,11 +3520,6 @@ static struct net_device_stats *bcmgenet_get_stats(struct net_device *dev)
 		rx_errors += rx_ring->errors;
 		rx_dropped += rx_ring->dropped;
 	}
-	rx_ring = &priv->rx_rings[DESC_INDEX];
-	rx_bytes += rx_ring->bytes;
-	rx_packets += rx_ring->packets;
-	rx_errors += rx_ring->errors;
-	rx_dropped += rx_ring->dropped;
 
 	dev->stats.tx_bytes = tx_bytes;
 	dev->stats.tx_packets = tx_packets;
@@ -4125,16 +3966,13 @@ static int bcmgenet_probe(struct platform_device *pdev)
 	if (err)
 		goto err_clk_disable;
 
-	/* setup number of real queues  + 1 (GENET_V1 has 0 hardware queues
-	 * just the ring 16 descriptor based TX
-	 */
+	/* setup number of real queues + 1 */
 	netif_set_real_num_tx_queues(priv->dev, priv->hw_params->tx_queues + 1);
 	netif_set_real_num_rx_queues(priv->dev, priv->hw_params->rx_queues + 1);
 
 	/* Set default coalescing parameters */
-	for (i = 0; i < priv->hw_params->rx_queues; i++)
+	for (i = 0; i <= priv->hw_params->rx_queues; i++)
 		priv->rx_rings[i].rx_max_coalesced_frames = 1;
-	priv->rx_rings[DESC_INDEX].rx_max_coalesced_frames = 1;
 
 	/* libphy will determine the link state */
 	netif_carrier_off(dev);
@@ -4257,7 +4095,6 @@ static int bcmgenet_resume(struct device *d)
 		goto out_clk_disable;
 	}
 
-	/* Always enable ring 16 - descriptor ring */
 	bcmgenet_enable_dma(priv, dma_ctrl);
 
 	if (!device_may_wakeup(d))
drivers/net/ethernet/broadcom/genet/bcmgenet.h +5 -7
index ed7402fb7fdaa..371e01e2c1895 100644
@@ -18,6 +18,9 @@
 
 #include "../unimac.h"
 
+/* Maximum number of hardware queues, downsized if needed */
+#define GENET_MAX_MQ_CNT	4
+
 /* total number of Buffer Descriptors, same for Rx/Tx */
 #define TOTAL_DESC				256
 
@@ -513,7 +516,6 @@ struct bcmgenet_tx_ring {
 	unsigned long	packets;
 	unsigned long	bytes;
 	unsigned int	index;		/* ring index */
-	unsigned int	queue;		/* queue index */
 	struct enet_cb	*cbs;		/* tx ring buffer control block*/
 	unsigned int	size;		/* size of each tx ring */
 	unsigned int    clean_ptr;      /* Tx ring clean pointer */
@@ -523,8 +525,6 @@ struct bcmgenet_tx_ring {
 	unsigned int	prod_index;	/* Tx ring producer index SW copy */
 	unsigned int	cb_ptr;		/* Tx ring initial CB ptr */
 	unsigned int	end_ptr;	/* Tx ring end CB ptr */
-	void (*int_enable)(struct bcmgenet_tx_ring *);
-	void (*int_disable)(struct bcmgenet_tx_ring *);
 	struct bcmgenet_priv *priv;
 };
 
@@ -553,8 +553,6 @@ struct bcmgenet_rx_ring {
 	struct bcmgenet_net_dim dim;
 	u32		rx_max_coalesced_frames;
 	u32		rx_coalesce_usecs;
-	void (*int_enable)(struct bcmgenet_rx_ring *);
-	void (*int_disable)(struct bcmgenet_rx_ring *);
 	struct bcmgenet_priv *priv;
 };
 
@@ -583,7 +581,7 @@ struct bcmgenet_priv {
 	struct enet_cb *tx_cbs;
 	unsigned int num_tx_bds;
 
-	struct bcmgenet_tx_ring tx_rings[DESC_INDEX + 1];
+	struct bcmgenet_tx_ring tx_rings[GENET_MAX_MQ_CNT + 1];
 
 	/* receive variables */
 	void __iomem *rx_bds;
@@ -593,7 +591,7 @@ struct bcmgenet_priv {
 	struct bcmgenet_rxnfc_rule rxnfc_rules[MAX_NUM_OF_FS_RULES];
 	struct list_head rxnfc_list;
 
-	struct bcmgenet_rx_ring rx_rings[DESC_INDEX + 1];
+	struct bcmgenet_rx_ring rx_rings[GENET_MAX_MQ_CNT + 1];
 
 	/* other misc variables */
 	struct bcmgenet_hw_params *hw_params;
drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c +2 -2
index 2033fb9d893e0..98358b71cef5c 100644
@@ -2,7 +2,7 @@
 /*
  * Broadcom GENET (Gigabit Ethernet) Wake-on-LAN support
  *
- * Copyright (c) 2014-2024 Broadcom
+ * Copyright (c) 2014-2025 Broadcom
  */
 
 #define pr_fmt(fmt)				"bcmgenet_wol: " fmt
@@ -180,7 +180,7 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
 	if (priv->wolopts & WAKE_FILTER) {
 		list_for_each_entry(rule, &priv->rxnfc_list, list)
 			if (rule->fs.ring_cookie == RX_CLS_FLOW_WAKE)
-				hfb_enable |= (1 << rule->fs.location);
+				hfb_enable |= (1 << (rule->fs.location + 1));
 		reg = (hfb_ctrl_reg & ~RBUF_HFB_EN) | RBUF_ACPI_EN;
 		bcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL);
 	}
Signature · 1 line
2.53.0
author maintainer
#78 lore raw

PATCH 76/666 net: bcmgenet: support reclaiming unsent Tx packets

In reply to Greg Kroah-Hartman

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

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

From: Doug Berger <[email protected]>

[ Upstream commit f1bacae8b655163dcbc3c54b9e714ef1a8986d7b ]

When disabling the transmitter any outstanding packets can now be reclaimed by bcmgenet_tx_reclaim_all() rather than by the bcmgenet_fini_dma() function.

Stable-dep-of: 5393b2b5bee2 ("net: bcmgenet: fix racing timeout handler")

---
 .../net/ethernet/broadcom/genet/bcmgenet.c    | 37 +++++++++++++++----
 1 file changed, 30 insertions(+), 7 deletions(-)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +30 -7
index 8b73f1ed97a4c..35b613930238c 100644
@@ -1876,12 +1876,39 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
 }
 
 static unsigned int bcmgenet_tx_reclaim(struct net_device *dev,
-				struct bcmgenet_tx_ring *ring)
+				struct bcmgenet_tx_ring *ring,
+				bool all)
 {
-	unsigned int released;
+	struct bcmgenet_priv *priv = netdev_priv(dev);
+	struct device *kdev = &priv->pdev->dev;
+	unsigned int released, drop, wr_ptr;
+	struct enet_cb *cb_ptr;
+	struct sk_buff *skb;
 
 	spin_lock_bh(&ring->lock);
 	released = __bcmgenet_tx_reclaim(dev, ring);
+	if (all) {
+		skb = NULL;
+		drop = (ring->prod_index - ring->c_index) & DMA_C_INDEX_MASK;
+		released += drop;
+		ring->prod_index = ring->c_index & DMA_C_INDEX_MASK;
+		while (drop--) {
+			cb_ptr = bcmgenet_put_txcb(priv, ring);
+			skb = cb_ptr->skb;
+			bcmgenet_free_tx_cb(kdev, cb_ptr);
+			if (skb && cb_ptr == GENET_CB(skb)->first_cb) {
+				dev_consume_skb_any(skb);
+				skb = NULL;
+			}
+		}
+		if (skb)
+			dev_consume_skb_any(skb);
+		bcmgenet_tdma_ring_writel(priv, ring->index,
+					  ring->prod_index, TDMA_PROD_INDEX);
+		wr_ptr = ring->write_ptr * WORDS_PER_BD(priv);
+		bcmgenet_tdma_ring_writel(priv, ring->index, wr_ptr,
+					  TDMA_WRITE_PTR);
+	}
 	spin_unlock_bh(&ring->lock);
 
 	return released;
@@ -1918,7 +1945,7 @@ static void bcmgenet_tx_reclaim_all(struct net_device *dev)
 	int i = 0;
 
 	do {
-		bcmgenet_tx_reclaim(dev, &priv->tx_rings[i++]);
+		bcmgenet_tx_reclaim(dev, &priv->tx_rings[i++], true);
 	} while (i <= priv->hw_params->tx_queues && netif_is_multiqueue(dev));
 }
 
@@ -2915,10 +2942,6 @@ static void bcmgenet_fini_dma(struct bcmgenet_priv *priv)
 	bcmgenet_fini_rx_napi(priv);
 	bcmgenet_fini_tx_napi(priv);
 
-	for (i = 0; i < priv->num_tx_bds; i++)
-		dev_kfree_skb(bcmgenet_free_tx_cb(&priv->pdev->dev,
-						  priv->tx_cbs + i));
-
 	for (i = 0; i <= priv->hw_params->tx_queues; i++) {
 		txq = netdev_get_tx_queue(priv->dev, i);
 		netdev_tx_reset_queue(txq);
Signature · 1 line
2.53.0
author maintainer
#79 lore raw

PATCH 77/666 net: bcmgenet: switch to use 64bit statistics

In reply to Greg Kroah-Hartman

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

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

From: Zak Kemble <[email protected]>

[ Upstream commit 59aa6e3072aa7e51e9040e8c342d0c0825c5f48f ]

Update the driver to use ndo_get_stats64, rtnl_link_stats64 and u64_stats_t counters for statistics.

Stable-dep-of: 5393b2b5bee2 ("net: bcmgenet: fix racing timeout handler")

---
 .../net/ethernet/broadcom/genet/bcmgenet.c    | 246 ++++++++++++------
 .../net/ethernet/broadcom/genet/bcmgenet.h    |  29 ++-
 2 files changed, 187 insertions(+), 88 deletions(-)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +164 -82
index 35b613930238c..0fe11e98f738d 100644
@@ -950,12 +950,13 @@ static int bcmgenet_set_pauseparam(struct net_device *dev,
 
 /* standard ethtool support functions. */
 enum bcmgenet_stat_type {
-	BCMGENET_STAT_NETDEV = -1,
+	BCMGENET_STAT_RTNL = -1,
 	BCMGENET_STAT_MIB_RX,
 	BCMGENET_STAT_MIB_TX,
 	BCMGENET_STAT_RUNT,
 	BCMGENET_STAT_MISC,
 	BCMGENET_STAT_SOFT,
+	BCMGENET_STAT_SOFT64,
 };
 
 struct bcmgenet_stats {
@@ -965,13 +966,15 @@ struct bcmgenet_stats {
 	enum bcmgenet_stat_type type;
 	/* reg offset from UMAC base for misc counters */
 	u16 reg_offset;
+	/* sync for u64 stats counters */
+	int syncp_offset;
 };
 
-#define STAT_NETDEV(m) { \
+#define STAT_RTNL(m) { \
 	.stat_string = __stringify(m), \
-	.stat_sizeof = sizeof(((struct net_device_stats *)0)->m), \
-	.stat_offset = offsetof(struct net_device_stats, m), \
-	.type = BCMGENET_STAT_NETDEV, \
+	.stat_sizeof = sizeof(((struct rtnl_link_stats64 *)0)->m), \
+	.stat_offset = offsetof(struct rtnl_link_stats64, m), \
+	.type = BCMGENET_STAT_RTNL, \
 }
 
 #define STAT_GENET_MIB(str, m, _type) { \
@@ -981,6 +984,14 @@ struct bcmgenet_stats {
 	.type = _type, \
 }
 
+#define STAT_GENET_SOFT_MIB64(str, s, m) { \
+	.stat_string = str, \
+	.stat_sizeof = sizeof(((struct bcmgenet_priv *)0)->s.m), \
+	.stat_offset = offsetof(struct bcmgenet_priv, s.m), \
+	.type = BCMGENET_STAT_SOFT64, \
+	.syncp_offset = offsetof(struct bcmgenet_priv, s.syncp), \
+}
+
 #define STAT_GENET_MIB_RX(str, m) STAT_GENET_MIB(str, m, BCMGENET_STAT_MIB_RX)
 #define STAT_GENET_MIB_TX(str, m) STAT_GENET_MIB(str, m, BCMGENET_STAT_MIB_TX)
 #define STAT_GENET_RUNT(str, m) STAT_GENET_MIB(str, m, BCMGENET_STAT_RUNT)
@@ -995,18 +1006,18 @@ struct bcmgenet_stats {
 }
 
 #define STAT_GENET_Q(num) \
-	STAT_GENET_SOFT_MIB("txq" __stringify(num) "_packets", \
-			tx_rings[num].packets), \
-	STAT_GENET_SOFT_MIB("txq" __stringify(num) "_bytes", \
-			tx_rings[num].bytes), \
-	STAT_GENET_SOFT_MIB("rxq" __stringify(num) "_bytes", \
-			rx_rings[num].bytes),	 \
-	STAT_GENET_SOFT_MIB("rxq" __stringify(num) "_packets", \
-			rx_rings[num].packets), \
-	STAT_GENET_SOFT_MIB("rxq" __stringify(num) "_errors", \
-			rx_rings[num].errors), \
-	STAT_GENET_SOFT_MIB("rxq" __stringify(num) "_dropped", \
-			rx_rings[num].dropped)
+	STAT_GENET_SOFT_MIB64("txq" __stringify(num) "_packets", \
+			tx_rings[num].stats64, packets), \
+	STAT_GENET_SOFT_MIB64("txq" __stringify(num) "_bytes", \
+			tx_rings[num].stats64, bytes), \
+	STAT_GENET_SOFT_MIB64("rxq" __stringify(num) "_bytes", \
+			rx_rings[num].stats64, bytes),	 \
+	STAT_GENET_SOFT_MIB64("rxq" __stringify(num) "_packets", \
+			rx_rings[num].stats64, packets), \
+	STAT_GENET_SOFT_MIB64("rxq" __stringify(num) "_errors", \
+			rx_rings[num].stats64, errors), \
+	STAT_GENET_SOFT_MIB64("rxq" __stringify(num) "_dropped", \
+			rx_rings[num].stats64, dropped)
 
 /* There is a 0xC gap between the end of RX and beginning of TX stats and then
  * between the end of TX stats and the beginning of the RX RUNT
@@ -1018,15 +1029,15 @@ struct bcmgenet_stats {
  */
 static const struct bcmgenet_stats bcmgenet_gstrings_stats[] = {
 	/* general stats */
-	STAT_NETDEV(rx_packets),
-	STAT_NETDEV(tx_packets),
-	STAT_NETDEV(rx_bytes),
-	STAT_NETDEV(tx_bytes),
-	STAT_NETDEV(rx_errors),
-	STAT_NETDEV(tx_errors),
-	STAT_NETDEV(rx_dropped),
-	STAT_NETDEV(tx_dropped),
-	STAT_NETDEV(multicast),
+	STAT_RTNL(rx_packets),
+	STAT_RTNL(tx_packets),
+	STAT_RTNL(rx_bytes),
+	STAT_RTNL(tx_bytes),
+	STAT_RTNL(rx_errors),
+	STAT_RTNL(tx_errors),
+	STAT_RTNL(rx_dropped),
+	STAT_RTNL(tx_dropped),
+	STAT_RTNL(multicast),
 	/* UniMAC RSV counters */
 	STAT_GENET_MIB_RX("rx_64_octets", mib.rx.pkt_cnt.cnt_64),
 	STAT_GENET_MIB_RX("rx_65_127_oct", mib.rx.pkt_cnt.cnt_127),
@@ -1114,6 +1125,20 @@ static const struct bcmgenet_stats bcmgenet_gstrings_stats[] = {
 
 #define BCMGENET_STATS_LEN	ARRAY_SIZE(bcmgenet_gstrings_stats)
 
+#define BCMGENET_STATS64_ADD(stats, m, v) \
+	do { \
+		u64_stats_update_begin(&stats->syncp); \
+		u64_stats_add(&stats->m, v); \
+		u64_stats_update_end(&stats->syncp); \
+	} while (0)
+
+#define BCMGENET_STATS64_INC(stats, m) \
+	do { \
+		u64_stats_update_begin(&stats->syncp); \
+		u64_stats_inc(&stats->m); \
+		u64_stats_update_end(&stats->syncp); \
+	} while (0)
+
 static void bcmgenet_get_drvinfo(struct net_device *dev,
 				 struct ethtool_drvinfo *info)
 {
@@ -1197,8 +1222,9 @@ static void bcmgenet_update_mib_counters(struct bcmgenet_priv *priv)
 
 		s = &bcmgenet_gstrings_stats[i];
 		switch (s->type) {
-		case BCMGENET_STAT_NETDEV:
+		case BCMGENET_STAT_RTNL:
 		case BCMGENET_STAT_SOFT:
+		case BCMGENET_STAT_SOFT64:
 			continue;
 		case BCMGENET_STAT_RUNT:
 			offset += BCMGENET_STAT_OFFSET;
@@ -1236,28 +1262,40 @@ static void bcmgenet_get_ethtool_stats(struct net_device *dev,
 				       u64 *data)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
+	struct rtnl_link_stats64 stats64;
+	struct u64_stats_sync *syncp;
+	unsigned int start;
 	int i;
 
 	if (netif_running(dev))
 		bcmgenet_update_mib_counters(priv);
 
-	dev->netdev_ops->ndo_get_stats(dev);
+	dev_get_stats(dev, &stats64);
 
 	for (i = 0; i < BCMGENET_STATS_LEN; i++) {
 		const struct bcmgenet_stats *s;
 		char *p;
 
 		s = &bcmgenet_gstrings_stats[i];
-		if (s->type == BCMGENET_STAT_NETDEV)
-			p = (char *)&dev->stats;
-		else
-			p = (char *)priv;
-		p += s->stat_offset;
-		if (sizeof(unsigned long) != sizeof(u32) &&
-		    s->stat_sizeof == sizeof(unsigned long))
-			data[i] = *(unsigned long *)p;
-		else
-			data[i] = *(u32 *)p;
+		p = (char *)priv;
+
+		if (s->type == BCMGENET_STAT_SOFT64) {
+			syncp = (struct u64_stats_sync *)(p + s->syncp_offset);
+			do {
+				start = u64_stats_fetch_begin(syncp);
+				data[i] = u64_stats_read((u64_stats_t *)(p + s->stat_offset));
+			} while (u64_stats_fetch_retry(syncp, start));
+		} else {
+			if (s->type == BCMGENET_STAT_RTNL)
+				p = (char *)&stats64;
+
+			p += s->stat_offset;
+			if (sizeof(unsigned long) != sizeof(u32) &&
+				s->stat_sizeof == sizeof(unsigned long))
+				data[i] = *(unsigned long *)p;
+			else
+				data[i] = *(u32 *)p;
+		}
 	}
 }
 
@@ -1826,6 +1864,7 @@ static struct sk_buff *bcmgenet_free_rx_cb(struct device *dev,
 static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
 					  struct bcmgenet_tx_ring *ring)
 {
+	struct bcmgenet_tx_stats64 *stats = &ring->stats64;
 	struct bcmgenet_priv *priv = netdev_priv(dev);
 	unsigned int txbds_processed = 0;
 	unsigned int bytes_compl = 0;
@@ -1866,8 +1905,10 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
 	ring->free_bds += txbds_processed;
 	ring->c_index = c_index;
 
-	ring->packets += pkts_compl;
-	ring->bytes += bytes_compl;
+	u64_stats_update_begin(&stats->syncp);
+	u64_stats_add(&stats->packets, pkts_compl);
+	u64_stats_add(&stats->bytes, bytes_compl);
+	u64_stats_update_end(&stats->syncp);
 
 	netdev_tx_completed_queue(netdev_get_tx_queue(dev, ring->index),
 				  pkts_compl, bytes_compl);
@@ -1953,8 +1994,10 @@ static void bcmgenet_tx_reclaim_all(struct net_device *dev)
  * the transmit checksum offsets in the descriptors
  */
 static struct sk_buff *bcmgenet_add_tsb(struct net_device *dev,
-					struct sk_buff *skb)
+					struct sk_buff *skb,
+					struct bcmgenet_tx_ring *ring)
 {
+	struct bcmgenet_tx_stats64 *stats = &ring->stats64;
 	struct bcmgenet_priv *priv = netdev_priv(dev);
 	struct status_64 *status = NULL;
 	struct sk_buff *new_skb;
@@ -1971,7 +2014,7 @@ static struct sk_buff *bcmgenet_add_tsb(struct net_device *dev,
 		if (!new_skb) {
 			dev_kfree_skb_any(skb);
 			priv->mib.tx_realloc_tsb_failed++;
-			dev->stats.tx_dropped++;
+			BCMGENET_STATS64_INC(stats, dropped);
 			return NULL;
 		}
 		dev_consume_skb_any(skb);
@@ -2059,7 +2102,7 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
 	GENET_CB(skb)->bytes_sent = skb->len;
 
 	/* add the Transmit Status Block */
-	skb = bcmgenet_add_tsb(dev, skb);
+	skb = bcmgenet_add_tsb(dev, skb, ring);
 	if (!skb) {
 		ret = NETDEV_TX_OK;
 		goto out;
@@ -2201,6 +2244,7 @@ static struct sk_buff *bcmgenet_rx_refill(struct bcmgenet_priv *priv,
 static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
 				     unsigned int budget)
 {
+	struct bcmgenet_rx_stats64 *stats = &ring->stats64;
 	struct bcmgenet_priv *priv = ring->priv;
 	struct net_device *dev = priv->dev;
 	struct enet_cb *cb;
@@ -2223,7 +2267,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
 		   DMA_P_INDEX_DISCARD_CNT_MASK;
 	if (discards > ring->old_discards) {
 		discards = discards - ring->old_discards;
-		ring->errors += discards;
+		BCMGENET_STATS64_ADD(stats, errors, discards);
 		ring->old_discards += discards;
 
 		/* Clear HW register when we reach 75% of maximum 0xFFFF */
@@ -2249,7 +2293,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
 		skb = bcmgenet_rx_refill(priv, cb);
 
 		if (unlikely(!skb)) {
-			ring->dropped++;
+			BCMGENET_STATS64_INC(stats, dropped);
 			goto next;
 		}
 
@@ -2276,8 +2320,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
 
 		if (unlikely(len > RX_BUF_LENGTH)) {
 			netif_err(priv, rx_status, dev, "oversized packet\n");
-			dev->stats.rx_length_errors++;
-			dev->stats.rx_errors++;
+			BCMGENET_STATS64_INC(stats, length_errors);
 			dev_kfree_skb_any(skb);
 			goto next;
 		}
@@ -2285,7 +2328,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
 		if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) {
 			netif_err(priv, rx_status, dev,
 				  "dropping fragmented packet!\n");
-			ring->errors++;
+			BCMGENET_STATS64_INC(stats, errors);
 			dev_kfree_skb_any(skb);
 			goto next;
 		}
@@ -2298,15 +2341,22 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
 						DMA_RX_RXER))) {
 			netif_err(priv, rx_status, dev, "dma_flag=0x%x\n",
 				  (unsigned int)dma_flag);
+			u64_stats_update_begin(&stats->syncp);
 			if (dma_flag & DMA_RX_CRC_ERROR)
-				dev->stats.rx_crc_errors++;
+				u64_stats_inc(&stats->crc_errors);
 			if (dma_flag & DMA_RX_OV)
-				dev->stats.rx_over_errors++;
+				u64_stats_inc(&stats->over_errors);
 			if (dma_flag & DMA_RX_NO)
-				dev->stats.rx_frame_errors++;
+				u64_stats_inc(&stats->frame_errors);
 			if (dma_flag & DMA_RX_LG)
-				dev->stats.rx_length_errors++;
-			dev->stats.rx_errors++;
+				u64_stats_inc(&stats->length_errors);
+			if ((dma_flag & (DMA_RX_CRC_ERROR |
+						DMA_RX_OV |
+						DMA_RX_NO |
+						DMA_RX_LG |
+						DMA_RX_RXER)) == DMA_RX_RXER)
+				u64_stats_inc(&stats->errors);
+			u64_stats_update_end(&stats->syncp);
 			dev_kfree_skb_any(skb);
 			goto next;
 		} /* error packet */
@@ -2326,10 +2376,13 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
 
 		/*Finish setting up the received SKB and send it to the kernel*/
 		skb->protocol = eth_type_trans(skb, priv->dev);
-		ring->packets++;
-		ring->bytes += len;
+
+		u64_stats_update_begin(&stats->syncp);
+		u64_stats_inc(&stats->packets);
+		u64_stats_add(&stats->bytes, len);
 		if (dma_flag & DMA_RX_MULT)
-			dev->stats.multicast++;
+			u64_stats_inc(&stats->multicast);
+		u64_stats_update_end(&stats->syncp);
 
 		/* Notify kernel */
 		napi_gro_receive(&ring->napi, skb);
@@ -3430,7 +3483,7 @@ static void bcmgenet_timeout(struct net_device *dev, unsigned int txqueue)
 
 	netif_trans_update(dev);
 
-	dev->stats.tx_errors++;
+	BCMGENET_STATS64_INC((&priv->tx_rings[txqueue].stats64), errors);
 
 	netif_tx_wake_all_queues(dev);
 }
@@ -3519,39 +3572,68 @@ static int bcmgenet_set_mac_addr(struct net_device *dev, void *p)
 	return 0;
 }
 
-static struct net_device_stats *bcmgenet_get_stats(struct net_device *dev)
+static void bcmgenet_get_stats64(struct net_device *dev,
+				 struct rtnl_link_stats64 *stats)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
-	unsigned long tx_bytes = 0, tx_packets = 0;
-	unsigned long rx_bytes = 0, rx_packets = 0;
-	unsigned long rx_errors = 0, rx_dropped = 0;
-	struct bcmgenet_tx_ring *tx_ring;
-	struct bcmgenet_rx_ring *rx_ring;
+	struct bcmgenet_tx_stats64 *tx_stats;
+	struct bcmgenet_rx_stats64 *rx_stats;
+	u64 rx_length_errors, rx_over_errors;
+	u64 rx_crc_errors, rx_frame_errors;
+	u64 tx_errors, tx_dropped;
+	u64 rx_errors, rx_dropped;
+	u64 tx_bytes, tx_packets;
+	u64 rx_bytes, rx_packets;
+	unsigned int start;
 	unsigned int q;
+	u64 multicast;
 
 	for (q = 0; q <= priv->hw_params->tx_queues; q++) {
-		tx_ring = &priv->tx_rings[q];
-		tx_bytes += tx_ring->bytes;
-		tx_packets += tx_ring->packets;
+		tx_stats = &priv->tx_rings[q].stats64;
+		do {
+			start = u64_stats_fetch_begin(&tx_stats->syncp);
+			tx_bytes = u64_stats_read(&tx_stats->bytes);
+			tx_packets = u64_stats_read(&tx_stats->packets);
+			tx_errors = u64_stats_read(&tx_stats->errors);
+			tx_dropped = u64_stats_read(&tx_stats->dropped);
+		} while (u64_stats_fetch_retry(&tx_stats->syncp, start));
+
+		stats->tx_bytes += tx_bytes;
+		stats->tx_packets += tx_packets;
+		stats->tx_errors += tx_errors;
+		stats->tx_dropped += tx_dropped;
 	}
 
 	for (q = 0; q <= priv->hw_params->rx_queues; q++) {
-		rx_ring = &priv->rx_rings[q];
-
-		rx_bytes += rx_ring->bytes;
-		rx_packets += rx_ring->packets;
-		rx_errors += rx_ring->errors;
-		rx_dropped += rx_ring->dropped;
+		rx_stats = &priv->rx_rings[q].stats64;
+		do {
+			start = u64_stats_fetch_begin(&rx_stats->syncp);
+			rx_bytes = u64_stats_read(&rx_stats->bytes);
+			rx_packets = u64_stats_read(&rx_stats->packets);
+			rx_errors = u64_stats_read(&rx_stats->errors);
+			rx_dropped = u64_stats_read(&rx_stats->dropped);
+			rx_length_errors = u64_stats_read(&rx_stats->length_errors);
+			rx_over_errors = u64_stats_read(&rx_stats->over_errors);
+			rx_crc_errors = u64_stats_read(&rx_stats->crc_errors);
+			rx_frame_errors = u64_stats_read(&rx_stats->frame_errors);
+			multicast = u64_stats_read(&rx_stats->multicast);
+		} while (u64_stats_fetch_retry(&rx_stats->syncp, start));
+
+		rx_errors += rx_length_errors;
+		rx_errors += rx_crc_errors;
+		rx_errors += rx_frame_errors;
+
+		stats->rx_bytes += rx_bytes;
+		stats->rx_packets += rx_packets;
+		stats->rx_errors += rx_errors;
+		stats->rx_dropped += rx_dropped;
+		stats->rx_missed_errors += rx_errors;
+		stats->rx_length_errors += rx_length_errors;
+		stats->rx_over_errors += rx_over_errors;
+		stats->rx_crc_errors += rx_crc_errors;
+		stats->rx_frame_errors += rx_frame_errors;
+		stats->multicast += multicast;
 	}
-
-	dev->stats.tx_bytes = tx_bytes;
-	dev->stats.tx_packets = tx_packets;
-	dev->stats.rx_bytes = rx_bytes;
-	dev->stats.rx_packets = rx_packets;
-	dev->stats.rx_errors = rx_errors;
-	dev->stats.rx_missed_errors = rx_errors;
-	dev->stats.rx_dropped = rx_dropped;
-	return &dev->stats;
 }
 
 static int bcmgenet_change_carrier(struct net_device *dev, bool new_carrier)
@@ -3579,7 +3661,7 @@ static const struct net_device_ops bcmgenet_netdev_ops = {
 	.ndo_set_mac_address	= bcmgenet_set_mac_addr,
 	.ndo_eth_ioctl		= phy_do_ioctl_running,
 	.ndo_set_features	= bcmgenet_set_features,
-	.ndo_get_stats		= bcmgenet_get_stats,
+	.ndo_get_stats64	= bcmgenet_get_stats64,
 	.ndo_change_carrier	= bcmgenet_change_carrier,
 };
 
drivers/net/ethernet/broadcom/genet/bcmgenet.h +23 -6
index 371e01e2c1895..89b071da31142 100644
@@ -155,6 +155,27 @@ struct bcmgenet_mib_counters {
 	u32	tx_realloc_tsb_failed;
 };
 
+struct bcmgenet_tx_stats64 {
+	struct u64_stats_sync syncp;
+	u64_stats_t	packets;
+	u64_stats_t	bytes;
+	u64_stats_t	errors;
+	u64_stats_t	dropped;
+};
+
+struct bcmgenet_rx_stats64 {
+	struct u64_stats_sync syncp;
+	u64_stats_t	bytes;
+	u64_stats_t	packets;
+	u64_stats_t	errors;
+	u64_stats_t	dropped;
+	u64_stats_t	multicast;
+	u64_stats_t	length_errors;
+	u64_stats_t	over_errors;
+	u64_stats_t	crc_errors;
+	u64_stats_t	frame_errors;
+};
+
 #define UMAC_MIB_START			0x400
 
 #define UMAC_MDIO_CMD			0x614
@@ -513,8 +534,7 @@ struct bcmgenet_skb_cb {
 struct bcmgenet_tx_ring {
 	spinlock_t	lock;		/* ring lock */
 	struct napi_struct napi;	/* NAPI per tx queue */
-	unsigned long	packets;
-	unsigned long	bytes;
+	struct bcmgenet_tx_stats64 stats64;
 	unsigned int	index;		/* ring index */
 	struct enet_cb	*cbs;		/* tx ring buffer control block*/
 	unsigned int	size;		/* size of each tx ring */
@@ -538,10 +558,7 @@ struct bcmgenet_net_dim {
 
 struct bcmgenet_rx_ring {
 	struct napi_struct napi;	/* Rx NAPI struct */
-	unsigned long	bytes;
-	unsigned long	packets;
-	unsigned long	errors;
-	unsigned long	dropped;
+	struct bcmgenet_rx_stats64 stats64;
 	unsigned int	index;		/* Rx ring index */
 	struct enet_cb	*cbs;		/* Rx ring buffer control block */
 	unsigned int	size;		/* Rx ring size */
Signature · 1 line
2.53.0
author maintainer
#80 lore raw

PATCH 78/666 net: bcmgenet: fix racing timeout handler

In reply to Greg Kroah-Hartman

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

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

From: Justin Chen <[email protected]>

[ Upstream commit 5393b2b5bee2ac51a0043dc7f4ac3475f053d08d ]

The bcmgenet_timeout handler tries to take down all tx queues when a single queue times out. This is over zealous and causes many race conditions with queues that are still chugging along. Instead lets only restart the timed out queue.

---
 .../net/ethernet/broadcom/genet/bcmgenet.c    | 22 ++++++++-----------
 1 file changed, 9 insertions(+), 13 deletions(-)
drivers/net/ethernet/broadcom/genet/bcmgenet.c +9 -13
index 0fe11e98f738d..f012025a517dd 100644
@@ -3465,27 +3465,23 @@ static void bcmgenet_dump_tx_queue(struct bcmgenet_tx_ring *ring)
 static void bcmgenet_timeout(struct net_device *dev, unsigned int txqueue)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
-	u32 int1_enable = 0;
-	unsigned int q;
+	struct bcmgenet_tx_ring *ring = &priv->tx_rings[txqueue];
+	struct netdev_queue *txq = netdev_get_tx_queue(dev, txqueue);
 
 	netif_dbg(priv, tx_err, dev, "bcmgenet_timeout\n");
 
-	for (q = 0; q <= priv->hw_params->tx_queues; q++)
-		bcmgenet_dump_tx_queue(&priv->tx_rings[q]);
-
-	bcmgenet_tx_reclaim_all(dev);
+	bcmgenet_dump_tx_queue(ring);
 
-	for (q = 0; q <= priv->hw_params->tx_queues; q++)
-		int1_enable |= (1 << q);
+	bcmgenet_tx_reclaim(dev, ring, true);
 
-	/* Re-enable TX interrupts if disabled */
-	bcmgenet_intrl2_1_writel(priv, int1_enable, INTRL2_CPU_MASK_CLEAR);
+	/* Re-enable the TX interrupt for this ring */
+	bcmgenet_intrl2_1_writel(priv, 1 << txqueue, INTRL2_CPU_MASK_CLEAR);
 
-	netif_trans_update(dev);
+	txq_trans_cond_update(txq);
 
-	BCMGENET_STATS64_INC((&priv->tx_rings[txqueue].stats64), errors);
+	BCMGENET_STATS64_INC((&ring->stats64), errors);
 
-	netif_tx_wake_all_queues(dev);
+	netif_tx_wake_queue(txq);
 }
 
 #define MAX_MDF_FILTER	17
Signature · 1 line
2.53.0
author maintainer
#81 lore raw

PATCH 79/666 eth: fbnic: Use wake instead of start

In reply to Greg Kroah-Hartman

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

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

From: Mohsin Bashir <[email protected]>

[ Upstream commit 12ff2a4aee6c86746623d5aed24389dbf6dffded ]

fbnic_up() calls netif_tx_start_all_queues(), which only clears __QUEUE_STATE_DRV_XOFF. If qdisc backlog has accumulated on any TX queue before the reconfiguration (e.g. ring resize via ethtool -G), start does not call __netif_schedule() to kick the qdisc, so the pending backlog is never drained and the queue stalls.

Switch to netif_tx_wake_all_queues(), which clears DRV_XOFF and also calls __netif_schedule() on every queue, ensuring any backlog that built up before the down/up cycle is promptly dequeued.

Fixes bc6107771bb4 ("eth: fbnic: Allocate a netdevice and napi vectors with queues")
---
 drivers/net/ethernet/meta/fbnic/fbnic_pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/meta/fbnic/fbnic_pci.c +1 -1
index 72bdc6c76c0c5..53bb1d691cc0c 100644
@@ -137,7 +137,7 @@ void fbnic_up(struct fbnic_net *fbn)
 
 	/* Enable Tx/Rx processing */
 	fbnic_napi_enable(fbn);
-	netif_tx_start_all_queues(fbn->netdev);
+	netif_tx_wake_all_queues(fbn->netdev);
 
 	fbnic_service_task_start(fbn);
 }
Signature · 1 line
2.53.0
author maintainer
#82 lore raw

PATCH 80/666 netfilter: xt_socket: enable defrag after all other checks

In reply to Greg Kroah-Hartman

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

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

From: Florian Westphal <[email protected]>

[ Upstream commit 542be3fa5aff54210a02954c38f07e53ea9bdafd ]

Originally this did not matter because defrag was enabled once per netns and only disabled again on netns dismantle. When this got changed I should have adjusted checkentry to not leave defrag enabled on error.

Fixes de8c12110a13 ("netfilter: disable defrag once its no longer needed")
---
 net/netfilter/xt_socket.c | 23 ++++++-----------------
 1 file changed, 6 insertions(+), 17 deletions(-)
net/netfilter/xt_socket.c +6 -17
index 76e01f292aaff..811e53bee4085 100644
@@ -168,52 +168,41 @@ static int socket_mt_enable_defrag(struct net *net, int family)
 static int socket_mt_v1_check(const struct xt_mtchk_param *par)
 {
 	const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo;
-	int err;
-
-	err = socket_mt_enable_defrag(par->net, par->family);
-	if (err)
-		return err;
 
 	if (info->flags & ~XT_SOCKET_FLAGS_V1) {
 		pr_info_ratelimited("unknown flags 0x%x\n",
 				    info->flags & ~XT_SOCKET_FLAGS_V1);
 		return -EINVAL;
 	}
-	return 0;
+
+	return socket_mt_enable_defrag(par->net, par->family);
 }
 
 static int socket_mt_v2_check(const struct xt_mtchk_param *par)
 {
 	const struct xt_socket_mtinfo2 *info = (struct xt_socket_mtinfo2 *) par->matchinfo;
-	int err;
-
-	err = socket_mt_enable_defrag(par->net, par->family);
-	if (err)
-		return err;
 
 	if (info->flags & ~XT_SOCKET_FLAGS_V2) {
 		pr_info_ratelimited("unknown flags 0x%x\n",
 				    info->flags & ~XT_SOCKET_FLAGS_V2);
 		return -EINVAL;
 	}
-	return 0;
+
+	return socket_mt_enable_defrag(par->net, par->family);
 }
 
 static int socket_mt_v3_check(const struct xt_mtchk_param *par)
 {
 	const struct xt_socket_mtinfo3 *info =
 				    (struct xt_socket_mtinfo3 *)par->matchinfo;
-	int err;
 
-	err = socket_mt_enable_defrag(par->net, par->family);
-	if (err)
-		return err;
 	if (info->flags & ~XT_SOCKET_FLAGS_V3) {
 		pr_info_ratelimited("unknown flags 0x%x\n",
 				    info->flags & ~XT_SOCKET_FLAGS_V3);
 		return -EINVAL;
 	}
-	return 0;
+
+	return socket_mt_enable_defrag(par->net, par->family);
 }
 
 static void socket_mt_destroy(const struct xt_mtdtor_param *par)
Signature · 1 line
2.53.0
author maintainer
#83 lore raw

PATCH 81/666 netfilter: nft_fwd_netdev: check ttl/hl before forwarding

In reply to Greg Kroah-Hartman

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

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

From: Florian Westphal <[email protected]>

[ Upstream commit 1dfd95bdf4d18d263aa8fad06bfb9f4d9c992b18 ]

Drop packets if their ttl/hl is too small for forwarding.

Fixes d32de98ea70f ("netfilter: nft_fwd_netdev: allow to forward packets via neighbour layer")
---
 net/netfilter/nft_fwd_netdev.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
net/netfilter/nft_fwd_netdev.c +10 -0
index 152a9fb4d23af..256e832f1bb99 100644
@@ -116,6 +116,11 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr,
 			goto out;
 		}
 		iph = ip_hdr(skb);
+		if (iph->ttl <= 1) {
+			verdict = NF_DROP;
+			goto out;
+		}
+
 		ip_decrease_ttl(iph);
 		neigh_table = NEIGH_ARP_TABLE;
 		break;
@@ -132,6 +137,11 @@ static void nft_fwd_neigh_eval(const struct nft_expr *expr,
 			goto out;
 		}
 		ip6h = ipv6_hdr(skb);
+		if (ip6h->hop_limit <= 1) {
+			verdict = NF_DROP;
+			goto out;
+		}
+
 		ip6h->hop_limit--;
 		neigh_table = NEIGH_ND_TABLE;
 		break;
Signature · 1 line
2.53.0
author maintainer
#84 lore raw

PATCH 82/666 bpf: fix mm lifecycle in open-coded task_vma iterator

In reply to Greg Kroah-Hartman

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

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

From: Puranjay Mohan <[email protected]>

[ Upstream commit d8e27d2d22b6e2df3a0125b8c08e9aace38c954c ]

The open-coded task_vma iterator reads task->mm locklessly and acquires mmap_read_trylock() but never calls mmget(). If the task exits concurrently, the mm_struct can be freed as it is not SLAB_TYPESAFE_BY_RCU, resulting in a use-after-free.

Safely read task->mm with a trylock on alloc_lock and acquire an mm reference. Drop the reference via bpf_iter_mmput_async() in _destroy() and error paths. bpf_iter_mmput_async() is a local wrapper around mmput_async() with a fallback to mmput() on !CONFIG_MMU.

Reject irqs-disabled contexts (including NMI) up front. Operations used by _next() and _destroy() (mmap_read_unlock, bpf_iter_mmput_async) take spinlocks with IRQs disabled (pool->lock, pi_lock). Running from NMI or from a tracepoint that fires with those locks held could deadlock.

A trylock on alloc_lock is used instead of the blocking task_lock() (get_task_mm) to avoid a deadlock when a softirq BPF program iterates a task that already holds its alloc_lock on the same CPU.

Fixes 4ac454682158 ("bpf: Introduce task_vma open-coded iterator kfuncs")
---
 kernel/bpf/task_iter.c | 54 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 51 insertions(+), 3 deletions(-)
kernel/bpf/task_iter.c +51 -3
index 5af9e130e500f..c37ae44bd0a53 100644
@@ -10,6 +10,7 @@
 #include <linux/bpf_mem_alloc.h>
 #include <linux/btf_ids.h>
 #include <linux/mm_types.h>
+#include <linux/sched/mm.h>
 #include "mmap_unlock_work.h"
 
 static const char * const iter_task_type_names[] = {
@@ -798,6 +799,15 @@ const struct bpf_func_proto bpf_find_vma_proto = {
 	.arg5_type	= ARG_ANYTHING,
 };
 
+static inline void bpf_iter_mmput_async(struct mm_struct *mm)
+{
+#ifdef CONFIG_MMU
+	mmput_async(mm);
+#else
+	mmput(mm);
+#endif
+}
+
 struct bpf_iter_task_vma_kern_data {
 	struct task_struct *task;
 	struct mm_struct *mm;
@@ -829,6 +839,24 @@ __bpf_kfunc int bpf_iter_task_vma_new(struct bpf_iter_task_vma *it,
 	BUILD_BUG_ON(sizeof(struct bpf_iter_task_vma_kern) != sizeof(struct bpf_iter_task_vma));
 	BUILD_BUG_ON(__alignof__(struct bpf_iter_task_vma_kern) != __alignof__(struct bpf_iter_task_vma));
 
+	/* bpf_iter_mmput_async() needs mmput_async() which requires CONFIG_MMU */
+	if (!IS_ENABLED(CONFIG_MMU)) {
+		kit->data = NULL;
+		return -EOPNOTSUPP;
+	}
+
+	/*
+	 * Reject irqs-disabled contexts including NMI. Operations used
+	 * by _next() and _destroy() (mmap_read_unlock, bpf_iter_mmput_async)
+	 * can take spinlocks with IRQs disabled (pi_lock, pool->lock).
+	 * Running from NMI or from a tracepoint that fires with those
+	 * locks held could deadlock.
+	 */
+	if (irqs_disabled()) {
+		kit->data = NULL;
+		return -EBUSY;
+	}
+
 	/* is_iter_reg_valid_uninit guarantees that kit hasn't been initialized
 	 * before, so non-NULL kit->data doesn't point to previously
 	 * bpf_mem_alloc'd bpf_iter_task_vma_kern_data
@@ -838,7 +866,25 @@ __bpf_kfunc int bpf_iter_task_vma_new(struct bpf_iter_task_vma *it,
 		return -ENOMEM;
 
 	kit->data->task = get_task_struct(task);
+	/*
+	 * Safely read task->mm and acquire an mm reference.
+	 *
+	 * Cannot use get_task_mm() because its task_lock() is a
+	 * blocking spin_lock that would deadlock if the target task
+	 * already holds alloc_lock on this CPU (e.g. a softirq BPF
+	 * program iterating a task interrupted while holding its
+	 * alloc_lock).
+	 */
+	if (!spin_trylock(&task->alloc_lock)) {
+		err = -EBUSY;
+		goto err_cleanup_iter;
+	}
 	kit->data->mm = task->mm;
+	if (kit->data->mm && !(task->flags & PF_KTHREAD))
+		mmget(kit->data->mm);
+	else
+		kit->data->mm = NULL;
+	spin_unlock(&task->alloc_lock);
 	if (!kit->data->mm) {
 		err = -ENOENT;
 		goto err_cleanup_iter;
@@ -848,15 +894,16 @@ __bpf_kfunc int bpf_iter_task_vma_new(struct bpf_iter_task_vma *it,
 	irq_work_busy = bpf_mmap_unlock_get_irq_work(&kit->data->work);
 	if (irq_work_busy || !mmap_read_trylock(kit->data->mm)) {
 		err = -EBUSY;
-		goto err_cleanup_iter;
+		goto err_cleanup_mmget;
 	}
 
 	vma_iter_init(&kit->data->vmi, kit->data->mm, addr);
 	return 0;
 
+err_cleanup_mmget:
+	bpf_iter_mmput_async(kit->data->mm);
 err_cleanup_iter:
-	if (kit->data->task)
-		put_task_struct(kit->data->task);
+	put_task_struct(kit->data->task);
 	bpf_mem_free(&bpf_global_ma, kit->data);
 	/* NULL kit->data signals failed bpf_iter_task_vma initialization */
 	kit->data = NULL;
@@ -879,6 +926,7 @@ __bpf_kfunc void bpf_iter_task_vma_destroy(struct bpf_iter_task_vma *it)
 	if (kit->data) {
 		bpf_mmap_unlock_mm(kit->data->work, kit->data->mm);
 		put_task_struct(kit->data->task);
+		bpf_iter_mmput_async(kit->data->mm);
 		bpf_mem_free(&bpf_global_ma, kit->data);
 	}
 }
Signature · 1 line
2.53.0
author maintainer
#85 lore raw

PATCH 83/666 bpf: switch task_vma iterator from mmap_lock to per-VMA locks

In reply to Greg Kroah-Hartman

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

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

From: Puranjay Mohan <[email protected]>

[ Upstream commit bee9ef4a40a277bf401be43d39ba7f7f063cf39c ]

The open-coded task_vma iterator holds mmap_lock for the entire duration of iteration, increasing contention on this highly contended lock.

Switch to per-VMA locking. Find the next VMA via an RCU-protected maple tree walk and lock it with lock_vma_under_rcu(). lock_next_vma() is not used because its fallback takes mmap_read_lock(), and the iterator must work in non-sleepable contexts.

lock_vma_under_rcu() is a point lookup (mas_walk) that finds the VMA containing a given address but cannot iterate across gaps. An RCU-protected vma_next() walk (mas_find) first locates the next VMA's vm_start to pass to lock_vma_under_rcu().

Between the RCU walk and the lock, the VMA may be removed, shrunk, or write-locked. On failure, advance past it using vm_end from the RCU walk. Because the VMA slab is SLAB_TYPESAFE_BY_RCU, vm_end may be stale; fall back to PAGE_SIZE advancement when it does not make forward progress. Concurrent VMA insertions at addresses already passed by the iterator are not detected.

CONFIG_PER_VMA_LOCK is required; return -EOPNOTSUPP without it.

Stable-dep-of: 4cbee026db54 ("bpf: return VMA snapshot from task_vma iterator")

---
 kernel/bpf/task_iter.c | 91 +++++++++++++++++++++++++++++++++---------
 1 file changed, 73 insertions(+), 18 deletions(-)
kernel/bpf/task_iter.c +73 -18
index c37ae44bd0a53..aee03c55602a0 100644
@@ -10,6 +10,7 @@
 #include <linux/bpf_mem_alloc.h>
 #include <linux/btf_ids.h>
 #include <linux/mm_types.h>
+#include <linux/mmap_lock.h>
 #include <linux/sched/mm.h>
 #include "mmap_unlock_work.h"
 
@@ -811,8 +812,8 @@ static inline void bpf_iter_mmput_async(struct mm_struct *mm)
 struct bpf_iter_task_vma_kern_data {
 	struct task_struct *task;
 	struct mm_struct *mm;
-	struct mmap_unlock_irq_work *work;
-	struct vma_iterator vmi;
+	struct vm_area_struct *locked_vma;
+	u64 next_addr;
 };
 
 struct bpf_iter_task_vma {
@@ -833,21 +834,19 @@ __bpf_kfunc int bpf_iter_task_vma_new(struct bpf_iter_task_vma *it,
 				      struct task_struct *task, u64 addr)
 {
 	struct bpf_iter_task_vma_kern *kit = (void *)it;
-	bool irq_work_busy = false;
 	int err;
 
 	BUILD_BUG_ON(sizeof(struct bpf_iter_task_vma_kern) != sizeof(struct bpf_iter_task_vma));
 	BUILD_BUG_ON(__alignof__(struct bpf_iter_task_vma_kern) != __alignof__(struct bpf_iter_task_vma));
 
-	/* bpf_iter_mmput_async() needs mmput_async() which requires CONFIG_MMU */
-	if (!IS_ENABLED(CONFIG_MMU)) {
+	if (!IS_ENABLED(CONFIG_PER_VMA_LOCK)) {
 		kit->data = NULL;
 		return -EOPNOTSUPP;
 	}
 
 	/*
 	 * Reject irqs-disabled contexts including NMI. Operations used
-	 * by _next() and _destroy() (mmap_read_unlock, bpf_iter_mmput_async)
+	 * by _next() and _destroy() (vma_end_read, bpf_iter_mmput_async)
 	 * can take spinlocks with IRQs disabled (pi_lock, pool->lock).
 	 * Running from NMI or from a tracepoint that fires with those
 	 * locks held could deadlock.
@@ -890,18 +889,10 @@ __bpf_kfunc int bpf_iter_task_vma_new(struct bpf_iter_task_vma *it,
 		goto err_cleanup_iter;
 	}
 
-	/* kit->data->work == NULL is valid after bpf_mmap_unlock_get_irq_work */
-	irq_work_busy = bpf_mmap_unlock_get_irq_work(&kit->data->work);
-	if (irq_work_busy || !mmap_read_trylock(kit->data->mm)) {
-		err = -EBUSY;
-		goto err_cleanup_mmget;
-	}
-
-	vma_iter_init(&kit->data->vmi, kit->data->mm, addr);
+	kit->data->locked_vma = NULL;
+	kit->data->next_addr = addr;
 	return 0;
 
-err_cleanup_mmget:
-	bpf_iter_mmput_async(kit->data->mm);
 err_cleanup_iter:
 	put_task_struct(kit->data->task);
 	bpf_mem_free(&bpf_global_ma, kit->data);
@@ -910,13 +901,76 @@ __bpf_kfunc int bpf_iter_task_vma_new(struct bpf_iter_task_vma *it,
 	return err;
 }
 
+/*
+ * Find and lock the next VMA at or after data->next_addr.
+ *
+ * lock_vma_under_rcu() is a point lookup (mas_walk): it finds the VMA
+ * containing a given address but cannot iterate. An RCU-protected
+ * maple tree walk with vma_next() (mas_find) is needed first to locate
+ * the next VMA's vm_start across any gap.
+ *
+ * Between the RCU walk and the lock, the VMA may be removed, shrunk,
+ * or write-locked. On failure, advance past it using vm_end from the
+ * RCU walk. SLAB_TYPESAFE_BY_RCU can make vm_end stale, so fall back
+ * to PAGE_SIZE advancement to guarantee forward progress.
+ */
+static struct vm_area_struct *
+bpf_iter_task_vma_find_next(struct bpf_iter_task_vma_kern_data *data)
+{
+	struct vm_area_struct *vma;
+	struct vma_iterator vmi;
+	unsigned long start, end;
+
+retry:
+	rcu_read_lock();
+	vma_iter_init(&vmi, data->mm, data->next_addr);
+	vma = vma_next(&vmi);
+	if (!vma) {
+		rcu_read_unlock();
+		return NULL;
+	}
+	start = vma->vm_start;
+	end = vma->vm_end;
+	rcu_read_unlock();
+
+	vma = lock_vma_under_rcu(data->mm, start);
+	if (!vma) {
+		if (end <= data->next_addr)
+			data->next_addr += PAGE_SIZE;
+		else
+			data->next_addr = end;
+		goto retry;
+	}
+
+	if (unlikely(vma->vm_end <= data->next_addr)) {
+		data->next_addr += PAGE_SIZE;
+		vma_end_read(vma);
+		goto retry;
+	}
+
+	return vma;
+}
+
 __bpf_kfunc struct vm_area_struct *bpf_iter_task_vma_next(struct bpf_iter_task_vma *it)
 {
 	struct bpf_iter_task_vma_kern *kit = (void *)it;
+	struct vm_area_struct *vma;
 
 	if (!kit->data) /* bpf_iter_task_vma_new failed */
 		return NULL;
-	return vma_next(&kit->data->vmi);
+
+	if (kit->data->locked_vma) {
+		vma_end_read(kit->data->locked_vma);
+		kit->data->locked_vma = NULL;
+	}
+
+	vma = bpf_iter_task_vma_find_next(kit->data);
+	if (!vma)
+		return NULL;
+
+	kit->data->locked_vma = vma;
+	kit->data->next_addr = vma->vm_end;
+	return vma;
 }
 
 __bpf_kfunc void bpf_iter_task_vma_destroy(struct bpf_iter_task_vma *it)
@@ -924,7 +978,8 @@ __bpf_kfunc void bpf_iter_task_vma_destroy(struct bpf_iter_task_vma *it)
 	struct bpf_iter_task_vma_kern *kit = (void *)it;
 
 	if (kit->data) {
-		bpf_mmap_unlock_mm(kit->data->work, kit->data->mm);
+		if (kit->data->locked_vma)
+			vma_end_read(kit->data->locked_vma);
 		put_task_struct(kit->data->task);
 		bpf_iter_mmput_async(kit->data->mm);
 		bpf_mem_free(&bpf_global_ma, kit->data);
Signature · 1 line
2.53.0
author maintainer
#86 lore raw

PATCH 84/666 bpf: return VMA snapshot from task_vma iterator

In reply to Greg Kroah-Hartman

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

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

From: Puranjay Mohan <[email protected]>

[ Upstream commit 4cbee026db54cad39c39db4d356100cb133412b3 ]

Holding the per-VMA lock across the BPF program body creates a lock ordering problem when helpers acquire locks that depend on mmap_lock:

vm_lock -> i_rwsem -> mmap_lock -> vm_lock

Snapshot the VMA under the per-VMA lock in _next() via memcpy(), then drop the lock before returning. The BPF program accesses only the snapshot.

The verifier only trusts vm_mm and vm_file pointers (see BTF_TYPE_SAFE_TRUSTED_OR_NULL in verifier.c). vm_file is reference- counted with get_file() under the lock and released via fput() on the next iteration or in _destroy(). vm_mm is already correct because lock_vma_under_rcu() verifies vma->vm_mm == mm. All other pointers are left as-is by memcpy() since the verifier treats them as untrusted.

---
 kernel/bpf/task_iter.c | 42 ++++++++++++++++++++++++++++++------------
 1 file changed, 30 insertions(+), 12 deletions(-)
kernel/bpf/task_iter.c +30 -12
index aee03c55602a0..fc5f463ca529a 100644
@@ -812,7 +812,7 @@ static inline void bpf_iter_mmput_async(struct mm_struct *mm)
 struct bpf_iter_task_vma_kern_data {
 	struct task_struct *task;
 	struct mm_struct *mm;
-	struct vm_area_struct *locked_vma;
+	struct vm_area_struct snapshot;
 	u64 next_addr;
 };
 
@@ -846,7 +846,7 @@ __bpf_kfunc int bpf_iter_task_vma_new(struct bpf_iter_task_vma *it,
 
 	/*
 	 * Reject irqs-disabled contexts including NMI. Operations used
-	 * by _next() and _destroy() (vma_end_read, bpf_iter_mmput_async)
+	 * by _next() and _destroy() (vma_end_read, fput, bpf_iter_mmput_async)
 	 * can take spinlocks with IRQs disabled (pi_lock, pool->lock).
 	 * Running from NMI or from a tracepoint that fires with those
 	 * locks held could deadlock.
@@ -889,7 +889,7 @@ __bpf_kfunc int bpf_iter_task_vma_new(struct bpf_iter_task_vma *it,
 		goto err_cleanup_iter;
 	}
 
-	kit->data->locked_vma = NULL;
+	kit->data->snapshot.vm_file = NULL;
 	kit->data->next_addr = addr;
 	return 0;
 
@@ -951,26 +951,45 @@ bpf_iter_task_vma_find_next(struct bpf_iter_task_vma_kern_data *data)
 	return vma;
 }
 
+static void bpf_iter_task_vma_snapshot_reset(struct vm_area_struct *snap)
+{
+	if (snap->vm_file) {
+		fput(snap->vm_file);
+		snap->vm_file = NULL;
+	}
+}
+
 __bpf_kfunc struct vm_area_struct *bpf_iter_task_vma_next(struct bpf_iter_task_vma *it)
 {
 	struct bpf_iter_task_vma_kern *kit = (void *)it;
-	struct vm_area_struct *vma;
+	struct vm_area_struct *snap, *vma;
 
 	if (!kit->data) /* bpf_iter_task_vma_new failed */
 		return NULL;
 
-	if (kit->data->locked_vma) {
-		vma_end_read(kit->data->locked_vma);
-		kit->data->locked_vma = NULL;
-	}
+	snap = &kit->data->snapshot;
+
+	bpf_iter_task_vma_snapshot_reset(snap);
 
 	vma = bpf_iter_task_vma_find_next(kit->data);
 	if (!vma)
 		return NULL;
 
-	kit->data->locked_vma = vma;
+	memcpy(snap, vma, sizeof(*snap));
+
+	/*
+	 * The verifier only trusts vm_mm and vm_file (see
+	 * BTF_TYPE_SAFE_TRUSTED_OR_NULL in verifier.c). Take a reference
+	 * on vm_file; vm_mm is already correct because lock_vma_under_rcu()
+	 * verifies vma->vm_mm == mm. All other pointers are untrusted by
+	 * the verifier and left as-is.
+	 */
+	if (snap->vm_file)
+		get_file(snap->vm_file);
+
 	kit->data->next_addr = vma->vm_end;
-	return vma;
+	vma_end_read(vma);
+	return snap;
 }
 
 __bpf_kfunc void bpf_iter_task_vma_destroy(struct bpf_iter_task_vma *it)
@@ -978,8 +997,7 @@ __bpf_kfunc void bpf_iter_task_vma_destroy(struct bpf_iter_task_vma *it)
 	struct bpf_iter_task_vma_kern *kit = (void *)it;
 
 	if (kit->data) {
-		if (kit->data->locked_vma)
-			vma_end_read(kit->data->locked_vma);
+		bpf_iter_task_vma_snapshot_reset(&kit->data->snapshot);
 		put_task_struct(kit->data->task);
 		bpf_iter_mmput_async(kit->data->mm);
 		bpf_mem_free(&bpf_global_ma, kit->data);
Signature · 1 line
2.53.0
author maintainer
#87 lore raw

PATCH 85/666 bpf: Fix RCU stall in bpf_fd_array_map_clear()

In reply to Greg Kroah-Hartman

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

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

From: Sechang Lim <[email protected]>

[ Upstream commit 4406942e65ca128c56c67443832988873c21d2e9 ]

Add a missing cond_resched() in bpf_fd_array_map_clear() loop.

For PROG_ARRAY maps with many entries this loop calls prog_array_map_poke_run() per entry which can be expensive, and without yielding this can cause RCU stalls under load:

rcu: Stack dump where RCU GP kthread last ran:

  CPU: 0 UID: 0 PID: 30932 Comm: kworker/0:2 Not tainted 6.14.0-13195-g967e8def1100 #2 PREEMPT(undef)
  Workqueue: events prog_array_map_clear_deferred
  RIP: 0010:write_comp_data+0x38/0x90 kernel/kcov.c:246
  Call Trace:
   <TASK>
   prog_array_map_poke_run+0x77/0x380 kernel/bpf/arraymap.c:1096
   __fd_array_map_delete_elem+0x197/0x310 kernel/bpf/arraymap.c:925
   bpf_fd_array_map_clear kernel/bpf/arraymap.c:1000 [inline]
   prog_array_map_clear_deferred+0x119/0x1b0 kernel/bpf/arraymap.c:1141
   process_one_work+0x898/0x19d0 kernel/workqueue.c:3238
   process_scheduled_works kernel/workqueue.c:3319 [inline]
   worker_thread+0x770/0x10b0 kernel/workqueue.c:3400
   kthread+0x465/0x880 kernel/kthread.c:464
   ret_from_fork+0x4d/0x80 arch/x86/kernel/process.c:153
   ret_from_fork_asm+0x19/0x30 arch/x86/entry/entry_64.S:245
   </TASK>
Fixes da765a2f5993 ("bpf: Add poke dependency tracking for prog array maps")
---
 kernel/bpf/arraymap.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/bpf/arraymap.c +3 -1
index 6cdbb4c33d31d..7ec69545fe056 100644
@@ -998,8 +998,10 @@ static void bpf_fd_array_map_clear(struct bpf_map *map, bool need_defer)
 	struct bpf_array *array = container_of(map, struct bpf_array, map);
 	int i;
 
-	for (i = 0; i < array->map.max_entries; i++)
+	for (i = 0; i < array->map.max_entries; i++) {
 		__fd_array_map_delete_elem(map, &i, need_defer);
+		cond_resched();
+	}
 }
 
 static void prog_array_map_seq_show_elem(struct bpf_map *map, void *key,
Signature · 1 line
2.53.0
author maintainer
#88 lore raw

PATCH 86/666 net: hamradio: 6pack: fix uninit-value in sixpack_receive_buf

In reply to Greg Kroah-Hartman

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

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

From: Mashiro Chen <[email protected]>

[ Upstream commit bf9a38803b2626b01cc769aaf13485d8650f576f ]

sixpack_receive_buf() does not properly skip bytes with TTY error flags. The while loop iterates through the flags buffer but never advances the data pointer (cp), and passes the original count (including error bytes) to sixpack_decode(). This causes sixpack_decode() to process bytes that should have been skipped due to TTY errors. The TTY layer does not guarantee that cp[i] holds a meaningful value when fp[i] is set, so passing those positions to sixpack_decode() results in KMSAN reporting an uninit-value read.

Fix this by processing bytes one at a time, advancing cp on each iteration, and only passing valid (non-error) bytes to sixpack_decode(). This matches the pattern used by slip_receive_buf() and mkiss_receive_buf() for the same purpose.

---
 drivers/net/hamradio/6pack.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)
drivers/net/hamradio/6pack.c +4 -5
index 0c766c9c31955..437e5e391a770 100644
@@ -391,7 +391,6 @@ static void sixpack_receive_buf(struct tty_struct *tty, const u8 *cp,
 				const u8 *fp, size_t count)
 {
 	struct sixpack *sp;
-	size_t count1;
 
 	if (!count)
 		return;
@@ -401,16 +400,16 @@ static void sixpack_receive_buf(struct tty_struct *tty, const u8 *cp,
 		return;
 
 	/* Read the characters out of the buffer */
-	count1 = count;
-	while (count) {
-		count--;
+	while (count--) {
 		if (fp && *fp++) {
 			if (!test_and_set_bit(SIXPF_ERROR, &sp->flags))
 				sp->dev->stats.rx_errors++;
+			cp++;
 			continue;
 		}
+		sixpack_decode(sp, cp, 1);
+		cp++;
 	}
-	sixpack_decode(sp, cp, count1);
 
 	tty_unthrottle(tty);
 }
Signature · 1 line
2.53.0
author maintainer
#89 lore raw

PATCH 87/666 bpf: Relax scalar id equivalence for state pruning

In reply to Greg Kroah-Hartman

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

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

From: Puranjay Mohan <[email protected]>

[ Upstream commit b0388bafa4949bd30af7b3be5ee415f2a25ac014 ]

Scalar register IDs are used by the verifier to track relationships between registers and enable bounds propagation across those relationships. Once an ID becomes singular (i.e. only a single register/stack slot carries it), it can no longer contribute to bounds propagation and effectively becomes stale. The previous commit makes the verifier clear such ids before caching the state.

When comparing the current and cached states for pruning, these stale IDs can cause technically equivalent states to be considered different and thus prevent pruning.

For example, in the selftest added in the next commit, two registers - r6 and r7 are not linked to any other registers and get cached with id=0, in the current state, they are both linked to each other with id=A. Before this commit, check_scalar_ids would give temporary ids to r6 and r7 (say tid1 and tid2) and then check_ids() would map tid1->A, and when it would see tid2->A, it would not consider these state equivalent.

Relax scalar ID equivalence by treating rold->id == 0 as "independent":
if the old state did not rely on any ID relationships for a register, then any ID/linking present in the current state only adds constraints and is always safe to accept for pruning. Implement this by returning true immediately in check_scalar_ids() when old_id == 0.

Maintain correctness for the opposite direction (old_id != 0 && cur_id == 0) by still allocating a temporary ID for cur_id == 0. This avoids incorrectly allowing multiple independent current registers (id==0) to satisfy a single linked old ID during mapping.

Stable-dep-of: 2f2ec8e7730e ("bpf: Enforce regsafe base id consistency for BPF_ADD_CONST scalars")

---
 kernel/bpf/verifier.c                         | 63 +++++++++++++++----
 .../selftests/bpf/progs/verifier_scalar_ids.c |  8 ++-
 2 files changed, 56 insertions(+), 15 deletions(-)
kernel/bpf/verifier.c +51 -12
index feb90c6e94620..87d631917f4dd 100644
@@ -17425,13 +17425,29 @@ static bool check_ids(u32 old_id, u32 cur_id, struct bpf_idmap *idmap)
 	return false;
 }
 
-/* Similar to check_ids(), but allocate a unique temporary ID
- * for 'old_id' or 'cur_id' of zero.
- * This makes pairs like '0 vs unique ID', 'unique ID vs 0' valid.
+/*
+ * Compare scalar register IDs for state equivalence.
+ *
+ * When old_id == 0, the old register is independent - not linked to any
+ * other register. Any linking in the current state only adds constraints,
+ * making it more restrictive. Since the old state didn't rely on any ID
+ * relationships for this register, it's always safe to accept cur regardless
+ * of its ID. Hence, return true immediately.
+ *
+ * When old_id != 0 but cur_id == 0, we need to ensure that different
+ * independent registers in cur don't incorrectly satisfy the ID matching
+ * requirements of linked registers in old.
+ *
+ * Example: if old has r6.id=X and r7.id=X (linked), but cur has r6.id=0
+ * and r7.id=0 (both independent), without temp IDs both would map old_id=X
+ * to cur_id=0 and pass. With temp IDs: r6 maps X->temp1, r7 tries to map
+ * X->temp2, but X is already mapped to temp1, so the check fails correctly.
  */
 static bool check_scalar_ids(u32 old_id, u32 cur_id, struct bpf_idmap *idmap)
 {
-	old_id = old_id ? old_id : ++idmap->tmp_id_gen;
+	if (!old_id)
+		return true;
+
 	cur_id = cur_id ? cur_id : ++idmap->tmp_id_gen;
 
 	return check_ids(old_id, cur_id, idmap);
@@ -17600,11 +17616,21 @@ static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold,
 		}
 		if (!rold->precise && exact == NOT_EXACT)
 			return true;
-		if ((rold->id & BPF_ADD_CONST) != (rcur->id & BPF_ADD_CONST))
-			return false;
-		if ((rold->id & BPF_ADD_CONST) && (rold->off != rcur->off))
-			return false;
-		/* Why check_ids() for scalar registers?
+		/*
+		 * Linked register tracking uses rold->id to detect relationships.
+		 * When rold->id == 0, the register is independent and any linking
+		 * in rcur only adds constraints. When rold->id != 0, we must verify
+		 * id mapping and (for BPF_ADD_CONST) offset consistency.
+		 *
+		 * +------------------+-----------+------------------+---------------+
+		 * |                  | rold->id  | rold + ADD_CONST | rold->id == 0 |
+		 * |------------------+-----------+------------------+---------------|
+		 * | rcur->id         | range,ids | false            | range         |
+		 * | rcur + ADD_CONST | false     | range,ids,off    | range         |
+		 * | rcur->id == 0    | range,ids | false            | range         |
+		 * +------------------+-----------+------------------+---------------+
+		 *
+		 * Why check_ids() for scalar registers?
 		 *
 		 * Consider the following BPF code:
 		 *   1: r6 = ... unbound scalar, ID=a ...
@@ -17628,9 +17654,22 @@ static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold,
 		 * ---
 		 * Also verify that new value satisfies old value range knowledge.
 		 */
-		return range_within(rold, rcur) &&
-		       tnum_in(rold->var_off, rcur->var_off) &&
-		       check_scalar_ids(rold->id, rcur->id, idmap);
+
+		/* ADD_CONST mismatch: different linking semantics */
+		if ((rold->id & BPF_ADD_CONST) && !(rcur->id & BPF_ADD_CONST))
+			return false;
+
+		if (rold->id && !(rold->id & BPF_ADD_CONST) && (rcur->id & BPF_ADD_CONST))
+			return false;
+
+		/* Both have offset linkage: offsets must match */
+		if ((rold->id & BPF_ADD_CONST) && rold->off != rcur->off)
+			return false;
+
+		if (!check_scalar_ids(rold->id, rcur->id, idmap))
+			return false;
+
+		return range_within(rold, rcur) && tnum_in(rold->var_off, rcur->var_off);
 	case PTR_TO_MAP_KEY:
 	case PTR_TO_MAP_VALUE:
 	case PTR_TO_MEM:
tools/testing/selftests/bpf/progs/verifier_scalar_ids.c +5 -3
index 7c5e5e6d10ebc..dc65218e93c47 100644
@@ -723,9 +723,9 @@ __success __log_level(2)
 /* The exit instruction should be reachable from two states,
  * use two matches and "processed .. insns" to ensure this.
  */
-__msg("13: (95) exit")
-__msg("13: (95) exit")
-__msg("processed 18 insns")
+__msg("15: (95) exit")
+__msg("15: (95) exit")
+__msg("processed 20 insns")
 __flag(BPF_F_TEST_STATE_FREQ)
 __naked void two_old_ids_one_cur_id(void)
 {
@@ -734,9 +734,11 @@ __naked void two_old_ids_one_cur_id(void)
 	"call %[bpf_ktime_get_ns];"
 	"r0 &= 0xff;"
 	"r6 = r0;"
+	"r8 = r0;"
 	"call %[bpf_ktime_get_ns];"
 	"r0 &= 0xff;"
 	"r7 = r0;"
+	"r9 = r0;"
 	"r0 = 0;"
 	/* Maybe make r{6,7} IDs identical */
 	"if r6 > r7 goto l0_%=;"
Signature · 1 line
2.53.0
author maintainer
#90 lore raw

PATCH 88/666 bpf: Enforce regsafe base id consistency for BPF_ADD_CONST scalars

In reply to Greg Kroah-Hartman

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

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

From: Daniel Borkmann <[email protected]>

[ Upstream commit 2f2ec8e7730e21fc9bd49e0de9cdd58213ea24d0 ]

When regsafe() compares two scalar registers that both carry BPF_ADD_CONST, check_scalar_ids() maps their full compound id (aka base | BPF_ADD_CONST flag) as one idmap entry. However, it never verifies that the underlying base ids, that is, with the flag stripped are consistent with existing idmap mappings.

This allows construction of two verifier states where the old state has R3 = R2 + 10 (both sharing base id A) while the current state has R3 = R4 + 10 (base id C, unrelated to R2). The idmap creates two independent entries: A->B (for R2) and A|flag->C|flag (for R3), without catching that A->C conflicts with A->B. State pruning then incorrectly succeeds.

Fix this by additionally verifying base ID mapping consistency whenever BPF_ADD_CONST is set: after mapping the compound ids, also invoke check_ids() on the base IDs (flag bits stripped). This ensures that if A was already mapped to B from comparing the source register, any ADD_CONST derivative must also derive from B, not an unrelated C.

---
 kernel/bpf/verifier.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)
kernel/bpf/verifier.c +16 -1
index 87d631917f4dd..f5e9ee63fff99 100644
@@ -17442,6 +17442,13 @@ static bool check_ids(u32 old_id, u32 cur_id, struct bpf_idmap *idmap)
  * and r7.id=0 (both independent), without temp IDs both would map old_id=X
  * to cur_id=0 and pass. With temp IDs: r6 maps X->temp1, r7 tries to map
  * X->temp2, but X is already mapped to temp1, so the check fails correctly.
+ *
+ * When old_id has BPF_ADD_CONST set, the compound id (base | flag) and the
+ * base id (flag stripped) must both map consistently. Example: old has
+ * r2.id=A, r3.id=A|flag (r3 = r2 + delta), cur has r2.id=B, r3.id=C|flag
+ * (r3 derived from unrelated r4). Without the base check, idmap gets two
+ * independent entries A->B and A|flag->C|flag, missing that A->C conflicts
+ * with A->B. The base ID cross-check catches this.
  */
 static bool check_scalar_ids(u32 old_id, u32 cur_id, struct bpf_idmap *idmap)
 {
@@ -17450,7 +17457,15 @@ static bool check_scalar_ids(u32 old_id, u32 cur_id, struct bpf_idmap *idmap)
 
 	cur_id = cur_id ? cur_id : ++idmap->tmp_id_gen;
 
-	return check_ids(old_id, cur_id, idmap);
+	if (!check_ids(old_id, cur_id, idmap))
+		return false;
+	if (old_id & BPF_ADD_CONST) {
+		old_id &= ~BPF_ADD_CONST;
+		cur_id &= ~BPF_ADD_CONST;
+		if (!check_ids(old_id, cur_id, idmap))
+			return false;
+	}
+	return true;
 }
 
 static void clean_func_state(struct bpf_verifier_env *env,
Signature · 1 line
2.53.0
author maintainer
#91 lore raw

PATCH 89/666 selftests/bpf: fix __jited_unpriv tag name

In reply to Greg Kroah-Hartman

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

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

From: Eduard Zingerman <[email protected]>

[ Upstream commit cdd54fe98c00549264a92613af6bb0e9a5fd0d1c ]

__jited_unpriv was using "test_jited=" as its tag name, same as the priv variant __jited. Fix by using "test_jited_unpriv=".

---
 tools/testing/selftests/bpf/progs/bpf_misc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/bpf/progs/bpf_misc.h +1 -1
index eccaf955e3947..9c0d71f0b3cc3 100644
@@ -115,7 +115,7 @@
 #define __description(desc)	__attribute__((btf_decl_tag("comment:test_description=" desc)))
 #define __msg_unpriv(msg)	__attribute__((btf_decl_tag("comment:test_expect_msg_unpriv=" XSTR(__COUNTER__) "=" msg)))
 #define __xlated_unpriv(msg)	__attribute__((btf_decl_tag("comment:test_expect_xlated_unpriv=" XSTR(__COUNTER__) "=" msg)))
-#define __jited_unpriv(msg)	__attribute__((btf_decl_tag("comment:test_jited=" XSTR(__COUNTER__) "=" msg)))
+#define __jited_unpriv(msg)	__attribute__((btf_decl_tag("comment:test_jited_unpriv=" XSTR(__COUNTER__) "=" msg)))
 #define __failure_unpriv	__attribute__((btf_decl_tag("comment:test_expect_failure_unpriv")))
 #define __success_unpriv	__attribute__((btf_decl_tag("comment:test_expect_success_unpriv")))
 #define __log_level(lvl)	__attribute__((btf_decl_tag("comment:test_log_level="#lvl)))
Signature · 1 line
2.53.0
author maintainer
#92 lore raw

PATCH 90/666 net/sched: act_ct: Only release RCU read lock after ct_ft

In reply to Greg Kroah-Hartman

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

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

From: Jamal Hadi Salim <[email protected]>

[ Upstream commit f462dca0c8415bf0058d0ffa476354c4476d0f09 ]

When looking up a flow table in act_ct in tcf_ct_flow_table_get(), rhashtable_lookup_fast() internally opens and closes an RCU read critical section before returning ct_ft.
The tcf_ct_flow_table_cleanup_work() can complete before refcount_inc_not_zero() is invoked on the returned ct_ft resulting in a UAF on the already freed ct_ft object. This vulnerability can lead to privilege escalation.

Analysis from [email protected]:
When initializing act_ct, tcf_ct_init() is called, which internally triggers tcf_ct_flow_table_get().

static int tcf_ct_flow_table_get(struct net *net, struct tcf_ct_params *params)

{
                struct zones_ht_key key = { .net = net, .zone = params->zone };
                struct tcf_ct_flow_table *ct_ft;
                int err = -ENOMEM;

                mutex_lock(&zones_mutex);
                ct_ft = rhashtable_lookup_fast(&zones_ht, &key, zones_params); // [1]
                if (ct_ft && refcount_inc_not_zero(&ct_ft->ref)) // [2]
                                goto out_unlock;
                ...
}

static __always_inline void *rhashtable_lookup_fast(
struct rhashtable *ht, const void *key, const struct rhashtable_params params)

{
                void *obj;

                rcu_read_lock();
                obj = rhashtable_lookup(ht, key, params);
                rcu_read_unlock();

                return obj;
}

At [1], rhashtable_lookup_fast() looks up and returns the corresponding ct_ft from zones_ht . The lookup is performed within an RCU read critical section through rcu_read_lock() / rcu_read_unlock(), which prevents the object from being freed. However, at the point of function return, rcu_read_unlock() has already been called, and there is nothing preventing ct_ft from being freed before reaching refcount_inc_not_zero(&ct_ft->ref) at [2]. This interval becomes the race window, during which ct_ft can be freed.

Free Process:

tcf_ct_flow_table_put() is executed through the path tcf_ct_cleanup() call_rcu() tcf_ct_params_free_rcu() tcf_ct_params_free() tcf_ct_flow_table_put().

static void tcf_ct_flow_table_put(struct tcf_ct_flow_table *ct_ft)

{
                if (refcount_dec_and_test(&ct_ft->ref)) {
                                rhashtable_remove_fast(&zones_ht, &ct_ft->node, zones_params);
                                INIT_RCU_WORK(&ct_ft->rwork, tcf_ct_flow_table_cleanup_work); // [3]
                                queue_rcu_work(act_ct_wq, &ct_ft->rwork);
                }
}

At [3], tcf_ct_flow_table_cleanup_work() is scheduled as RCU work

static void tcf_ct_flow_table_cleanup_work(struct work_struct *work)

{
                struct tcf_ct_flow_table *ct_ft;
                struct flow_block *block;

                ct_ft = container_of(to_rcu_work(work), struct tcf_ct_flow_table,
                                                                rwork);
                nf_flow_table_free(&ct_ft->nf_ft);
                block = &ct_ft->nf_ft.flow_block;
                down_write(&ct_ft->nf_ft.flow_block_lock);
                WARN_ON(!list_empty(&block->cb_list));
                up_write(&ct_ft->nf_ft.flow_block_lock);
                kfree(ct_ft); // [4]

                module_put(THIS_MODULE);
}

tcf_ct_flow_table_cleanup_work() frees ct_ft at [4]. When this function executes between [1] and [2], UAF occurs.

This race condition has a very short race window, making it generally difficult to trigger. Therefore, to trigger the vulnerability an msleep(100) was inserted after[1]

Fixes 138470a9b2cc2 ("net/sched: act_ct: fix lockdep splat in tcf_ct_flow_table_get")
Reported-by [email protected]
---
 net/sched/act_ct.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
net/sched/act_ct.c +6 -2
index 945b64be4c1f1..c82755749211c 100644
@@ -326,9 +326,13 @@ static int tcf_ct_flow_table_get(struct net *net, struct tcf_ct_params *params)
 	int err = -ENOMEM;
 
 	mutex_lock(&zones_mutex);
-	ct_ft = rhashtable_lookup_fast(&zones_ht, &key, zones_params);
-	if (ct_ft && refcount_inc_not_zero(&ct_ft->ref))
+	rcu_read_lock();
+	ct_ft = rhashtable_lookup(&zones_ht, &key, zones_params);
+	if (ct_ft && refcount_inc_not_zero(&ct_ft->ref)) {
+		rcu_read_unlock();
 		goto out_unlock;
+	}
+	rcu_read_unlock();
 
 	ct_ft = kzalloc(sizeof(*ct_ft), GFP_KERNEL);
 	if (!ct_ft)
Signature · 1 line
2.53.0
author maintainer
#93 lore raw

PATCH 91/666 selftests: netfilter: nft_tproxy.sh: adjust to socat changes

In reply to Greg Kroah-Hartman

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

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

From: Florian Westphal <[email protected]>

[ Upstream commit 61119542663cac70898aef532eb57ee41ea9b477 ]

Like e65d8b6f3092 ("selftests: drv-net: adjust to socat changes") we need to add shut-none for this test too.

The extra 0-packet can trigger a second (unexpected) reply from the server.

---
 .../selftests/net/netfilter/nft_tproxy_udp.sh      | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
tools/testing/selftests/net/netfilter/nft_tproxy_udp.sh +7 -7
index d16de13fe5a75..1dc7b04501459 100755
@@ -190,13 +190,13 @@ table inet filter {
 }
 EOF
 
-	timeout "$timeout" ip netns exec "$nsrouter" socat -u "$socat_ipproto" udp-listen:12345,fork,ip-transparent,reuseport udp:"$ns1_ip_port",ip-transparent,reuseport,bind="$ns2_ip_port" 2>/dev/null &
+	timeout "$timeout" ip netns exec "$nsrouter" socat -u "$socat_ipproto" udp-listen:12345,fork,ip-transparent,reuseport,shut-none udp:"$ns1_ip_port",ip-transparent,reuseport,bind="$ns2_ip_port",shut-none 2>/dev/null &
 	local tproxy_pid=$!
 
-	timeout "$timeout" ip netns exec "$ns2" socat "$socat_ipproto" udp-listen:8080,fork SYSTEM:"echo PONG_NS2" 2>/dev/null &
+	timeout "$timeout" ip netns exec "$ns2" socat "$socat_ipproto" udp-listen:8080,fork,shut-none SYSTEM:"echo PONG_NS2" 2>/dev/null &
 	local server2_pid=$!
 
-	timeout "$timeout" ip netns exec "$ns3" socat "$socat_ipproto" udp-listen:8080,fork SYSTEM:"echo PONG_NS3" 2>/dev/null &
+	timeout "$timeout" ip netns exec "$ns3" socat "$socat_ipproto" udp-listen:8080,fork,shut-none SYSTEM:"echo PONG_NS3" 2>/dev/null &
 	local server3_pid=$!
 
 	busywait "$BUSYWAIT_TIMEOUT" listener_ready "$nsrouter" 12345 "-u"
@@ -205,7 +205,7 @@ EOF
 
 	local result
 	# request from ns1 to ns2 (forwarded traffic)
-	result=$(echo I_M_PROXIED | ip netns exec "$ns1" socat -t 2 -T 2 STDIO udp:"$ns2_ip_port",sourceport=18888)
+	result=$(echo I_M_PROXIED | ip netns exec "$ns1" socat -t 2 -T 2 STDIO udp:"$ns2_ip_port",sourceport=18888,shut-none)
 	if [ "$result" == "$expect_ns1_ns2" ] ;then
 		echo "PASS: tproxy test $testname: ns1 got reply \"$result\" connecting to ns2"
 	else
@@ -214,7 +214,7 @@ EOF
 	fi
 
 	# request from ns1 to ns3 (forwarded traffic)
-	result=$(echo I_M_PROXIED | ip netns exec "$ns1" socat -t 2 -T 2 STDIO udp:"$ns3_ip_port")
+	result=$(echo I_M_PROXIED | ip netns exec "$ns1" socat -t 2 -T 2 STDIO udp:"$ns3_ip_port",shut-none)
 	if [ "$result" = "$expect_ns1_ns3" ] ;then
 		echo "PASS: tproxy test $testname: ns1 got reply \"$result\" connecting to ns3"
 	else
@@ -223,7 +223,7 @@ EOF
 	fi
 
 	# request from nsrouter to ns2 (localy originated traffic)
-	result=$(echo I_M_PROXIED | ip netns exec "$nsrouter" socat -t 2 -T 2 STDIO udp:"$ns2_ip_port")
+	result=$(echo I_M_PROXIED | ip netns exec "$nsrouter" socat -t 2 -T 2 STDIO udp:"$ns2_ip_port",shut-none)
 	if [ "$result" == "$expect_nsrouter_ns2" ] ;then
 		echo "PASS: tproxy test $testname: nsrouter got reply \"$result\" connecting to ns2"
 	else
@@ -232,7 +232,7 @@ EOF
 	fi
 
 	# request from nsrouter to ns3 (localy originated traffic)
-	result=$(echo I_M_PROXIED | ip netns exec "$nsrouter" socat -t 2 -T 2 STDIO udp:"$ns3_ip_port")
+	result=$(echo I_M_PROXIED | ip netns exec "$nsrouter" socat -t 2 -T 2 STDIO udp:"$ns3_ip_port",shut-none)
 	if [ "$result" = "$expect_nsrouter_ns3" ] ;then
 		echo "PASS: tproxy test $testname: nsrouter got reply \"$result\" connecting to ns3"
 	else
Signature · 1 line
2.53.0
author maintainer
#94 lore raw

PATCH 92/666 net: airoha: Implement BQL support

In reply to Greg Kroah-Hartman

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

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

From: Lorenzo Bianconi <[email protected]>

[ Upstream commit 1d304174106c93ce05f6088813ad7203b3eb381a ]

Introduce BQL support in the airoha_eth driver reporting to the kernel info about tx hw DMA queues in order to avoid bufferbloat and keep the latency small.

Stable-dep-of: 656121b15503 ("net: airoha: Add missing RX_CPU_IDX() configuration in airoha_qdma_cleanup_rx_queue()")

---
 drivers/net/ethernet/mediatek/airoha_eth.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/ethernet/mediatek/airoha_eth.c +6 -2
index 7a85550e5ecb3..268d3050c0178 100644
@@ -1729,9 +1729,11 @@ static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
 			WRITE_ONCE(desc->msg1, 0);
 
 			if (skb) {
+				u16 queue = skb_get_queue_mapping(skb);
 				struct netdev_queue *txq;
 
-				txq = netdev_get_tx_queue(skb->dev, qid);
+				txq = netdev_get_tx_queue(skb->dev, queue);
+				netdev_tx_completed_queue(txq, 1, skb->len);
 				if (netif_tx_queue_stopped(txq) &&
 				    q->ndesc - q->queued >= q->free_thr)
 					netif_tx_wake_queue(txq);
@@ -2510,7 +2512,9 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
 	q->queued += i;
 
 	skb_tx_timestamp(skb);
-	if (!netdev_xmit_more())
+	netdev_tx_sent_queue(txq, skb->len);
+
+	if (netif_xmit_stopped(txq) || !netdev_xmit_more())
 		airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid),
 				TX_RING_CPU_IDX_MASK,
 				FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head));
Signature · 1 line
2.53.0
author maintainer
#95 lore raw

PATCH 93/666 net: airoha: Add missing RX_CPU_IDX() configuration in airoha_qdma_cleanup_rx_queue()

In reply to Greg Kroah-Hartman

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

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

From: Lorenzo Bianconi <[email protected]>

[ Upstream commit 656121b155030086b01cfce9bd31b0c925ee6860 ]

When the descriptor index written in REG_RX_CPU_IDX() is equal to the one stored in REG_RX_DMA_IDX(), the hw will stop since the QDMA RX ring is empty.
Add missing REG_RX_CPU_IDX() configuration in airoha_qdma_cleanup_rx_queue routine during QDMA RX ring cleanup.

---
 drivers/net/ethernet/mediatek/airoha_eth.c | 5 +++++
 1 file changed, 5 insertions(+)
drivers/net/ethernet/mediatek/airoha_eth.c +5 -0
index 268d3050c0178..d8af267f64f71 100644
@@ -1641,6 +1641,11 @@ static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q)
 	}
 
 	q->head = q->tail;
+	/* Set RX_DMA_IDX to RX_CPU_IDX to notify the hw the QDMA RX ring is
+	 * empty.
+	 */
+	airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
+			FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head));
 	airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
 			FIELD_PREP(RX_RING_DMA_IDX_MASK, q->tail));
 }
Signature · 1 line
2.53.0
author maintainer
#96 lore raw

PATCH 94/666 bpf: Allow instructions with arena source and non-arena dest registers

In reply to Greg Kroah-Hartman

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

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

From: Emil Tsalapatis <[email protected]>

[ Upstream commit ac61bffe91d4bda08806e12957c6d64756d042db ]

The compiler sometimes stores the result of a PTR_TO_ARENA and SCALAR operation into the scalar register rather than the pointer register. Relax the verifier to allow operations between a source arena register and a destination non-arena register, marking the destination's value as a PTR_TO_ARENA.

Fixes 6082b6c328b5 ("bpf: Recognize addr_space_cast instruction in the verifier.")
---
 kernel/bpf/verifier.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)
kernel/bpf/verifier.c +11 -3
index f5e9ee63fff99..56a74ce4a29b9 100644
@@ -14434,11 +14434,20 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
 	int err;
 
 	dst_reg = &regs[insn->dst_reg];
-	src_reg = NULL;
+	if (BPF_SRC(insn->code) == BPF_X)
+		src_reg = &regs[insn->src_reg];
+	else
+		src_reg = NULL;
 
-	if (dst_reg->type == PTR_TO_ARENA) {
+	/* Case where at least one operand is an arena. */
+	if (dst_reg->type == PTR_TO_ARENA || (src_reg && src_reg->type == PTR_TO_ARENA)) {
 		struct bpf_insn_aux_data *aux = cur_aux(env);
 
+		if (dst_reg->type != PTR_TO_ARENA)
+			*dst_reg = *src_reg;
+
+		dst_reg->subreg_def = env->insn_idx + 1;
+
 		if (BPF_CLASS(insn->code) == BPF_ALU64)
 			/*
 			 * 32-bit operations zero upper bits automatically.
@@ -14454,7 +14463,6 @@ static int adjust_reg_min_max_vals(struct bpf_verifier_env *env,
 		ptr_reg = dst_reg;
 
 	if (BPF_SRC(insn->code) == BPF_X) {
-		src_reg = &regs[insn->src_reg];
 		if (src_reg->type != SCALAR_VALUE) {
 			if (dst_reg->type != SCALAR_VALUE) {
 				/* Combining two pointers by any ALU op yields
Signature · 1 line
2.53.0
author maintainer
#97 lore raw

PATCH 95/666 net/rds: Optimize rds_ib_laddr_check

In reply to Greg Kroah-Hartman

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

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

From: Håkon Bugge <[email protected]>

[ Upstream commit 236f718ac885965fa886440b9898dfae185c9733 ]

rds_ib_laddr_check() creates a CM_ID and attempts to bind the address in question to it. This in order to qualify the allegedly local address as a usable IB/RoCE address.

In the field, ExaWatcher runs rds-ping to all ports in the fabric from all local ports. This using all active ToS'es. In a full rack system, we have 14 cell servers and eight db servers. Typically, 6 ToS'es are used. This implies 528 rds-ping invocations per ExaWatcher's "RDSinfo" interval.

Adding to this, each rds-ping invocation creates eight sockets and binds the local address to them:

socket(AF_RDS, SOCK_SEQPACKET, 0) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(0),

	sin_addr=inet_addr("192.168.36.2")}, 16) = 0
socket(AF_RDS, SOCK_SEQPACKET, 0)       = 4
bind(4, {sa_family=AF_INET, sin_port=htons(0),
	sin_addr=inet_addr("192.168.36.2")}, 16) = 0
socket(AF_RDS, SOCK_SEQPACKET, 0)       = 5
bind(5, {sa_family=AF_INET, sin_port=htons(0),
	sin_addr=inet_addr("192.168.36.2")}, 16) = 0
socket(AF_RDS, SOCK_SEQPACKET, 0)       = 6
bind(6, {sa_family=AF_INET, sin_port=htons(0),
	sin_addr=inet_addr("192.168.36.2")}, 16) = 0
socket(AF_RDS, SOCK_SEQPACKET, 0)       = 7
bind(7, {sa_family=AF_INET, sin_port=htons(0),
	sin_addr=inet_addr("192.168.36.2")}, 16) = 0
socket(AF_RDS, SOCK_SEQPACKET, 0)       = 8
bind(8, {sa_family=AF_INET, sin_port=htons(0),
	sin_addr=inet_addr("192.168.36.2")}, 16) = 0
socket(AF_RDS, SOCK_SEQPACKET, 0)       = 9
bind(9, {sa_family=AF_INET, sin_port=htons(0),
	sin_addr=inet_addr("192.168.36.2")}, 16) = 0
socket(AF_RDS, SOCK_SEQPACKET, 0)       = 10
bind(10, {sa_family=AF_INET, sin_port=htons(0),
	sin_addr=inet_addr("192.168.36.2")}, 16) = 0

So, at every interval ExaWatcher executes rds-ping's, 4224 CM_IDs are allocated, considering this full-rack system. After the a CM_ID has been allocated, rdma_bind_addr() is called, with the port number being zero. This implies that the CMA will attempt to search for an un-used ephemeral port. Simplified, the algorithm is to start at a random position in the available port space, and then if needed, iterate until an un-used port is found.

The book-keeping of used ports uses the idr system, which again uses slab to allocate new struct idr_layer's. The size is 2092 bytes and slab tries to reduce the wasted space. Hence, it chooses an order:3 allocation, for which 15 idr_layer structs will fit and only 1388 bytes are wasted per the 32KiB order:3 chunk.

Although this order:3 allocation seems like a good space/speed trade-off, it does not resonate well with how it used by the CMA. The combination of the randomized starting point in the port space (which has close to zero spatial locality) and the close proximity in time of the 4224 invocations of the rds-ping's, creates a memory hog for order:3 allocations.

These costly allocations may need reclaims and/or compaction. At worst, they may fail and produce a stack trace such as (from uek4):

[<ffffffff811a72d5>] __inc_zone_page_state+0x35/0x40
[<ffffffff811c2e97>] page_add_file_rmap+0x57/0x60
[<ffffffffa37ca1df>] remove_migration_pte+0x3f/0x3c0 [ksplice_6cn872bt_vmlinux_new]
[<ffffffff811c3de8>] rmap_walk+0xd8/0x340
[<ffffffff811e8860>] remove_migration_ptes+0x40/0x50
[<ffffffff811ea83c>] migrate_pages+0x3ec/0x890
[<ffffffff811afa0d>] compact_zone+0x32d/0x9a0
[<ffffffff811b00ed>] compact_zone_order+0x6d/0x90
[<ffffffff811b03b2>] try_to_compact_pages+0x102/0x270
[<ffffffff81190e56>] __alloc_pages_direct_compact+0x46/0x100
[<ffffffff8119165b>] __alloc_pages_nodemask+0x74b/0xaa0
[<ffffffff811d8411>] alloc_pages_current+0x91/0x110
[<ffffffff811e3b0b>] new_slab+0x38b/0x480
[<ffffffffa41323c7>] __slab_alloc+0x3b7/0x4a0 [ksplice_s0dk66a8_vmlinux_new]
[<ffffffff811e42ab>] kmem_cache_alloc+0x1fb/0x250
[<ffffffff8131fdd6>] idr_layer_alloc+0x36/0x90
[<ffffffff8132029c>] idr_get_empty_slot+0x28c/0x3d0
[<ffffffff813204ad>] idr_alloc+0x4d/0xf0
[<ffffffffa051727d>] cma_alloc_port+0x4d/0xa0 [rdma_cm]
[<ffffffffa0517cbe>] rdma_bind_addr+0x2ae/0x5b0 [rdma_cm]
[<ffffffffa09d8083>] rds_ib_laddr_check+0x83/0x2c0 [ksplice_6l2xst5i_rds_rdma_new]
[<ffffffffa05f892b>] rds_trans_get_preferred+0x5b/0xa0 [rds]
[<ffffffffa05f09f2>] rds_bind+0x212/0x280 [rds]
[<ffffffff815b4016>] SYSC_bind+0xe6/0x120
[<ffffffff815b4d3e>] SyS_bind+0xe/0x10
[<ffffffff816b031a>] system_call_fastpath+0x18/0xd4

To avoid these excessive calls to rdma_bind_addr(), we optimize rds_ib_laddr_check() by simply checking if the address in question has been used before. The rds_rdma module keeps track of addresses associated with IB devices, and the function rds_ib_get_device() is used to determine if the address already has been qualified as a valid local address. If not found, we call the legacy rds_ib_laddr_check(), now renamed to rds_ib_laddr_check_cm().

Stable-dep-of: ebf71dd4aff4 ("net/rds: Restrict use of RDS/IB to the initial network namespace")

---
 net/rds/ib.c      | 20 ++++++++++++++++++--
 net/rds/ib.h      |  1 +
 net/rds/ib_rdma.c |  2 +-
 3 files changed, 20 insertions(+), 3 deletions(-)
net/rds/ib.c +18 -2
index 9826fe7f9d008..996f007cd516b 100644
@@ -403,8 +403,8 @@ static void rds6_ib_ic_info(struct socket *sock, unsigned int len,
  * allowed to influence which paths have priority.  We could call userspace
  * asserting this policy "routing".
  */
-static int rds_ib_laddr_check(struct net *net, const struct in6_addr *addr,
-			      __u32 scope_id)
+static int rds_ib_laddr_check_cm(struct net *net, const struct in6_addr *addr,
+				 __u32 scope_id)
 {
 	int ret;
 	struct rdma_cm_id *cm_id;
@@ -489,6 +489,22 @@ static int rds_ib_laddr_check(struct net *net, const struct in6_addr *addr,
 	return ret;
 }
 
+static int rds_ib_laddr_check(struct net *net, const struct in6_addr *addr,
+			      __u32 scope_id)
+{
+	struct rds_ib_device *rds_ibdev = NULL;
+
+	if (ipv6_addr_v4mapped(addr)) {
+		rds_ibdev = rds_ib_get_device(addr->s6_addr32[3]);
+		if (rds_ibdev) {
+			rds_ib_dev_put(rds_ibdev);
+			return 0;
+		}
+	}
+
+	return rds_ib_laddr_check_cm(net, addr, scope_id);
+}
+
 static void rds_ib_unregister_client(void)
 {
 	ib_unregister_client(&rds_ib_client);
net/rds/ib.h +1 -0
index 8ef3178ed4d61..5ff346a1e8baa 100644
@@ -381,6 +381,7 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn,
 	__rds_ib_conn_error(conn, KERN_WARNING "RDS/IB: " fmt)
 
 /* ib_rdma.c */
+struct rds_ib_device *rds_ib_get_device(__be32 ipaddr);
 int rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev,
 			 struct in6_addr *ipaddr);
 void rds_ib_add_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn);
net/rds/ib_rdma.c +1 -1
index 30fca2169aa7a..468fd60d818ff 100644
@@ -47,7 +47,7 @@ struct rds_ib_dereg_odp_mr {
 
 static void rds_ib_odp_mr_worker(struct work_struct *work);
 
-static struct rds_ib_device *rds_ib_get_device(__be32 ipaddr)
+struct rds_ib_device *rds_ib_get_device(__be32 ipaddr)
 {
 	struct rds_ib_device *rds_ibdev;
 	struct rds_ib_ipaddr *i_ipaddr;
Signature · 1 line
2.53.0
author maintainer
#98 lore raw

PATCH 96/666 net/rds: Restrict use of RDS/IB to the initial network namespace

In reply to Greg Kroah-Hartman

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

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

From: Greg Jumper <[email protected]>

[ Upstream commit ebf71dd4aff46e8e421d455db3e231ba43d2fa8a ]

Prevent using RDS/IB in network namespaces other than the initial one. The existing RDS/IB code will not work properly in non-initial network namespaces.

Fixes d5a8ac28a7ff ("RDS-TCP: Make RDS-TCP work correctly when it is set up in a netns other than init_net")
Reported-by [email protected]
---
 net/rds/af_rds.c | 10 ++++++++--
 net/rds/ib.c     |  4 ++++
 2 files changed, 12 insertions(+), 2 deletions(-)
net/rds/af_rds.c +8 -2
index 8435a20968ef5..f0840169d5e31 100644
@@ -357,7 +357,8 @@ static int rds_cong_monitor(struct rds_sock *rs, sockptr_t optval, int optlen)
 	return ret;
 }
 
-static int rds_set_transport(struct rds_sock *rs, sockptr_t optval, int optlen)
+static int rds_set_transport(struct net *net, struct rds_sock *rs,
+			     sockptr_t optval, int optlen)
 {
 	int t_type;
 
@@ -373,6 +374,10 @@ static int rds_set_transport(struct rds_sock *rs, sockptr_t optval, int optlen)
 	if (t_type < 0 || t_type >= RDS_TRANS_COUNT)
 		return -EINVAL;
 
+	/* RDS/IB is restricted to the initial network namespace */
+	if (t_type != RDS_TRANS_TCP && !net_eq(net, &init_net))
+		return -EPROTOTYPE;
+
 	rs->rs_transport = rds_trans_get(t_type);
 
 	return rs->rs_transport ? 0 : -ENOPROTOOPT;
@@ -433,6 +438,7 @@ static int rds_setsockopt(struct socket *sock, int level, int optname,
 			  sockptr_t optval, unsigned int optlen)
 {
 	struct rds_sock *rs = rds_sk_to_rs(sock->sk);
+	struct net *net = sock_net(sock->sk);
 	int ret;
 
 	if (level != SOL_RDS) {
@@ -461,7 +467,7 @@ static int rds_setsockopt(struct socket *sock, int level, int optname,
 		break;
 	case SO_RDS_TRANSPORT:
 		lock_sock(sock->sk);
-		ret = rds_set_transport(rs, optval, optlen);
+		ret = rds_set_transport(net, rs, optval, optlen);
 		release_sock(sock->sk);
 		break;
 	case SO_TIMESTAMP_OLD:
net/rds/ib.c +4 -0
index 996f007cd516b..ce5be43c5fbac 100644
@@ -494,6 +494,10 @@ static int rds_ib_laddr_check(struct net *net, const struct in6_addr *addr,
 {
 	struct rds_ib_device *rds_ibdev = NULL;
 
+	/* RDS/IB is restricted to the initial network namespace */
+	if (!net_eq(net, &init_net))
+		return -EPROTOTYPE;
+
 	if (ipv6_addr_v4mapped(addr)) {
 		rds_ibdev = rds_ib_get_device(addr->s6_addr32[3]);
 		if (rds_ibdev) {
Signature · 1 line
2.53.0
author maintainer
#99 lore raw

PATCH 97/666 bpf: Fix OOB in pcpu_init_value

In reply to Greg Kroah-Hartman

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

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

From: Lang Xu <[email protected]>

[ Upstream commit 576afddfee8d1108ee299bf10f581593540d1a36 ]

An out-of-bounds read occurs when copying element from a BPF_MAP_TYPE_CGROUP_STORAGE map to another pcpu map with the same value_size that is not rounded up to 8 bytes.

The issue happens when:
1. A CGROUP_STORAGE map is created with value_size not aligned to 8 bytes (e.g., 4 bytes)
2. A pcpu map is created with the same value_size (e.g., 4 bytes)
3. Update element in 2 with data in 1

pcpu_init_value assumes that all sources are rounded up to 8 bytes, and invokes copy_map_value_long to make a data copy, However, the assumption doesn't stand since there are some cases where the source may not be rounded up to 8 bytes, e.g., CGROUP_STORAGE, skb->data. the verifier verifies exactly the size that the source claims, not the size rounded up to 8 bytes by kernel, an OOB happens when the source has only 4 bytes while the copy size(4) is rounded up to 8.

---
 kernel/bpf/hashtab.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/hashtab.c +1 -1
index 26883a997e717..9f9026a619d59 100644
@@ -995,7 +995,7 @@ static void pcpu_init_value(struct bpf_htab *htab, void __percpu *pptr,
 
 		for_each_possible_cpu(cpu) {
 			if (cpu == current_cpu)
-				copy_map_value_long(&htab->map, per_cpu_ptr(pptr, cpu), value);
+				copy_map_value(&htab->map, per_cpu_ptr(pptr, cpu), value);
 			else /* Since elem is preallocated, we cannot touch special fields */
 				zero_map_value(&htab->map, per_cpu_ptr(pptr, cpu));
 		}
Signature · 1 line
2.53.0
author maintainer
#100 lore raw

PATCH 98/666 ppp: require CAP_NET_ADMIN in target netns for unattached ioctls

In reply to Greg Kroah-Hartman

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

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

From: Taegu Ha <[email protected]>

[ Upstream commit 2bb6379416fd19f44c3423a00bfd8626259f6067 ]

/dev/ppp open is currently authorized against file->f_cred->user_ns, while unattached administrative ioctls operate on current->nsproxy->net_ns.

As a result, a local unprivileged user can create a new user namespace with CLONE_NEWUSER, gain CAP_NET_ADMIN only in that new user namespace, and still issue PPPIOCNEWUNIT, PPPIOCATTACH, or PPPIOCATTCHAN against an inherited network namespace.

Require CAP_NET_ADMIN in the user namespace that owns the target network namespace before handling unattached PPP administrative ioctls.

This preserves normal pppd operation in the network namespace it is actually privileged in, while rejecting the userns-only inherited-netns case.

Fixes 273ec51dd7ce ("net: ppp_generic - introduce net-namespace functionality v2")
---
 drivers/net/ppp/ppp_generic.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/net/ppp/ppp_generic.c +3 -0
index afc1566488b32..e08ce91bc19a9 100644
@@ -1064,6 +1064,9 @@ static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
 	struct ppp_net *pn;
 	int __user *p = (int __user *)arg;
 
+	if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
+		return -EPERM;
+
 	switch (cmd) {
 	case PPPIOCNEWUNIT:
 		/* Create a new ppp unit */
Signature · 1 line
2.53.0
author maintainer
#101 lore raw

PATCH 99/666 net: ipa: Fix programming of QTIME_TIMESTAMP_CFG

In reply to Greg Kroah-Hartman

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

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

From: Luca Weiss <[email protected]>

[ Upstream commit de08f9585692813bd41ee654fca0487664c4de30 ]

The 'val' variable gets overwritten multiple times, discarding previous values. Looking at the git log shows these should be combined with |= instead.

---
 drivers/net/ipa/ipa_main.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/ipa/ipa_main.c +3 -3
index 5f3dd5a2dcf46..f374a590d1c5e 100644
@@ -361,7 +361,7 @@ static void ipa_qtime_config(struct ipa *ipa)
 {
 	const struct reg *reg;
 	u32 offset;
-	u32 val;
+	u32 val = 0;
 
 	/* Timer clock divider must be disabled when we change the rate */
 	reg = ipa_reg(ipa, TIMERS_XO_CLK_DIV_CFG);
@@ -374,8 +374,8 @@ static void ipa_qtime_config(struct ipa *ipa)
 		val |= reg_bit(reg, DPL_TIMESTAMP_SEL);
 	}
 	/* Configure tag and NAT Qtime timestamp resolution as well */
-	val = reg_encode(reg, TAG_TIMESTAMP_LSB, TAG_TIMESTAMP_SHIFT);
-	val = reg_encode(reg, NAT_TIMESTAMP_LSB, NAT_TIMESTAMP_SHIFT);
+	val |= reg_encode(reg, TAG_TIMESTAMP_LSB, TAG_TIMESTAMP_SHIFT);
+	val |= reg_encode(reg, NAT_TIMESTAMP_LSB, NAT_TIMESTAMP_SHIFT);
 
 	iowrite32(val, ipa->reg_virt + reg_offset(reg));
 
Signature · 1 line
2.53.0
author maintainer
#102 lore raw

PATCH 100/666 net: ipa: Fix decoding EV_PER_EE for IPA v5.0+

In reply to Greg Kroah-Hartman

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

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

From: Luca Weiss <[email protected]>

[ Upstream commit 1335b903cf2e8aeaca87fd665683384c731ec941 ]

Initially 'reg' and 'val' are assigned from HW_PARAM_2.

But since IPA v5.0+ takes EV_PER_EE from HW_PARAM_4 (instead of NUM_EV_PER_EE from HW_PARAM_2), we not only need to re-assign 'reg' but also read the register value of that register into 'val' so that reg_decode() works on the correct value.

---
 drivers/net/ipa/gsi.c | 1 +
 1 file changed, 1 insertion(+)
drivers/net/ipa/gsi.c +1 -0
index 4c3227e77898c..624649484d627 100644
@@ -2044,6 +2044,7 @@ static int gsi_ring_setup(struct gsi *gsi)
 		count = reg_decode(reg, NUM_EV_PER_EE, val);
 	} else {
 		reg = gsi_reg(gsi, HW_PARAM_4);
+		val = ioread32(gsi->virt + reg_offset(reg));
 		count = reg_decode(reg, EV_PER_EE, val);
 	}
 	if (!count) {
Signature · 1 line
2.53.0
author maintainer
#103 lore raw

PATCH 101/666 dt-bindings: net: dsa: nxp,sja1105: make spi-cpol optional for sja1110

In reply to Greg Kroah-Hartman

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

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

From: Josua Mayer <[email protected]>

[ Upstream commit 600f01dc4bd0c736b3ffea9f7976136d8bf1b136 ]

Currently, the binding requires 'spi-cpha' for SJA1105 and 'spi-cpol' for SJA1110.

However, the SJA1110 supports both SPI modes 0 and 2. Mode 2 (cpha=0, cpol=1) is used by the NXP LX2160 Bluebox 3.

On the SolidRun i.MX8DXL HummingBoard Telematics, mode 0 is stable, while forcing mode 2 introduces CRC errors especially during bursts.

Drop the requirement on spi-cpol for SJA1110.

Fixes af2eab1a8243 ("dt-bindings: net: nxp,sja1105: document spi-cpol/cpha")
---
 Documentation/devicetree/bindings/net/dsa/nxp,sja1105.yaml | 2 --
 1 file changed, 2 deletions(-)
Documentation/devicetree/bindings/net/dsa/nxp,sja1105.yaml +0 -2
index 9432565f4f5d3..8bfa2ea579f0c 100644
@@ -131,8 +131,6 @@ allOf:
     else:
       properties:
         spi-cpha: false
-      required:
-        - spi-cpol
 
 unevaluatedProperties: false
 
Signature · 1 line
2.53.0
author maintainer
#104 lore raw

PATCH 102/666 net: phy: fix a return path in get_phy_c45_ids()

In reply to Greg Kroah-Hartman

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

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

From: Charles Perry <[email protected]>

[ Upstream commit 6f533abe7bbad2eef1e42c639b6bb9dad2b02362 ]

The return value of phy_c45_probe_present() is stored in "ret", not "phy_reg", fix this. "phy_reg" always has a positive value if we reach this return path (since it would have returned earlier otherwise), which means that the original goal of the patch of not considering -ENODEV fatal wasn't achieved.

---
 drivers/net/phy/phy_device.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/phy/phy_device.c +2 -2
index 7f995d0e51f7b..eb478e4961cb9 100644
@@ -873,8 +873,8 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr,
 				/* returning -ENODEV doesn't stop bus
 				 * scanning
 				 */
-				return (phy_reg == -EIO ||
-					phy_reg == -ENODEV) ? -ENODEV : -EIO;
+				return (ret == -EIO ||
+					ret == -ENODEV) ? -ENODEV : -EIO;
 
 			if (!ret)
 				continue;
Signature · 1 line
2.53.0
author maintainer
#105 lore raw

PATCH 103/666 net/mlx5e: Fix features not applied during netdev registration

In reply to Greg Kroah-Hartman

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

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

From: Gal Pressman <[email protected]>

[ Upstream commit 9994ad4df82d64e57135c0f0906897685f5a9e87 ]

mlx5e_fix_features() returns early when the netdevice is not present. This is correct during profile transitions where priv is cleared, but it also incorrectly blocks feature fixups during register_netdev(), when the device is also not yet present.

It is not trivial to distinguish between both cases as we cannot use priv to carry state, and in both cases reg_state == NETREG_REGISTERED.

Force a netdev features update after register_netdev() completes, where the device is present and fix_features() can actually work.

This is not a pretty solution, as it results in an additional features update call (register_netdevice() already calls __netdev_update_features() internally), but it is the simplest, cleanest, and most robust way I found to fix this issue after multiple attempts.

This fixes an issue on systems where CQE compression is enabled by default, RXHASH remains enabled after registration despite the two features being mutually exclusive.

Fixes ab4b01bfdaa6 ("net/mlx5e: Verify dev is present for fix features ndo")
---
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 8 ++++++++
 1 file changed, 8 insertions(+)
drivers/net/ethernet/mellanox/mlx5/core/en_main.c +8 -0
index 5736ed61e6eba..dbfb900980de7 100644
@@ -6466,6 +6466,14 @@ static int _mlx5e_probe(struct auxiliary_device *adev)
 		goto err_resume;
 	}
 
+	/* mlx5e_fix_features() returns early when the device is not present
+	 * to avoid dereferencing cleared priv during profile changes.
+	 * This also causes it to be a no-op during register_netdev(), where
+	 * the device is not yet present.
+	 * Trigger an additional features update that will actually work.
+	 */
+	mlx5e_update_features(netdev);
+
 	mlx5e_dcbnl_init_app(priv);
 	mlx5_core_uplink_netdev_set(mdev, netdev);
 	mlx5e_params_print_info(mdev, &priv->channels.params);
Signature · 1 line
2.53.0
author maintainer
#106 lore raw

PATCH 104/666 net/mlx5e: IPsec, fix ASO poll timeout with read_poll_timeout_atomic()

In reply to Greg Kroah-Hartman

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

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

From: Gal Pressman <[email protected]>

[ Upstream commit edccdd1eb94712da97a6ce71123ec27890add754 ]

The do-while poll loop uses jiffies for its timeout:
expires = jiffies + msecs_to_jiffies(10);

jiffies is sampled at an arbitrary point within the current tick, so the first partial tick contributes anywhere from a full tick down to nearly zero real time. For small msecs_to_jiffies() results this is significant, the effective poll window can be much shorter than the requested 10ms, and in the worst case the loop exits after a single iteration (e.g., when HZ=100), well before the device has delivered the CQE.

Replace the loop with read_poll_timeout_atomic(), which counts elapsed time via udelay() accounting rather than jiffies, guaranteeing the full poll window regardless of HZ.

Additionally, read_poll_timeout_atomic() executes the poll operation one more time after the timeout has expired, giving the CQE a final chance to be detected. The old do-while loop could exit without a final poll if the timeout expired during the udelay() between iterations.

Fixes 76e463f6508b ("net/mlx5e: Overcome slow response for first IPsec ASO WQE")
---
 .../mellanox/mlx5/core/en_accel/ipsec_offload.c      | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +4 -8
index 40fe3d1e2342c..8f22559e373cd 100644
@@ -1,6 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
 /* Copyright (c) 2017, Mellanox Technologies inc. All rights reserved. */
 
+#include <linux/iopoll.h>
+
 #include "mlx5_core.h"
 #include "en.h"
 #include "ipsec.h"
@@ -593,7 +595,6 @@ int mlx5e_ipsec_aso_query(struct mlx5e_ipsec_sa_entry *sa_entry,
 	struct mlx5_wqe_aso_ctrl_seg *ctrl;
 	struct mlx5e_hw_objs *res;
 	struct mlx5_aso_wqe *wqe;
-	unsigned long expires;
 	u8 ds_cnt;
 	int ret;
 
@@ -615,13 +616,8 @@ int mlx5e_ipsec_aso_query(struct mlx5e_ipsec_sa_entry *sa_entry,
 	mlx5e_ipsec_aso_copy(ctrl, data);
 
 	mlx5_aso_post_wqe(aso->aso, false, &wqe->ctrl);
-	expires = jiffies + msecs_to_jiffies(10);
-	do {
-		ret = mlx5_aso_poll_cq(aso->aso, false);
-		if (ret)
-			/* We are in atomic context */
-			udelay(10);
-	} while (ret && time_is_after_jiffies(expires));
+	read_poll_timeout_atomic(mlx5_aso_poll_cq, ret, !ret, 10,
+				 10 * USEC_PER_MSEC, false, aso->aso, false);
 	if (!ret)
 		memcpy(sa_entry->ctx, aso->ctx, MLX5_ST_SZ_BYTES(ipsec_aso));
 	spin_unlock_bh(&aso->lock);
Signature · 1 line
2.53.0
author maintainer
#107 lore raw

PATCH 105/666 bpf: reject short IPv4/IPv6 inputs in bpf_prog_test_run_skb

In reply to Greg Kroah-Hartman

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

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

From: Sun Jian <[email protected]>

[ Upstream commit 12bec2bd4b76d81c5d3996bd14ec1b7f4d983747 ]

bpf_prog_test_run_skb() calls eth_type_trans() first and then uses skb->protocol to initialize sk family and address fields for the test run.

For IPv4 and IPv6 packets, it may access ip_hdr(skb) or ipv6_hdr(skb) even when the provided test input only contains an Ethernet header.

Reject the input earlier if the Ethernet frame carries IPv4/IPv6 EtherType but the L3 header is too short.

Fold the IPv4/IPv6 header length checks into the existing protocol switch and return -EINVAL before accessing the network headers.

---
 net/bpf/test_run.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)
net/bpf/test_run.c +12 -8
index 18257cf6bb488..7f12abc8a80cb 100644
@@ -1061,19 +1061,23 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
 
 	switch (skb->protocol) {
 	case htons(ETH_P_IP):
-		sk->sk_family = AF_INET;
-		if (sizeof(struct iphdr) <= skb_headlen(skb)) {
-			sk->sk_rcv_saddr = ip_hdr(skb)->saddr;
-			sk->sk_daddr = ip_hdr(skb)->daddr;
+		if (skb_headlen(skb) < sizeof(struct iphdr)) {
+			ret = -EINVAL;
+			goto out;
 		}
+		sk->sk_family = AF_INET;
+		sk->sk_rcv_saddr = ip_hdr(skb)->saddr;
+		sk->sk_daddr = ip_hdr(skb)->daddr;
 		break;
 #if IS_ENABLED(CONFIG_IPV6)
 	case htons(ETH_P_IPV6):
-		sk->sk_family = AF_INET6;
-		if (sizeof(struct ipv6hdr) <= skb_headlen(skb)) {
-			sk->sk_v6_rcv_saddr = ipv6_hdr(skb)->saddr;
-			sk->sk_v6_daddr = ipv6_hdr(skb)->daddr;
+		if (skb_headlen(skb) < sizeof(struct ipv6hdr)) {
+			ret = -EINVAL;
+			goto out;
 		}
+		sk->sk_family = AF_INET6;
+		sk->sk_v6_rcv_saddr = ipv6_hdr(skb)->saddr;
+		sk->sk_v6_daddr = ipv6_hdr(skb)->daddr;
 		break;
 #endif
 	default:
Signature · 1 line
2.53.0
author maintainer
#108 lore raw

PATCH 106/666 Bluetooth: L2CAP: Fix printing wrong information if SDU length exceeds MTU

In reply to Greg Kroah-Hartman

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

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

From: Luiz Augusto von Dentz <[email protected]>

[ Upstream commit 15bf35a660eb82a49f8397fc3d3acada8dae13db ]

The code was printing skb->len and sdu_len in the places where it should be sdu_len and chan->imtu respectively to match the if conditions.

---
 net/bluetooth/l2cap_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/bluetooth/l2cap_core.c +1 -1
index 307f7fe975b59..bb927603c2d15 100644
@@ -6657,7 +6657,7 @@ static int l2cap_ecred_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
 
 		if (sdu_len > chan->imtu) {
 			BT_ERR("Too big LE L2CAP SDU length: len %u > %u",
-			       skb->len, sdu_len);
+			       sdu_len, chan->imtu);
 			l2cap_send_disconn_req(chan, ECONNRESET);
 			err = -EMSGSIZE;
 			goto failed;
Signature · 1 line
2.53.0
author maintainer
#109 lore raw

PATCH 107/666 Bluetooth: hci_ldisc: Clear HCI_UART_PROTO_INIT on error

In reply to Greg Kroah-Hartman

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

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

From: Jonathan Rissanen <[email protected]>

[ Upstream commit 68d39ea5e0adc9ecaea1ce8abd842ec972eb8718 ]

When hci_register_dev() fails in hci_uart_register_dev() HCI_UART_PROTO_INIT is not cleared before calling hu->proto->close(hu) and setting hu->hdev to NULL. This means incoming UART data will reach the protocol-specific recv handler in hci_uart_tty_receive() after resources are freed.

Clear HCI_UART_PROTO_INIT with a write lock before calling hu->proto->close() and setting hu->hdev to NULL. The write lock ensures all active readers have completed and no new reader can enter the protocol recv path before resources are freed.

This allows the protocol-specific recv functions to remove the "HCI_UART_REGISTERED" guard without risking a null pointer dereference if hci_register_dev() fails.

Fixes 5df5dafc171b ("Bluetooth: hci_uart: Fix another race during initialization")
---
 drivers/bluetooth/hci_ldisc.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/bluetooth/hci_ldisc.c +3 -0
index 436ee77d4bf2f..0d06b83816d1c 100644
@@ -692,6 +692,9 @@ static int hci_uart_register_dev(struct hci_uart *hu)
 
 	if (hci_register_dev(hdev) < 0) {
 		BT_ERR("Can't register HCI device");
+		percpu_down_write(&hu->proto_lock);
+		clear_bit(HCI_UART_PROTO_INIT, &hu->flags);
+		percpu_up_write(&hu->proto_lock);
 		hu->proto->close(hu);
 		hu->hdev = NULL;
 		hci_free_dev(hdev);
Signature · 1 line
2.53.0
author maintainer
#110 lore raw

PATCH 108/666 Bluetooth: fix locking in hci_conn_request_evt() with HCI_PROTO_DEFER

In reply to Greg Kroah-Hartman

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

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

From: Pauli Virtanen <[email protected]>

[ Upstream commit 5c7209a341ff2ac338b2b0375c34a307b37c9ac2 ]

When protocol sets HCI_PROTO_DEFER, hci_conn_request_evt() calls hci_connect_cfm(conn) without hdev->lock. Generally hci_connect_cfm() assumes it is held, and if conn is deleted concurrently -> UAF.

Only SCO and ISO set HCI_PROTO_DEFER and only for defer setup listen, and HCI_EV_CONN_REQUEST is not generated for ISO. In the non-deferred listening socket code paths, hci_connect_cfm(conn) is called with hdev->lock held.

Fix by holding the lock.

Fixes 70c464256310 ("Bluetooth: Refactor connection request handling")
---
 net/bluetooth/hci_event.c | 3 ---
 1 file changed, 3 deletions(-)
net/bluetooth/hci_event.c +0 -3
index 8a14c00ad7278..92270b99ee0f2 100644
@@ -3284,8 +3284,6 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
 
 	memcpy(conn->dev_class, ev->dev_class, 3);
 
-	hci_dev_unlock(hdev);
-
 	if (ev->link_type == ACL_LINK ||
 	    (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
 		struct hci_cp_accept_conn_req cp;
@@ -3319,7 +3317,6 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data,
 		hci_connect_cfm(conn, 0);
 	}
 
-	return;
 unlock:
 	hci_dev_unlock(hdev);
 }
Signature · 1 line
2.53.0
author maintainer
#111 lore raw

PATCH 109/666 Bluetooth: l2cap: Add missing chan lock in l2cap_ecred_reconf_rsp

In reply to Greg Kroah-Hartman

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

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

From: Dudu Lu <[email protected]>

[ Upstream commit 42776497cdbc9a665b384a6dcb85f0d4bd927eab ]

l2cap_ecred_reconf_rsp() calls l2cap_chan_del() without holding l2cap_chan_lock(). Every other l2cap_chan_del() caller in the file acquires the lock first. A remote BLE device can send a crafted L2CAP ECRED reconfiguration response to corrupt the channel list while another thread is iterating it.

Add l2cap_chan_hold() and l2cap_chan_lock() before l2cap_chan_del(), and l2cap_chan_unlock() and l2cap_chan_put() after, matching the pattern used in l2cap_ecred_conn_rsp() and l2cap_conn_del().

Fixes 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
---
 net/bluetooth/l2cap_core.c | 6 ++++++
 1 file changed, 6 insertions(+)
net/bluetooth/l2cap_core.c +6 -0
index bb927603c2d15..b01107370cbcb 100644
@@ -5399,7 +5399,13 @@ static inline int l2cap_ecred_reconf_rsp(struct l2cap_conn *conn,
 		if (chan->ident != cmd->ident)
 			continue;
 
+		l2cap_chan_hold(chan);
+		l2cap_chan_lock(chan);
+
 		l2cap_chan_del(chan, ECONNRESET);
+
+		l2cap_chan_unlock(chan);
+		l2cap_chan_put(chan);
 	}
 
 	return 0;
Signature · 1 line
2.53.0