6.12.39-rc1 review
Subsystems (6)
Greg Kroah-Hartman
maintainercover 6.12.39-rc1 review
This is the start of the stable review cycle for the 6.12.39 release. There are 163 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 Thu, 17 Jul 2025 13:07:32 +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.39-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.39-rc1
Mark Brown <[email protected]>
arm64: Filter out SME hwcaps when FEAT_SME isn't implemented
Namjae Jeon <[email protected]>
ksmbd: fix potential use-after-free in oplock/lease break ack
Yeoreum Yun <[email protected]>
kasan: remove kasan_find_vm_area() to prevent possible deadlock
Jiawen Wu <[email protected]>
net: wangxun: revert the adjustment of the IRQ vector sequence
Gao Xiang <[email protected]>
erofs: fix rare pcluster memory leak after unmounting
Willem de Bruijn <[email protected]>
selftests/bpf: adapt one more case in test_lru_map to the new target_free
Daniel J. Ogorchock <[email protected]>
HID: nintendo: avoid bluetooth suspend/resume stalls
Chia-Lin Kao (AceLan) <[email protected]>
HID: quirks: Add quirk for 2 Chicony Electronics HP 5MP Cameras
Zhang Heng <[email protected]>
HID: Add IGNORE quirk for SMARTLINKTECHNOLOGY
Fangrui Song <[email protected]>
riscv: vdso: Exclude .rodata from the PT_DYNAMIC segment
Willem de Bruijn <[email protected]>
bpf: Adjust free target to avoid global starvation of LRU map
Nicolas Pitre <[email protected]>
vt: add missing notification when switching back to text mode
Filipe Manana <[email protected]>
btrfs: fix assertion when building free space tree
Long Li <[email protected]>
net: mana: Record doorbell physical address in PF mode
Akira Inoue <[email protected]>
HID: lenovo: Add support for ThinkPad X1 Tablet Thin Keyboard Gen2
Shuai Zhang <[email protected]>
driver: bluetooth: hci_qca:fix unable to load the BT driver
Xiaowei Li <[email protected]>
net: usb: qmi_wwan: add SIMCom 8230C composition
Tim Crawford <[email protected]>
ALSA: hda/realtek: Add quirks for some Clevo laptops
Yasmin Fitzgerald <[email protected]>
ALSA: hda/realtek - Enable mute LED on HP Pavilion Laptop 15-eg100
Yuzuru10 <[email protected]>
ASoC: amd: yc: add quirk for Acer Nitro ANV15-41 internal mic
Fengnan Chang <[email protected]>
io_uring: make fallocate be hashed work
Takashi Iwai <[email protected]>
ALSA: hda/realtek: Add mic-mute LED setup for ASUS UM5606
Tamura Dai <[email protected]>
ASoC: SOF: Intel: hda: Use devm_kstrdup() to avoid memleak.
Tiwei Bie <[email protected]>
um: vector: Reduce stack usage in vector_eth_configure()
Thomas Fourier <[email protected]>
atm: idt77252: Add missing `dma_map_error()`
Ronnie Sahlberg <[email protected]>
ublk: sanity check add_dev input for underflow
Somnath Kotur <[email protected]>
bnxt_en: Set DMA unmap len correctly for XDP_REDIRECT
Shravya KN <[email protected]>
bnxt_en: Fix DCB ETS validation
Alok Tiwari <[email protected]>
net: ll_temac: Fix missing tx_pending check in ethtools_set_ringparam()
Jianbo Liu <[email protected]>
net/mlx5e: Add new prio for promiscuous mode
Carolina Jubran <[email protected]>
net/mlx5e: Fix race between DIM disable and net_dim()
Sean Nyekjaer <[email protected]>
can: m_can: m_can_handle_lost_msg(): downgrade msg lost in rx message to debug level
Shuicheng Lin <[email protected]>
drm/xe/pm: Correct comment of xe_pm_set_vram_threshold()
Hangbin Liu <[email protected]>
selftests: net: lib: fix shift count out of range
Petr Machata <[email protected]>
selftests: net: lib: Move logging from forwarding/lib.sh here
Oleksij Rempel <[email protected]>
net: phy: microchip: limit 100M workaround to link-down events on LAN88xx
Oleksij Rempel <[email protected]>
net: phy: microchip: Use genphy_soft_reset() to purge stale LPA bits
Mingming Cao <[email protected]>
ibmvnic: Fix hardcoded NUM_RX_STATS/NUM_TX_STATS with dynamic sizeof
Kito Xu <[email protected]>
net: appletalk: Fix device refcount leak in atrtr_create()
Eric Dumazet <[email protected]>
netfilter: flowtable: account for Ethernet header in nf_flow_pppoe_proto()
Chao Yu <[email protected]>
erofs: fix to add missing tracepoint in erofs_readahead()
Gao Xiang <[email protected]>
erofs: refine readahead tracepoint
Gao Xiang <[email protected]>
erofs: tidy up zdata.c
Gao Xiang <[email protected]>
erofs: get rid of z_erofs_next_pcluster_t
Chunhai Guo <[email protected]>
erofs: free pclusters if no cached folio is attached
Michal Wajdeczko <[email protected]>
drm/xe/pf: Clear all LMTT pages on alloc
Zheng Qixing <[email protected]>
nbd: fix uaf in nbd_genl_connect() error path
Henry Martin <[email protected]>
wifi: mt76: mt7925: Fix null-ptr-deref in mt7925_thermal_init()
Ben Skeggs <[email protected]>
drm/nouveau/gsp: fix potential leak of memory used during acpi init
Felix Fietkau <[email protected]>
wifi: rt2x00: fix remove callback type mismatch
Johannes Berg <[email protected]>
wifi: mac80211: fix non-transmitted BSSID profile search
Lachlan Hodges <[email protected]>
wifi: mac80211: correctly identify S1G short beacon
Nigel Croxon <[email protected]>
raid10: cleanup memleak at raid10_make_request
Wang Jinchao <[email protected]>
md/raid1: Fix stack memory use after return in raid1_reshape
Mikko Perttunen <[email protected]>
drm/tegra: nvdec: Fix dma_alloc_coherent error check
Daniil Dulov <[email protected]>
wifi: zd1211rw: Fix potential NULL pointer dereference in zd_mac_tx_to_dev()
Lachlan Hodges <[email protected]>
wifi: cfg80211: fix S1G beacon head validation in nl80211
David Howells <[email protected]>
netfs: Fix ref leak on inserted extra subreq in write retry
Jakub Kicinski <[email protected]>
netlink: make sure we allow at least one dump skb
Kuniyuki Iwashima <[email protected]>
netlink: Fix rmem check in netlink_broadcast_deliver().
Peter Ujfalusi <[email protected]>
ASoC: Intel: sof-function-topology-lib: Print out the unsupported dmic count
Gao Xiang <[email protected]>
erofs: address D-cache aliasing
Chao Yu <[email protected]>
erofs: fix to add missing tracepoint in erofs_read_folio()
Al Viro <[email protected]>
ksmbd: fix a mount write count leak in ksmbd_vfs_kern_path_locked()
Stefan Metzmacher <[email protected]>
smb: server: make use of rdma_destroy_qp()
Sascha Hauer <[email protected]>
clk: scmi: Handle case where child clocks are initialized before their parents
Jann Horn <[email protected]>
x86/mm: Disable hugetlb page table sharing on 32-bit
Mikhail Paulyshka <[email protected]>
x86/rdrand: Disable RDSEED on AMD Cyan Skillfish
Xiaolei Wang <[email protected]>
clk: imx: Fix an out-of-bounds access in dispmix_csr_clk_dev_data
Miguel Ojeda <[email protected]>
rust: init: allow dead_code warnings for Rust >= 1.89.0
Harry Yoo <[email protected]>
lib/alloc_tag: do not acquire non-existent lock in alloc_tag_top_users()
Alexander Gordeev <[email protected]>
mm/vmalloc: leave lazy MMU mode on PTE mapping error
Florian Fainelli <[email protected]>
scripts/gdb: fix interrupts.py after maple tree conversion
Florian Fainelli <[email protected]>
scripts/gdb: de-reference per-CPU MCE interrupts
Florian Fainelli <[email protected]>
scripts/gdb: fix interrupts display after MCP on x86
Baolin Wang <[email protected]>
mm: fix the inaccurate memory statistics issue for users
Wei Yang <[email protected]>
maple_tree: fix mt_destroy_walk() on root leaf node
Achill Gilgenast <[email protected]>
kallsyms: fix build without execinfo
Zhe Qiao <[email protected]>
Revert "PCI/ACPI: Fix allocated memory release on error in pci_acpi_scan_root()"
Rafael J. Wysocki <[email protected]>
Revert "ACPI: battery: negate current when discharging"
Matthew Brost <[email protected]>
drm/xe: Allocate PF queue size on pow2 boundary
Thomas Zimmermann <[email protected]>
drm/framebuffer: Acquire internal references on GEM handles
Kuen-Han Tsai <[email protected]>
Revert "usb: gadget: u_serial: Add null pointer check in gs_start_io"
Kuen-Han Tsai <[email protected]>
usb: gadget: u_serial: Fix race condition in TTY wakeup
Matthew Brost <[email protected]>
Revert "drm/xe/xe2: Enable Indirect Ring State support for Xe2"
Matthew Auld <[email protected]>
drm/xe/bmg: fix compressed VRAM handling
Simona Vetter <[email protected]>
drm/gem: Fix race in drm_gem_handle_create_tail()
Christian König <[email protected]>
drm/ttm: fix error handling in ttm_buffer_object_transfer
Matthew Brost <[email protected]>
drm/sched: Increment job count before swapping tail spsc queue
Thomas Zimmermann <[email protected]>
drm/gem: Acquire references on GEM handles for framebuffers
Philip Yang <[email protected]>
drm/amdkfd: Don't call mmput from MMU notifier callback
Alessio Belle <[email protected]>
drm/imagination: Fix kernel crash when hard resetting the GPU
Michael Lo <[email protected]>
wifi: mt76: mt7925: fix invalid array index in ssid assignment during hw scan
Ming Yen Hsieh <[email protected]>
wifi: mt76: mt7925: fix the wrong config for tx interrupt
Deren Wu <[email protected]>
wifi: mt76: mt7925: prevent NULL pointer dereference in mt7925_sta_set_decap_offload()
Deren Wu <[email protected]>
wifi: mt76: mt7921: prevent decap offload config before STA initialization
Vitor Soares <[email protected]>
wifi: mwifiex: discard erroneous disassoc frames on STA interface
Mathy Vanhoef <[email protected]>
wifi: prevent A-MSDU attacks in mesh networks
Uwe Kleine-König <[email protected]>
pwm: mediatek: Ensure to disable clocks in error path
Uwe Kleine-König <[email protected]>
pwm: Fix invalid state detection
Bartosz Golaszewski <[email protected]>
pinctrl: qcom: msm: mark certain pins as invalid for interrupts
Håkon Bugge <[email protected]>
md/md-bitmap: fix GPF in bitmap_get_stats()
Haoxiang Li <[email protected]>
net: ethernet: rtsn: Fix a null pointer dereference in rtsn_probe()
Guillaume Nault <[email protected]>
gre: Fix IPv6 multicast route creation.
Arun Raghavan <[email protected]>
ASoC: fsl_sai: Force a software reset when starting in consumer mode
Thorsten Blum <[email protected]>
ALSA: ad1816a: Fix potential NULL pointer deref in snd_card_ad1816a_pnp()
Liam Merwick <[email protected]>
KVM: Allow CPU to reschedule while setting per-page memory attributes
Sean Christopherson <[email protected]>
KVM: SVM: Reject SEV{-ES} intra host migration if vCPU creation is in-flight
Nikunj A Dadhania <[email protected]>
KVM: SVM: Add missing member in SNP_LAUNCH_START command structure
David Woodhouse <[email protected]>
KVM: x86/xen: Allow 'out of range' event channel ports in IRQ routing table.
JP Kobryn <[email protected]>
x86/mce: Make sure CMCI banks are cleared during shutdown on Intel
Yazen Ghannam <[email protected]>
x86/mce: Ensure user polling settings are honored when restarting timer
Yazen Ghannam <[email protected]>
x86/mce: Don't remove sysfs if thresholding sysfs init fails
Yazen Ghannam <[email protected]>
x86/mce/amd: Fix threshold limit reset
Yazen Ghannam <[email protected]>
x86/mce/amd: Add default names for MCA banks and blocks
Dan Carpenter <[email protected]>
ipmi:msghandler: Fix potential memory corruption in ipmi_create_user()
David Howells <[email protected]>
rxrpc: Fix oops due to non-existence of prealloc backlog struct
David Howells <[email protected]>
rxrpc: Fix bug due to prealloc collision
Victor Nogueira <[email protected]>
net/sched: Abort __tc_modify_qdisc if parent class does not exist
Chintan Vankar <[email protected]>
net: ethernet: ti: am65-cpsw-nuss: Fix skb size by accounting for skb_shared_info
Yue Haibing <[email protected]>
atm: clip: Fix NULL pointer dereference in vcc_sendmsg()
Kuniyuki Iwashima <[email protected]>
atm: clip: Fix infinite recursive call of clip_push().
Kuniyuki Iwashima <[email protected]>
atm: clip: Fix memory leak of struct clip_vcc.
Kuniyuki Iwashima <[email protected]>
atm: clip: Fix potential null-ptr-deref in to_atmarpd().
Oleksij Rempel <[email protected]>
net: phy: smsc: Fix link failure in forced mode with Auto-MDIX
Oleksij Rempel <[email protected]>
net: phy: smsc: Force predictable MDI-X state on LAN87xx
Oleksij Rempel <[email protected]>
net: phy: smsc: Fix Auto-MDIX configuration when disabled by strap
EricChan <[email protected]>
net: stmmac: Fix interrupt handling for level-triggered mode in DWC_XGMAC2
Michal Luczaj <[email protected]>
vsock: Fix IOCTL_VM_SOCKETS_GET_LOCAL_CID to check also transport_local
Michal Luczaj <[email protected]>
vsock: Fix transport_* TOCTOU
Michal Luczaj <[email protected]>
vsock: Fix transport_{g2h,h2g} TOCTOU
Jiayuan Chen <[email protected]>
tcp: Correct signedness in skb remaining space calculation
Kuniyuki Iwashima <[email protected]>
tipc: Fix use-after-free in tipc_conn_close().
Stefano Garzarella <[email protected]>
vsock: fix vsock_proto declaration
Kuniyuki Iwashima <[email protected]>
netlink: Fix wraparounds of sk->sk_rmem_alloc.
Luo Jie <[email protected]>
net: phy: qcom: qca808x: Fix WoL issue by utilizing at8031_set_wol()
Luo Jie <[email protected]>
net: phy: qcom: move the WoL function to shared library
Kevin Brodsky <[email protected]>
arm64: poe: Handle spurious Overlay faults
Jason Xing <[email protected]>
bnxt_en: eliminate the compile warning in bnxt_request_irq due to CONFIG_RFS_ACCEL
kuyo chang <[email protected]>
sched/deadline: Fix dl_server runtime calculation formula
Al Viro <[email protected]>
fix proc_sys_compare() handling of in-lookup dentries
Mario Limonciello <[email protected]>
pinctrl: amd: Clear GPIO debounce for suspend
Luiz Augusto von Dentz <[email protected]>
Bluetooth: hci_event: Fix not marking Broadcast Sink BIS as connected
Luiz Augusto von Dentz <[email protected]>
Bluetooth: hci_sync: Fix not disabling advertising instance
Richard Fitzgerald <[email protected]>
ASoC: cs35l56: probe() should fail if the device ID is not recognized
Peter Zijlstra <[email protected]>
perf: Revert to requiring CAP_SYS_ADMIN for uprobes
Peter Zijlstra <[email protected]>
sched/core: Fix migrate_swap() vs. hotplug
Nam Cao <[email protected]>
irqchip/irq-msi-lib: Select CONFIG_GENERIC_MSI_IRQ
Luo Gengkun <[email protected]>
perf/core: Fix the WARN_ON_ONCE is out of lock protected region
Charles Keepax <[email protected]>
ASoC: Intel: soc-acpi: arl: Correct order of cs42l43 matches
Bard Liao <[email protected]>
ASoC: Intel: soc-acpi-intel-arl-match: set get_function_tplg_files ops
Bard Liao <[email protected]>
ASoC: Intel: add sof_sdw_get_tplg_files ops
Bard Liao <[email protected]>
ASoC: soc-acpi: add get_function_tplg_files ops
Simon Trimmer <[email protected]>
ASoC: Intel: soc-acpi: arl: Add match entries for new cs42l43 laptops
Simon Trimmer <[email protected]>
ASoC: Intel: soc-acpi: arl: Correct naming of a cs35l56 address struct
Bard Liao <[email protected]>
ASoC: Intel: SND_SOC_INTEL_SOF_BOARD_HELPERS select SND_SOC_ACPI_INTEL_MATCH
Shengjiu Wang <[email protected]>
ASoC: fsl_asrc: use internal measured ratio for non-ideal ratio mode
Srinivasan Shanmugam <[email protected]>
drm/amdgpu: Replace Mutex with Spinlock for RLCG register access to avoid Priority Inversion in SRIOV
Eric Biggers <[email protected]>
crypto: s390/sha - Fix uninitialized variable in SHA-1 and SHA-2
Flora Cui <[email protected]>
drm/amdgpu/ip_discovery: add missing ip_discovery fw
Flora Cui <[email protected]>
drm/amdgpu/discovery: use specific ip_discovery.bin for legacy asics
Kaustabh Chakraborty <[email protected]>
drm/exynos: exynos7_drm_decon: add vblank check in IRQ handling
Linus Torvalds <[email protected]>
eventpoll: don't decrement ep refcount while still holding the ep mutex
-------------
Diffstat:
Documentation/bpf/map_hash.rst | 8 +- Documentation/bpf/map_lru_hash_update.dot | 6 +- Makefile | 4 +- arch/arm64/kernel/cpufeature.c | 45 ++-- arch/arm64/kernel/process.c | 5 + arch/arm64/mm/fault.c | 30 ++- arch/riscv/kernel/vdso/vdso.lds.S | 2 +- arch/s390/crypto/sha1_s390.c | 2 + arch/s390/crypto/sha256_s390.c | 3 + arch/s390/crypto/sha512_s390.c | 3 + arch/um/drivers/vector_kern.c | 42 ++-- arch/x86/Kconfig | 2 +- arch/x86/include/asm/msr-index.h | 1 + arch/x86/kernel/cpu/amd.c | 7 + arch/x86/kernel/cpu/mce/amd.c | 28 ++- arch/x86/kernel/cpu/mce/core.c | 24 +- arch/x86/kernel/cpu/mce/intel.c | 1 + arch/x86/kvm/svm/sev.c | 4 + arch/x86/kvm/xen.c | 15 +- drivers/acpi/battery.c | 19 +- drivers/atm/idt77252.c | 5 + drivers/block/nbd.c | 6 +- drivers/block/ublk_drv.c | 3 +- drivers/bluetooth/hci_qca.c | 13 +- drivers/char/ipmi/ipmi_msghandler.c | 3 +- drivers/clk/clk-scmi.c | 20 +- drivers/clk/imx/clk-imx95-blk-ctl.c | 12 +- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 30 ++- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 3 +- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 43 ++-- drivers/gpu/drm/drm_framebuffer.c | 31 ++- drivers/gpu/drm/drm_gem.c | 74 +++++- drivers/gpu/drm/drm_internal.h | 2 + drivers/gpu/drm/exynos/exynos7_drm_decon.c | 4 + drivers/gpu/drm/imagination/pvr_power.c | 4 +- drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 20 +- drivers/gpu/drm/tegra/nvdec.c | 6 +- drivers/gpu/drm/ttm/ttm_bo_util.c | 13 +- drivers/gpu/drm/xe/xe_gt_pagefault.c | 1 + drivers/gpu/drm/xe/xe_lmtt.c | 11 + drivers/gpu/drm/xe/xe_migrate.c | 2 +- drivers/gpu/drm/xe/xe_pci.c | 1 - drivers/gpu/drm/xe/xe_pm.c | 8 +- drivers/hid/hid-ids.h | 6 + drivers/hid/hid-lenovo.c | 8 + drivers/hid/hid-multitouch.c | 8 +- drivers/hid/hid-nintendo.c | 38 +++- drivers/hid/hid-quirks.c | 3 + drivers/irqchip/Kconfig | 1 + drivers/md/md-bitmap.c | 3 +- drivers/md/raid1.c | 1 + drivers/md/raid10.c | 10 +- drivers/net/can/m_can/m_can.c | 2 +- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 10 +- drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c | 2 + drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 2 +- drivers/net/ethernet/ibm/ibmvnic.h | 8 +- drivers/net/ethernet/mellanox/mlx5/core/en/fs.h | 9 +- drivers/net/ethernet/mellanox/mlx5/core/en_dim.c | 4 +- drivers/net/ethernet/mellanox/mlx5/core/en_fs.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 13 +- drivers/net/ethernet/microsoft/mana/gdma_main.c | 3 + drivers/net/ethernet/renesas/rtsn.c | 5 + drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 24 +- drivers/net/ethernet/ti/am65-cpsw-nuss.c | 4 +- drivers/net/ethernet/wangxun/libwx/wx_lib.c | 16 +- drivers/net/ethernet/wangxun/libwx/wx_type.h | 2 +- drivers/net/ethernet/wangxun/ngbe/ngbe_main.c | 2 +- drivers/net/ethernet/wangxun/ngbe/ngbe_type.h | 2 +- drivers/net/ethernet/wangxun/txgbe/txgbe_irq.c | 4 +- drivers/net/ethernet/wangxun/txgbe/txgbe_type.h | 4 +- drivers/net/ethernet/xilinx/ll_temac_main.c | 2 +- drivers/net/phy/microchip.c | 3 +- drivers/net/phy/qcom/at803x.c | 27 --- drivers/net/phy/qcom/qca808x.c | 2 +- drivers/net/phy/qcom/qcom-phy-lib.c | 25 ++ drivers/net/phy/qcom/qcom.h | 5 + drivers/net/phy/smsc.c | 57 ++++- drivers/net/usb/qmi_wwan.c | 1 + drivers/net/wireless/marvell/mwifiex/util.c | 4 +- .../net/wireless/mediatek/mt76/mt76_connac_mcu.c | 4 +- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 3 + drivers/net/wireless/mediatek/mt76/mt7925/init.c | 2 + drivers/net/wireless/mediatek/mt76/mt7925/main.c | 6 + drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 4 +- drivers/net/wireless/mediatek/mt76/mt7925/regs.h | 2 +- drivers/net/wireless/ralink/rt2x00/rt2x00soc.c | 4 +- drivers/net/wireless/ralink/rt2x00/rt2x00soc.h | 2 +- drivers/net/wireless/zydas/zd1211rw/zd_mac.c | 6 +- drivers/pci/pci-acpi.c | 23 +- drivers/pinctrl/pinctrl-amd.c | 11 + drivers/pinctrl/qcom/pinctrl-msm.c | 20 ++ drivers/pwm/core.c | 2 +- drivers/pwm/pwm-mediatek.c | 13 +- drivers/tty/vt/vt.c | 1 + drivers/usb/gadget/function/u_serial.c | 12 +- fs/btrfs/free-space-tree.c | 16 +- fs/erofs/data.c | 21 +- fs/erofs/decompressor.c | 12 +- fs/erofs/fileio.c | 6 +- fs/erofs/internal.h | 2 +- fs/erofs/zdata.c | 251 +++++++++----------- fs/erofs/zutil.c | 7 +- fs/eventpoll.c | 12 +- fs/netfs/write_collect.c | 2 +- fs/proc/inode.c | 2 +- fs/proc/proc_sysctl.c | 18 +- fs/proc/task_mmu.c | 14 +- fs/smb/server/smb2pdu.c | 29 +-- fs/smb/server/transport_rdma.c | 5 +- fs/smb/server/vfs.c | 1 + include/drm/drm_file.h | 3 + include/drm/drm_framebuffer.h | 7 + include/drm/spsc_queue.h | 4 +- include/linux/ieee80211.h | 45 +++- include/linux/mm.h | 5 + include/linux/psp-sev.h | 2 + include/net/af_vsock.h | 2 +- include/net/netfilter/nf_flow_table.h | 2 +- include/sound/soc-acpi.h | 13 ++ include/trace/events/erofs.h | 2 +- io_uring/opdef.c | 1 + kernel/bpf/bpf_lru_list.c | 9 +- kernel/bpf/bpf_lru_list.h | 1 + kernel/events/core.c | 6 +- kernel/sched/core.c | 5 + kernel/sched/deadline.c | 10 +- kernel/stop_machine.c | 20 +- lib/alloc_tag.c | 3 + lib/maple_tree.c | 1 + mm/kasan/report.c | 13 +- mm/vmalloc.c | 22 +- net/appletalk/ddp.c | 1 + net/atm/clip.c | 64 ++++-- net/bluetooth/hci_event.c | 3 + net/bluetooth/hci_sync.c | 2 +- net/ipv4/tcp.c | 2 +- net/ipv6/addrconf.c | 9 +- net/mac80211/mlme.c | 7 +- net/mac80211/parse.c | 6 +- net/netlink/af_netlink.c | 90 +++++--- net/rxrpc/call_accept.c | 4 + net/sched/sch_api.c | 23 +- net/tipc/topsrv.c | 2 + net/vmw_vsock/af_vsock.c | 57 ++++- net/wireless/nl80211.c | 7 +- net/wireless/util.c | 52 ++++- rust/kernel/init/macros.rs | 2 + scripts/gdb/linux/constants.py.in | 7 + scripts/gdb/linux/interrupts.py | 16 +- scripts/gdb/linux/mapletree.py | 252 +++++++++++++++++++++ scripts/gdb/linux/xarray.py | 28 +++ sound/isa/ad1816a/ad1816a.c | 2 +- sound/pci/hda/patch_realtek.c | 7 + sound/soc/amd/yc/acp6x-mach.c | 7 + sound/soc/codecs/cs35l56-shared.c | 2 +- sound/soc/fsl/fsl_asrc.c | 3 +- sound/soc/fsl/fsl_sai.c | 14 +- sound/soc/intel/boards/Kconfig | 1 + sound/soc/intel/common/Makefile | 2 +- sound/soc/intel/common/soc-acpi-intel-arl-match.c | 66 +++++- sound/soc/intel/common/sof-function-topology-lib.c | 136 +++++++++++ sound/soc/intel/common/sof-function-topology-lib.h | 15 ++ sound/soc/sof/intel/hda.c | 6 +- tools/arch/x86/include/asm/msr-index.h | 1 + tools/include/linux/kallsyms.h | 4 + tools/testing/selftests/bpf/test_lru_map.c | 105 ++++----- tools/testing/selftests/net/forwarding/lib.sh | 113 --------- tools/testing/selftests/net/lib.sh | 115 ++++++++++ virt/kvm/kvm_main.c | 3 + 172 files changed, 1953 insertions(+), 867 deletions(-)
Greg Kroah-Hartman
maintainerPATCH 1/163 eventpoll: dont decrement ep refcount while still holding the ep mutex
6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds <[email protected]>
commit 8c2e52ebbe885c7eeaabd3b7ddcdc1246fc400d2 upstream.
Jann Horn points out that epoll is decrementing the ep refcount and then doing a
mutex_unlock(&ep->mtx);
afterwards. That's very wrong, because it can lead to a use-after-free.
That pattern is actually fine for the very last reference, because the code in question will delay the actual call to "ep_free(ep)" until after it has unlocked the mutex.
But it's wrong for the much subtler "next to last" case when somebody *else* may also be dropping their reference and free the ep while we're still using the mutex.
Note that this is true even if that other user is also using the same ep
mutex: mutexes, unlike spinlocks, can not be used for object ownership, even if they guarantee mutual exclusion.
A mutex "unlock" operation is not atomic, and as one user is still accessing the mutex as part of unlocking it, another user can come in and get the now released mutex and free the data structure while the first user is still cleaning up.
See our mutex documentation in Documentation/locking/mutex-design.rst, in particular the section [1] about semantics:
"mutex_unlock() may access the mutex structure even after it has
internally released the lock already - so it's not safe for another context to acquire the mutex and assume that the mutex_unlock() context is not using the structure anymore"
So if we drop our ep ref before the mutex unlock, but we weren't the last one, we may then unlock the mutex, another user comes in, drops _their_ reference and releases the 'ep' as it now has no users - all while the mutex_unlock() is still accessing it.
Fix this by simply moving the ep refcount dropping to outside the mutex:
the refcount itself is atomic, and doesn't need mutex protection (that's the whole _point_ of refcounts: unlike mutexes, they are inherently about object lifetimes).
--- fs/eventpoll.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
fs/eventpoll.c +5 -7
@@ -854,7 +854,7 @@ static bool __ep_remove(struct eventpollkfree_rcu (epi, rcu);percpu_counter_dec (&ep->user->epoll_watches); -return ep_refcount_dec_and_test (ep); +return true; }/*
@@ -862,14 +862,14 @@ static bool __ep_remove(struct eventpoll*/ static void ep_remove_safe (struct eventpoll *ep,struct epitem *epi) { -WARN_ON_ONCE (__ep_remove (ep, epi, false)); +if (__ep_remove (ep, epi, false)) +WARN_ON_ONCE (ep_refcount_dec_and_test (ep)); }static void ep_clear_and_put (struct eventpoll *ep) {struct rb_node *rbp, *next;struct epitem *epi; -bool dispose;/* We need to release all tasks waiting for these file */ if (waitqueue_active (&ep->poll_wait))
@@ -902,10 +902,8 @@ static void ep_clear_and_put(struct evencond_resched (); } - dispose =ep_refcount_dec_and_test (ep);mutex_unlock (&ep->mtx); - -if (dispose) +if (ep_refcount_dec_and_test (ep))ep_free (ep); }
@@ -1108,7 +1106,7 @@ again: dispose =__ep_remove (ep, epi, true);mutex_unlock (&ep->mtx); -if (dispose) +if (dispose &&ep_refcount_dec_and_test (ep))ep_free (ep); goto again; }
Greg Kroah-Hartman
maintainerPATCH 2/163 drm/exynos: exynos7_drm_decon: add vblank check in IRQ handling
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kaustabh Chakraborty <[email protected]>
commit b846350aa272de99bf6fecfa6b08e64ebfb13173 upstream.
If there's support for another console device (such as a TTY serial), the kernel occasionally panics during boot. The panic message and a relevant snippet of the call stack is as follows:
Unable to handle kernel NULL pointer dereference at virtual address 000000000000000
Call trace:
drm_crtc_handle_vblank+0x10/0x30 (P)
decon_irq_handler+0x88/0xb4
[...]Otherwise, the panics don't happen. This indicates that it's some sort of race condition.
Add a check to validate if the drm device can handle vblanks before calling drm_crtc_handle_vblank() to avoid this.
--- drivers/gpu/drm/exynos/exynos7_drm_decon.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/gpu/drm/exynos/exynos7_drm_decon.c +4 -0
@@ -601,6 +601,10 @@ static irqreturn_t decon_irq_handler(intif (!ctx->drm_dev) goto out; +/* check if crtc and vblank have been initialized properly */ +if (!drm_dev_has_vblank (ctx->drm_dev)) + goto out; +if (!ctx->i80_if) {drm_crtc_handle_vblank (&ctx->crtc->base);
Greg Kroah-Hartman
maintainerPATCH 3/163 drm/amdgpu/discovery: use specific ip_discovery.bin for legacy asics
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Flora Cui <[email protected]>
commit 25f602fbbcc8271f6e72211b54808ba21e677762 upstream.
vega10/vega12/vega20/raven/raven2/picasso/arcturus/aldebaran
--- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 28 +++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +27 -1
@@ -112,6 +112,12 @@#endif MODULE_FIRMWARE ("amdgpu/ip_discovery.bin" ); +MODULE_FIRMWARE ("amdgpu/vega10_ip_discovery.bin" ); +MODULE_FIRMWARE ("amdgpu/vega12_ip_discovery.bin" ); +MODULE_FIRMWARE ("amdgpu/vega20_ip_discovery.bin" ); +MODULE_FIRMWARE ("amdgpu/raven_ip_discovery.bin" ); +MODULE_FIRMWARE ("amdgpu/raven2_ip_discovery.bin" ); +MODULE_FIRMWARE ("amdgpu/picasso_ip_discovery.bin" );#define mmIP_DISCOVERY_VERSION 0x16A00#define mmRCC_CONFIG_MEMSIZE 0xde3
@@ -400,7 +406,27 @@ static const char *amdgpu_discovery_get_if (amdgpu_discovery ==2 )return "amdgpu/ip_discovery.bin" ; -return NULL ; +switch (adev->asic_type) { +case CHIP_VEGA10 : +return "amdgpu/vega10_ip_discovery.bin" ; +case CHIP_VEGA12 : +return "amdgpu/vega12_ip_discovery.bin" ; +case CHIP_RAVEN : +if (adev->apu_flags &AMD_APU_IS_RAVEN2 ) +return "amdgpu/raven2_ip_discovery.bin" ; +else if (adev->apu_flags &AMD_APU_IS_PICASSO ) +return "amdgpu/picasso_ip_discovery.bin" ; +else +return "amdgpu/raven_ip_discovery.bin" ; +case CHIP_VEGA20 : +return "amdgpu/vega20_ip_discovery.bin" ; +case CHIP_ARCTURUS : +return "amdgpu/arcturus_ip_discovery.bin" ; +case CHIP_ALDEBARAN : +return "amdgpu/aldebaran_ip_discovery.bin" ; +default : +return NULL ; + } }static int amdgpu_discovery_init (struct amdgpu_device *adev)
Greg Kroah-Hartman
maintainerPATCH 4/163 drm/amdgpu/ip_discovery: add missing ip_discovery fw
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Flora Cui <[email protected]>
commit 2f6dd741cdcdadb9e125cc66d4fcfbe5ab92d36a upstream.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +2 -0
@@ -118,6 +118,8 @@ MODULE_FIRMWARE("amdgpu/vega20_ip_discovMODULE_FIRMWARE ("amdgpu/raven_ip_discovery.bin" );MODULE_FIRMWARE ("amdgpu/raven2_ip_discovery.bin" );MODULE_FIRMWARE ("amdgpu/picasso_ip_discovery.bin" ); +MODULE_FIRMWARE ("amdgpu/arcturus_ip_discovery.bin" ); +MODULE_FIRMWARE ("amdgpu/aldebaran_ip_discovery.bin" );#define mmIP_DISCOVERY_VERSION 0x16A00#define mmRCC_CONFIG_MEMSIZE 0xde3
Greg Kroah-Hartman
maintainerPATCH 5/163 crypto: s390/sha - Fix uninitialized variable in SHA-1 and SHA-2
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit 68279380266a5fa70e664de754503338e2ec3f43 upstream.
Commit 88c02b3f79a6 ("s390/sha3: Support sha3 performance enhancements") added the field s390_sha_ctx::first_message_part and made it be used by s390_sha_update() (now s390_sha_update_blocks()). At the time, s390_sha_update() was used by all the s390 SHA-1, SHA-2, and SHA-3 algorithms. However, only the initialization functions for SHA-3 were updated, leaving SHA-1 and SHA-2 using first_message_part uninitialized.
This could cause e.g. the function code CPACF_KIMD_SHA_512 | CPACF_KIMD_NIP to be used instead of just CPACF_KIMD_SHA_512. This apparently was harmless, as the SHA-1 and SHA-2 function codes ignore CPACF_KIMD_NIP; it is recognized only by the SHA-3 function codes
(https://lore.kernel.org/r/[email protected]/).
Therefore, this bug was found only when first_message_part was later converted to a boolean and UBSAN detected its uninitialized use. Regardless, let's fix this by just initializing to zero.
Note: in 6.16, we need to patch SHA-1, SHA-384, and SHA-512. In 6.15 and earlier, we'll also need to patch SHA-224 and SHA-256, as they hadn't yet been librarified (which incidentally fixed this bug).
--- arch/s390/crypto/sha1_s390.c | 2 ++ arch/s390/crypto/sha256_s390.c | 3 +++ arch/s390/crypto/sha512_s390.c | 3 +++ 3 files changed, 8 insertions(+)
arch/s390/crypto/sha1_s390.c +2 -0
@@ -38,6 +38,7 @@ static int s390_sha1_init(struct shash_d sctx->state[4 ] =SHA1_H4 ; sctx->count =0 ; sctx->func =CPACF_KIMD_SHA_1 ; + sctx->first_message_part =0 ;return 0 ; }
@@ -62,6 +63,7 @@ static int s390_sha1_import(struct shashmemcpy (sctx->state, ictx->state,sizeof (ictx->state));memcpy (sctx->buf, ictx->buffer,sizeof (ictx->buffer)); sctx->func =CPACF_KIMD_SHA_1 ; + sctx->first_message_part =0 ;return 0 ; }
arch/s390/crypto/sha256_s390.c +3 -0
@@ -31,6 +31,7 @@ static int s390_sha256_init(struct shash sctx->state[7 ] =SHA256_H7 ; sctx->count =0 ; sctx->func =CPACF_KIMD_SHA_256 ; + sctx->first_message_part =0 ;return 0 ; }
@@ -55,6 +56,7 @@ static int sha256_import(struct shash_dememcpy (sctx->state, ictx->state,sizeof (ictx->state));memcpy (sctx->buf, ictx->buf,sizeof (ictx->buf)); sctx->func =CPACF_KIMD_SHA_256 ; + sctx->first_message_part =0 ;return 0 ; }
@@ -90,6 +92,7 @@ static int s390_sha224_init(struct shash sctx->state[7 ] =SHA224_H7 ; sctx->count =0 ; sctx->func =CPACF_KIMD_SHA_256 ; + sctx->first_message_part =0 ;return 0 ; }
arch/s390/crypto/sha512_s390.c +3 -0
@@ -32,6 +32,7 @@ static int sha512_init(struct shash_desc *(__u64 *)&ctx->state[14 ] =SHA512_H7 ; ctx->count =0 ; ctx->func =CPACF_KIMD_SHA_512 ; + ctx->first_message_part =0 ;return 0 ; }
@@ -60,6 +61,7 @@ static int sha512_import(struct shash_dememcpy (sctx->state, ictx->state,sizeof (ictx->state));memcpy (sctx->buf, ictx->buf,sizeof (ictx->buf)); sctx->func =CPACF_KIMD_SHA_512 ; + sctx->first_message_part =0 ;return 0 ; }
@@ -97,6 +99,7 @@ static int sha384_init(struct shash_desc *(__u64 *)&ctx->state[14 ] =SHA384_H7 ; ctx->count =0 ; ctx->func =CPACF_KIMD_SHA_512 ; + ctx->first_message_part =0 ;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 6/163 drm/amdgpu: Replace Mutex with Spinlock for RLCG register access to avoid Priority Inversion in SRIOV
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
commit dc0297f3198bd60108ccbd167ee5d9fa4af31ed0 upstream.
RLCG Register Access is a way for virtual functions to safely access GPU registers in a virtualized environment., including TLB flushes and register reads. When multiple threads or VFs try to access the same registers simultaneously, it can lead to race conditions. By using the RLCG interface, the driver can serialize access to the registers. This means that only one thread can access the registers at a time, preventing conflicts and ensuring that operations are performed correctly. Additionally, when a low-priority task holds a mutex that a high-priority task needs, ie., If a thread holding a spinlock tries to acquire a mutex, it can lead to priority inversion. register access in amdgpu_virt_rlcg_reg_rw especially in a fast code path is critical.
The call stack shows that the function amdgpu_virt_rlcg_reg_rw is being called, which attempts to acquire the mutex. This function is invoked from amdgpu_sriov_wreg, which in turn is called from gmc_v11_0_flush_gpu_tlb.
The [ BUG: Invalid wait context ] indicates that a thread is trying to acquire a mutex while it is in a context that does not allow it to sleep (like holding a spinlock).
Fixes the below:
[ 253.013423] =============================
[ 253.013434] [ BUG: Invalid wait context ]
[ 253.013446] 6.12.0-amdstaging-drm-next-lol-050225 #14 Tainted: G U OE
[ 253.013464] -----------------------------
[ 253.013475] kworker/0:1/10 is trying to lock:
[ 253.013487] ffff9f30542e3cf8 (&adev->virt.rlcg_reg_lock){+.+.}-{3:3}, at: amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
[ 253.013815] other info that might help us debug this:
[ 253.013827] context-{4:4}
[ 253.013835] 3 locks held by kworker/0:1/10:
[ 253.013847] #0: ffff9f3040050f58 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work+0x3f5/0x680
[ 253.013877] #1: ffffb789c008be40 ((work_completion)(&wfc.work)){+.+.}-{0:0}, at: process_one_work+0x1d6/0x680
[ 253.013905] #2: ffff9f3054281838 (&adev->gmc.invalidate_lock){+.+.}-{2:2}, at: gmc_v11_0_flush_gpu_tlb+0x198/0x4f0 [amdgpu]
[ 253.014154] stack backtrace:
[ 253.014164] CPU: 0 UID: 0 PID: 10 Comm: kworker/0:1 Tainted: G U OE 6.12.0-amdstaging-drm-next-lol-050225 #14
[ 253.014189] Tainted: [U]=USER, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[ 253.014203] Hardware name: Microsoft Corporation Virtual Machine/Virtual Machine, BIOS Hyper-V UEFI Release v4.1 11/18/2024
[ 253.014224] Workqueue: events work_for_cpu_fn
[ 253.014241] Call Trace:
[ 253.014250] <TASK>
[ 253.014260] dump_stack_lvl+0x9b/0xf0
[ 253.014275] dump_stack+0x10/0x20
[ 253.014287] __lock_acquire+0xa47/0x2810
[ 253.014303] ? srso_alias_return_thunk+0x5/0xfbef5
[ 253.014321] lock_acquire+0xd1/0x300
[ 253.014333] ? amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
[ 253.014562] ? __lock_acquire+0xa6b/0x2810
[ 253.014578] __mutex_lock+0x85/0xe20
[ 253.014591] ? amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
[ 253.014782] ? sched_clock_noinstr+0x9/0x10
[ 253.014795] ? srso_alias_return_thunk+0x5/0xfbef5
[ 253.014808] ? local_clock_noinstr+0xe/0xc0
[ 253.014822] ? amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
[ 253.015012] ? srso_alias_return_thunk+0x5/0xfbef5
[ 253.015029] mutex_lock_nested+0x1b/0x30
[ 253.015044] ? mutex_lock_nested+0x1b/0x30
[ 253.015057] amdgpu_virt_rlcg_reg_rw+0xf6/0x330 [amdgpu]
[ 253.015249] amdgpu_sriov_wreg+0xc5/0xd0 [amdgpu]
[ 253.015435] gmc_v11_0_flush_gpu_tlb+0x44b/0x4f0 [amdgpu]
[ 253.015667] gfx_v11_0_hw_init+0x499/0x29c0 [amdgpu]
[ 253.015901] ? __pfx_smu_v13_0_update_pcie_parameters+0x10/0x10 [amdgpu]
[ 253.016159] ? srso_alias_return_thunk+0x5/0xfbef5
[ 253.016173] ? smu_hw_init+0x18d/0x300 [amdgpu]
[ 253.016403] amdgpu_device_init+0x29ad/0x36a0 [amdgpu]
[ 253.016614] amdgpu_driver_load_kms+0x1a/0xc0 [amdgpu]
[ 253.017057] amdgpu_pci_probe+0x1c2/0x660 [amdgpu]
[ 253.017493] local_pci_probe+0x4b/0xb0
[ 253.017746] work_for_cpu_fn+0x1a/0x30
[ 253.017995] process_one_work+0x21e/0x680
[ 253.018248] worker_thread+0x190/0x330
[ 253.018500] ? __pfx_worker_thread+0x10/0x10
[ 253.018746] kthread+0xe7/0x120
[ 253.018988] ? __pfx_kthread+0x10/0x10
[ 253.019231] ret_from_fork+0x3c/0x60
[ 253.019468] ? __pfx_kthread+0x10/0x10
[ 253.019701] ret_from_fork_asm+0x1a/0x30
[ 253.019939] </TASK>v2: s/spin_trylock/spin_lock_irqsave to be safe (Christian).
--- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 5 +++-- drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +1 -1
@@ -4144,7 +4144,6 @@ int amdgpu_device_init(struct amdgpu_devmutex_init (&adev->grbm_idx_mutex);mutex_init (&adev->mn_lock);mutex_init (&adev->virt.vf_errors.lock); -mutex_init (&adev->virt.rlcg_reg_lock);hash_init (adev->mn_hash);mutex_init (&adev->psp.mutex);mutex_init (&adev->notifier_lock);
@@ -4170,6 +4169,7 @@ int amdgpu_device_init(struct amdgpu_devspin_lock_init (&adev->se_cac_idx_lock);spin_lock_init (&adev->audio_endpt_idx_lock);spin_lock_init (&adev->mm_stats.lock); +spin_lock_init (&adev->virt.rlcg_reg_lock);spin_lock_init (&adev->wb.lock);INIT_LIST_HEAD (&adev->reset_list);
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +3 -2
@@ -1010,6 +1010,7 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgpvoid *scratch_reg2;void *scratch_reg3;void *spare_int; +unsigned long flags;if (!adev->gfx.rlc.rlcg_reg_access_supported) { dev_err(adev->dev,
@@ -1031,7 +1032,7 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgp scratch_reg2 = (void __iomem *)adev->rmmio +4 * reg_access_ctrl->scratch_reg2; scratch_reg3 = (void __iomem *)adev->rmmio +4 * reg_access_ctrl->scratch_reg3; -mutex_lock (&adev->virt.rlcg_reg_lock); +spin_lock_irqsave (&adev->virt.rlcg_reg_lock, flags);if (reg_access_ctrl->spare_int) spare_int = (void __iomem *)adev->rmmio +4 * reg_access_ctrl->spare_int;
@@ -1090,7 +1091,7 @@ u32 amdgpu_virt_rlcg_reg_rw(struct amdgp ret =readl (scratch_reg0); -mutex_unlock (&adev->virt.rlcg_reg_lock); +spin_unlock_irqrestore (&adev->virt.rlcg_reg_lock, flags);return ret; }
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h +2 -1
@@ -275,7 +275,8 @@ struct amdgpu_virt {/* the ucode id to signal the autoload */ uint32_t autoload_ucode_id; -struct mutex rlcg_reg_lock; +/* Spinlock to protect access to the RLCG register interface */ +spinlock_t rlcg_reg_lock; };struct amdgpu_video_codec_info ;
Greg Kroah-Hartman
maintainerPATCH 7/163 ASoC: fsl_asrc: use internal measured ratio for non-ideal ratio mode
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang <[email protected]>
[ Upstream commit cbe876121633dadb2b0ce52711985328638e9aab ]
When USRC=0, there is underrun issue for the non-ideal ratio mode; according to the reference mannual, the internal measured ratio can be used with USRC=1 and IDRC=0.
--- sound/soc/fsl/fsl_asrc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
sound/soc/fsl/fsl_asrc.c +2 -1
@@ -517,7 +517,8 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate)regmap_update_bits (asrc->regmap,REG_ASRCTR ,ASRCTR_ATSi_MASK (index),ASRCTR_ATS (index));regmap_update_bits (asrc->regmap,REG_ASRCTR , -ASRCTR_USRi_MASK (index),0 ); +ASRCTR_IDRi_MASK (index) |ASRCTR_USRi_MASK (index), +ASRCTR_USR (index));/* Set the input and output clock sources */ regmap_update_bits(asrc->regmap, REG_ASRCSR,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 8/163 ASoC: Intel: SND_SOC_INTEL_SOF_BOARD_HELPERS select SND_SOC_ACPI_INTEL_MATCH
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bard Liao <[email protected]>
[ Upstream commit 960aed31eedbaeb2e47b1bc485b462fd38a53311 ]
The helpers that are provided by SND_SOC_ACPI_INTEL_MATCH (soc-acpi-intel-ssp-common) are used in SND_SOC_INTEL_SOF_BOARD_HELPERS (sof_board_helpers).SND_SOC_ACPI_INTEL_MATCH is selected by machine drivers. When skl_hda_dsp_generic uses the board helpers, it select SND_SOC_INTEL_SOF_BOARD_HELPERS only but not SND_SOC_ACPI_INTEL_MATCH which initroduce the undefined symbol errors. However, it makes more sense that SND_SOC_INTEL_SOF_BOARD_HELPERS select SND_SOC_ACPI_INTEL_MATCH itself.
--- sound/soc/intel/boards/Kconfig | 1 + 1 file changed, 1 insertion(+)
sound/soc/intel/boards/Kconfig +1 -0
@@ -42,6 +42,7 @@ config SND_SOC_INTEL_SOF_NUVOTON_COMMON tristate config SND_SOC_INTEL_SOF_BOARD_HELPERS + select SND_SOC_ACPI_INTEL_MATCH tristate if SND_SOC_INTEL_CATPT
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 9/163 ASoC: Intel: soc-acpi: arl: Correct naming of a cs35l56 address struct
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Trimmer <[email protected]>
[ Upstream commit a3003af649efb6f3d86d379d1e9a966ea6d5f5ab ]
As there are many combinations these follow a naming scheme to make the content of link structures clearer:
cs35l56_<controller link>_<l or r><unique instance id>_adr
Stable-dep-of: a7528e9beadb ("ASoC: Intel: soc-acpi: arl: Correct order of cs42l43 matches")
--- sound/soc/intel/common/soc-acpi-intel-arl-match.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
sound/soc/intel/common/soc-acpi-intel-arl-match.c +3 -3
@@ -138,7 +138,7 @@ static const struct snd_soc_acpi_adr_device cs35l56_2_r1_adr[] = { }, }; -static const struct snd_soc_acpi_adr_device cs35l56_3_l1_adr[] = { +static const struct snd_soc_acpi_adr_device cs35l56_3_l3_adr[] = { { .adr =0x00033301fa355601ull , .num_endpoints =1 ,
@@ -306,8 +306,8 @@ static const struct snd_soc_acpi_link_adr arl_cs42l43_l0_cs35l56_2_l23[] = { }, { .mask = BIT(3), - .num_adr = ARRAY_SIZE(cs35l56_3_l1_adr), - .adr_d = cs35l56_3_l1_adr, + .num_adr = ARRAY_SIZE(cs35l56_3_l3_adr), + .adr_d = cs35l56_3_l3_adr, }, {} };
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 10/163 ASoC: Intel: soc-acpi: arl: Add match entries for new cs42l43 laptops
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Trimmer <[email protected]>
[ Upstream commit d7f671b2f566379f275c13e25a29fa7001bb278f ]
Add some new match table entries on Arrowlake for some coming cs42l43 laptops.
Stable-dep-of: a7528e9beadb ("ASoC: Intel: soc-acpi: arl: Correct order of cs42l43 matches")
--- .../intel/common/soc-acpi-intel-arl-match.c | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+)
sound/soc/intel/common/soc-acpi-intel-arl-match.c +43 -0
@@ -147,6 +147,24 @@ static const struct snd_soc_acpi_adr_device cs35l56_3_l3_adr[] = { }, }; +static const struct snd_soc_acpi_adr_device cs35l56_2_r3_adr[] = { + { + .adr =0x00023301fa355601ull , + .num_endpoints =1 , + .endpoints = &spk_r_endpoint, + .name_prefix ="AMP2" + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l56_3_l1_adr[] = { + { + .adr =0x00033101fa355601ull , + .num_endpoints =1 , + .endpoints = &spk_l_endpoint, + .name_prefix ="AMP1" + }, +}; +static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = { {/* Jack Playback Endpoint */ .num =0 ,
@@ -312,6 +330,25 @@ static const struct snd_soc_acpi_link_adr arl_cs42l43_l0_cs35l56_2_l23[] = { {} }; +static const struct snd_soc_acpi_link_adr arl_cs42l43_l0_cs35l56_3_l23[] = { + { + .mask =BIT (0 ), + .num_adr =ARRAY_SIZE (cs42l43_0_adr), + .adr_d = cs42l43_0_adr, + }, + { + .mask =BIT (2 ), + .num_adr =ARRAY_SIZE (cs35l56_2_r3_adr), + .adr_d = cs35l56_2_r3_adr, + }, + { + .mask =BIT (3 ), + .num_adr =ARRAY_SIZE (cs35l56_3_l1_adr), + .adr_d = cs35l56_3_l1_adr, + }, + {} +}; +static const struct snd_soc_acpi_link_adr arl_rvp[] = { { .mask =BIT (0 ),
@@ -406,6 +443,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l23.tplg", }, + { + .link_mask = BIT(0) | BIT(2) | BIT(3), + .links = arl_cs42l43_l0_cs35l56_3_l23, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l23.tplg", + }, { .link_mask = BIT(0) | BIT(2), .links = arl_cs42l43_l0_cs35l56_l2,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 11/163 ASoC: soc-acpi: add get_function_tplg_files ops
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bard Liao <[email protected]>
[ Upstream commit d1e70eed0b30bd2b15fc6c93b5701be564bbe353 ]
We always use a single topology that contains all PCM devices belonging to a machine configuration.
However, with SDCA, we want to be able to load function topologies based on the supported device functions. This change is in preparation for loading those function topologies.
Stable-dep-of: a7528e9beadb ("ASoC: Intel: soc-acpi: arl: Correct order of cs42l43 matches")
--- include/sound/soc-acpi.h | 13 +++++++++++++ 1 file changed, 13 insertions(+)
include/sound/soc-acpi.h +13 -0
@@ -10,6 +10,7 @@#include <linux/acpi.h> #include <linux/mod_devicetable.h> #include <linux/soundwire/sdw.h> +#include <sound/soc.h> struct snd_soc_acpi_package_context {char *name;/* package name */
@@ -189,6 +190,15 @@ struct snd_soc_acpi_link_adr {* is not constant since this field may be updated at run-time * @sof_tplg_filename: Sound Open Firmware topology file name, if enabled * @tplg_quirk_mask: quirks to select different topology files dynamically +* @get_function_tplg_files: This is an optional callback, if specified then instead of +* the single sof_tplg_filename the callback will return the list of function topology +* files to be loaded. +* Return value: The number of the files or negative ERRNO. 0 means that the single topology +* file should be used, no function topology split can be used on the machine. +* @card: the pointer of the card +* @mach: the pointer of the machine driver +* @prefix: the prefix of the topology file name. Typically, it is the path. +* @tplg_files: the pointer of the array of the topology file names. */ /* Descriptor for SST ASoC machine driver */ struct snd_soc_acpi_mach {
@@ -207,6 +217,9 @@ struct snd_soc_acpi_mach {struct snd_soc_acpi_mach_params mach_params;const char *sof_tplg_filename;const u32 tplg_quirk_mask; +int (*get_function_tplg_files)(struct snd_soc_card *card, +const struct snd_soc_acpi_mach *mach, +const char *prefix,const char ***tplg_files); };#define SND_SOC_ACPI_MAX_CODECS 3
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 12/163 ASoC: Intel: add sof_sdw_get_tplg_files ops
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bard Liao <[email protected]>
[ Upstream commit 2fbeff33381cf017facbf5f13d34693baa5a2296 ]
Add sof_sdw_get_tplg_files ops to get sub-topology file names for the sof_sdw card.
Stable-dep-of: a7528e9beadb ("ASoC: Intel: soc-acpi: arl: Correct order of cs42l43 matches")
--- sound/soc/intel/common/Makefile | 2 +- .../intel/common/sof-function-topology-lib.c | 135 ++++++++++++++++++ .../intel/common/sof-function-topology-lib.h | 15 ++ 3 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 sound/soc/intel/common/sof-function-topology-lib.c create mode 100644 sound/soc/intel/common/sof-function-topology-lib.h
sound/soc/intel/common/Makefile +1 -1
@@ -14,7 +14,7 @@ snd-soc-acpi-intel-match-y := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-matc soc-acpi-intel-lnl-match.o \ soc-acpi-intel-ptl-match.o \ soc-acpi-intel-hda-match.o \ - soc-acpi-intel-sdw-mockup-match.o + soc-acpi-intel-sdw-mockup-match.o sof-function-topology-lib.o snd-soc-acpi-intel-match-y += soc-acpi-intel-ssp-common.o
sound/soc/intel/common/sof-function-topology-lib.c new file +135 -0
135 lines not on this page · raw message
sound/soc/intel/common/sof-function-topology-lib.h new file +15 -0
@@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* soc-acpi-intel-get-tplg.h - get-tplg-files ops +* +* Copyright (c) 2025, Intel Corporation. +* +*/ + +#ifndef _SND_SOC_ACPI_INTEL_GET_TPLG_H +#define _SND_SOC_ACPI_INTEL_GET_TPLG_H + +int sof_sdw_get_tplg_files (struct snd_soc_card *card,const struct snd_soc_acpi_mach *mach, +const char *prefix,const char ***tplg_files); + +#endif
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 13/163 ASoC: Intel: soc-acpi-intel-arl-match: set get_function_tplg_files ops
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bard Liao <[email protected]>
[ Upstream commit d348b4181cd15ed432c2ae7eb33ef1bb7dfd7527 ]
The audio configs with multi-function SDCA codecs can use the sof_sdw_get_tplg_files ops to get function topologies dynamically.
Stable-dep-of: a7528e9beadb ("ASoC: Intel: soc-acpi: arl: Correct order of cs42l43 matches")
--- sound/soc/intel/common/soc-acpi-intel-arl-match.c | 9 +++++++++ 1 file changed, 9 insertions(+)
sound/soc/intel/common/soc-acpi-intel-arl-match.c +9 -0
@@ -8,6 +8,7 @@#include <sound/soc-acpi.h> #include <sound/soc-acpi-intel-match.h> #include <sound/soc-acpi-intel-ssp-common.h> +#include "sof-function-topology-lib.h" static const struct snd_soc_acpi_endpoint single_endpoint = { .num =0 ,
@@ -436,42 +437,49 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = { .links = arl_cs42l43_l0_cs35l56_l23, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l23.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, }, { .link_mask = BIT(0) | BIT(2) | BIT(3), .links = arl_cs42l43_l0_cs35l56_2_l23, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l23.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, }, { .link_mask = BIT(0) | BIT(2) | BIT(3), .links = arl_cs42l43_l0_cs35l56_3_l23, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l23.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, }, { .link_mask = BIT(0) | BIT(2), .links = arl_cs42l43_l0_cs35l56_l2, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l2.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, }, { .link_mask = BIT(0), .links = arl_cs42l43_l0, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-arl-cs42l43-l0.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, }, { .link_mask = BIT(2), .links = arl_cs42l43_l2, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-arl-cs42l43-l2.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, }, { .link_mask = BIT(2) | BIT(3), .links = arl_cs42l43_l2_cs35l56_l3, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-arl-cs42l43-l2-cs35l56-l3.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, }, { .link_mask = 0x1, /* link0 required */
@@ -490,6 +498,7 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = { .links = arl_rt722_l0_rt1320_l2, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-arl-rt722-l0_rt1320-l2.tplg", + .get_function_tplg_files = sof_sdw_get_tplg_files, }, {}, };
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 14/163 ASoC: Intel: soc-acpi: arl: Correct order of cs42l43 matches
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Keepax <[email protected]>
[ Upstream commit a7528e9beadbddcec21b394ce5fa8dc4e5cdaa24 ]
Matches should go from more specific to less specific, correct the ordering of two cs42l43 entries.
--- sound/soc/intel/common/soc-acpi-intel-arl-match.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
sound/soc/intel/common/soc-acpi-intel-arl-match.c +6 -6
@@ -468,17 +468,17 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = { .get_function_tplg_files = sof_sdw_get_tplg_files, }, { - .link_mask = BIT(2), - .links = arl_cs42l43_l2, + .link_mask = BIT(2) | BIT(3), + .links = arl_cs42l43_l2_cs35l56_l3, .drv_name = "sof_sdw", - .sof_tplg_filename = "sof-arl-cs42l43-l2.tplg", + .sof_tplg_filename = "sof-arl-cs42l43-l2-cs35l56-l3.tplg", .get_function_tplg_files = sof_sdw_get_tplg_files, }, { - .link_mask = BIT(2) | BIT(3), - .links = arl_cs42l43_l2_cs35l56_l3, + .link_mask = BIT(2), + .links = arl_cs42l43_l2, .drv_name = "sof_sdw", - .sof_tplg_filename = "sof-arl-cs42l43-l2-cs35l56-l3.tplg", + .sof_tplg_filename = "sof-arl-cs42l43-l2.tplg", .get_function_tplg_files = sof_sdw_get_tplg_files, }, {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 15/163 perf/core: Fix the WARN_ON_ONCE is out of lock protected region
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luo Gengkun <[email protected]>
[ Upstream commit 7b4c5a37544ba22c6ebe72c0d4ea56c953459fa5 ]
commit 3172fb986666 ("perf/core: Fix WARN in perf_cgroup_switch()") try to fix a concurrency problem between perf_cgroup_switch and perf_cgroup_event_disable. But it does not to move the WARN_ON_ONCE into lock-protected region, so the warning is still be triggered.
--- kernel/events/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/events/core.c +2 -2
@@ -905,8 +905,6 @@ static void perf_cgroup_switch(struct task_struct *task)if (READ_ONCE (cpuctx->cgrp) ==NULL )return ; -WARN_ON_ONCE (cpuctx->ctx.nr_cgroups ==0 ); - cgrp =perf_cgroup_from_task (task,NULL );if (READ_ONCE (cpuctx->cgrp) == cgrp)return ;
@@ -918,6 +916,8 @@ static void perf_cgroup_switch(struct task_struct *task)if (READ_ONCE (cpuctx->cgrp) ==NULL )return ; +WARN_ON_ONCE (cpuctx->ctx.nr_cgroups ==0 ); +perf_ctx_disable (&cpuctx->ctx, true);ctx_sched_out (&cpuctx->ctx,NULL ,EVENT_ALL |EVENT_CGROUP );
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 16/163 irqchip/irq-msi-lib: Select CONFIG_GENERIC_MSI_IRQ
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nam Cao <[email protected]>
[ Upstream commit eb2c93e7028b4c9fe4761734d65ee40712d1c242 ]
irq-msi-lib directly uses struct msi_domain_info and more things which are only available when CONFIG_GENERIC_MSI_IRQ=y.
However, there is no dependency specified and CONFIG_IRQ_MSI_LIB can be enabled without CONFIG_GENERIC_MSI_IRQ, which causes the kernel build fail.
Make IRQ_MSI_LIB select GENEREIC_MSI_IRQ to prevent that.
--- drivers/irqchip/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/irqchip/Kconfig +1 -0
@@ -71,6 +71,7 @@ config ARM_VIC_NR config IRQ_MSI_LIB bool + select GENERIC_MSI_IRQ config ARMADA_370_XP_IRQ bool
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 17/163 sched/core: Fix migrate_swap() vs. hotplug
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit 009836b4fa52f92cba33618e773b1094affa8cd2 ]
Quoted 42 lines · Kuyo Chang
So, the potential race scenario is:
CPU0 CPU1 // doing migrate_swap(cpu0/cpu1) stop_two_cpus() ... // doing _cpu_down() sched_cpu_deactivate() set_cpu_active(cpu, false); balance_push_set(cpu, true); cpu_stop_queue_two_works __cpu_stop_queue_work(stopper1,...); __cpu_stop_queue_work(stopper2,..); stop_cpus_in_progress -> true preempt_enable(); ... 1st balance_push stop_one_cpu_nowait cpu_stop_queue_work __cpu_stop_queue_work list_add_tail -> 1st add push_work wake_up_q(&wakeq); -> "wakeq is empty. This implies that the stopper is at wakeq@migrate_swap." preempt_disable wake_up_q(&wakeq); wake_up_process // wakeup migrate/0 try_to_wake_up ttwu_queue ttwu_queue_cond ->meet below case if (cpu == smp_processor_id()) return false; ttwu_do_activate //migrate/0 wakeup done wake_up_process // wakeup migrate/1 try_to_wake_up ttwu_queue ttwu_queue_cond ttwu_queue_wakelist __ttwu_queue_wakelist __smp_call_single_queue preempt_enable();
Quoted 9 lines
2nd balance_push stop_one_cpu_nowait cpu_stop_queue_work __cpu_stop_queue_work list_add_tail -> 2nd add push_work, so the double list add is detected ... ... cpu1 get ipi, do sched_ttwu_pending, wakeup migrate/1
So this balance_push() is part of schedule(), and schedule() is supposed to switch to stopper task, but because of this race condition, stopper task is stuck in WAKING state and not actually visible to be picked.
Therefore CPU1 can do another schedule() and end up doing another balance_push() even though the last one hasn't been done yet.
This is a confluence of fail, where both wake_q and ttwu_wakelist can cause crucial wakeups to be delayed, resulting in the malfunction of balance_push.
Since there is only a single stopper thread to be woken, the wake_q doesn't really add anything here, and can be removed in favour of direct wakeups of the stopper thread.
Then add a clause to ttwu_queue_cond() to ensure the stopper threads are never queued / delayed.
Of all 3 moving parts, the last addition was the balance_push() machinery, so pick that as the point the bug was introduced.
--- kernel/sched/core.c | 5 +++++ kernel/stop_machine.c | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 10 deletions(-)
kernel/sched/core.c +5 -0
@@ -3891,6 +3891,11 @@ static inline bool ttwu_queue_cond(struct task_struct *p, int cpu)if (task_on_scx (p))return false; +#ifdef CONFIG_SMP +if (p->sched_class == &stop_sched_class) +return false; +#endif +/* * Do not complicate things with the async wake_list while the CPU is * in hotplug state.
kernel/stop_machine.c +10 -10
@@ -82,18 +82,15 @@ static void cpu_stop_signal_done(struct cpu_stop_done *done) }static void __cpu_stop_queue_work (struct cpu_stopper *stopper, -struct cpu_stop_work *work, -struct wake_q_head *wakeq) +struct cpu_stop_work *work) {list_add_tail (&work->list, &stopper->works); -wake_q_add (wakeq, stopper->thread); }/* queue @work to @stopper. if offline, @work is completed immediately */ static bool cpu_stop_queue_work (unsigned int cpu,struct cpu_stop_work *work) {struct cpu_stopper *stopper = &per_cpu (cpu_stopper, cpu); -DEFINE_WAKE_Q (wakeq);unsigned long flags;bool enabled;
@@ -101,12 +98,13 @@ static bool cpu_stop_queue_work(unsigned int cpu, struct cpu_stop_work *work)raw_spin_lock_irqsave (&stopper->lock, flags); enabled = stopper->enabled;if (enabled) -__cpu_stop_queue_work (stopper, work, &wakeq); +__cpu_stop_queue_work (stopper, work);else if (work->done)cpu_stop_signal_done (work->done);raw_spin_unlock_irqrestore (&stopper->lock, flags); -wake_up_q (&wakeq); +if (enabled) +wake_up_process (stopper->thread);preempt_enable ();return enabled;
@@ -263,7 +261,6 @@ static int cpu_stop_queue_two_works(int cpu1, struct cpu_stop_work *work1, {struct cpu_stopper *stopper1 =per_cpu_ptr (&cpu_stopper, cpu1);struct cpu_stopper *stopper2 =per_cpu_ptr (&cpu_stopper, cpu2); -DEFINE_WAKE_Q (wakeq);int err; retry:
@@ -299,8 +296,8 @@ static int cpu_stop_queue_two_works(int cpu1, struct cpu_stop_work *work1, } err =0 ; -__cpu_stop_queue_work (stopper1, work1, &wakeq); -__cpu_stop_queue_work (stopper2, work2, &wakeq); +__cpu_stop_queue_work (stopper1, work1); +__cpu_stop_queue_work (stopper2, work2); unlock:raw_spin_unlock (&stopper2->lock);
@@ -315,7 +312,10 @@ static int cpu_stop_queue_two_works(int cpu1, struct cpu_stop_work *work1, goto retry; } -wake_up_q (&wakeq); +if (!err) { +wake_up_process (stopper1->thread); +wake_up_process (stopper2->thread); + }preempt_enable ();return err;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 18/163 perf: Revert to requiring CAP_SYS_ADMIN for uprobes
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit ba677dbe77af5ffe6204e0f3f547f3ba059c6302 ]
Jann reports that uprobes can be used destructively when used in the middle of an instruction. The kernel only verifies there is a valid instruction at the requested offset, but due to variable instruction length cannot determine if this is an instruction as seen by the intended execution stream.
Additionally, Mark Rutland notes that on architectures that mix data in the text segment (like arm64), a similar things can be done if the data word is 'mistaken' for an instruction.
As such, require CAP_SYS_ADMIN for uprobes.
--- kernel/events/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/events/core.c +1 -1
@@ -10737,7 +10737,7 @@ static int perf_uprobe_event_init(struct perf_event *event)if (event->attr.type != perf_uprobe.type)return -ENOENT ; -if (!perfmon_capable ()) +if (!capable (CAP_SYS_ADMIN ))return -EACCES ;/*
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 19/163 ASoC: cs35l56: probe() should fail if the device ID is not recognized
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <[email protected]>
[ Upstream commit 3b3312f28ee2d9c386602f8521e419cfc69f4823 ]
Return an error from driver probe if the DEVID read from the chip is not one supported by this driver.
In cs35l56_hw_init() there is a check for valid DEVID, but the invalid case was returning the value of ret. At this point in the code ret == 0 so the caller would think that cs35l56_hw_init() was successful.
--- sound/soc/codecs/cs35l56-shared.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/soc/codecs/cs35l56-shared.c +1 -1
@@ -811,7 +811,7 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)break ;default :dev_err (cs35l56_base->dev,"Unknown device %x\n" , devid); -return ret; +return -ENODEV ; } cs35l56_base->type = devid &0xFF ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 20/163 Bluetooth: hci_sync: Fix not disabling advertising instance
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit ef9675b0ef030d135413e8638989f3a7d1f3217a ]
As the code comments on hci_setup_ext_adv_instance_sync suggests the advertising instance needs to be disabled in order to update its parameters, but it was wrongly checking that !adv->pending.
--- net/bluetooth/hci_sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/bluetooth/hci_sync.c +1 -1
@@ -1345,7 +1345,7 @@ int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)* Command Disallowed error, so we must first disable the * instance if it is active. */ -if (adv && !adv->pending) { +if (adv) { err =hci_disable_ext_adv_instance_sync (hdev, instance);if (err)return err;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 21/163 Bluetooth: hci_event: Fix not marking Broadcast Sink BIS as connected
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit c7349772c268ec3c91d83cbfbbcf63f1bd7c256c ]
Upon receiving HCI_EVT_LE_BIG_SYNC_ESTABLISHED with status 0x00 (success) the corresponding BIS hci_conn state shall be set to BT_CONNECTED otherwise they will be left with BT_OPEN which is invalid at that point, also create the debugfs and sysfs entries following the same logic as the likes of Broadcast Source BIS and CIS connections.
--- net/bluetooth/hci_event.c | 3 +++ 1 file changed, 3 insertions(+)
net/bluetooth/hci_event.c +3 -0
@@ -6945,7 +6945,10 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, bis->iso_qos.bcast.in.sdu =le16_to_cpu (ev->max_pdu);if (!ev->status) { + bis->state =BT_CONNECTED ;set_bit (HCI_CONN_BIG_SYNC , &bis->flags); +hci_debugfs_create_conn (bis); +hci_conn_add_sysfs (bis);hci_iso_setup_path (bis); } }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 22/163 pinctrl: amd: Clear GPIO debounce for suspend
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
[ Upstream commit 8ff4fb276e2384a87ae7f65f3c28e1e139dbb3fe ]
soc-button-array hardcodes a debounce value by means of gpio_keys which uses pinctrl-amd as a backend to program debounce for a GPIO.
This hardcoded value doesn't match what the firmware intended to be programmed in _AEI. The hardcoded debounce leads to problems waking from suspend. There isn't appetite to conditionalize the behavior in soc-button-array or gpio-keys so clear it when the system suspends to avoid problems with being able to resume.
--- drivers/pinctrl/pinctrl-amd.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/pinctrl/pinctrl-amd.c +11 -0
@@ -933,6 +933,17 @@ static int amd_gpio_suspend_hibernate_common(struct device *dev, bool is_suspend pin, is_suspend ? "suspend" : "hibernate"); } +/* +* debounce enabled over suspend has shown issues with a GPIO +* being unable to wake the system, as we're only interested in +* the actual wakeup event, clear it. +*/ +if (gpio_dev->saved_regs[i] & (DB_CNTRl_MASK <<DB_CNTRL_OFF )) { +amd_gpio_set_debounce (gpio_dev, pin,0 ); +pm_pr_dbg ("Clearing debounce for GPIO #%d during %s.\n" , + pin, is_suspend ?"suspend" :"hibernate" ); + } +raw_spin_unlock_irqrestore (&gpio_dev->lock, flags); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 23/163 fix proc_sys_compare() handling of in-lookup dentries
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
[ Upstream commit b969f9614885c20f903e1d1f9445611daf161d6d ]
There's one case where ->d_compare() can be called for an in-lookup dentry; usually that's nothing special from ->d_compare() point of view, but... proc_sys_compare() is weird.
The thing is, /proc/sys subdirectories can look differently for different processes. Up to and including having the same name resolve to different dentries - all of them hashed.
The way it's done is ->d_compare() refusing to admit a match unless this dentry is supposed to be visible to this caller. The information needed to discriminate between them is stored in inode; it is set during proc_sys_lookup() and until it's done d_splice_alias() we really can't tell who should that dentry be visible for.
Normally there's no negative dentries in /proc/sys; we can run into a dying dentry in RCU dcache lookup, but those can be safely rejected.
However, ->d_compare() is also called for in-lookup dentries, before they get positive - or hashed, for that matter. In case of match we will wait until dentry leaves in-lookup state and repeat ->d_compare() afterwards. In other words, the right behaviour is to treat the name match as sufficient for in-lookup dentries; if dentry is not for us, we'll see that when we recheck once proc_sys_lookup() is done with it.
While we are at it, fix the misspelled READ_ONCE and WRITE_ONCE there.
--- fs/proc/inode.c | 2 +- fs/proc/proc_sysctl.c | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-)
fs/proc/inode.c +1 -1
@@ -42,7 +42,7 @@ static void proc_evict_inode(struct inode *inode) head = ei->sysctl;if (head) { -RCU_INIT_POINTER (ei->sysctl,NULL ); +WRITE_ONCE (ei->sysctl,NULL );proc_sys_evict_inode (inode, head); } }
fs/proc/proc_sysctl.c +11 -7
@@ -911,17 +911,21 @@ static int proc_sys_compare(const struct dentry *dentry,struct ctl_table_header *head;struct inode *inode; -/* Although proc doesn't have negative dentries, rcu-walk means -* that inode here can be NULL */ -/* AV: can it, indeed? */ - inode =d_inode_rcu (dentry); -if (!inode) -return 1 ;if (name->len != len)return 1 ;if (memcmp (name->name, str, len))return 1 ; - head =rcu_dereference (PROC_I (inode)->sysctl); + +// false positive is fine here - we'll recheck anyway +if (d_in_lookup (dentry)) +return 0 ; + + inode =d_inode_rcu (dentry); +// we just might have run into dentry in the middle of __dentry_kill() +if (!inode) +return 1 ; + + head =READ_ONCE (PROC_I (inode)->sysctl);return !head || !sysctl_is_seen (head); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 24/163 sched/deadline: Fix dl_server runtime calculation formula
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: kuyo chang <[email protected]>
[ Upstream commit fc975cfb36393db1db517fbbe366e550bcdcff14 ]
In our testing with 6.12 based kernel on a big.LITTLE system, we were seeing instances of RT tasks being blocked from running on the LITTLE cpus for multiple seconds of time, apparently by the dl_server. This far exceeds the default configured 50ms per second runtime.
This is due to the fair dl_server runtime calculation being scaled for frequency & capacity of the cpu.
Consider the following case under a Big.LITTLE architecture:
Assume the runtime is: 50,000,000 ns, and Frequency/capacity scale-invariance defined as below:
Frequency scale-invariance: 100
Capacity scale-invariance: 50
First by Frequency scale-invariance,
the runtime is scaled to 50,000,000 * 100 >> 10 = 4,882,812 Then by capacity scale-invariance,
it is further scaled to 4,882,812 * 50 >> 10 = 238,418. So it will scaled to 238,418 ns.
This smaller "accounted runtime" value is what ends up being subtracted against the fair-server's runtime for the current period. Thus after 50ms of real time, we've only accounted ~238us against the fair servers runtime. This 209:1 ratio in this example means that on the smaller cpu the fair server is allowed to continue running, blocking RT tasks, for over 10 seconds before it exhausts its supposed 50ms of runtime. And on other hardware configurations it can be even worse.
For the fair deadline_server, to prevent realtime tasks from being unexpectedly delayed, we really do want to use fixed time, and not scaled time for smaller capacity/frequency cpus. So remove the scaling from the fair server's accounting to fix this.
--- kernel/sched/deadline.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
kernel/sched/deadline.c +5 -5
@@ -1485,7 +1485,9 @@ static void update_curr_dl_se(struct rq *rq, struct sched_dl_entity *dl_se, s64if (dl_entity_is_special (dl_se))return ; - scaled_delta_exec =dl_scaled_delta_exec (rq, dl_se, delta_exec); + scaled_delta_exec = delta_exec; +if (!dl_server (dl_se)) + scaled_delta_exec =dl_scaled_delta_exec (rq, dl_se, delta_exec); dl_se->runtime -= scaled_delta_exec;
@@ -1592,7 +1594,7 @@ static void update_curr_dl_se(struct rq *rq, struct sched_dl_entity *dl_se, s64*/ void dl_server_update_idle_time (struct rq *rq,struct task_struct *p) { -s64 delta_exec, scaled_delta_exec; +s64 delta_exec;if (!rq->fair_server.dl_defer)return ;
@@ -1605,9 +1607,7 @@ void dl_server_update_idle_time(struct rq *rq, struct task_struct *p)if (delta_exec <0 )return ; - scaled_delta_exec =dl_scaled_delta_exec (rq, &rq->fair_server, delta_exec); - - rq->fair_server.runtime -= scaled_delta_exec; + rq->fair_server.runtime -= delta_exec;if (rq->fair_server.runtime <0 ) { rq->fair_server.dl_defer_running =0 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 25/163 bnxt_en: eliminate the compile warning in bnxt_request_irq due to CONFIG_RFS_ACCEL
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Xing <[email protected]>
[ Upstream commit b9fd9888a5654e59f6c6249337e36c53c1faa329 ]
I received a kernel-test-bot report[1] that shows the [-Wunused-but-set-variable] warning. Since the previous commit I made, as the 'Fixes' tag shows, gives users an option to turn on and off the CONFIG_RFS_ACCEL, the issue then can be discovered and reproduced with GCC specifically.
Like Simon and Jakub suggested, use fewer #ifdefs which leads to fewer bugs.
[1]
All warnings (new ones prefixed by >>):
drivers/net/ethernet/broadcom/bnxt/bnxt.c: In function 'bnxt_request_irq':
Quoted 1 line
Quoted 1 line
drivers/net/ethernet/broadcom/bnxt/bnxt.c:10703:9: warning: variable 'j' set but not used [-Wunused-but-set-variable]
10703 | int i, j, rc = 0;
| ^
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +4 -6
@@ -11061,11 +11061,9 @@ static void bnxt_free_irq(struct bnxt *bp)static int bnxt_request_irq (struct bnxt *bp) { +struct cpu_rmap *rmap =NULL ;int i, j, rc =0 ;unsigned long flags =0 ; -#ifdef CONFIG_RFS_ACCEL -struct cpu_rmap *rmap; -#endif rc =bnxt_setup_int_mode (bp);if (rc) {
@@ -11080,15 +11078,15 @@ static int bnxt_request_irq(struct bnxt *bp)int map_idx =bnxt_cp_num_to_irq_num (bp, i);struct bnxt_irq *irq = &bp->irq_tbl[map_idx]; -#ifdef CONFIG_RFS_ACCEL -if (rmap && bp->bnapi[i]->rx_ring) { +if (IS_ENABLED (CONFIG_RFS_ACCEL ) && + rmap && bp->bnapi[i]->rx_ring) { rc =irq_cpu_rmap_add (rmap, irq->vector);if (rc)netdev_warn (bp->dev,"failed adding irq rmap for ring %d\n" , j); j++; } -#endif + rc =request_irq (irq->vector, irq->handler, flags, irq->name, bp->bnapi[i]);if (rc)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 26/163 arm64: poe: Handle spurious Overlay faults
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kevin Brodsky <[email protected]>
[ Upstream commit 22f3a4f6085951eff28bd1e44d3f388c1d9a5f44 ]
We do not currently issue an ISB after updating POR_EL0 when context-switching it, for instance. The rationale is that if the old value of POR_EL0 is more restrictive and causes a fault during uaccess, the access will be retried [1]. In other words, we are trading an ISB on every context-switching for the (unlikely) possibility of a spurious fault. We may also miss faults if the new value of POR_EL0 is more restrictive, but that's considered acceptable.
However, as things stand, a spurious Overlay fault results in uaccess failing right away since it causes fault_from_pkey() to return true. If an Overlay fault is reported, we therefore need to double check POR_EL0 against vma_pkey(vma) - this is what arch_vma_access_permitted() already does.
As it turns out, we already perform that explicit check if no Overlay fault is reported, and we need to keep that check (see comment added in fault_from_pkey()). Net result: the Overlay ISS2 bit isn't of much help to decide whether a pkey fault occurred.
Remove the check for the Overlay bit from fault_from_pkey() and add a comment to try and explain the situation. While at it, also add a comment to permission_overlay_switch() in case anyone gets surprised by the lack of ISB.
[1] https://lore.kernel.org/linux-arm-kernel/[email protected]/
--- arch/arm64/kernel/process.c | 5 +++++ arch/arm64/mm/fault.c | 30 +++++++++++++++++++++--------- 2 files changed, 26 insertions(+), 9 deletions(-)
arch/arm64/kernel/process.c +5 -0
@@ -544,6 +544,11 @@ static void permission_overlay_switch(struct task_struct *next) current->thread.por_el0 =read_sysreg_s (SYS_POR_EL0 );if (current->thread.por_el0 != next->thread.por_el0) {write_sysreg_s (next->thread.por_el0,SYS_POR_EL0 ); +/* +* No ISB required as we can tolerate spurious Overlay faults - +* the fault handler will check again based on the new value +* of POR_EL0. +*/ } }
arch/arm64/mm/fault.c +21 -9
@@ -487,17 +487,29 @@ static void do_bad_area(unsigned long far, unsigned long esr, } } -static bool fault_from_pkey (unsigned long esr,struct vm_area_struct *vma, -unsigned int mm_flags) +static bool fault_from_pkey (struct vm_area_struct *vma,unsigned int mm_flags) { -unsigned long iss2 =ESR_ELx_ISS2 (esr); -if (!system_supports_poe ())return false; -if (esr_fsc_is_permission_fault (esr) && (iss2 & ESR_ELx_Overlay)) -return true; - +/* +* We do not check whether an Overlay fault has occurred because we +* cannot make a decision based solely on its value: +* +* - If Overlay is set, a fault did occur due to POE, but it may be +* spurious in those cases where we update POR_EL0 without ISB (e.g. +* on context-switch). We would then need to manually check POR_EL0 +* against vma_pkey(vma), which is exactly what +* arch_vma_access_permitted() does. +* +* - If Overlay is not set, we may still need to report a pkey fault. +* This is the case if an access was made within a mapping but with no +* page mapped, and POR_EL0 forbids the access (according to +* vma_pkey()). Such access will result in a SIGSEGV regardless +* because core code checks arch_vma_access_permitted(), but in order +* to report the correct error code - SEGV_PKUERR - we must handle +* that case here. +*/ return !arch_vma_access_permitted(vma, mm_flags & FAULT_FLAG_WRITE, mm_flags & FAULT_FLAG_INSTRUCTION,
@@ -595,7 +607,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr, goto bad_area; } -if (fault_from_pkey (esr, vma, mm_flags)) { +if (fault_from_pkey (vma, mm_flags)) { pkey =vma_pkey (vma);vma_end_read (vma); fault =0 ;
@@ -639,7 +651,7 @@ static int __kprobes do_page_fault(unsigned long far, unsigned long esr, goto bad_area; } -if (fault_from_pkey (esr, vma, mm_flags)) { +if (fault_from_pkey (vma, mm_flags)) { pkey =vma_pkey (vma);mmap_read_unlock (mm); fault =0 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 27/163 net: phy: qcom: move the WoL function to shared library
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luo Jie <[email protected]>
[ Upstream commit e31cf3cce2102af984656fed6e2254cbdd46da02 ]
Move the WoL (Wake-on-LAN) functionality to a shared library to enable its reuse by the QCA808X PHY driver, incorporating support for WoL functionality similar to the implementation in at8031_set_wol().
Stable-dep-of: 4ab9ada765b7 ("net: phy: qcom: qca808x: Fix WoL issue by utilizing at8031_set_wol()")
--- drivers/net/phy/qcom/at803x.c | 27 --------------------------- drivers/net/phy/qcom/qcom-phy-lib.c | 25 +++++++++++++++++++++++++ drivers/net/phy/qcom/qcom.h | 5 +++++ 3 files changed, 30 insertions(+), 27 deletions(-)
drivers/net/phy/qcom/at803x.c +0 -27
@@ -26,9 +26,6 @@#define AT803X_LED_CONTROL 0x18 -#define AT803X_PHY_MMD3_WOL_CTRL 0x8012 -#define AT803X_WOL_EN BIT(5) -#define AT803X_REG_CHIP_CONFIG 0x1f#define AT803X_BT_BX_REG_SEL 0x8000
@@ -866,30 +863,6 @@ static int at8031_config_init(struct phy_device *phydev)return at803x_config_init (phydev); } -static int at8031_set_wol (struct phy_device *phydev, -struct ethtool_wolinfo *wol) -{ -int ret; - -/* First setup MAC address and enable WOL interrupt */ - ret =at803x_set_wol (phydev, wol); -if (ret) -return ret; - -if (wol->wolopts &WAKE_MAGIC ) -/* Enable WOL function for 1588 */ - ret =phy_modify_mmd (phydev,MDIO_MMD_PCS , -AT803X_PHY_MMD3_WOL_CTRL , -0 ,AT803X_WOL_EN ); -else -/* Disable WoL function for 1588 */ - ret =phy_modify_mmd (phydev,MDIO_MMD_PCS , -AT803X_PHY_MMD3_WOL_CTRL , -AT803X_WOL_EN ,0 ); - -return ret; -} -static int at8031_config_intr (struct phy_device *phydev) {struct at803x_priv *priv = phydev->priv;
drivers/net/phy/qcom/qcom-phy-lib.c +25 -0
@@ -115,6 +115,31 @@ int at803x_set_wol(struct phy_device *phydev, }EXPORT_SYMBOL_GPL (at803x_set_wol); +int at8031_set_wol (struct phy_device *phydev, +struct ethtool_wolinfo *wol) +{ +int ret; + +/* First setup MAC address and enable WOL interrupt */ + ret =at803x_set_wol (phydev, wol); +if (ret) +return ret; + +if (wol->wolopts &WAKE_MAGIC ) +/* Enable WOL function for 1588 */ + ret =phy_modify_mmd (phydev,MDIO_MMD_PCS , +AT803X_PHY_MMD3_WOL_CTRL , +0 ,AT803X_WOL_EN ); +else +/* Disable WoL function for 1588 */ + ret =phy_modify_mmd (phydev,MDIO_MMD_PCS , +AT803X_PHY_MMD3_WOL_CTRL , +AT803X_WOL_EN ,0 ); + +return ret; +} +EXPORT_SYMBOL_GPL (at8031_set_wol); +void at803x_get_wol (struct phy_device *phydev,struct ethtool_wolinfo *wol) {
drivers/net/phy/qcom/qcom.h +5 -0
@@ -172,6 +172,9 @@#define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B#define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A +#define AT803X_PHY_MMD3_WOL_CTRL 0x8012 +#define AT803X_WOL_EN BIT(5) +#define AT803X_DEBUG_ADDR 0x1D#define AT803X_DEBUG_DATA 0x1E
@@ -215,6 +218,8 @@ int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,int at803x_debug_reg_write (struct phy_device *phydev,u16 reg,u16 data);int at803x_set_wol (struct phy_device *phydev,struct ethtool_wolinfo *wol); +int at8031_set_wol (struct phy_device *phydev, +struct ethtool_wolinfo *wol);void at803x_get_wol (struct phy_device *phydev,struct ethtool_wolinfo *wol);int at803x_ack_interrupt (struct phy_device *phydev);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 28/163 net: phy: qcom: qca808x: Fix WoL issue by utilizing at8031_set_wol()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luo Jie <[email protected]>
[ Upstream commit 4ab9ada765b7acb5cd02fe27632ec2586b7868ee ]
The previous commit unintentionally removed the code responsible for enabling WoL via MMD3 register 0x8012 BIT5. As a result, Wake-on-LAN (WoL) support for the QCA808X PHY is no longer functional.
The WoL (Wake-on-LAN) feature for the QCA808X PHY is enabled via MMD3 register 0x8012, BIT5. This implementation is aligned with the approach used in at8031_set_wol().
--- drivers/net/phy/qcom/qca808x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/phy/qcom/qca808x.c +1 -1
@@ -633,7 +633,7 @@ static struct phy_driver qca808x_driver[] = { .handle_interrupt = at803x_handle_interrupt, .get_tunable = at803x_get_tunable, .set_tunable = at803x_set_tunable, - .set_wol = at803x_set_wol, + .set_wol = at8031_set_wol, .get_wol = at803x_get_wol, .get_features = qca808x_get_features, .config_aneg = qca808x_config_aneg,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 29/163 netlink: Fix wraparounds of sk->sk_rmem_alloc.
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit ae8f160e7eb24240a2a79fc4c815c6a0d4ee16cc ]
Netlink has this pattern in some places
if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf) atomic_add(skb->truesize, &sk->sk_rmem_alloc);
, which has the same problem fixed by commit 5a465a0da13e ("udp:
Fix multiple wraparounds of sk->sk_rmem_alloc.").
For example, if we set INT_MAX to SO_RCVBUFFORCE, the condition is always false as the two operands are of int.
Then, a single socket can eat as many skb as possible until OOM happens, and we can see multiple wraparounds of sk->sk_rmem_alloc.
Let's fix it by using atomic_add_return() and comparing the two variables as unsigned int.
Before:
[root@fedora ~]# ss -f netlink
Recv-Q Send-Q Local Address:Port Peer Address:Port
-1668710080 0 rtnl:nl_wraparound/293 *
After:
[root@fedora ~]# ss -f netlink
Recv-Q Send-Q Local Address:Port Peer Address:Port
2147483072 0 rtnl:nl_wraparound/290 *
^
`--- INT_MAX - 576
--- net/netlink/af_netlink.c | 81 ++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 32 deletions(-)
net/netlink/af_netlink.c +49 -32
@@ -387,7 +387,6 @@ static void netlink_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)WARN_ON (skb->sk !=NULL ); skb->sk = sk; skb->destructor = netlink_skb_destructor; -atomic_add (skb->truesize, &sk->sk_rmem_alloc);sk_mem_charge (sk, skb->truesize); }
@@ -1216,41 +1215,48 @@ struct sk_buff *netlink_alloc_large_skb(unsigned int size, int broadcast)int netlink_attachskb (struct sock *sk,struct sk_buff *skb,long *timeo,struct sock *ssk) { +DECLARE_WAITQUEUE (wait, current);struct netlink_sock *nlk; +unsigned int rmem; nlk =nlk_sk (sk); + rmem =atomic_add_return (skb->truesize, &sk->sk_rmem_alloc); -if ((atomic_read (&sk->sk_rmem_alloc) > sk->sk_rcvbuf || -test_bit (NETLINK_S_CONGESTED , &nlk->state))) { -DECLARE_WAITQUEUE (wait, current); -if (!*timeo) { -if (!ssk ||netlink_is_kernel (ssk)) -netlink_overrun (sk); -sock_put (sk); -kfree_skb (skb); -return -EAGAIN ; - } - -__set_current_state (TASK_INTERRUPTIBLE ); -add_wait_queue (&nlk->wait, &wait); +if ((rmem == skb->truesize || rmem <READ_ONCE (sk->sk_rcvbuf)) && + !test_bit (NETLINK_S_CONGESTED , &nlk->state)) { +netlink_skb_set_owner_r (skb, sk); +return 0 ; + } -if ((atomic_read (&sk->sk_rmem_alloc) > sk->sk_rcvbuf || -test_bit (NETLINK_S_CONGESTED , &nlk->state)) && - !sock_flag (sk,SOCK_DEAD )) - *timeo =schedule_timeout (*timeo); +atomic_sub (skb->truesize, &sk->sk_rmem_alloc); -__set_current_state (TASK_RUNNING ); -remove_wait_queue (&nlk->wait, &wait); +if (!*timeo) { +if (!ssk ||netlink_is_kernel (ssk)) +netlink_overrun (sk);sock_put (sk); +kfree_skb (skb); +return -EAGAIN ; + } -if (signal_pending (current)) { -kfree_skb (skb); -return sock_intr_errno (*timeo); - } -return 1 ; +__set_current_state (TASK_INTERRUPTIBLE ); +add_wait_queue (&nlk->wait, &wait); + rmem =atomic_read (&sk->sk_rmem_alloc); + +if (((rmem && rmem + skb->truesize >READ_ONCE (sk->sk_rcvbuf)) || +test_bit (NETLINK_S_CONGESTED , &nlk->state)) && + !sock_flag (sk,SOCK_DEAD )) + *timeo =schedule_timeout (*timeo); + +__set_current_state (TASK_RUNNING ); +remove_wait_queue (&nlk->wait, &wait); +sock_put (sk); + +if (signal_pending (current)) { +kfree_skb (skb); +return sock_intr_errno (*timeo); } -netlink_skb_set_owner_r (skb, sk); -return 0 ; + +return 1 ; }static int __netlink_sendskb (struct sock *sk,struct sk_buff *skb)
@@ -1310,6 +1316,7 @@ static int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb, ret = -ECONNREFUSED ;if (nlk->netlink_rcv !=NULL ) { ret = skb->len; +atomic_add (skb->truesize, &sk->sk_rmem_alloc);netlink_skb_set_owner_r (skb, sk);NETLINK_CB (skb).sk = ssk;netlink_deliver_tap_kernel (sk, ssk, skb);
@@ -1386,13 +1393,19 @@ EXPORT_SYMBOL_GPL(netlink_strict_get_check);static int netlink_broadcast_deliver (struct sock *sk,struct sk_buff *skb) {struct netlink_sock *nlk =nlk_sk (sk); +unsigned int rmem, rcvbuf; -if (atomic_read (&sk->sk_rmem_alloc) <= sk->sk_rcvbuf && + rmem =atomic_add_return (skb->truesize, &sk->sk_rmem_alloc); + rcvbuf =READ_ONCE (sk->sk_rcvbuf); + +if ((rmem != skb->truesize || rmem <= rcvbuf) && !test_bit (NETLINK_S_CONGESTED , &nlk->state)) {netlink_skb_set_owner_r (skb, sk);__netlink_sendskb (sk, skb); -return atomic_read (&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >>1 ); +return rmem > (rcvbuf >>1 ); } + +atomic_sub (skb->truesize, &sk->sk_rmem_alloc);return -1 ; }
@@ -2252,6 +2265,7 @@ static int netlink_dump(struct sock *sk, bool lock_taken)struct module *module;int err = -ENOBUFS ;int alloc_min_size; +unsigned int rmem;int alloc_size;if (!lock_taken)
@@ -2261,9 +2275,6 @@ static int netlink_dump(struct sock *sk, bool lock_taken) goto errout_skb; } -if (atomic_read (&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) - goto errout_skb; -/* NLMSG_GOODSIZE is small to avoid high order allocations being * required, but it makes sense to _attempt_ a 16K bytes allocation * to reduce number of system calls on dump operations, if user
@@ -2286,6 +2297,12 @@ static int netlink_dump(struct sock *sk, bool lock_taken)if (!skb) goto errout_skb; + rmem =atomic_add_return (skb->truesize, &sk->sk_rmem_alloc); +if (rmem >=READ_ONCE (sk->sk_rcvbuf)) { +atomic_sub (skb->truesize, &sk->sk_rmem_alloc); + goto errout_skb; + } +/* Trim skb to allocated size. User is expected to provide buffer as * large as max(min_dump_alloc, 16KiB (mac_recvmsg_len capped at * netlink_recvmsg())). dump will pack as many smaller messages as
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 30/163 vsock: fix `vsock_proto` declaration
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefano Garzarella <[email protected]>
[ Upstream commit 1e3b66e326015f77bc4b36976bebeedc2ac0f588 ]
Quoted 1 line
From commit
634f1a7110b4("vsock: support sockmap"), `struct proto
vsock_proto`, defined in af_vsock.c, is not static anymore, since it's used by vsock_bpf.c.
If CONFIG_BPF_SYSCALL is not defined, make C=2 will print a warning:
$ make O=build C=2 W=1 net/vmw_vsock/
...
CC [M] net/vmw_vsock/af_vsock.o
CHECK ../net/vmw_vsock/af_vsock.c
../net/vmw_vsock/af_vsock.c:123:14: warning: symbol 'vsock_proto' was not declared. Should it be static?Declare vsock_proto regardless of CONFIG_BPF_SYSCALL, since it's defined in af_vsock.c, which is built regardless of CONFIG_BPF_SYSCALL.
--- include/net/af_vsock.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/net/af_vsock.h +1 -1
@@ -242,8 +242,8 @@ int __vsock_dgram_recvmsg(struct socket *sock, struct msghdr *msg,int vsock_dgram_recvmsg (struct socket *sock,struct msghdr *msg,size_t len,int flags); -#ifdef CONFIG_BPF_SYSCALL extern struct proto vsock_proto; +#ifdef CONFIG_BPF_SYSCALL int vsock_bpf_update_proto (struct sock *sk,struct sk_psock *psock,bool restore);void __init vsock_bpf_build_proto (void );#else
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 31/163 tipc: Fix use-after-free in tipc_conn_close().
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 667eeab4999e981c96b447a4df5f20bdf5c26f13 ]
syzbot reported a null-ptr-deref in tipc_conn_close() during netns dismantle. [0]
tipc_topsrv_stop() iterates tipc_net(net)->topsrv->conn_idr and calls tipc_conn_close() for each tipc_conn.
The problem is that tipc_conn_close() is called after releasing the IDR lock.
At the same time, there might be tipc_conn_recv_work() running and it could call tipc_conn_close() for the same tipc_conn and release its last ->kref.
Once we release the IDR lock in tipc_topsrv_stop(), there is no guarantee that the tipc_conn is alive.
Let's hold the ref before releasing the lock and put the ref after tipc_conn_close() in tipc_topsrv_stop().
[0]:
BUG: KASAN: use-after-free in tipc_conn_close+0x122/0x140 net/tipc/topsrv.c:165
Read of size 8 at addr ffff888099305a08 by task kworker/u4:3/435
CPU: 0 PID: 435 Comm: kworker/u4:3 Not tainted 4.19.204-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Workqueue: netns cleanup_net
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x1fc/0x2ef lib/dump_stack.c:118
print_address_description.cold+0x54/0x219 mm/kasan/report.c:256
kasan_report_error.cold+0x8a/0x1b9 mm/kasan/report.c:354
kasan_report mm/kasan/report.c:412 [inline]
__asan_report_load8_noabort+0x88/0x90 mm/kasan/report.c:433
tipc_conn_close+0x122/0x140 net/tipc/topsrv.c:165
tipc_topsrv_stop net/tipc/topsrv.c:701 [inline]
tipc_topsrv_exit_net+0x27b/0x5c0 net/tipc/topsrv.c:722
ops_exit_list+0xa5/0x150 net/core/net_namespace.c:153
cleanup_net+0x3b4/0x8b0 net/core/net_namespace.c:553
process_one_work+0x864/0x1570 kernel/workqueue.c:2153
worker_thread+0x64c/0x1130 kernel/workqueue.c:2296
kthread+0x33f/0x460 kernel/kthread.c:259
ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:415
Allocated by task 23:
kmem_cache_alloc_trace+0x12f/0x380 mm/slab.c:3625
kmalloc include/linux/slab.h:515 [inline]
kzalloc include/linux/slab.h:709 [inline]
tipc_conn_alloc+0x43/0x4f0 net/tipc/topsrv.c:192
tipc_topsrv_accept+0x1b5/0x280 net/tipc/topsrv.c:470
process_one_work+0x864/0x1570 kernel/workqueue.c:2153
worker_thread+0x64c/0x1130 kernel/workqueue.c:2296
kthread+0x33f/0x460 kernel/kthread.c:259
ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:415
Freed by task 23:
__cache_free mm/slab.c:3503 [inline]
kfree+0xcc/0x210 mm/slab.c:3822
tipc_conn_kref_release net/tipc/topsrv.c:150 [inline]
kref_put include/linux/kref.h:70 [inline]
conn_put+0x2cd/0x3a0 net/tipc/topsrv.c:155
process_one_work+0x864/0x1570 kernel/workqueue.c:2153
worker_thread+0x64c/0x1130 kernel/workqueue.c:2296
kthread+0x33f/0x460 kernel/kthread.c:259
ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:415
The buggy address belongs to the object at ffff888099305a00
which belongs to the cache kmalloc-512 of size 512
The buggy address is located 8 bytes inside of
512-byte region [ffff888099305a00, ffff888099305c00)
The buggy address belongs to the page:
page:ffffea000264c140 count:1 mapcount:0 mapping:ffff88813bff0940 index:0x0
flags: 0xfff00000000100(slab)
raw: 00fff00000000100 ffffea00028b6b88 ffffea0002cd2b08 ffff88813bff0940
raw: 0000000000000000 ffff888099305000 0000000100000006 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff888099305900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff888099305980: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff888099305a00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff888099305a80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff888099305b00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb--- net/tipc/topsrv.c | 2 ++ 1 file changed, 2 insertions(+)
net/tipc/topsrv.c +2 -0
@@ -704,8 +704,10 @@ static void tipc_topsrv_stop(struct net *net)for (id =0 ; srv->idr_in_use; id++) { con =idr_find (&srv->conn_idr, id);if (con) { +conn_get (con);spin_unlock_bh (&srv->idr_lock);tipc_conn_close (con); +conn_put (con);spin_lock_bh (&srv->idr_lock); } }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 32/163 tcp: Correct signedness in skb remaining space calculation
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <[email protected]>
[ Upstream commit d3a5f2871adc0c61c61869f37f3e697d97f03d8c ]
Syzkaller reported a bug [1] where sk->sk_forward_alloc can overflow.
When we send data, if an skb exists at the tail of the write queue, the kernel will attempt to append the new data to that skb. However, the code that checks for available space in the skb is flawed:
'''
copy = size_goal - skb->len
'''
The types of the variables involved are:
'''
copy: ssize_t (s64 on 64-bit systems)size_goal: intskb->len: unsigned int
'''
Due to C's type promotion rules, the signed size_goal is converted to an unsigned int to match skb->len before the subtraction. The result is an unsigned int.
When this unsigned int result is then assigned to the s64 copy variable, it is zero-extended, preserving its non-negative value. Consequently, copy is always >= 0.
Assume we are sending 2GB of data and size_goal has been adjusted to a value smaller than skb->len. The subtraction will result in copy holding a very large positive integer. In the subsequent logic, this large value is used to update sk->sk_forward_alloc, which can easily cause it to overflow.
The syzkaller reproducer uses TCP_REPAIR to reliably create this condition. However, this can also occur in real-world scenarios. The tcp_bound_to_half_wnd() function can also reduce size_goal to a small value. This would cause the subsequent tcp_wmem_schedule() to set sk->sk_forward_alloc to a value close to INT_MAX. Further memory allocation requests would then cause sk_forward_alloc to wrap around and become negative.
[1]: https://syzkaller.appspot.com/bug?extid=de6565462ab540f50e47
--- net/ipv4/tcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/tcp.c +1 -1
@@ -1145,7 +1145,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size) goto do_error;while (msg_data_left (msg)) { -ssize_t copy =0 ; +int copy =0 ; skb =tcp_write_queue_tail (sk);if (skb)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 33/163 vsock: Fix transport_{g2h,h2g} TOCTOU
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Luczaj <[email protected]>
[ Upstream commit 209fd720838aaf1420416494c5505096478156b4 ]
vsock_find_cid() and vsock_dev_do_ioctl() may race with module unload. transport_{g2h,h2g} may become NULL after the NULL check.
Introduce vsock_transport_local_cid() to protect from a potential null-ptr-deref.
KASAN: null-ptr-deref in range [0x0000000000000118-0x000000000000011f] RIP: 0010:vsock_find_cid+0x47/0x90 Call Trace: __vsock_bind+0x4b2/0x720 vsock_bind+0x90/0xe0 __sys_bind+0x14d/0x1e0 __x64_sys_bind+0x6e/0xc0 do_syscall_64+0x92/0x1c0 entry_SYSCALL_64_after_hwframe+0x4b/0x53 KASAN: null-ptr-deref in range [0x0000000000000118-0x000000000000011f] RIP: 0010:vsock_dev_do_ioctl.isra.0+0x58/0xf0 Call Trace: __x64_sys_ioctl+0x12d/0x190 do_syscall_64+0x92/0x1c0 entry_SYSCALL_64_after_hwframe+0x4b/0x53
--- net/vmw_vsock/af_vsock.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-)
net/vmw_vsock/af_vsock.c +21 -6
@@ -531,9 +531,25 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk) }EXPORT_SYMBOL_GPL (vsock_assign_transport); +/* +* Provide safe access to static transport_{h2g,g2h,dgram,local} callbacks. +* Otherwise we may race with module removal. Do not use on `vsk->transport`. +*/ +static u32 vsock_registered_transport_cid (const struct vsock_transport **transport) +{ +u32 cid =VMADDR_CID_ANY ; + +mutex_lock (&vsock_register_mutex); +if (*transport) + cid = (*transport)->get_local_cid (); +mutex_unlock (&vsock_register_mutex); + +return cid; +} +bool vsock_find_cid (unsigned int cid) { -if (transport_g2h && cid == transport_g2h->get_local_cid ()) +if (cid ==vsock_registered_transport_cid (&transport_g2h))return true;if (transport_h2g && cid ==VMADDR_CID_HOST )
@@ -2502,18 +2518,17 @@ static long vsock_dev_do_ioctl(struct file *filp, unsigned int cmd, void __user *ptr) { u32 __user *p = ptr; -u32 cid =VMADDR_CID_ANY ;int retval =0 ; +u32 cid;switch (cmd) {case IOCTL_VM_SOCKETS_GET_LOCAL_CID :/* To be compatible with the VMCI behavior, we prioritize the * guest CID instead of well-know host CID (VMADDR_CID_HOST). */ -if (transport_g2h) - cid = transport_g2h->get_local_cid (); -else if (transport_h2g) - cid = transport_h2g->get_local_cid (); + cid =vsock_registered_transport_cid (&transport_g2h); +if (cid ==VMADDR_CID_ANY ) + cid =vsock_registered_transport_cid (&transport_h2g);if (put_user (cid, p) !=0 ) retval = -EFAULT ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 34/163 vsock: Fix transport_* TOCTOU
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Luczaj <[email protected]>
[ Upstream commit 687aa0c5581b8d4aa87fd92973e4ee576b550cdf ]
Transport assignment may race with module unload. Protect new_transport from becoming a stale pointer.
This also takes care of an insecure call in vsock_use_local_transport(); add a lockdep assert.
BUG: unable to handle page fault for address: fffffbfff8056000 Oops: Oops: 0000 [#1] SMP KASAN RIP: 0010:vsock_assign_transport+0x366/0x600 Call Trace: vsock_connect+0x59c/0xc40 __sys_connect+0xe8/0x100 __x64_sys_connect+0x6e/0xc0 do_syscall_64+0x92/0x1c0 entry_SYSCALL_64_after_hwframe+0x4b/0x53
--- net/vmw_vsock/af_vsock.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-)
net/vmw_vsock/af_vsock.c +23 -5
@@ -407,6 +407,8 @@ EXPORT_SYMBOL_GPL(vsock_enqueue_accept);static bool vsock_use_local_transport (unsigned int remote_cid) { +lockdep_assert_held (&vsock_register_mutex); +if (!transport_local)return false;
@@ -464,6 +466,8 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk) remote_flags = vsk->remote_addr.svm_flags; +mutex_lock (&vsock_register_mutex); +switch (sk->sk_type) {case SOCK_DGRAM : new_transport = transport_dgram;
@@ -479,12 +483,15 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk) new_transport = transport_h2g;break ;default : -return -ESOCKTNOSUPPORT ; + ret = -ESOCKTNOSUPPORT ; + goto err; }if (vsk->transport) { -if (vsk->transport == new_transport) -return 0 ; +if (vsk->transport == new_transport) { + ret =0 ; + goto err; + }/* transport->release() must be called with sock lock acquired. * This path can only be taken during vsock_connect(), where we
@@ -508,8 +515,16 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk)/* We increase the module refcnt to prevent the transport unloading * while there are open sockets assigned to it. */ -if (!new_transport || !try_module_get (new_transport->module)) -return -ENODEV ; +if (!new_transport || !try_module_get (new_transport->module)) { + ret = -ENODEV ; + goto err; + } + +/* It's safe to release the mutex after a successful try_module_get(). +* Whichever transport `new_transport` points at, it won't go away until +* the last module_put() below or in vsock_deassign_transport(). +*/ +mutex_unlock (&vsock_register_mutex);if (sk->sk_type ==SOCK_SEQPACKET ) { if (!new_transport->seqpacket_allow ||
@@ -528,6 +543,9 @@ int vsock_assign_transport(struct vsock_sock *vsk, struct vsock_sock *psk) vsk->transport = new_transport;return 0 ; +err: +mutex_unlock (&vsock_register_mutex); +return ret; }EXPORT_SYMBOL_GPL (vsock_assign_transport);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 35/163 vsock: Fix IOCTL_VM_SOCKETS_GET_LOCAL_CID to check also `transport_local`
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Luczaj <[email protected]>
[ Upstream commit 1e7d9df379a04ccd0c2f82f39fbb69d482e864cc ]
Support returning VMADDR_CID_LOCAL in case no other vsock transport is available.
--- net/vmw_vsock/af_vsock.c | 2 ++ 1 file changed, 2 insertions(+)
net/vmw_vsock/af_vsock.c +2 -0
@@ -2547,6 +2547,8 @@ static long vsock_dev_do_ioctl(struct file *filp, cid =vsock_registered_transport_cid (&transport_g2h);if (cid ==VMADDR_CID_ANY ) cid =vsock_registered_transport_cid (&transport_h2g); +if (cid ==VMADDR_CID_ANY ) + cid =vsock_registered_transport_cid (&transport_local);if (put_user (cid, p) !=0 ) retval = -EFAULT ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 36/163 net: stmmac: Fix interrupt handling for level-triggered mode in DWC_XGMAC2
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: EricChan <[email protected]>
[ Upstream commit 78b7920a03351a8402de2f81914c1d2e2bdf24b7 ]
According to the Synopsys Controller IP XGMAC-10G Ethernet MAC Databook v3.30a (section 2.7.2), when the INTM bit in the DMA_Mode register is set to 2, the sbd_perch_tx_intr_o[] and sbd_perch_rx_intr_o[] signals operate in level-triggered mode. However, in this configuration, the DMA does not assert the XGMAC_NIS status bit for Rx or Tx interrupt events.
This creates a functional regression where the condition
if (likely(intr_status & XGMAC_NIS)) in dwxgmac2_dma_interrupt() will never evaluate to true, preventing proper interrupt handling for level-triggered mode. The hardware specification explicitly states that "The DMA does not assert the NIS status bit for the Rx or Tx interrupt events" (Synopsys DWC_XGMAC2 Databook v3.30a, sec. 2.7.2).
The fix ensures correct handling of both edge and level-triggered interrupts while maintaining backward compatibility with existing configurations. It has been tested on the hardware device (not publicly available), and it can properly trigger the RX and TX interrupt handling in both the INTM=0 and INTM=2 configurations.
--- .../ethernet/stmicro/stmmac/dwxgmac2_dma.c | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-)
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c +11 -13
@@ -364,19 +364,17 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv, }/* TX/RX NORMAL interrupts */ -if (likely (intr_status &XGMAC_NIS )) { -if (likely (intr_status &XGMAC_RI )) { -u64_stats_update_begin (&stats->syncp); -u64_stats_inc (&stats->rx_normal_irq_n[chan]); -u64_stats_update_end (&stats->syncp); - ret |= handle_rx; - } -if (likely (intr_status & (XGMAC_TI |XGMAC_TBU ))) { -u64_stats_update_begin (&stats->syncp); -u64_stats_inc (&stats->tx_normal_irq_n[chan]); -u64_stats_update_end (&stats->syncp); - ret |= handle_tx; - } +if (likely (intr_status &XGMAC_RI )) { +u64_stats_update_begin (&stats->syncp); +u64_stats_inc (&stats->rx_normal_irq_n[chan]); +u64_stats_update_end (&stats->syncp); + ret |= handle_rx; + } +if (likely (intr_status & (XGMAC_TI |XGMAC_TBU ))) { +u64_stats_update_begin (&stats->syncp); +u64_stats_inc (&stats->tx_normal_irq_n[chan]); +u64_stats_update_end (&stats->syncp); + ret |= handle_tx; }/* Clear interrupts */
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 37/163 net: phy: smsc: Fix Auto-MDIX configuration when disabled by strap
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
[ Upstream commit a141af8eb2272ab0f677a7f2653874840bc9b214 ]
Correct the Auto-MDIX configuration to ensure userspace settings are respected when the feature is disabled by the AUTOMDIX_EN hardware strap.
The LAN9500 PHY allows its default MDI-X mode to be configured via a hardware strap. If this strap sets the default to "MDI-X off", the driver was previously unable to enable Auto-MDIX from userspace.
When handling the ETH_TP_MDI_AUTO case, the driver would set the SPECIAL_CTRL_STS_AMDIX_ENABLE_ bit but neglected to set the required SPECIAL_CTRL_STS_OVRRD_AMDIX_ bit. Without the override flag, the PHY falls back to its hardware strap default, ignoring the software request.
This patch corrects the behavior by also setting the override bit when enabling Auto-MDIX. This ensures that the userspace configuration takes precedence over the hardware strap, allowing Auto-MDIX to be enabled correctly in all scenarios.
--- drivers/net/phy/smsc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/phy/smsc.c +2 -1
@@ -167,7 +167,8 @@ static int lan87xx_config_aneg(struct phy_device *phydev)SPECIAL_CTRL_STS_AMDIX_STATE_ ;break ;case ETH_TP_MDI_AUTO : - val =SPECIAL_CTRL_STS_AMDIX_ENABLE_ ; + val =SPECIAL_CTRL_STS_OVRRD_AMDIX_ | +SPECIAL_CTRL_STS_AMDIX_ENABLE_ ;break ;default :return genphy_config_aneg (phydev);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 38/163 net: phy: smsc: Force predictable MDI-X state on LAN87xx
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
[ Upstream commit 0713e55533c88a20edb53eea6517dc56786a0078 ]
Override the hardware strap configuration for MDI-X mode to ensure a predictable initial state for the driver. The initial mode of the LAN87xx PHY is determined by the AUTOMDIX_EN strap pin, but the driver has no documented way to read its latched status.
This unpredictability means the driver cannot know if the PHY has initialized with Auto-MDIX enabled or disabled, preventing it from providing a reliable interface to the user.
This patch introduces a config_init hook that forces the PHY into a known state by explicitly enabling Auto-MDIX.
--- drivers/net/phy/smsc.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-)
drivers/net/phy/smsc.c +28 -1
@@ -262,6 +262,33 @@ int lan87xx_read_status(struct phy_device *phydev) }EXPORT_SYMBOL_GPL (lan87xx_read_status); +static int lan87xx_phy_config_init (struct phy_device *phydev) +{ +int rc; + +/* The LAN87xx PHY's initial MDI-X mode is determined by the AUTOMDIX_EN +* hardware strap, but the driver cannot read the strap's status. This +* creates an unpredictable initial state. +* +* To ensure consistent and reliable behavior across all boards, +* override the strap configuration on initialization and force the PHY +* into a known state with Auto-MDIX enabled, which is the expected +* default for modern hardware. +*/ + rc =phy_modify (phydev,SPECIAL_CTRL_STS , +SPECIAL_CTRL_STS_OVRRD_AMDIX_ | +SPECIAL_CTRL_STS_AMDIX_ENABLE_ | +SPECIAL_CTRL_STS_AMDIX_STATE_ , +SPECIAL_CTRL_STS_OVRRD_AMDIX_ | +SPECIAL_CTRL_STS_AMDIX_ENABLE_ ); +if (rc <0 ) +return rc; + + phydev->mdix_ctrl =ETH_TP_MDI_AUTO ; + +return smsc_phy_config_init (phydev); +} +static int lan874x_phy_config_init (struct phy_device *phydev) {u16 val;
@@ -695,7 +722,7 @@ static struct phy_driver smsc_phy_driver[] = {/* basic functions */ .read_status = lan87xx_read_status, - .config_init = smsc_phy_config_init, + .config_init = lan87xx_phy_config_init, .soft_reset = smsc_phy_reset, .config_aneg = lan87xx_config_aneg,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 39/163 net: phy: smsc: Fix link failure in forced mode with Auto-MDIX
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
[ Upstream commit 9dfe110cc0f6ef42af8e81ce52aef34a647d0b8a ]
Force a fixed MDI-X mode when auto-negotiation is disabled to prevent link instability.
When forcing the link speed and duplex on a LAN9500 PHY (e.g., with ethtool -s eth0 autoneg off ...) while leaving MDI-X control in auto mode, the PHY fails to establish a stable link. This occurs because the PHY's Auto-MDIX algorithm is not designed to operate when auto-negotiation is disabled. In this state, the PHY continuously toggles the TX/RX signal pairs, which prevents the link partner from synchronizing.
This patch resolves the issue by detecting when auto-negotiation is disabled. If the MDI-X control mode is set to 'auto', the driver now forces a specific, stable mode (ETH_TP_MDI) to prevent the pair toggling. This choice of a fixed MDI mode mirrors the behavior the hardware would exhibit if the AUTOMDIX_EN strap were configured for a fixed MDI connection.
--- drivers/net/phy/smsc.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-)
drivers/net/phy/smsc.c +22 -3
@@ -155,10 +155,29 @@ static int smsc_phy_reset(struct phy_device *phydev)static int lan87xx_config_aneg (struct phy_device *phydev) { -int rc; +u8 mdix_ctrl;int val; +int rc; + +/* When auto-negotiation is disabled (forced mode), the PHY's +* Auto-MDIX will continue toggling the TX/RX pairs. +* +* To establish a stable link, we must select a fixed MDI mode. +* If the user has not specified a fixed MDI mode (i.e., mdix_ctrl is +* 'auto'), we default to ETH_TP_MDI. This choice of a ETH_TP_MDI mode +* mirrors the behavior the hardware would exhibit if the AUTOMDIX_EN +* strap were configured for a fixed MDI connection. +*/ +if (phydev->autoneg ==AUTONEG_DISABLE ) { +if (phydev->mdix_ctrl ==ETH_TP_MDI_AUTO ) + mdix_ctrl =ETH_TP_MDI ; +else + mdix_ctrl = phydev->mdix_ctrl; + }else { + mdix_ctrl = phydev->mdix_ctrl; + } -switch (phydev->mdix_ctrl) { +switch (mdix_ctrl) {case ETH_TP_MDI : val =SPECIAL_CTRL_STS_OVRRD_AMDIX_ ;break ;
@@ -184,7 +203,7 @@ static int lan87xx_config_aneg(struct phy_device *phydev) rc |= val;phy_write (phydev,SPECIAL_CTRL_STS , rc); - phydev->mdix = phydev->mdix_ctrl; + phydev->mdix = mdix_ctrl;return genphy_config_aneg (phydev); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 40/163 atm: clip: Fix potential null-ptr-deref in to_atmarpd().
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 706cc36477139c1616a9b2b96610a8bb520b7119 ]
atmarpd is protected by RTNL since commit f3a0592b37b8 ("[ATM]: clip causes unregister hang").
However, it is not enough because to_atmarpd() is called without RTNL, especially clip_neigh_solicit() / neigh_ops->solicit() is unsleepable.
Also, there is no RTNL dependency around atmarpd.
Let's use a private mutex and RCU to protect access to atmarpd in to_atmarpd().
--- net/atm/clip.c | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-)
net/atm/clip.c +29 -15
@@ -45,7 +45,8 @@#include <net/atmclip.h> static struct net_device *clip_devs; -static struct atm_vcc *atmarpd; +static struct atm_vcc __rcu *atmarpd; +static DEFINE_MUTEX (atmarpd_lock);static struct timer_list idle_timer;static const struct neigh_ops clip_neigh_ops;
@@ -53,24 +54,35 @@ static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip) {struct sock *sk;struct atmarp_ctrl *ctrl; +struct atm_vcc *vcc;struct sk_buff *skb; +int err =0 ;pr_debug ("(%d)\n" , type); -if (!atmarpd) -return -EUNATCH ; + +rcu_read_lock (); + vcc =rcu_dereference (atmarpd); +if (!vcc) { + err = -EUNATCH ; + goto unlock; + } skb =alloc_skb (sizeof (struct atmarp_ctrl ),GFP_ATOMIC ); -if (!skb) -return -ENOMEM ; +if (!skb) { + err = -ENOMEM ; + goto unlock; + } ctrl =skb_put (skb,sizeof (struct atmarp_ctrl )); ctrl->type = type; ctrl->itf_num = itf; ctrl->ip = ip; -atm_force_charge (atmarpd, skb->truesize); +atm_force_charge (vcc, skb->truesize); - sk =sk_atm (atmarpd); + sk =sk_atm (vcc);skb_queue_tail (&sk->sk_receive_queue, skb); sk->sk_data_ready (sk); -return 0 ; +unlock: +rcu_read_unlock (); +return err; }static void link_vcc (struct clip_vcc *clip_vcc,struct atmarp_entry *entry)
@@ -607,10 +619,12 @@ static void atmarpd_close(struct atm_vcc *vcc) {pr_debug ("\n" ); -rtnl_lock (); - atmarpd =NULL ; +mutex_lock (&atmarpd_lock); +RCU_INIT_POINTER (atmarpd,NULL ); +mutex_unlock (&atmarpd_lock); + +synchronize_rcu ();skb_queue_purge (&sk_atm (vcc)->sk_receive_queue); -rtnl_unlock ();pr_debug ("(done)\n" );module_put (THIS_MODULE );
@@ -631,15 +645,15 @@ static struct atm_dev atmarpd_dev = {static int atm_init_atmarp (struct atm_vcc *vcc) { -rtnl_lock (); +mutex_lock (&atmarpd_lock);if (atmarpd) { -rtnl_unlock (); +mutex_unlock (&atmarpd_lock);return -EADDRINUSE ; }mod_timer (&idle_timer, jiffies +CLIP_CHECK_INTERVAL *HZ ); - atmarpd = vcc; +rcu_assign_pointer (atmarpd, vcc);set_bit (ATM_VF_META , &vcc->flags);set_bit (ATM_VF_READY , &vcc->flags);/* allow replies and avoid getting closed if signaling dies */
@@ -648,7 +662,7 @@ static int atm_init_atmarp(struct atm_vcc *vcc) vcc->push =NULL ; vcc->pop =NULL ;/* crash */ vcc->push_oam =NULL ;/* crash */ -rtnl_unlock (); +mutex_unlock (&atmarpd_lock);return 0 ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 41/163 atm: clip: Fix memory leak of struct clip_vcc.
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 62dba28275a9a3104d4e33595c7b3328d4032d8d ]
ioctl(ATMARP_MKIP) allocates struct clip_vcc and set it to vcc->user_back.
The code assumes that vcc_destroy_socket() passes NULL skb to vcc->push() when the socket is close()d, and then clip_push() frees clip_vcc.
However, ioctl(ATMARPD_CTRL) sets NULL to vcc->push() in atm_init_atmarp(), resulting in memory leak.
Let's serialise two ioctl() by lock_sock() and check vcc->push() in atm_init_atmarp() to prevent memleak.
--- net/atm/clip.c | 8 ++++++++ 1 file changed, 8 insertions(+)
net/atm/clip.c +8 -0
@@ -645,6 +645,9 @@ static struct atm_dev atmarpd_dev = {static int atm_init_atmarp (struct atm_vcc *vcc) { +if (vcc->push == clip_push) +return -EINVAL ; +mutex_lock (&atmarpd_lock);if (atmarpd) {mutex_unlock (&atmarpd_lock);
@@ -669,6 +672,7 @@ static int atm_init_atmarp(struct atm_vcc *vcc)static int clip_ioctl (struct socket *sock,unsigned int cmd,unsigned long arg) {struct atm_vcc *vcc =ATM_SD (sock); +struct sock *sk = sock->sk;int err =0 ;switch (cmd) {
@@ -689,14 +693,18 @@ static int clip_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) err =clip_create (arg);break ;case ATMARPD_CTRL : +lock_sock (sk); err =atm_init_atmarp (vcc);if (!err) { sock->state =SS_CONNECTED ;__module_get (THIS_MODULE ); } +release_sock (sk);break ;case ATMARP_MKIP : +lock_sock (sk); err =clip_mkip (vcc, arg); +release_sock (sk);break ;case ATMARP_SETENTRY : err =clip_setentry (vcc, (__force __be32 )arg);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 42/163 atm: clip: Fix infinite recursive call of clip_push().
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit c489f3283dbfc0f3c00c312149cae90d27552c45 ]
syzbot reported the splat below. [0]
This happens if we call ioctl(ATMARP_MKIP) more than once.
During the first call, clip_mkip() sets clip_push() to vcc->push(), and the second call copies it to clip_vcc->old_push().
Later, when the socket is close()d, vcc_destroy_socket() passes NULL skb to clip_push(), which calls clip_vcc->old_push(), triggering the infinite recursion.
Let's prevent the second ioctl(ATMARP_MKIP) by checking vcc->user_back, which is allocated by the first call as clip_vcc.
Note also that we use lock_sock() to prevent racy calls.
[0]:
BUG: TASK stack guard page was hit at ffffc9000d66fff8 (stack is ffffc9000d670000..ffffc9000d678000) Oops: stack guard page: 0000 [#1] SMP KASAN NOPTI CPU: 0 UID: 0 PID: 5322 Comm: syz.0.0 Not tainted 6.16.0-rc4-syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 RIP: 0010:clip_push+0x5/0x720 net/atm/clip.c:191 Code: e0 8f aa 8c e8 1c ad 5b fa eb ae 66 2e 0f 1f 84 00 00 00 00 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 55 <41> 57 41 56 41 55 41 54 53 48 83 ec 20 48 89 f3 49 89 fd 48 bd 00 RSP: 0018:ffffc9000d670000 EFLAGS: 00010246 RAX: 1ffff1100235a4a5 RBX: ffff888011ad2508 RCX: ffff8880003c0000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff888037f01000 RBP: dffffc0000000000 R08: ffffffff8fa104f7 R09: 1ffffffff1f4209e R10: dffffc0000000000 R11: ffffffff8a99b300 R12: ffffffff8a99b300 R13: ffff888037f01000 R14: ffff888011ad2500 R15: ffff888037f01578 FS: 000055557ab6d500(0000) GS:ffff88808d250000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffc9000d66fff8 CR3: 0000000043172000 CR4: 0000000000352ef0 Call Trace: <TASK> clip_push+0x6dc/0x720 net/atm/clip.c:200 clip_push+0x6dc/0x720 net/atm/clip.c:200 clip_push+0x6dc/0x720 net/atm/clip.c:200 ... clip_push+0x6dc/0x720 net/atm/clip.c:200 clip_push+0x6dc/0x720 net/atm/clip.c:200 clip_push+0x6dc/0x720 net/atm/clip.c:200 vcc_destroy_socket net/atm/common.c:183 [inline] vcc_release+0x157/0x460 net/atm/common.c:205 __sock_release net/socket.c:647 [inline] sock_close+0xc0/0x240 net/socket.c:1391 __fput+0x449/0xa70 fs/file_table.c:465 task_work_run+0x1d1/0x260 kernel/task_work.c:227 resume_user_mode_work include/linux/resume_user_mode.h:50 [inline] exit_to_user_mode_loop+0xec/0x110 kernel/entry/common.c:114 exit_to_user_mode_prepare include/linux/entry-common.h:330 [inline] syscall_exit_to_user_mode_work include/linux/entry-common.h:414 [inline] syscall_exit_to_user_mode include/linux/entry-common.h:449 [inline] do_syscall_64+0x2bd/0x3b0 arch/x86/entry/syscall_64.c:100 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7ff31c98e929 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fffb5aa1f78 EFLAGS: 00000246 ORIG_RAX: 00000000000001b4 RAX: 0000000000000000 RBX: 0000000000012747 RCX: 00007ff31c98e929 RDX: 0000000000000000 RSI: 000000000000001e RDI: 0000000000000003 RBP: 00007ff31cbb7ba0 R08: 0000000000000001 R09: 0000000db5aa226f R10: 00007ff31c7ff030 R11: 0000000000000246 R12: 00007ff31cbb608c R13: 00007ff31cbb6080 R14: ffffffffffffffff R15: 00007fffb5aa2090 </TASK> Modules linked in:
--- net/atm/clip.c | 2 ++ 1 file changed, 2 insertions(+)
net/atm/clip.c +2 -0
@@ -429,6 +429,8 @@ static int clip_mkip(struct atm_vcc *vcc, int timeout)if (!vcc->push)return -EBADFD ; +if (vcc->user_back) +return -EINVAL ; clip_vcc =kmalloc (sizeof (struct clip_vcc ),GFP_KERNEL );if (!clip_vcc)return -ENOMEM ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 43/163 atm: clip: Fix NULL pointer dereference in vcc_sendmsg()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yue Haibing <[email protected]>
[ Upstream commit 22fc46cea91df3dce140a7dc6847c6fcf0354505 ]
atmarpd_dev_ops does not implement the send method, which may cause crash as bellow.
BUG: kernel NULL pointer dereference, address: 0000000000000000 PGD 0 P4D 0 Oops: Oops: 0010 [#1] SMP KASAN NOPTI CPU: 0 UID: 0 PID: 5324 Comm: syz.0.0 Not tainted 6.15.0-rc6-syzkaller-00346-g5723cc3450bc #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 RIP: 0010:0x0 Code: Unable to access opcode bytes at 0xffffffffffffffd6. RSP: 0018:ffffc9000d3cf778 EFLAGS: 00010246 RAX: 1ffffffff1910dd1 RBX: 00000000000000c0 RCX: dffffc0000000000 RDX: ffffc9000dc82000 RSI: ffff88803e4c4640 RDI: ffff888052cd0000 RBP: ffffc9000d3cf8d0 R08: ffff888052c9143f R09: 1ffff1100a592287 R10: dffffc0000000000 R11: 0000000000000000 R12: 1ffff92001a79f00 R13: ffff888052cd0000 R14: ffff88803e4c4640 R15: ffffffff8c886e88 FS: 00007fbc762566c0(0000) GS:ffff88808d6c2000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffffffffffffd6 CR3: 0000000041f1b000 CR4: 0000000000352ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> vcc_sendmsg+0xa10/0xc50 net/atm/common.c:644 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg+0x219/0x270 net/socket.c:727 ____sys_sendmsg+0x52d/0x830 net/socket.c:2566 ___sys_sendmsg+0x21f/0x2a0 net/socket.c:2620 __sys_sendmmsg+0x227/0x430 net/socket.c:2709 __do_sys_sendmmsg net/socket.c:2736 [inline] __se_sys_sendmmsg net/socket.c:2733 [inline] __x64_sys_sendmmsg+0xa0/0xc0 net/socket.c:2733 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xf6/0x210 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f
--- net/atm/clip.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
net/atm/clip.c +9 -1
@@ -632,8 +632,16 @@ static void atmarpd_close(struct atm_vcc *vcc)module_put (THIS_MODULE ); } +static int atmarpd_send (struct atm_vcc *vcc,struct sk_buff *skb) +{ +atm_return_tx (vcc, skb); +dev_kfree_skb_any (skb); +return 0 ; +} +static const struct atmdev_ops atmarpd_dev_ops = { - .close = atmarpd_close + .close = atmarpd_close, + .send = atmarpd_send };
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 44/163 net: ethernet: ti: am65-cpsw-nuss: Fix skb size by accounting for skb_shared_info
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chintan Vankar <[email protected]>
[ Upstream commit 02c4d6c26f1f662da8885b299c224ca6628ad232 ]
While transitioning from netdev_alloc_ip_align() to build_skb(), memory for the "skb_shared_info" member of an "skb" was not allocated. Fix this by allocating "PAGE_SIZE" as the skb length, accounting for the packet length, headroom and tailroom, thereby including the required memory space for skb_shared_info.
--- drivers/net/ethernet/ti/am65-cpsw-nuss.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/net/ethernet/ti/am65-cpsw-nuss.c +1 -3
@@ -612,8 +612,6 @@ static struct sk_buff *am65_cpsw_build_skb(void *page_addr, {struct sk_buff *skb; - len +=AM65_CPSW_HEADROOM ; - skb =build_skb (page_addr, len);if (unlikely (!skb))return NULL ;
@@ -1217,7 +1215,7 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_rx_flow *flow, } skb =am65_cpsw_build_skb (page_addr, ndev, -AM65_CPSW_MAX_PACKET_SIZE , headroom); +PAGE_SIZE , headroom);if (unlikely (!skb)) { new_page = page; goto requeue;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 45/163 net/sched: Abort __tc_modify_qdisc if parent class does not exist
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Nogueira <[email protected]>
[ Upstream commit ffdde7bf5a439aaa1955ebd581f5c64ab1533963 ]
Lion's patch [1] revealed an ancient bug in the qdisc API. Whenever a user creates/modifies a qdisc specifying as a parent another qdisc, the qdisc API will, during grafting, detect that the user is not trying to attach to a class and reject. However grafting is performed after qdisc_create (and thus the qdiscs' init callback) is executed. In qdiscs that eventually call qdisc_tree_reduce_backlog during init or change (such as fq, hhf, choke, etc), an issue arises. For example, executing the following commands:
sudo tc qdisc add dev lo root handle a: htb default 2 sudo tc qdisc add dev lo parent a: handle beef fq
Qdiscs such as fq, hhf, choke, etc unconditionally invoke qdisc_tree_reduce_backlog() in their control path init() or change() which then causes a failure to find the child class; however, that does not stop the unconditional invocation of the assumed child qdisc's qlen_notify with a null class. All these qdiscs make the assumption that class is non-null.
The solution is ensure that qdisc_leaf() which looks up the parent class, and is invoked prior to qdisc_create(), should return failure on not finding the class.
In this patch, we leverage qdisc_leaf to return ERR_PTRs whenever the parentid doesn't correspond to a class, so that we can detect it earlier on and abort before qdisc_create is called.
[1] https://lore.kernel.org/netdev/[email protected]/
--- net/sched/sch_api.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-)
net/sched/sch_api.c +16 -7
@@ -334,17 +334,22 @@ struct Qdisc *qdisc_lookup_rcu(struct net_device *dev, u32 handle)return q; } -static struct Qdisc *qdisc_leaf (struct Qdisc *p,u32 classid) +static struct Qdisc *qdisc_leaf (struct Qdisc *p,u32 classid, +struct netlink_ext_ack *extack) {unsigned long cl;const struct Qdisc_class_ops *cops = p->ops->cl_ops; -if (cops ==NULL ) -return NULL ; +if (cops ==NULL ) { +NL_SET_ERR_MSG (extack,"Parent qdisc is not classful" ); +return ERR_PTR (-EOPNOTSUPP ); + } cl = cops->find (p, classid); -if (cl ==0 ) -return NULL ; +if (cl ==0 ) { +NL_SET_ERR_MSG (extack,"Specified class not found" ); +return ERR_PTR (-ENOENT ); + }return cops->leaf (p, cl); }
@@ -1526,7 +1531,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,NL_SET_ERR_MSG (extack,"Failed to find qdisc with specified classid" );return -ENOENT ; } - q =qdisc_leaf (p, clid); + q =qdisc_leaf (p, clid, extack); }else if (dev_ingress_queue (dev)) { q =rtnl_dereference (dev_ingress_queue (dev)->qdisc_sleeping); }
@@ -1537,6 +1542,8 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,NL_SET_ERR_MSG (extack,"Cannot find specified qdisc on specified device" );return -ENOENT ; } +if (IS_ERR (q)) +return PTR_ERR (q);if (tcm->tcm_handle && q->handle != tcm->tcm_handle) {NL_SET_ERR_MSG (extack,"Invalid handle" );
@@ -1630,7 +1637,9 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,NL_SET_ERR_MSG (extack,"Failed to find specified qdisc" );return -ENOENT ; } - q =qdisc_leaf (p, clid); + q =qdisc_leaf (p, clid, extack); +if (IS_ERR (q)) +return PTR_ERR (q); }else if (dev_ingress_queue_create (dev)) { q =rtnl_dereference (dev_ingress_queue (dev)->qdisc_sleeping); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 46/163 rxrpc: Fix bug due to prealloc collision
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit 69e4186773c6445b258fb45b6e1df18df831ec45 ]
When userspace is using AF_RXRPC to provide a server, it has to preallocate incoming calls and assign to them call IDs that will be used to thread related recvmsg() and sendmsg() together. The preallocated call IDs will automatically be attached to calls as they come in until the pool is empty.
To the kernel, the call IDs are just arbitrary numbers, but userspace can use the call ID to hold a pointer to prepared structs. In any case, the user isn't permitted to create two calls with the same call ID (call IDs become available again when the call ends) and EBADSLT should result from sendmsg() if an attempt is made to preallocate a call with an in-use call ID.
However, the cleanup in the error handling will trigger both assertions in rxrpc_cleanup_call() because the call isn't marked complete and isn't marked as having been released.
Fix this by setting the call state in rxrpc_service_prealloc_one() and then marking it as being released before calling the cleanup function.
--- net/rxrpc/call_accept.c | 1 + 1 file changed, 1 insertion(+)
net/rxrpc/call_accept.c +1 -0
@@ -149,6 +149,7 @@ static int rxrpc_service_prealloc_one(struct rxrpc_sock *rx, id_in_use:write_unlock (&rx->call_lock); +rxrpc_prefail_call (call,RXRPC_CALL_LOCAL_ERROR , -EBADSLT );rxrpc_cleanup_call (call);_leave (" = -EBADSLT" );return -EBADSLT ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 47/163 rxrpc: Fix oops due to non-existence of prealloc backlog struct
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
commit 880a88f318cf1d2a0f4c0a7ff7b07e2062b434a4 upstream.
If an AF_RXRPC service socket is opened and bound, but calls are preallocated, then rxrpc_alloc_incoming_call() will oops because the rxrpc_backlog struct doesn't get allocated until the first preallocation is made.
Fix this by returning NULL from rxrpc_alloc_incoming_call() if there is no backlog struct. This will cause the incoming call to be aborted.
--- net/rxrpc/call_accept.c | 3 +++ 1 file changed, 3 insertions(+)
net/rxrpc/call_accept.c +3 -0
@@ -254,6 +254,9 @@ static struct rxrpc_call *rxrpc_alloc_inunsigned short call_tail, conn_tail, peer_tail;unsigned short call_count, conn_count; +if (!b) +return NULL ; +/* #calls >= #conns >= #peers must hold true. */ call_head =smp_load_acquire (&b->call_backlog_head); call_tail = b->call_backlog_tail;
Greg Kroah-Hartman
maintainerPATCH 48/163 ipmi:msghandler: Fix potential memory corruption in ipmi_create_user()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit fa332f5dc6fc662ad7d3200048772c96b861cf6b upstream.
The "intf" list iterator is an invalid pointer if the correct "intf->intf_num" is not found. Calling atomic_dec(&intf->nr_users) on and invalid pointer will lead to memory corruption.
We don't really need to call atomic_dec() if we haven't called atomic_add_return() so update the if (intf->in_shutdown) path as well.
Message-ID: <[email protected]>
[ - Dropped change to the if (intf->in_shutdown) block since that logic
doesn't exist yet.
- Modified out_unlock to release the srcu lock instead of the mutex since we don't have the mutex here yet. ]
--- drivers/char/ipmi/ipmi_msghandler.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/char/ipmi/ipmi_msghandler.c +2 -1
@@ -1241,7 +1241,7 @@ int ipmi_create_user(unsigned int }/* Not found, return an error */ rv = -EINVAL ; - goto out_kfree; + goto out_unlock; found:if (atomic_add_return (1 , &intf->nr_users) > max_users) {
@@ -1283,6 +1283,7 @@ int ipmi_create_user(unsigned int out_kfree:atomic_dec (&intf->nr_users); +out_unlock:srcu_read_unlock (&ipmi_interfaces_srcu, index);vfree (new_user);return rv;
Greg Kroah-Hartman
maintainerPATCH 49/163 x86/mce/amd: Add default names for MCA banks and blocks
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yazen Ghannam <[email protected]>
commit d66e1e90b16055d2f0ee76e5384e3f119c3c2773 upstream.
Ensure that sysfs init doesn't fail for new/unrecognized bank types or if a bank has additional blocks available.
Most MCA banks have a single thresholding block, so the block takes the same name as the bank.
Unified Memory Controllers (UMCs) are a special case where there are two blocks and each has a unique name.
However, the microarchitecture allows for five blocks. Any new MCA bank types with more than one block will be missing names for the extra blocks. The MCE sysfs will fail to initialize in this case.
--- arch/x86/kernel/cpu/mce/amd.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
arch/x86/kernel/cpu/mce/amd.c +10 -3
@@ -1099,13 +1099,20 @@ static const char *get_name(unsigned int } bank_type =smca_get_bank_type (cpu, bank); -if (bank_type >=N_SMCA_BANK_TYPES ) -return NULL ;if (b && (bank_type ==SMCA_UMC || bank_type ==SMCA_UMC_V2 )) {if (b->block <ARRAY_SIZE (smca_umc_block_names))return smca_umc_block_names[b->block]; -return NULL ; + } + +if (b && b->block) { +snprintf (buf_mcatype,MAX_MCATYPE_NAME_LEN ,"th_block_%u" , b->block); +return buf_mcatype; + } + +if (bank_type >=N_SMCA_BANK_TYPES ) { +snprintf (buf_mcatype,MAX_MCATYPE_NAME_LEN ,"th_bank_%u" , bank); +return buf_mcatype; }if (per_cpu (smca_bank_counts, cpu)[bank_type] ==1 )
Greg Kroah-Hartman
maintainerPATCH 50/163 x86/mce/amd: Fix threshold limit reset
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yazen Ghannam <[email protected]>
commit 5f6e3b720694ad771911f637a51930f511427ce1 upstream.
The MCA threshold limit must be reset after servicing the interrupt.
Currently, the restart function doesn't have an explicit check for this. It makes some assumptions based on the current limit and what's in the registers. These assumptions don't always hold, so the limit won't be reset in some cases.
Make the reset condition explicit. Either an interrupt/overflow has occurred or the bank is being initialized.
--- arch/x86/kernel/cpu/mce/amd.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
arch/x86/kernel/cpu/mce/amd.c +7 -8
@@ -327,7 +327,6 @@ static void smca_configure(unsigned intstruct thresh_restart {struct threshold_block *b; -int reset;int set_lvt_off;int lvt_off;u16 old_limit;
@@ -422,13 +421,13 @@ static void threshold_restart_bank(voidrdmsr (tr->b->address, lo, hi); -if (tr->b->threshold_limit < (hi &THRESHOLD_MAX )) - tr->reset =1 ;/* limit cannot be lower than err count */ - -if (tr->reset) {/* reset err count and overflow bit */ - hi = - (hi & ~(MASK_ERR_COUNT_HI |MASK_OVERFLOW_HI )) | - (THRESHOLD_MAX - tr->b->threshold_limit); +/* +* Reset error count and overflow bit. +* This is done during init or after handling an interrupt. +*/ +if (hi &MASK_OVERFLOW_HI || tr->set_lvt_off) { + hi &= ~(MASK_ERR_COUNT_HI |MASK_OVERFLOW_HI ); + hi |=THRESHOLD_MAX - tr->b->threshold_limit; }else if (tr->old_limit) {/* change limit w/o reset */ int new_count = (hi &THRESHOLD_MAX ) + (tr->old_limit - tr->b->threshold_limit);
Greg Kroah-Hartman
maintainerPATCH 51/163 x86/mce: Dont remove sysfs if thresholding sysfs init fails
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yazen Ghannam <[email protected]>
commit 4c113a5b28bfd589e2010b5fc8867578b0135ed7 upstream.
Currently, the MCE subsystem sysfs interface will be removed if the thresholding sysfs interface fails to be created. A common failure is due to new MCA bank types that are not recognized and don't have a short name set.
The MCA thresholding feature is optional and should not break the common MCE sysfs interface. Also, new MCA bank types are occasionally introduced, and updates will be needed to recognize them. But likewise, this should not break the common sysfs interface.
Keep the MCE sysfs interface regardless of the status of the thresholding sysfs interface.
--- arch/x86/kernel/cpu/mce/core.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
arch/x86/kernel/cpu/mce/core.c +1 -7
@@ -2756,15 +2756,9 @@ static int mce_cpu_dead(unsigned int cpustatic int mce_cpu_online (unsigned int cpu) {struct timer_list *t =this_cpu_ptr (&mce_timer); -int ret;mce_device_create (cpu); - - ret =mce_threshold_create_device (cpu); -if (ret) { -mce_device_remove (cpu); -return ret; - } +mce_threshold_create_device (cpu);mce_reenable_cpu ();mce_start_timer (t);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 52/163 x86/mce: Ensure user polling settings are honored when restarting timer
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yazen Ghannam <[email protected]>
commit 00c092de6f28ebd32208aef83b02d61af2229b60 upstream.
Users can disable MCA polling by setting the "ignore_ce" parameter or by setting "check_interval=0". This tells the kernel to *not* start the MCE timer on a CPU.
If the user did not disable CMCI, then storms can occur. When these happen, the MCE timer will be started with a fixed interval. After the storm subsides, the timer's next interval is set to check_interval.
This disregards the user's input through "ignore_ce" and "check_interval". Furthermore, if "check_interval=0", then the new timer will run faster than expected.
Create a new helper to check these conditions and use it when a CMCI storm ends.
[ bp: Massage. ]
--- arch/x86/kernel/cpu/mce/core.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-)
arch/x86/kernel/cpu/mce/core.c +10 -6
@@ -1688,6 +1688,11 @@ static void mc_poll_banks_default(void)void (*mc_poll_banks)(void ) = mc_poll_banks_default; +static bool should_enable_timer (unsigned long iv) +{ +return !mca_cfg.ignore_ce && iv; +} +static void mce_timer_fn (struct timer_list *t) {struct timer_list *cpu_t =this_cpu_ptr (&mce_timer);
@@ -1711,7 +1716,7 @@ static void mce_timer_fn(struct timer_liif (mce_get_storm_mode ()) {__start_timer (t,HZ ); - }else { + }else if (should_enable_timer (iv)) {__this_cpu_write (mce_next_interval, iv);__start_timer (t, iv); }
@@ -2111,11 +2116,10 @@ static void mce_start_timer(struct timer {unsigned long iv = check_interval *HZ ; -if (mca_cfg.ignore_ce || !iv) -return ; - -this_cpu_write (mce_next_interval, iv); -__start_timer (t, iv); +if (should_enable_timer (iv)) { +this_cpu_write (mce_next_interval, iv); +__start_timer (t, iv); + } }static void __mcheck_cpu_setup_timer (void )
Greg Kroah-Hartman
maintainerPATCH 53/163 x86/mce: Make sure CMCI banks are cleared during shutdown on Intel
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: JP Kobryn <[email protected]>
commit 30ad231a5029bfa16e46ce868497b1a5cdd3c24d upstream.
CMCI banks are not cleared during shutdown on Intel CPUs. As a side effect, when a kexec is performed, CPUs coming back online are unable to rediscover/claim these occupied banks which breaks MCE reporting.
Clear the CPU ownership during shutdown via cmci_clear() so the banks can be reclaimed and MCE reporting will become functional once more.
[ bp: Massage commit message. ]
--- arch/x86/kernel/cpu/mce/intel.c | 1 + 1 file changed, 1 insertion(+)
arch/x86/kernel/cpu/mce/intel.c +1 -0
@@ -477,6 +477,7 @@ void mce_intel_feature_init(struct cpuinvoid mce_intel_feature_clear (struct cpuinfo_x86 *c) {intel_clear_lmce (); +cmci_clear (); }bool intel_filter_mce (struct mce *m)
Greg Kroah-Hartman
maintainerPATCH 54/163 KVM: x86/xen: Allow out of range event channel ports in IRQ routing table.
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Woodhouse <[email protected]>
commit a7f4dff21fd744d08fa956c243d2b1795f23cbf7 upstream.
To avoid imposing an ordering constraint on userspace, allow 'invalid' event channel targets to be configured in the IRQ routing table.
This is the same as accepting interrupts targeted at vCPUs which don't exist yet, which is already the case for both Xen event channels *and* for MSIs (which don't do any filtering of permitted APIC ID targets at all).
If userspace actually *triggers* an IRQ with an invalid target, that will fail cleanly, as kvm_xen_set_evtchn_fast() also does the same range check.
If KVM enforced that the IRQ target must be valid at the time it is *configured*, that would force userspace to create all vCPUs and do various other parts of setup (in this case, setting the Xen long_mode) before restoring the IRQ table.
--- arch/x86/kvm/xen.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
arch/x86/kvm/xen.c +13 -2
@@ -1916,8 +1916,19 @@ int kvm_xen_setup_evtchn(struct kvm *kvm {struct kvm_vcpu *vcpu; -if (ue->u.xen_evtchn.port >=max_evtchn_port (kvm)) -return -EINVAL ; +/* +* Don't check for the port being within range of max_evtchn_port(). +* Userspace can configure what ever targets it likes; events just won't +* be delivered if/while the target is invalid, just like userspace can +* configure MSIs which target non-existent APICs. +* +* This allow on Live Migration and Live Update, the IRQ routing table +* can be restored *independently* of other things like creating vCPUs, +* without imposing an ordering dependency on userspace. In this +* particular case, the problematic ordering would be with setting the +* Xen 'long mode' flag, which changes max_evtchn_port() to allow 4096 +* instead of 1024 event channels. +*/ /* We only support 2 level event channels for now */ if (ue->u.xen_evtchn.priority !=KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL )
Greg Kroah-Hartman
maintainerPATCH 55/163 KVM: SVM: Add missing member in SNP_LAUNCH_START command structure
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikunj A Dadhania <[email protected]>
commit 51a4273dcab39dd1e850870945ccec664352d383 upstream.
The sev_data_snp_launch_start structure should include a 4-byte desired_tsc_khz field before the gosvw field, which was missed in the initial implementation. As a result, the structure is 4 bytes shorter than expected by the firmware, causing the gosvw field to start 4 bytes early. Fix this by adding the missing 4-byte member for the desired TSC frequency.
--- include/linux/psp-sev.h | 2 ++ 1 file changed, 2 insertions(+)
include/linux/psp-sev.h +2 -0
@@ -594,6 +594,7 @@ struct sev_data_snp_addr {* @imi_en: launch flow is launching an IMI (Incoming Migration Image) for the * purpose of guest-assisted migration. * @rsvd: reserved +* @desired_tsc_khz: hypervisor desired mean TSC freq in kHz of the guest * @gosvw: guest OS-visible workarounds, as defined by hypervisor */ struct sev_data_snp_launch_start {
@@ -603,6 +604,7 @@ struct sev_data_snp_launch_start { u32 ma_en:1; /* In */ u32 imi_en:1; /* In */ u32 rsvd:30; +u32 desired_tsc_khz;/* In */ u8 gosvw[16 ];/* In */ } __packed;
Greg Kroah-Hartman
maintainerPATCH 56/163 KVM: SVM: Reject SEV{-ES} intra host migration if vCPU creation is in-flight
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit ecf371f8b02d5e31b9aa1da7f159f1b2107bdb01 upstream.
Reject migration of SEV{-ES} state if either the source or destination VM is actively creating a vCPU, i.e. if kvm_vm_ioctl_create_vcpu() is in the section between incrementing created_vcpus and online_vcpus. The bulk of vCPU creation runs _outside_ of kvm->lock to allow creating multiple vCPUs in parallel, and so sev_info.es_active can get toggled from false=>true in the destination VM after (or during) svm_vcpu_create(), resulting in an SEV{-ES} VM effectively having a non-SEV{-ES} vCPU.
The issue manifests most visibly as a crash when trying to free a vCPU's NULL VMSA page in an SEV-ES VM, but any number of things can go wrong.
BUG: unable to handle page fault for address: ffffebde00000000 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: Oops: 0000 [#1] SMP KASAN NOPTI CPU: 227 UID: 0 PID: 64063 Comm: syz.5.60023 Tainted: G U O 6.15.0-smp-DEV #2 NONE Tainted: [U]=USER, [O]=OOT_MODULE Hardware name: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 12.52.0-0 10/28/2024 RIP: 0010:constant_test_bit arch/x86/include/asm/bitops.h:206 [inline] RIP: 0010:arch_test_bit arch/x86/include/asm/bitops.h:238 [inline] RIP: 0010:_test_bit include/asm-generic/bitops/instrumented-non-atomic.h:142 [inline] RIP: 0010:PageHead include/linux/page-flags.h:866 [inline] RIP: 0010:___free_pages+0x3e/0x120 mm/page_alloc.c:5067 Code: <49> f7 06 40 00 00 00 75 05 45 31 ff eb 0c 66 90 4c 89 f0 4c 39 f0 RSP: 0018:ffff8984551978d0 EFLAGS: 00010246 RAX: 0000777f80000001 RBX: 0000000000000000 RCX: ffffffff918aeb98 RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffffebde00000000 RBP: 0000000000000000 R08: ffffebde00000007 R09: 1ffffd7bc0000000 R10: dffffc0000000000 R11: fffff97bc0000001 R12: dffffc0000000000 R13: ffff8983e19751a8 R14: ffffebde00000000 R15: 1ffffd7bc0000000 FS: 0000000000000000(0000) GS:ffff89ee661d3000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffebde00000000 CR3: 000000793ceaa000 CR4: 0000000000350ef0 DR0: 0000000000000000 DR1: 0000000000000b5f DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Call Trace: <TASK> sev_free_vcpu+0x413/0x630 arch/x86/kvm/svm/sev.c:3169 svm_vcpu_free+0x13a/0x2a0 arch/x86/kvm/svm/svm.c:1515 kvm_arch_vcpu_destroy+0x6a/0x1d0 arch/x86/kvm/x86.c:12396 kvm_vcpu_destroy virt/kvm/kvm_main.c:470 [inline] kvm_destroy_vcpus+0xd1/0x300 virt/kvm/kvm_main.c:490 kvm_arch_destroy_vm+0x636/0x820 arch/x86/kvm/x86.c:12895 kvm_put_kvm+0xb8e/0xfb0 virt/kvm/kvm_main.c:1310 kvm_vm_release+0x48/0x60 virt/kvm/kvm_main.c:1369 __fput+0x3e4/0x9e0 fs/file_table.c:465 task_work_run+0x1a9/0x220 kernel/task_work.c:227 exit_task_work include/linux/task_work.h:40 [inline] do_exit+0x7f0/0x25b0 kernel/exit.c:953 do_group_exit+0x203/0x2d0 kernel/exit.c:1102 get_signal+0x1357/0x1480 kernel/signal.c:3034 arch_do_signal_or_restart+0x40/0x690 arch/x86/kernel/signal.c:337 exit_to_user_mode_loop kernel/entry/common.c:111 [inline] exit_to_user_mode_prepare include/linux/entry-common.h:329 [inline] __syscall_exit_to_user_mode_work kernel/entry/common.c:207 [inline] syscall_exit_to_user_mode+0x67/0xb0 kernel/entry/common.c:218 do_syscall_64+0x7c/0x150 arch/x86/entry/syscall_64.c:100 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7f87a898e969 </TASK> Modules linked in: gq(O) gsmi: Log Shutdown Reason 0x03 CR2: ffffebde00000000 ---[ end trace 0000000000000000 ]---
Deliberately don't check for a NULL VMSA when freeing the vCPU, as crashing the host is likely desirable due to the VMSA being consumed by hardware. E.g. if KVM manages to allow VMRUN on the vCPU, hardware may read/write a bogus VMSA page. Accessing PFN 0 is "fine"-ish now that it's sequestered away thanks to L1TF, but panicking in this scenario is preferable to potentially running with corrupted state.
--- arch/x86/kvm/svm/sev.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/x86/kvm/svm/sev.c +4 -0
@@ -2058,6 +2058,10 @@ static int sev_check_source_vcpus(structstruct kvm_vcpu *src_vcpu;unsigned long i; +if (src->created_vcpus !=atomic_read (&src->online_vcpus) || + dst->created_vcpus !=atomic_read (&dst->online_vcpus)) +return -EBUSY ; +if (!sev_es_guest (src))return 0 ;
Greg Kroah-Hartman
maintainerPATCH 57/163 KVM: Allow CPU to reschedule while setting per-page memory attributes
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liam Merwick <[email protected]>
commit 47bb584237cc285e3a860b70c01f7bda9dcfb05b upstream.
When running an SEV-SNP guest with a sufficiently large amount of memory (1TB+), the host can experience CPU soft lockups when running an operation in kvm_vm_set_mem_attributes() to set memory attributes on the whole range of guest memory.
watchdog: BUG: soft lockup - CPU#8 stuck for 26s! [qemu-kvm:6372] CPU: 8 UID: 0 PID: 6372 Comm: qemu-kvm Kdump: loaded Not tainted 6.15.0-rc7.20250520.el9uek.rc1.x86_64 #1 PREEMPT(voluntary) Hardware name: Oracle Corporation ORACLE SERVER E4-2c/Asm,MB Tray,2U,E4-2c, BIOS 78016600 11/13/2024 RIP: 0010:xas_create+0x78/0x1f0 Code: 00 00 00 41 80 fc 01 0f 84 82 00 00 00 ba 06 00 00 00 bd 06 00 00 00 49 8b 45 08 4d 8d 65 08 41 39 d6 73 20 83 ed 06 48 85 c0 <74> 67 48 89 c2 83 e2 03 48 83 fa 02 75 0c 48 3d 00 10 00 00 0f 87 RSP: 0018:ffffad890a34b940 EFLAGS: 00000286 RAX: ffff96f30b261daa RBX: ffffad890a34b9c8 RCX: 0000000000000000 RDX: 000000000000001e RSI: 0000000000000000 RDI: 0000000000000000 RBP: 0000000000000018 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: ffffad890a356868 R13: ffffad890a356860 R14: 0000000000000000 R15: ffffad890a356868 FS: 00007f5578a2a400(0000) GS:ffff97ed317e1000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f015c70fb18 CR3: 00000001109fd006 CR4: 0000000000f70ef0 PKRU: 55555554 Call Trace: <TASK> xas_store+0x58/0x630 __xa_store+0xa5/0x130 xa_store+0x2c/0x50 kvm_vm_set_mem_attributes+0x343/0x710 [kvm] kvm_vm_ioctl+0x796/0xab0 [kvm] __x64_sys_ioctl+0xa3/0xd0 do_syscall_64+0x8c/0x7a0 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7f5578d031bb Code: ff ff ff 85 c0 79 9b 49 c7 c4 ff ff ff ff 5b 5d 4c 89 e0 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 2d 4c 0f 00 f7 d8 64 89 01 48 RSP: 002b:00007ffe0a742b88 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 000000004020aed2 RCX: 00007f5578d031bb RDX: 00007ffe0a742c80 RSI: 000000004020aed2 RDI: 000000000000000b RBP: 0000010000000000 R08: 0000010000000000 R09: 0000017680000000 R10: 0000000000000080 R11: 0000000000000246 R12: 00005575e5f95120 R13: 00007ffe0a742c80 R14: 0000000000000008 R15: 00005575e5f961e0
While looping through the range of memory setting the attributes, call cond_resched() to give the scheduler a chance to run a higher priority task on the runqueue if necessary and avoid staying in kernel mode long enough to trigger the lockup.
--- virt/kvm/kvm_main.c | 3 +++ 1 file changed, 3 insertions(+)
virt/kvm/kvm_main.c +3 -0
@@ -2557,6 +2557,8 @@ static int kvm_vm_set_mem_attributes(str r =xa_reserve (&kvm->mem_attr_array, i,GFP_KERNEL_ACCOUNT );if (r) goto out_unlock; + +cond_resched (); }kvm_handle_gfn_range (kvm, &pre_set_range);
@@ -2565,6 +2567,7 @@ static int kvm_vm_set_mem_attributes(str r =xa_err (xa_store (&kvm->mem_attr_array, i, entry,GFP_KERNEL_ACCOUNT ));KVM_BUG_ON (r, kvm); +cond_resched (); }kvm_handle_gfn_range (kvm, &post_set_range);
Greg Kroah-Hartman
maintainerPATCH 58/163 ALSA: ad1816a: Fix potential NULL pointer deref in snd_card_ad1816a_pnp()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
commit 043faef334a1f3d96ae88e1b7618bfa2b4946388 upstream.
Use pr_warn() instead of dev_warn() when 'pdev' is NULL to avoid a potential NULL pointer dereference.
--- sound/isa/ad1816a/ad1816a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/isa/ad1816a/ad1816a.c +1 -1
@@ -98,7 +98,7 @@ static int snd_card_ad1816a_pnp(int dev, struct pnp_card_link *card, pdev =pnp_request_card_device (card, id->devs[1 ].id,NULL );if (pdev ==NULL ) { mpu_port[dev] =-1 ; -dev_warn (&pdev->dev,"MPU401 device busy, skipping.\n" ); +pr_warn ("MPU401 device busy, skipping.\n" );return 0 ; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 59/163 ASoC: fsl_sai: Force a software reset when starting in consumer mode
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arun Raghavan <[email protected]>
commit dc78f7e59169d3f0e6c3c95d23dc8e55e95741e2 upstream.
On an imx8mm platform with an external clock provider, when running the receiver (arecord) and triggering an xrun with xrun_injection, we see a channel swap/offset. This happens sometimes when running only the receiver, but occurs reliably if a transmitter (aplay) is also concurrently running.
It seems that the SAI loses track of frame sync during the trigger stop -> trigger start cycle that occurs during an xrun. Doing just a FIFO reset in this case does not suffice, and only a software reset seems to get it back on track.
This looks like the same h/w bug that is already handled for the producer case, so we now do the reset unconditionally on config disable.
--- sound/soc/fsl/fsl_sai.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
sound/soc/fsl/fsl_sai.c +8 -6
@@ -771,13 +771,15 @@ static void fsl_sai_config_disable(struc* anymore. Add software reset to fix this issue. * This is a hardware bug, and will be fix in the * next sai version. +* +* In consumer mode, this can happen even after a +* single open/close, especially if both tx and rx +* are running concurrently. */ -if (!sai->is_consumer_mode[tx]) { -/* Software Reset */ -regmap_write (sai->regmap,FSL_SAI_xCSR (tx, ofs),FSL_SAI_CSR_SR ); -/* Clear SR bit to finish the reset */ -regmap_write (sai->regmap,FSL_SAI_xCSR (tx, ofs),0 ); - } +/* Software Reset */ +regmap_write (sai->regmap,FSL_SAI_xCSR (tx, ofs),FSL_SAI_CSR_SR ); +/* Clear SR bit to finish the reset */ +regmap_write (sai->regmap,FSL_SAI_xCSR (tx, ofs),0 ); } static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
Greg Kroah-Hartman
maintainerPATCH 60/163 gre: Fix IPv6 multicast route creation.
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Nault <[email protected]>
commit 4e914ef063de40397e25a025c70d9737a9e45a8c upstream.
Use addrconf_add_dev() instead of ipv6_find_idev() in addrconf_gre_config() so that we don't just get the inet6_dev, but also install the default ff00::/8 multicast route.
Before commit 3e6a0243ff00 ("gre: Fix again IPv6 link-local address generation."), the multicast route was created at the end of the function by addrconf_add_mroute(). But this code path is now only taken in one particular case (gre devices not bound to a local IP address and in EUI64 mode). For all other cases, the function exits early and addrconf_add_mroute() is not called anymore.
Using addrconf_add_dev() instead of ipv6_find_idev() in addrconf_gre_config(), fixes the problem as it will create the default multicast route for all gre devices. This also brings addrconf_gre_config() a bit closer to the normal netdevice IPv6 configuration code (addrconf_dev_config()).
--- net/ipv6/addrconf.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
net/ipv6/addrconf.c +2 -7
@@ -3548,11 +3548,9 @@ static void addrconf_gre_config(struct nASSERT_RTNL (); - idev =ipv6_find_idev (dev); -if (IS_ERR (idev)) { -pr_debug ("%s: add_dev failed\n" , __func__); + idev =addrconf_add_dev (dev); +if (IS_ERR (idev))return ; - }/* Generate the IPv6 link-local address using addrconf_addr_gen(), * unless we have an IPv4 GRE device not bound to an IP address and
@@ -3566,9 +3564,6 @@ static void addrconf_gre_config(struct n }add_v4_addrs (idev); - -if (dev->flags &IFF_POINTOPOINT ) -addrconf_add_mroute (dev); }#endif
Greg Kroah-Hartman
maintainerPATCH 61/163 net: ethernet: rtsn: Fix a null pointer dereference in rtsn_probe()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li <[email protected]>
commit 95a234f6affbf51f06338383537ab80d637bb785 upstream.
Add check for the return value of rcar_gen4_ptp_alloc() to prevent potential null pointer dereference.
--- drivers/net/ethernet/renesas/rtsn.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/ethernet/renesas/rtsn.c +5 -0
@@ -1259,7 +1259,12 @@ static int rtsn_probe(struct platform_device *pdev) priv =netdev_priv (ndev); priv->pdev = pdev; priv->ndev = ndev; + priv->ptp_priv =rcar_gen4_ptp_alloc (pdev); +if (!priv->ptp_priv) { + ret = -ENOMEM ; + goto error_free; + }spin_lock_init (&priv->lock);platform_set_drvdata (pdev, priv);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 62/163 md/md-bitmap: fix GPF in bitmap_get_stats()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Håkon Bugge <[email protected]>
commit c17fb542dbd1db745c9feac15617056506dd7195 upstream.
The commit message of commit 6ec1f0239485 ("md/md-bitmap: fix stats collection for external bitmaps") states:
Remove the external bitmap check as the statistics should be available regardless of bitmap storage location.
Return -EINVAL only for invalid bitmap with no storage (neither in superblock nor in external file).
But, the code does not adhere to the above, as it does only check for a valid super-block for "internal" bitmaps. Hence, we observe:
Oops: GPF, probably for non-canonical address 0x1cd66f1f40000028 RIP: 0010:bitmap_get_stats+0x45/0xd0 Call Trace: seq_read_iter+0x2b9/0x46a seq_read+0x12f/0x180 proc_reg_read+0x57/0xb0 vfs_read+0xf6/0x380 ksys_read+0x6d/0xf0 do_syscall_64+0x8c/0x1b0 entry_SYSCALL_64_after_hwframe+0x76/0x7e
We fix this by checking the existence of a super-block for both the internal and external case.
--- drivers/md/md-bitmap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/md/md-bitmap.c +1 -2
@@ -2355,8 +2355,7 @@ static int bitmap_get_stats(void *data,if (!bitmap)return -ENOENT ; -if (!bitmap->mddev->bitmap_info.external && - !bitmap->storage.sb_page) +if (!bitmap->storage.sb_page)return -EINVAL ; sb =kmap_local_page (bitmap->storage.sb_page); stats->sync_size =le64_to_cpu (sb->sync_size);
Greg Kroah-Hartman
maintainerPATCH 63/163 pinctrl: qcom: msm: mark certain pins as invalid for interrupts
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
commit 93712205ce2f1fb047739494c0399a26ea4f0890 upstream.
On some platforms, the UFS-reset pin has no interrupt logic in TLMM but is nevertheless registered as a GPIO in the kernel. This enables the user-space to trigger a BUG() in the pinctrl-msm driver by running, for
example: gpiomon -c 0 113 on RB2.
The exact culprit is requesting pins whose intr_detection_width setting is not 1 or 2 for interrupts. This hits a BUG() in msm_gpio_irq_set_type(). Potentially crashing the kernel due to an invalid request from user-space is not optimal, so let's go through the pins and mark those that would fail the check as invalid for the irq chip as we should not even register them as available irqs.
This function can be extended if we determine that there are more corner-cases like this.
--- drivers/pinctrl/qcom/pinctrl-msm.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
drivers/pinctrl/qcom/pinctrl-msm.c +20 -0
@@ -1035,6 +1035,25 @@ static bool msm_gpio_needs_dual_edge_partest_bit (d->hwirq, pctrl->skip_wake_irqs); } +static void msm_gpio_irq_init_valid_mask (struct gpio_chip *gc, +unsigned long *valid_mask, +unsigned int ngpios) +{ +struct msm_pinctrl *pctrl =gpiochip_get_data (gc); +const struct msm_pingroup *g; +int i; + +bitmap_fill (valid_mask, ngpios); + +for (i =0 ; i < ngpios; i++) { + g = &pctrl->soc->groups[i]; + +if (g->intr_detection_width !=1 && + g->intr_detection_width !=2 ) +clear_bit (i, valid_mask); + } +} +static int msm_gpio_irq_set_type (struct irq_data *d,unsigned int type) {struct gpio_chip *gc =irq_data_get_irq_chip_data (d);
@@ -1438,6 +1457,7 @@ static int msm_gpio_init(struct msm_pinc girq->default_type =IRQ_TYPE_NONE ; girq->handler = handle_bad_irq; girq->parents[0 ] = pctrl->irq; + girq->init_valid_mask = msm_gpio_irq_init_valid_mask; ret =gpiochip_add_data (&pctrl->chip, pctrl);if (ret) {
Greg Kroah-Hartman
maintainerPATCH 64/163 pwm: Fix invalid state detection
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
commit 9ee124caae1b0defd0e02c65686f539845a3ac9b upstream.
Commit 9dd42d019e63 ("pwm: Allow pwm state transitions from an invalid state") intended to allow some state transitions that were not allowed before. The idea is sane and back then I also got the code comment right, but the check for enabled is bogus. This resulted in state transitions for enabled states to be allowed to have invalid duty/period settings and thus it can happen that low-level drivers get requests for invalid states🙄.
Invert the check to allow state transitions for disabled states only.
--- drivers/pwm/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pwm/core.c +1 -1
@@ -148,7 +148,7 @@ static bool pwm_state_valid(const struct* and supposed to be ignored. So also ignore any strange values and * consider the state ok. */ -if (state->enabled) +if (!state->enabled)return true;if (!state->period)
Greg Kroah-Hartman
maintainerPATCH 65/163 pwm: mediatek: Ensure to disable clocks in error path
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <[email protected]>
commit 505b730ede7f5c4083ff212aa955155b5b92e574 upstream.
After enabling the clocks each error path must disable the clocks again. One of them failed to do so. Unify the error paths to use goto to make it harder for future changes to add a similar bug.
--- drivers/pwm/pwm-mediatek.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/pwm/pwm-mediatek.c +8 -5
@@ -130,8 +130,10 @@ static int pwm_mediatek_config(struct pwreturn ret; clk_rate =clk_get_rate (pc->clk_pwms[pwm->hwpwm]); -if (!clk_rate) -return -EINVAL ; +if (!clk_rate) { + ret = -EINVAL ; + goto out; + }/* Make sure we use the bus clock and not the 26MHz clock */ if (pc->soc->has_ck_26m_sel)
@@ -150,9 +152,9 @@ static int pwm_mediatek_config(struct pw }if (clkdiv >PWM_CLK_DIV_MAX ) { -pwm_mediatek_clk_disable (chip, pwm);dev_err (pwmchip_parent (chip),"period of %d ns not supported\n" , period_ns); -return -EINVAL ; + ret = -EINVAL ; + goto out; }if (pc->soc->pwm45_fixup && pwm->hwpwm >2 ) {
@@ -169,9 +171,10 @@ static int pwm_mediatek_config(struct pwpwm_mediatek_writel (pc, pwm->hwpwm, reg_width, cnt_period);pwm_mediatek_writel (pc, pwm->hwpwm, reg_thres, cnt_duty); +out:pwm_mediatek_clk_disable (chip, pwm); -return 0 ; +return ret; }static int pwm_mediatek_enable (struct pwm_chip *chip,struct pwm_device *pwm)
Greg Kroah-Hartman
maintainerPATCH 66/163 wifi: prevent A-MSDU attacks in mesh networks
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathy Vanhoef <[email protected]>
commit 737bb912ebbe4571195c56eba557c4d7315b26fb upstream.
This patch is a mitigation to prevent the A-MSDU spoofing vulnerability for mesh networks. The initial update to the IEEE 802.11 standard, in response to the FragAttacks, missed this case (CVE-2025-27558). It can be considered a variant of CVE-2020-24588 but for mesh networks.
This patch tries to detect if a standard MSDU was turned into an A-MSDU by an adversary. This is done by parsing a received A-MSDU as a standard MSDU, calculating the length of the Mesh Control header, and seeing if the 6 bytes after this header equal the start of an rfc1042 header. If equal, this is a strong indication of an ongoing attack attempt.
This defense was tested with mac80211_hwsim against a mesh network that uses an empty Mesh Address Extension field, i.e., when four addresses are used, and when using a 12-byte Mesh Address Extension field, i.e., when six addresses are used. Functionality of normal MSDUs and A-MSDUs was also tested, and confirmed working, when using both an empty and 12-byte Mesh Address Extension field.
It was also tested with mac80211_hwsim that A-MSDU attacks in non-mesh networks keep being detected and prevented.
Note that the vulnerability being patched, and the defense being implemented, was also discussed in the following paper and in the following IEEE 802.11 presentation:
https://papers.mathyvanhoef.com/wisec2025.pdf
https://mentor.ieee.org/802.11/dcn/25/11-25-0949-00-000m-a-msdu-mesh-spoof-protection.docx
--- net/wireless/util.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-)
net/wireless/util.c +50 -2
@@ -820,6 +820,52 @@ bool ieee80211_is_valid_amsdu(struct sk_ }EXPORT_SYMBOL (ieee80211_is_valid_amsdu); + +/* +* Detects if an MSDU frame was maliciously converted into an A-MSDU +* frame by an adversary. This is done by parsing the received frame +* as if it were a regular MSDU, even though the A-MSDU flag is set. +* +* For non-mesh interfaces, detection involves checking whether the +* payload, when interpreted as an MSDU, begins with a valid RFC1042 +* header. This is done by comparing the A-MSDU subheader's destination +* address to the start of the RFC1042 header. +* +* For mesh interfaces, the MSDU includes a 6-byte Mesh Control field +* and an optional variable-length Mesh Address Extension field before +* the RFC1042 header. The position of the RFC1042 header must therefore +* be calculated based on the mesh header length. +* +* Since this function intentionally parses an A-MSDU frame as an MSDU, +* it only assumes that the A-MSDU subframe header is present, and +* beyond this it performs its own bounds checks under the assumption +* that the frame is instead parsed as a non-aggregated MSDU. +*/ +static bool +is_amsdu_aggregation_attack (struct ethhdr *eth,struct sk_buff *skb, +enum nl80211_iftype iftype) +{ +int offset; + +/* Non-mesh case can be directly compared */ +if (iftype !=NL80211_IFTYPE_MESH_POINT ) +return ether_addr_equal (eth->h_dest, rfc1042_header); + + offset =__ieee80211_get_mesh_hdrlen (eth->h_dest[0 ]); +if (offset ==6 ) { +/* Mesh case with empty address extension field */ +return ether_addr_equal (eth->h_source, rfc1042_header); + }else if (offset +ETH_ALEN <= skb->len) { +/* Mesh case with non-empty address extension field */ +u8 temp[ETH_ALEN ]; + +skb_copy_bits (skb, offset, temp,ETH_ALEN ); +return ether_addr_equal (temp, rfc1042_header); + } + +return false; +} + void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, const u8 *addr, enum nl80211_iftype iftype, const unsigned int extra_headroom,
@@ -861,8 +907,10 @@ void ieee80211_amsdu_to_8023s(struct sk_/* the last MSDU has no padding */ if (subframe_len > remaining) goto purge; -/* mitigate A-MSDU aggregation injection attacks */ -if (ether_addr_equal (hdr.eth.h_dest, rfc1042_header)) +/* mitigate A-MSDU aggregation injection attacks, to be +* checked when processing first subframe (offset == 0). +*/ +if (offset ==0 &&is_amsdu_aggregation_attack (&hdr.eth, skb, iftype)) goto purge; offset +=sizeof (struct ethhdr );
Greg Kroah-Hartman
maintainerPATCH 67/163 wifi: mwifiex: discard erroneous disassoc frames on STA interface
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vitor Soares <[email protected]>
commit 3b602ddc0df723992721b0d286c90c9bdd755b34 upstream.
When operating in concurrent STA/AP mode with host MLME enabled, the firmware incorrectly sends disassociation frames to the STA interface when clients disconnect from the AP interface. This causes kernel warnings as the STA interface processes disconnect events that don't apply to it:
[ 1303.240540] WARNING: CPU: 0 PID: 513 at net/wireless/mlme.c:141 cfg80211_process_disassoc+0x78/0xec [cfg80211] [ 1303.250861] Modules linked in: 8021q garp stp mrp llc rfcomm bnep btnxpuart nls_iso8859_1 nls_cp437 onboard_us [ 1303.327651] CPU: 0 UID: 0 PID: 513 Comm: kworker/u9:2 Not tainted 6.16.0-rc1+ #3 PREEMPT [ 1303.335937] Hardware name: Toradex Verdin AM62 WB on Verdin Development Board (DT) [ 1303.343588] Workqueue: MWIFIEX_RX_WORK_QUEUE mwifiex_rx_work_queue [mwifiex] [ 1303.350856] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 1303.357904] pc : cfg80211_process_disassoc+0x78/0xec [cfg80211] [ 1303.364065] lr : cfg80211_process_disassoc+0x70/0xec [cfg80211] [ 1303.370221] sp : ffff800083053be0 [ 1303.373590] x29: ffff800083053be0 x28: 0000000000000000 x27: 0000000000000000 [ 1303.380855] x26: 0000000000000000 x25: 00000000ffffffff x24: ffff000002c5b8ae [ 1303.388120] x23: ffff000002c5b884 x22: 0000000000000001 x21: 0000000000000008 [ 1303.395382] x20: ffff000002c5b8ae x19: ffff0000064dd408 x18: 0000000000000006 [ 1303.402646] x17: 3a36333a61623a30 x16: 32206d6f72662063 x15: ffff800080bfe048 [ 1303.409910] x14: ffff000003625300 x13: 0000000000000001 x12: 0000000000000000 [ 1303.417173] x11: 0000000000000002 x10: ffff000003958600 x9 : ffff000003625300 [ 1303.424434] x8 : ffff00003fd9ef40 x7 : ffff0000039fc280 x6 : 0000000000000002 [ 1303.431695] x5 : ffff0000038976d4 x4 : 0000000000000000 x3 : 0000000000003186 [ 1303.438956] x2 : 000000004836ba20 x1 : 0000000000006986 x0 : 00000000d00479de [ 1303.446221] Call trace: [ 1303.448722] cfg80211_process_disassoc+0x78/0xec [cfg80211] (P) [ 1303.454894] cfg80211_rx_mlme_mgmt+0x64/0xf8 [cfg80211] [ 1303.460362] mwifiex_process_mgmt_packet+0x1ec/0x460 [mwifiex] [ 1303.466380] mwifiex_process_sta_rx_packet+0x1bc/0x2a0 [mwifiex] [ 1303.472573] mwifiex_handle_rx_packet+0xb4/0x13c [mwifiex] [ 1303.478243] mwifiex_rx_work_queue+0x158/0x198 [mwifiex] [ 1303.483734] process_one_work+0x14c/0x28c [ 1303.487845] worker_thread+0x2cc/0x3d4 [ 1303.491680] kthread+0x12c/0x208 [ 1303.495014] ret_from_fork+0x10/0x20
Add validation in the STA receive path to verify that disassoc/deauth frames originate from the connected AP. Frames that fail this check are discarded early, preventing them from reaching the MLME layer and triggering WARN_ON().
This filtering logic is similar with that used in the ieee80211_rx_mgmt_disassoc() function in mac80211, which drops disassoc frames that don't match the current BSSID (!ether_addr_equal(mgmt->bssid, sdata->vif.cfg.ap_addr)), ensuring only relevant frames are processed.
Tested on:
- 8997 with FW 16.68.1.p197
--- drivers/net/wireless/marvell/mwifiex/util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/wireless/marvell/mwifiex/util.c +3 -1
@@ -477,7 +477,9 @@ mwifiex_process_mgmt_packet(struct mwifi"auth: receive authentication from %pM\n" , ieee_hdr->addr3); }else { -if (!priv->wdev.connected) +if (!priv->wdev.connected || + !ether_addr_equal (ieee_hdr->addr3, + priv->curr_bss_params.bss_descriptor.mac_address))return 0 ;if (ieee80211_is_deauth (ieee_hdr->frame_control)) {
Greg Kroah-Hartman
maintainerPATCH 68/163 wifi: mt76: mt7921: prevent decap offload config before STA initialization
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deren Wu <[email protected]>
commit 7035a082348acf1d43ffb9ff735899f8e3863f8f upstream.
The decap offload configuration should only be applied after the STA has been successfully initialized. Attempting to configure it earlier can lead to corruption of the MAC configuration in the chip's hardware state.
Add an early check for msta->deflink.wcid.sta to ensure the station peer is properly initialized before proceeding with decapsulation offload configuration.
--- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7921/main.c +3 -0
@@ -1173,6 +1173,9 @@ static void mt7921_sta_set_decap_offloadstruct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;struct mt792x_dev *dev =mt792x_hw_dev (hw); +if (!msta->deflink.wcid.sta) +return ; +mt792x_mutex_acquire (dev);if (enabled)
Greg Kroah-Hartman
maintainerPATCH 69/163 wifi: mt76: mt7925: prevent NULL pointer dereference in mt7925_sta_set_decap_offload()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deren Wu <[email protected]>
commit 35ad47c0b3da04b00b19a8b9ed5632e2f2520472 upstream.
Add a NULL check for msta->vif before accessing its members to prevent a kernel panic in AP mode deployment. This also fix the issue reported in [1].
The crash occurs when this function is triggered before the station is fully initialized. The call trace shows a page fault at mt7925_sta_set_decap_offload() due to accessing resources when msta->vif is NULL.
Fix this by adding an early return if msta->vif is NULL and also check wcid.sta is ready. This ensures we only proceed with decap offload configuration when the station's state is properly initialized.
[14739.655703] Unable to handle kernel paging request at virtual address ffffffffffffffa0 [14739.811820] CPU: 0 UID: 0 PID: 895854 Comm: hostapd Tainted: G [14739.821394] Tainted: [C]=CRAP, [O]=OOT_MODULE [14739.825746] Hardware name: Raspberry Pi 4 Model B Rev 1.1 (DT) [14739.831577] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) [14739.838538] pc : mt7925_sta_set_decap_offload+0xc0/0x1b8 [mt7925_common] [14739.845271] lr : mt7925_sta_set_decap_offload+0x58/0x1b8 [mt7925_common] [14739.851985] sp : ffffffc085efb500 [14739.855295] x29: ffffffc085efb500 x28: 0000000000000000 x27: ffffff807803a158 [14739.862436] x26: ffffff8041ececb8 x25: 0000000000000001 x24: 0000000000000001 [14739.869577] x23: 0000000000000001 x22: 0000000000000008 x21: ffffff8041ecea88 [14739.876715] x20: ffffff8041c19ca0 x19: ffffff8078031fe0 x18: 0000000000000000 [14739.883853] x17: 0000000000000000 x16: ffffffe2aeac1110 x15: 000000559da48080 [14739.890991] x14: 0000000000000001 x13: 0000000000000000 x12: 0000000000000000 [14739.898130] x11: 0a10020001008e88 x10: 0000000000001a50 x9 : ffffffe26457bfa0 [14739.905269] x8 : ffffff8042013bb0 x7 : ffffff807fb6cbf8 x6 : dead000000000100 [14739.912407] x5 : dead000000000122 x4 : ffffff80780326c8 x3 : 0000000000000000 [14739.919546] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffffff8041ececb8 [14739.926686] Call trace: [14739.929130] mt7925_sta_set_decap_offload+0xc0/0x1b8 [mt7925_common] [14739.935505] ieee80211_check_fast_rx+0x19c/0x510 [mac80211] [14739.941344] _sta_info_move_state+0xe4/0x510 [mac80211] [14739.946860] sta_info_move_state+0x1c/0x30 [mac80211] [14739.952116] sta_apply_auth_flags.constprop.0+0x90/0x1b0 [mac80211] [14739.958708] sta_apply_parameters+0x234/0x5e0 [mac80211] [14739.964332] ieee80211_add_station+0xdc/0x190 [mac80211] [14739.969950] nl80211_new_station+0x46c/0x670 [cfg80211] [14739.975516] genl_family_rcv_msg_doit+0xdc/0x150 [14739.980158] genl_rcv_msg+0x218/0x298 [14739.983830] netlink_rcv_skb+0x64/0x138 [14739.987670] genl_rcv+0x40/0x60 [14739.990816] netlink_unicast+0x314/0x380 [14739.994742] netlink_sendmsg+0x198/0x3f0 [14739.998664] __sock_sendmsg+0x64/0xc0 [14740.002324] ____sys_sendmsg+0x260/0x298 [14740.006242] ___sys_sendmsg+0xb4/0x110
--- drivers/net/wireless/mediatek/mt76/mt7925/main.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7925/main.c +6 -0
@@ -1565,6 +1565,9 @@ static void mt7925_sta_set_decap_offloadunsigned long valid = mvif->valid_links;u8 i; +if (!msta->vif) +return ; +mt792x_mutex_acquire (dev); valid =ieee80211_vif_is_mld (vif) ? mvif->valid_links :BIT (0 );
@@ -1579,6 +1582,9 @@ static void mt7925_sta_set_decap_offloadelse clear_bit (MT_WCID_FLAG_HDR_TRANS , &mlink->wcid.flags); +if (!mlink->wcid.sta) +continue ; +mt7925_mcu_wtbl_update_hdr_trans (dev, vif, sta, i); }
Greg Kroah-Hartman
maintainerPATCH 70/163 wifi: mt76: mt7925: fix the wrong config for tx interrupt
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Yen Hsieh <[email protected]>
commit d20de55332e92f9e614c34783c00bb6ce2fec067 upstream.
MT_INT_TX_DONE_MCU_WM may cause tx interrupt to be mishandled during a reset failure, leading to the reset process failing. By using MT_INT_TX_DONE_MCU instead of MT_INT_TX_DONE_MCU_WM, the handling of tx interrupt is improved.
--- drivers/net/wireless/mediatek/mt76/mt7925/regs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/mediatek/mt76/mt7925/regs.h +1 -1
@@ -58,7 +58,7 @@#define MT_INT_TX_DONE_MCU (MT_INT_TX_DONE_MCU_WM | \ MT_INT_TX_DONE_FWDL) -#define MT_INT_TX_DONE_ALL (MT_INT_TX_DONE_MCU_WM | \ +#define MT_INT_TX_DONE_ALL (MT_INT_TX_DONE_MCU | \ MT_INT_TX_DONE_BAND0 | \ GENMASK(18, 4))
Greg Kroah-Hartman
maintainerPATCH 71/163 wifi: mt76: mt7925: fix invalid array index in ssid assignment during hw scan
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Lo <[email protected]>
commit c701574c54121af2720648572efbfe77564652d1 upstream.
Update the destination index to use 'n_ssids', which is incremented only when a valid SSID is present. Previously, both mt76_connac_mcu_hw_scan() and mt7925_mcu_hw_scan() used the loop index 'i' for the destination array, potentially leaving gaps if any source SSIDs had zero length.
--- drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c | 4 ++-- drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +2 -2
@@ -1696,8 +1696,8 @@ int mt76_connac_mcu_hw_scan(struct mt76_if (!sreq->ssids[i].ssid_len)continue ; - req->ssids[i].ssid_len =cpu_to_le32 (sreq->ssids[i].ssid_len); -memcpy (req->ssids[i].ssid, sreq->ssids[i].ssid, + req->ssids[n_ssids].ssid_len =cpu_to_le32 (sreq->ssids[i].ssid_len); +memcpy (req->ssids[n_ssids].ssid, sreq->ssids[i].ssid, sreq->ssids[i].ssid_len); n_ssids++; }
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +2 -2
@@ -2823,8 +2823,8 @@ int mt7925_mcu_hw_scan(struct mt76_phy *if (!sreq->ssids[i].ssid_len)continue ; - ssid->ssids[i].ssid_len =cpu_to_le32 (sreq->ssids[i].ssid_len); -memcpy (ssid->ssids[i].ssid, sreq->ssids[i].ssid, + ssid->ssids[n_ssids].ssid_len =cpu_to_le32 (sreq->ssids[i].ssid_len); +memcpy (ssid->ssids[n_ssids].ssid, sreq->ssids[i].ssid, sreq->ssids[i].ssid_len); n_ssids++; }
Greg Kroah-Hartman
maintainerPATCH 72/163 drm/imagination: Fix kernel crash when hard resetting the GPU
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alessio Belle <[email protected]>
commit d38376b3ee48d073c64e75e150510d7e6b4b04f7 upstream.
The GPU hard reset sequence calls pm_runtime_force_suspend() and pm_runtime_force_resume(), which according to their documentation should only be used during system-wide PM transitions to sleep states.
The main issue though is that depending on some internal runtime PM state as seen by pm_runtime_force_suspend() (whether the usage count is <= 1), pm_runtime_force_resume() might not resume the device unless needed. If that happens, the runtime PM resume callback pvr_power_device_resume() is not called, the GPU clocks are not re-enabled, and the kernel crashes on the next attempt to access GPU registers as part of the power-on sequence.
Replace calls to pm_runtime_force_suspend() and pm_runtime_force_resume() with direct calls to the driver's runtime PM callbacks, pvr_power_device_suspend() and pvr_power_device_resume(), to ensure clocks are re-enabled and avoid the kernel crash.
--- drivers/gpu/drm/imagination/pvr_power.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/imagination/pvr_power.c +2 -2
@@ -363,13 +363,13 @@ pvr_power_reset(struct pvr_device *pvr_dif (!err) {if (hard_reset) { pvr_dev->fw_dev.booted = false; -WARN_ON (pm_runtime_force_suspend (from_pvr_device (pvr_dev)->dev)); +WARN_ON (pvr_power_device_suspend (from_pvr_device (pvr_dev)->dev)); err =pvr_fw_hard_reset (pvr_dev);if (err) goto err_device_lost; - err =pm_runtime_force_resume (from_pvr_device (pvr_dev)->dev); + err =pvr_power_device_resume (from_pvr_device (pvr_dev)->dev); pvr_dev->fw_dev.booted = true;if (err) goto err_device_lost;
Greg Kroah-Hartman
maintainerPATCH 73/163 drm/amdkfd: Dont call mmput from MMU notifier callback
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philip Yang <[email protected]>
commit cf234231fcbc7d391e2135b9518613218cc5347f upstream.
If the process is exiting, the mmput inside mmu notifier callback from compactd or fork or numa balancing could release the last reference of mm struct to call exit_mmap and free_pgtable, this triggers deadlock with below backtrace.
The deadlock will leak kfd process as mmu notifier release is not called and cause VRAM leaking.
The fix is to take mm reference mmget_non_zero when adding prange to the deferred list to pair with mmput in deferred list work.
If prange split and add into pchild list, the pchild work_item.mm is not used, so remove the mm parameter from svm_range_unmap_split and svm_range_add_child.
The backtrace of hung task:
INFO: task python:348105 blocked for more than 64512 seconds. Call Trace: __schedule+0x1c3/0x550 schedule+0x46/0xb0 rwsem_down_write_slowpath+0x24b/0x4c0 unlink_anon_vmas+0xb1/0x1c0 free_pgtables+0xa9/0x130 exit_mmap+0xbc/0x1a0 mmput+0x5a/0x140 svm_range_cpu_invalidate_pagetables+0x2b/0x40 [amdgpu] mn_itree_invalidate+0x72/0xc0 __mmu_notifier_invalidate_range_start+0x48/0x60 try_to_unmap_one+0x10fa/0x1400 rmap_walk_anon+0x196/0x460 try_to_unmap+0xbb/0x210 migrate_page_unmap+0x54d/0x7e0 migrate_pages_batch+0x1c3/0xae0 migrate_pages_sync+0x98/0x240 migrate_pages+0x25c/0x520 compact_zone+0x29d/0x590 compact_zone_order+0xb6/0xf0 try_to_compact_pages+0xbe/0x220 __alloc_pages_direct_compact+0x96/0x1a0 __alloc_pages_slowpath+0x410/0x930 __alloc_pages_nodemask+0x3a9/0x3e0 do_huge_pmd_anonymous_page+0xd7/0x3e0 __handle_mm_fault+0x5e3/0x5f0 handle_mm_fault+0xf7/0x2e0 hmm_vma_fault.isra.0+0x4d/0xa0 walk_pmd_range.isra.0+0xa8/0x310 walk_pud_range+0x167/0x240 walk_pgd_range+0x55/0x100 __walk_page_range+0x87/0x90 walk_page_range+0xf6/0x160 hmm_range_fault+0x4f/0x90 amdgpu_hmm_range_get_pages+0x123/0x230 [amdgpu] amdgpu_ttm_tt_get_user_pages+0xb1/0x150 [amdgpu] init_user_pages+0xb1/0x2a0 [amdgpu] amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu+0x543/0x7d0 [amdgpu] kfd_ioctl_alloc_memory_of_gpu+0x24c/0x4e0 [amdgpu] kfd_ioctl+0x29d/0x500 [amdgpu]
--- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 43 ++++++++++++++++------------------- 1 file changed, 20 insertions(+), 23 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_svm.c +20 -23
@@ -1170,13 +1170,12 @@ svm_range_split_head(struct svm_range *p }static void -svm_range_add_child (struct svm_range *prange,struct mm_struct *mm, -struct svm_range *pchild,enum svm_work_list_ops op) +svm_range_add_child (struct svm_range *prange,struct svm_range *pchild,enum svm_work_list_ops op) {pr_debug ("add child 0x%p [0x%lx 0x%lx] to prange 0x%p child list %d\n" , pchild, pchild->start, pchild->last, prange, op); - pchild->work_item.mm = mm; + pchild->work_item.mm =NULL ; pchild->work_item.op = op;list_add_tail (&pchild->child_list, &prange->child_list); }
@@ -2384,15 +2383,17 @@ svm_range_add_list_work(struct svm_range prange->work_item.op != SVM_OP_UNMAP_RANGE) prange->work_item.op = op; }else { - prange->work_item.op = op; - -/* Pairs with mmput in deferred_list_work */ -mmget (mm); - prange->work_item.mm = mm; -list_add_tail (&prange->deferred_list, - &prange->svms->deferred_range_list); -pr_debug ("add prange 0x%p [0x%lx 0x%lx] to work list op %d\n" , - prange, prange->start, prange->last, op); +/* Pairs with mmput in deferred_list_work. +* If process is exiting and mm is gone, don't update mmu notifier. +*/ +if (mmget_not_zero (mm)) { + prange->work_item.mm = mm; + prange->work_item.op = op; +list_add_tail (&prange->deferred_list, + &prange->svms->deferred_range_list); +pr_debug ("add prange 0x%p [0x%lx 0x%lx] to work list op %d\n" , + prange, prange->start, prange->last, op); + } }spin_unlock (&svms->deferred_list_lock); }
@@ -2406,8 +2407,7 @@ void schedule_deferred_list_work(struct }static void -svm_range_unmap_split (struct mm_struct *mm,struct svm_range *parent, -struct svm_range *prange,unsigned long start, +svm_range_unmap_split (struct svm_range *parent,struct svm_range *prange,unsigned long start,unsigned long last) {struct svm_range *head;
@@ -2428,12 +2428,12 @@ svm_range_unmap_split(struct mm_struct *svm_range_split (tail, last +1 , tail->last, &head);if (head != prange && tail != prange) { -svm_range_add_child (parent, mm, head,SVM_OP_UNMAP_RANGE ); -svm_range_add_child (parent, mm, tail,SVM_OP_ADD_RANGE ); +svm_range_add_child (parent, head,SVM_OP_UNMAP_RANGE ); +svm_range_add_child (parent, tail,SVM_OP_ADD_RANGE ); }else if (tail != prange) { -svm_range_add_child (parent, mm, tail,SVM_OP_UNMAP_RANGE ); +svm_range_add_child (parent, tail,SVM_OP_UNMAP_RANGE ); }else if (head != prange) { -svm_range_add_child (parent, mm, head,SVM_OP_UNMAP_RANGE ); +svm_range_add_child (parent, head,SVM_OP_UNMAP_RANGE ); }else if (parent != prange) { prange->work_item.op =SVM_OP_UNMAP_RANGE ; }
@@ -2510,14 +2510,14 @@ svm_range_unmap_from_cpu(struct mm_struc l =min (last, pchild->last);if (l >= s)svm_range_unmap_from_gpus (pchild, s, l, trigger); -svm_range_unmap_split (mm, prange, pchild, start, last); +svm_range_unmap_split (prange, pchild, start, last);mutex_unlock (&pchild->lock); } s =max (start, prange->start); l =min (last, prange->last);if (l >= s)svm_range_unmap_from_gpus (prange, s, l, trigger); -svm_range_unmap_split (mm, prange, prange, start, last); +svm_range_unmap_split (prange, prange, start, last);if (unmap_parent)svm_range_add_list_work (svms, prange, mm,SVM_OP_UNMAP_RANGE );
@@ -2560,8 +2560,6 @@ svm_range_cpu_invalidate_pagetables(struif (range->event ==MMU_NOTIFY_RELEASE )return true; -if (!mmget_not_zero (mni->mm)) -return true; start = mni->interval_tree.start; last = mni->interval_tree.last;
@@ -2588,7 +2586,6 @@ svm_range_cpu_invalidate_pagetables(stru }svm_range_unlock (prange); -mmput (mni->mm);return true; }
Greg Kroah-Hartman
maintainerPATCH 74/163 drm/gem: Acquire references on GEM handles for framebuffers
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann <[email protected]>
commit 5307dce878d4126e1b375587318955bd019c3741 upstream.
A GEM handle can be released while the GEM buffer object is attached to a DRM framebuffer. This leads to the release of the dma-buf backing the buffer object, if any. [1] Trying to use the framebuffer in further mode-setting operations leads to a segmentation fault. Most easily happens with driver that use shadow planes for vmap-ing the dma-buf during a page flip. An example is shown below.
[ 156.791968] ------------[ cut here ]------------ [ 156.796830] WARNING: CPU: 2 PID: 2255 at drivers/dma-buf/dma-buf.c:1527 dma_buf_vmap+0x224/0x430 [...] [ 156.942028] RIP: 0010:dma_buf_vmap+0x224/0x430 [ 157.043420] Call Trace: [ 157.045898] <TASK> [ 157.048030] ? show_trace_log_lvl+0x1af/0x2c0 [ 157.052436] ? show_trace_log_lvl+0x1af/0x2c0 [ 157.056836] ? show_trace_log_lvl+0x1af/0x2c0 [ 157.061253] ? drm_gem_shmem_vmap+0x74/0x710 [ 157.065567] ? dma_buf_vmap+0x224/0x430 [ 157.069446] ? __warn.cold+0x58/0xe4 [ 157.073061] ? dma_buf_vmap+0x224/0x430 [ 157.077111] ? report_bug+0x1dd/0x390 [ 157.080842] ? handle_bug+0x5e/0xa0 [ 157.084389] ? exc_invalid_op+0x14/0x50 [ 157.088291] ? asm_exc_invalid_op+0x16/0x20 [ 157.092548] ? dma_buf_vmap+0x224/0x430 [ 157.096663] ? dma_resv_get_singleton+0x6d/0x230 [ 157.101341] ? __pfx_dma_buf_vmap+0x10/0x10 [ 157.105588] ? __pfx_dma_resv_get_singleton+0x10/0x10 [ 157.110697] drm_gem_shmem_vmap+0x74/0x710 [ 157.114866] drm_gem_vmap+0xa9/0x1b0 [ 157.118763] drm_gem_vmap_unlocked+0x46/0xa0 [ 157.123086] drm_gem_fb_vmap+0xab/0x300 [ 157.126979] drm_atomic_helper_prepare_planes.part.0+0x487/0xb10 [ 157.133032] ? lockdep_init_map_type+0x19d/0x880 [ 157.137701] drm_atomic_helper_commit+0x13d/0x2e0 [ 157.142671] ? drm_atomic_nonblocking_commit+0xa0/0x180 [ 157.147988] drm_mode_atomic_ioctl+0x766/0xe40 [...] [ 157.346424] ---[ end trace 0000000000000000 ]---
Acquiring GEM handles for the framebuffer's GEM buffer objects prevents this from happening. The framebuffer's cleanup later puts the handle references.
Commit 1a148af06000 ("drm/gem-shmem: Use dma_buf from GEM object instance") triggers the segmentation fault easily by using the dma-buf field more widely. The underlying issue with reference counting has been present before.
v2:
- acquire the handle instead of the BO (Christian)
- fix comment style (Christian)
- drop the Fixes tag (Christian)
- rename err_ gotos
- add missing Link tag
--- drivers/gpu/drm/drm_gem.c | 44 ++++++++++++++++++++++++--- drivers/gpu/drm/drm_gem_framebuffer_helper.c | 16 +++++---- drivers/gpu/drm/drm_internal.h | 2 + 3 files changed, 51 insertions(+), 11 deletions(-)
drivers/gpu/drm/drm_gem.c +40 -4
@@ -186,6 +186,35 @@ void drm_gem_private_object_fini(struct }EXPORT_SYMBOL (drm_gem_private_object_fini); +static void drm_gem_object_handle_get (struct drm_gem_object *obj) +{ +struct drm_device *dev = obj->dev; + +drm_WARN_ON (dev, !mutex_is_locked (&dev->object_name_lock)); + +if (obj->handle_count++ ==0 ) +drm_gem_object_get (obj); +} + +/** +* drm_gem_object_handle_get_unlocked - acquire reference on user-space handles +* @obj: GEM object +* +* Acquires a reference on the GEM buffer object's handle. Required +* to keep the GEM object alive. Call drm_gem_object_handle_put_unlocked() +* to release the reference. +*/ +void drm_gem_object_handle_get_unlocked (struct drm_gem_object *obj) +{ +struct drm_device *dev = obj->dev; + +guard (mutex)(&dev->object_name_lock); + +drm_WARN_ON (dev, !obj->handle_count);/* first ref taken in create-tail helper */ +drm_gem_object_handle_get (obj); +} +EXPORT_SYMBOL (drm_gem_object_handle_get_unlocked); +/** * drm_gem_object_handle_free - release resources bound to userspace handles * @obj: GEM object to clean up.
@@ -216,8 +245,14 @@ static void drm_gem_object_exported_dma_ } } -static void -drm_gem_object_handle_put_unlocked (struct drm_gem_object *obj) +/** +* drm_gem_object_handle_put_unlocked - releases reference on user-space handles +* @obj: GEM object +* +* Releases a reference on the GEM buffer object's handle. Possibly releases +* the GEM buffer object and associated dma-buf objects. +*/ +void drm_gem_object_handle_put_unlocked (struct drm_gem_object *obj) {struct drm_device *dev = obj->dev;bool final = false;
@@ -242,6 +277,7 @@ drm_gem_object_handle_put_unlocked(strucif (final)drm_gem_object_put (obj); } +EXPORT_SYMBOL (drm_gem_object_handle_put_unlocked);/* * Called at device or object close to release the file's
@@ -363,8 +399,8 @@ drm_gem_handle_create_tail(struct drm_fiint ret;WARN_ON (!mutex_is_locked (&dev->object_name_lock)); -if (obj->handle_count++ ==0 ) -drm_gem_object_get (obj); + +drm_gem_object_handle_get (obj);/* * Get the user-visible handle using idr. Preload and perform
drivers/gpu/drm/drm_gem_framebuffer_helper.c +9 -7
@@ -99,7 +99,7 @@ void drm_gem_fb_destroy(struct drm_frameunsigned int i;for (i =0 ; i < fb->format->num_planes; i++) -drm_gem_object_put (fb->obj[i]); +drm_gem_object_handle_put_unlocked (fb->obj[i]);drm_framebuffer_cleanup (fb);kfree (fb);
@@ -182,8 +182,10 @@ int drm_gem_fb_init_with_funcs(struct drif (!objs[i]) {drm_dbg_kms (dev,"Failed to lookup GEM object\n" ); ret = -ENOENT ; - goto err_gem_object_put; + goto err_gem_object_handle_put_unlocked; } +drm_gem_object_handle_get_unlocked (objs[i]); +drm_gem_object_put (objs[i]); min_size = (height -1 ) * mode_cmd->pitches[i] +drm_format_info_min_pitch (info, i, width)
@@ -193,22 +195,22 @@ int drm_gem_fb_init_with_funcs(struct drdrm_dbg_kms (dev,"GEM object size (%zu) smaller than minimum size (%u) for plane %d\n" , objs[i]->size, min_size, i); -drm_gem_object_put (objs[i]); +drm_gem_object_handle_put_unlocked (objs[i]); ret = -EINVAL ; - goto err_gem_object_put; + goto err_gem_object_handle_put_unlocked; } } ret =drm_gem_fb_init (dev, fb, mode_cmd, objs, i, funcs);if (ret) - goto err_gem_object_put; + goto err_gem_object_handle_put_unlocked;return 0 ; -err_gem_object_put: +err_gem_object_handle_put_unlocked:while (i >0 ) { --i; -drm_gem_object_put (objs[i]); +drm_gem_object_handle_put_unlocked (objs[i]); }return ret; }
drivers/gpu/drm/drm_internal.h +2 -0
@@ -153,6 +153,8 @@ void drm_sysfs_lease_event(struct drm_de/* drm_gem.c */ int drm_gem_init (struct drm_device *dev); +void drm_gem_object_handle_get_unlocked (struct drm_gem_object *obj); +void drm_gem_object_handle_put_unlocked (struct drm_gem_object *obj);int drm_gem_handle_create_tail (struct drm_file *file_priv,struct drm_gem_object *obj,u32 *handlep);
Greg Kroah-Hartman
maintainerPATCH 75/163 drm/sched: Increment job count before swapping tail spsc queue
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Brost <[email protected]>
commit 8af39ec5cf2be522c8eb43a3d8005ed59e4daaee upstream.
A small race exists between spsc_queue_push and the run-job worker, in which spsc_queue_push may return not-first while the run-job worker has already idled due to the job count being zero. If this race occurs, job scheduling stops, leading to hangs while waiting on the job’s DMA fences.
Seal this race by incrementing the job count before appending to the SPSC queue.
This race was observed on a drm-tip 6.16-rc1 build with the Xe driver in an SVM test case.
--- include/drm/spsc_queue.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
include/drm/spsc_queue.h +3 -1
@@ -70,9 +70,11 @@ static inline bool spsc_queue_push(strucpreempt_disable (); +atomic_inc (&queue->job_count); +smp_mb__after_atomic (); + tail = (struct spsc_node **)atomic_long_xchg (&queue->tail, (long )&node->next);WRITE_ONCE (*tail, node); -atomic_inc (&queue->job_count);/* * In case of first element verify new node will be visible to the consumer
Greg Kroah-Hartman
maintainerPATCH 76/163 drm/ttm: fix error handling in ttm_buffer_object_transfer
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian König <[email protected]>
commit 97e000acf2e20a86a50a0ec8c2739f0846f37509 upstream.
Unlocking the resv object was missing in the error path, additionally to that we should move over the resource only after the fence slot was reserved.
--- drivers/gpu/drm/ttm/ttm_bo_util.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/gpu/drm/ttm/ttm_bo_util.c +7 -6
@@ -254,6 +254,13 @@ static int ttm_buffer_object_transfer(st ret =dma_resv_trylock (&fbo->base.base._resv);WARN_ON (!ret); + ret =dma_resv_reserve_fences (&fbo->base.base._resv,1 ); +if (ret) { +dma_resv_unlock (&fbo->base.base._resv); +kfree (fbo); +return ret; + } +if (fbo->base.resource) {ttm_resource_set_bo (fbo->base.resource, &fbo->base); bo->resource =NULL ;
@@ -262,12 +269,6 @@ static int ttm_buffer_object_transfer(st fbo->base.bulk_move =NULL ; } - ret =dma_resv_reserve_fences (&fbo->base.base._resv,1 ); -if (ret) { -kfree (fbo); -return ret; - } -ttm_bo_get (bo); fbo->bo = bo;
Greg Kroah-Hartman
maintainerPATCH 77/163 drm/gem: Fix race in drm_gem_handle_create_tail()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simona Vetter <[email protected]>
commit bd46cece51a36ef088f22ef0416ac13b0a46d5b0 upstream.
Object creation is a careful dance where we must guarantee that the object is fully constructed before it is visible to other threads, and GEM buffer objects are no difference.
Final publishing happens by calling drm_gem_handle_create(). After that the only allowed thing to do is call drm_gem_object_put() because a concurrent call to the GEM_CLOSE ioctl with a correctly guessed id (which is trivial since we have a linear allocator) can already tear down the object again.
Luckily most drivers get this right, the very few exceptions I've pinged the relevant maintainers for. Unfortunately we also need drm_gem_handle_create() when creating additional handles for an already existing object (e.g. GETFB ioctl or the various bo import ioctl), and hence we cannot have a drm_gem_handle_create_and_put() as the only exported function to stop these issues from happening.
Now unfortunately the implementation of drm_gem_handle_create() isn't living up to standards: It does correctly finishe object initialization at the global level, and hence is safe against a concurrent tear down. But it also sets up the file-private aspects of the handle, and that part goes wrong: We fully register the object in the drm_file.object_idr before calling drm_vma_node_allow() or obj->funcs->open, which opens up races against concurrent removal of that handle in drm_gem_handle_delete().
Fix this with the usual two-stage approach of first reserving the handle id, and then only registering the object after we've completed the file-private setup.
Jacek reported this with a testcase of concurrently calling GEM_CLOSE on a freshly-created object (which also destroys the object), but it should be possible to hit this with just additional handles created through import or GETFB without completed destroying the underlying object with the concurrent GEM_CLOSE ioctl calls.
Note that the close-side of this race was fixed in f6cd7daecff5 ("drm:
Release driver references to handle before making it available again"), which means a cool 9 years have passed until someone noticed that we need to make this symmetry or there's still gaps left :-/ Without the 2-stage close approach we'd still have a race, therefore that's an integral part of this bugfix.
More importantly, this means we can have NULL pointers behind allocated id in our drm_file.object_idr. We need to check for that now:
- drm_gem_handle_delete() checks for ERR_OR_NULL already
- drm_gem.c:object_lookup() also chekcs for NULL
- drm_gem_release() should never be called if there's another thread still existing that could call into an IOCTL that creates a new handle, so cannot race. For paranoia I added a NULL check to drm_gem_object_release_handle() though.
- most drivers (etnaviv, i915, msm) are find because they use idr_find(), which maps both ENOENT and NULL to NULL.
- drivers using idr_for_each_entry() should also be fine, because idr_get_next does filter out NULL entries and continues the iteration.
- The same holds for drm_show_memory_stats().
v2: Use drm_WARN_ON (Thomas)
--- drivers/gpu/drm/drm_gem.c | 10 +++++++++- include/drm/drm_file.h | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-)
drivers/gpu/drm/drm_gem.c +9 -1
@@ -289,6 +289,9 @@ drm_gem_object_release_handle(int id, vostruct drm_file *file_priv = data;struct drm_gem_object *obj = ptr; +if (drm_WARN_ON (obj->dev, !data)) +return 0 ; +if (obj->funcs->close) obj->funcs->close (obj, file_priv);
@@ -409,7 +412,7 @@ drm_gem_handle_create_tail(struct drm_fiidr_preload (GFP_KERNEL );spin_lock (&file_priv->table_lock); - ret =idr_alloc (&file_priv->object_idr, obj,1 ,0 ,GFP_NOWAIT ); + ret =idr_alloc (&file_priv->object_idr,NULL ,1 ,0 ,GFP_NOWAIT );spin_unlock (&file_priv->table_lock);idr_preload_end ();
@@ -430,6 +433,11 @@ drm_gem_handle_create_tail(struct drm_fi goto err_revoke; } +/* mirrors drm_gem_handle_delete to avoid races */ +spin_lock (&file_priv->table_lock); + obj =idr_replace (&file_priv->object_idr, obj, handle); +WARN_ON (obj !=NULL ); +spin_unlock (&file_priv->table_lock); *handlep = handle;return 0 ;
include/drm/drm_file.h +3 -0
@@ -300,6 +300,9 @@ struct drm_file {* * Mapping of mm object handles to object pointers. Used by the GEM * subsystem. Protected by @table_lock. +* +* Note that allocated entries might be NULL as a transient state when +* creating or deleting a handle. */ struct idr object_idr;
Re: [PATCH 6.12 077/163] drm/gem: Fix race in drm_gem_handle_create_tail()
Hi
Am 15.07.25 um 15:12 schrieb Greg Kroah-Hartman:
Quoted 1 line
6.12-stable review patch. If anyone has any objections, please let me know.
Might not be worth it. We're discussing a rework of this patch if not an outright revert. And you wont see the error in 6.12 if you haven't also backported 1a148af06000 ("drm/gem-shmem: Use dma_buf from GEM object instance").
If you take the patch, you should also take commit f6bfc9afc751 ("drm/framebuffer: Acquire internal references on GEM handles").
Best regards
Thomas
Quoted 139 lines
------------------
From: Simona Vetter <[email protected]>
commit
bd46cece51a36ef088f22ef0416ac13b0a46d5b0upstream.Object creation is a careful dance where we must guarantee that the object is fully constructed before it is visible to other threads, and GEM buffer objects are no difference.
Final publishing happens by calling
drm_gem_handle_create(). After that the only allowed thing to do is calldrm_gem_object_put()because a concurrent call to theGEM_CLOSEioctl with a correctly guessed id (which is trivial since we have a linear allocator) can already tear down the object again.Luckily most drivers get this right, the very few exceptions I've pinged the relevant maintainers for. Unfortunately we also need
drm_gem_handle_create()when creating additional handles for an already existing object (e.g. GETFB ioctl or the various bo import ioctl), and hence we cannot have adrm_gem_handle_create_and_put()as the only exported function to stop these issues from happening.Now unfortunately the implementation of
drm_gem_handle_create()isn't living up to standards: It does correctly finishe object initialization at the global level, and hence is safe against a concurrent tear down. But it also sets up the file-private aspects of the handle, and that part goes wrong: We fully register the object in the drm_file.object_idr before callingdrm_vma_node_allow()orobj->funcs->open, which opens up races against concurrent removal of that handle indrm_gem_handle_delete().Fix this with the usual two-stage approach of first reserving the handle id, and then only registering the object after we've completed the file-private setup.
Jacek reported this with a testcase of concurrently calling
GEM_CLOSEon a freshly-created object (which also destroys the object), but it should be possible to hit this with just additional handles created through import or GETFB without completed destroying the underlying object with the concurrentGEM_CLOSEioctl calls.Note that the close-side of this race was fixed in
f6cd7daecff5("drm:
Release driver references to handle before making it available again"), which means a cool 9 years have passed until someone noticed that we need to make this symmetry or there's still gaps left :-/ Without the 2-stage close approach we'd still have a race, therefore that's an integral part of this bugfix.More importantly, this means we can have NULL pointers behind allocated id in our drm_file.object_idr. We need to check for that now:
-
drm_gem_handle_delete()checks forERR_OR_NULLalready- drm_gem.c:object_lookup() also chekcs for NULL
-
drm_gem_release()should never be called if there's another thread still existing that could call into an IOCTL that creates a new handle, so cannot race. For paranoia I added a NULL check todrm_gem_object_release_handle()though.- most drivers (etnaviv, i915, msm) are find because they use
idr_find(), which maps both ENOENT and NULL to NULL.- drivers using
idr_for_each_entry()should also be fine, becauseidr_get_nextdoes filter out NULL entries and continues the iteration.- The same holds for
drm_show_memory_stats().v2: Use
drm_WARN_ON(Thomas)Reported-by Jacek Lawrynowicz <[email protected]>Tested-by Jacek Lawrynowicz <[email protected]>Reviewed-by Thomas Zimmermann <[email protected]>Cc Jacek Lawrynowicz <[email protected]>Cc Maarten Lankhorst <[email protected]>Cc Maxime Ripard <[email protected]>Cc Thomas Zimmermann <[email protected]>Cc David Airlie <[email protected]>Cc Simona Vetter <[email protected]>Signed-off-by Simona Vetter <[email protected]>Signed-off-by Simona Vetter <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/gpu/drm/drm_gem.c | 10 +++++++++- include/drm/drm_file.h | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-)drivers/gpu/drm/drm_gem.c +9
-1@@ -289,6 +289,9 @@ drm_gem_object_release_handle(int id, vostruct drm_file *file_priv = data;struct drm_gem_object *obj = ptr; +if (drm_WARN_ON (obj->dev, !data)) +return 0 ; +if (obj->funcs->close) obj->funcs->close (obj, file_priv);@@ -409,7 +412,7 @@ drm_gem_handle_create_tail(struct drm_fiidr_preload (GFP_KERNEL );spin_lock (&file_priv->table_lock); - ret =idr_alloc (&file_priv->object_idr, obj,1 ,0 ,GFP_NOWAIT ); + ret =idr_alloc (&file_priv->object_idr,NULL ,1 ,0 ,GFP_NOWAIT );spin_unlock (&file_priv->table_lock);idr_preload_end ();@@ -430,6 +433,11 @@ drm_gem_handle_create_tail(struct drm_fi goto err_revoke; } +/* mirrors drm_gem_handle_delete to avoid races */ +spin_lock (&file_priv->table_lock); + obj =idr_replace (&file_priv->object_idr, obj, handle); +WARN_ON (obj !=NULL ); +spin_unlock (&file_priv->table_lock); *handlep = handle;return 0 ;include/drm/drm_file.h +3
-0@@ -300,6 +300,9 @@ struct drm_file {* * Mapping of mm object handles to object pointers. Used by the GEM * subsystem. Protected by @table_lock. +* +* Note that allocated entries might be NULL as a transient state when +* creating or deleting a handle. */ struct idr object_idr;
Signature · 7 lines
-- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Frankenstrasse 146, 90461 Nuernberg, Germany GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman HRB 36809 (AG Nuernberg)
Greg Kroah-Hartman
maintainerPATCH 78/163 drm/xe/bmg: fix compressed VRAM handling
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Auld <[email protected]>
commit fee58ca135a7b979c8b75e6d2eac60d695f9209b upstream.
There looks to be an issue in our compression handling when the BO pages are very fragmented, where we choose to skip the identity map and instead fall back to emitting the PTEs by hand when migrating memory, such that we can hopefully do more work per blit operation. However in such a case we need to ensure the src PTEs are correctly tagged with a compression enabled PAT index on dgpu xe2+, otherwise the copy will simply treat the src memory as uncompressed, leading to corruption if the memory was compressed by the user.
To fix this pass along use_comp_pat into emit_pte() on the src side, to indicate that compression should be considered.
v2 (Jonathan): tweak the commit message
--- drivers/gpu/drm/xe/xe_migrate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/xe/xe_migrate.c +1 -1
@@ -860,7 +860,7 @@ struct dma_fence *xe_migrate_copy(structif (src_is_vram &&xe_migrate_allow_identity (src_L0, &src_it))xe_res_next (&src_it, src_L0);else -emit_pte (m, bb, src_L0_pt, src_is_vram, copy_system_ccs, +emit_pte (m, bb, src_L0_pt, src_is_vram, copy_system_ccs || use_comp_pat, &src_it, src_L0, src);if (dst_is_vram &&xe_migrate_allow_identity (src_L0, &dst_it))
Greg Kroah-Hartman
maintainerPATCH 79/163 Revert "drm/xe/xe2: Enable Indirect Ring State support for Xe2"
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Brost <[email protected]>
commit daa099fed50a39256feb37d3fac146bf0d74152f upstream.
This reverts commit fe0154cf8222d9e38c60ccc124adb2f9b5272371.
Seeing some unexplained random failures during LRC context switches with indirect ring state enabled. The failures were always there, but the repro rate increased with the addition of WA BB as a separate BO. Commit 3a1edef8f4b5 ("drm/xe: Make WA BB part of LRC BO") helped to reduce the issues in the context switches, but didn't eliminate them completely.
Indirect ring state is not required for any current features, so disable for now until failures can be root caused.
--- drivers/gpu/drm/xe/xe_pci.c | 1 - 1 file changed, 1 deletion(-)
drivers/gpu/drm/xe/xe_pci.c +0 -1
@@ -164,7 +164,6 @@ static const struct xe_graphics_desc gra .has_asid = 1, \ .has_atomic_enable_pte_bit = 1, \ .has_flat_ccs = 1, \ - .has_indirect_ring_state = 1, \ .has_range_tlb_invalidation = 1, \ .has_usm = 1, \ .va_bits = 48, \
Greg Kroah-Hartman
maintainerPATCH 80/163 usb: gadget: u_serial: Fix race condition in TTY wakeup
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuen-Han Tsai <[email protected]>
commit c529c3730bd09115684644e26bf01ecbd7e2c2c9 upstream.
A race condition occurs when gs_start_io() calls either gs_start_rx() or gs_start_tx(), as those functions briefly drop the port_lock for usb_ep_queue(). This allows gs_close() and gserial_disconnect() to clear port.tty and port_usb, respectively.
Use the null-safe TTY Port helper function to wake up TTY.
Example
CPU1: CPU2:
gserial_connect() // lock
gs_close() // await lock
gs_start_rx() // unlock
usb_ep_queue()
gs_close() // lock, reset port.tty and unlock
gs_start_rx() // lock
tty_wakeup() // NPE
--- drivers/usb/gadget/function/u_serial.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/usb/gadget/function/u_serial.c +3 -3
@@ -294,8 +294,8 @@ __acquires(&port->port_lock)break ; } -if (do_tty_wake && port->port.tty) -tty_wakeup (port->port.tty); +if (do_tty_wake) +tty_port_tty_wakeup (&port->port);return status; }
@@ -577,7 +577,7 @@ static int gs_start_io(struct gs_port *pgs_start_tx (port);/* Unblock any pending writes into our circular buffer, in case * we didn't in gs_start_tx() */ -tty_wakeup (port->port.tty); +tty_port_tty_wakeup (&port->port); }else {/* Free reqs only if we are still connected */ if (port->port_usb) {
Greg Kroah-Hartman
maintainerPATCH 81/163 Revert "usb: gadget: u_serial: Add null pointer check in gs_start_io"
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuen-Han Tsai <[email protected]>
commit f6c7bc4a6823a0a959f40866a1efe99bd03c2c5b upstream.
This reverts commit ffd603f214237e250271162a5b325c6199a65382.
Commit ffd603f21423 ("usb: gadget: u_serial: Add null pointer check in gs_start_io") adds null pointer checks at the beginning of the gs_start_io() function to prevent a null pointer dereference. However, these checks are redundant because the function's comment already requires callers to hold the port_lock and ensure port.tty and port_usb are not null. All existing callers already follow these rules.
The true cause of the null pointer dereference is a race condition. When gs_start_io() calls either gs_start_rx() or gs_start_tx(), the port_lock is temporarily released for usb_ep_queue(). This allows port.tty and port_usb to be cleared.
--- drivers/usb/gadget/function/u_serial.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/usb/gadget/function/u_serial.c +1 -5
@@ -543,20 +543,16 @@ static int gs_alloc_requests(struct usb_static int gs_start_io (struct gs_port *port) {struct list_head *head = &port->read_pool; -struct usb_ep *ep; +struct usb_ep *ep = port->port_usb->out;int status;unsigned started; -if (!port->port_usb || !port->port.tty) -return -EIO ; -/* Allocate RX and TX I/O buffers. We can't easily do this much * earlier (with GFP_KERNEL) because the requests are coupled to * endpoints, as are the packet sizes we'll be using. Different * configurations may use different endpoints with a given port; * and high speed vs full speed changes packet sizes too. */ - ep = port->port_usb->out; status =gs_alloc_requests (ep, head, gs_read_complete, &port->read_allocated);if (status)
Greg Kroah-Hartman
maintainerPATCH 82/163 drm/framebuffer: Acquire internal references on GEM handles
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann <[email protected]>
commit f6bfc9afc7510cb5e6fbe0a17c507917b0120280 upstream.
Acquire GEM handles in drm_framebuffer_init() and release them in the corresponding drm_framebuffer_cleanup(). Ties the handle's lifetime to the framebuffer. Not all GEM buffer objects have GEM handles. If not set, no refcounting takes place. This is the case for some fbdev emulation. This is not a problem as these GEM objects do not use dma-bufs and drivers will not release them while fbdev emulation is running. Framebuffer flags keep a bit per color plane of which the framebuffer holds a GEM handle reference.
As all drivers use drm_framebuffer_init(), they will now all hold dma-buf references as fixed in commit 5307dce878d4 ("drm/gem: Acquire references on GEM handles for framebuffers").
In the GEM framebuffer helpers, restore the original ref counting on buffer objects. As the helpers for handle refcounting are now no longer called from outside the DRM core, unexport the symbols.
v3:
- don't mix internal flags with mode flags (Christian) v2:
- track framebuffer handle refs by flag
- drop gma500 cleanup (Christian)
--- drivers/gpu/drm/drm_framebuffer.c | 31 ++++++++++++++++++++-- drivers/gpu/drm/drm_gem.c | 38 +++++++++++++++++---------- drivers/gpu/drm/drm_gem_framebuffer_helper.c | 16 ++++------- drivers/gpu/drm/drm_internal.h | 2 - include/drm/drm_framebuffer.h | 7 ++++ 5 files changed, 68 insertions(+), 26 deletions(-)
drivers/gpu/drm/drm_framebuffer.c +29 -2
@@ -860,11 +860,23 @@ void drm_framebuffer_free(struct kref *kint drm_framebuffer_init (struct drm_device *dev,struct drm_framebuffer *fb,const struct drm_framebuffer_funcs *funcs) { +unsigned int i;int ret; +bool exists;if (WARN_ON_ONCE (fb->dev != dev || !fb->format))return -EINVAL ; +for (i =0 ; i < fb->format->num_planes; i++) { +if (drm_WARN_ON_ONCE (dev, fb->internal_flags &DRM_FRAMEBUFFER_HAS_HANDLE_REF (i))) + fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF (i); +if (fb->obj[i]) { + exists =drm_gem_object_handle_get_if_exists_unlocked (fb->obj[i]); +if (exists) + fb->internal_flags |=DRM_FRAMEBUFFER_HAS_HANDLE_REF (i); + } + } +INIT_LIST_HEAD (&fb->filp_head); fb->funcs = funcs;
@@ -873,7 +885,7 @@ int drm_framebuffer_init(struct drm_devi ret =__drm_mode_object_add (dev, &fb->base,DRM_MODE_OBJECT_FB , false, drm_framebuffer_free);if (ret) - goto out; + goto err;mutex_lock (&dev->mode_config.fb_lock); dev->mode_config.num_fb++;
@@ -881,7 +893,16 @@ int drm_framebuffer_init(struct drm_devimutex_unlock (&dev->mode_config.fb_lock);drm_mode_object_register (dev, &fb->base); -out: + +return 0 ; + +err: +for (i =0 ; i < fb->format->num_planes; i++) { +if (fb->internal_flags &DRM_FRAMEBUFFER_HAS_HANDLE_REF (i)) { +drm_gem_object_handle_put_unlocked (fb->obj[i]); + fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF (i); + } + }return ret; }EXPORT_SYMBOL (drm_framebuffer_init);
@@ -958,6 +979,12 @@ EXPORT_SYMBOL(drm_framebuffer_unregistervoid drm_framebuffer_cleanup (struct drm_framebuffer *fb) {struct drm_device *dev = fb->dev; +unsigned int i; + +for (i =0 ; i < fb->format->num_planes; i++) { +if (fb->internal_flags &DRM_FRAMEBUFFER_HAS_HANDLE_REF (i)) +drm_gem_object_handle_put_unlocked (fb->obj[i]); + }mutex_lock (&dev->mode_config.fb_lock);list_del (&fb->head);
drivers/gpu/drm/drm_gem.c +24 -14
@@ -197,23 +197,34 @@ static void drm_gem_object_handle_get(st }/** -* drm_gem_object_handle_get_unlocked - acquire reference on user-space handles +* drm_gem_object_handle_get_if_exists_unlocked - acquire reference on user-space handle, if any * @obj: GEM object * -* Acquires a reference on the GEM buffer object's handle. Required -* to keep the GEM object alive. Call drm_gem_object_handle_put_unlocked() -* to release the reference. +* Acquires a reference on the GEM buffer object's handle. Required to keep +* the GEM object alive. Call drm_gem_object_handle_put_if_exists_unlocked() +* to release the reference. Does nothing if the buffer object has no handle. +* +* Returns: +* True if a handle exists, or false otherwise */ -void drm_gem_object_handle_get_unlocked (struct drm_gem_object *obj) +bool drm_gem_object_handle_get_if_exists_unlocked (struct drm_gem_object *obj) {struct drm_device *dev = obj->dev;guard (mutex)(&dev->object_name_lock); -drm_WARN_ON (dev, !obj->handle_count);/* first ref taken in create-tail helper */ +/* +* First ref taken during GEM object creation, if any. Some +* drivers set up internal framebuffers with GEM objects that +* do not have a GEM handle. Hence, this counter can be zero. +*/ +if (!obj->handle_count) +return false; +drm_gem_object_handle_get (obj); + +return true; } -EXPORT_SYMBOL (drm_gem_object_handle_get_unlocked);/** * drm_gem_object_handle_free - release resources bound to userspace handles
@@ -246,7 +257,7 @@ static void drm_gem_object_exported_dma_ }/** -* drm_gem_object_handle_put_unlocked - releases reference on user-space handles +* drm_gem_object_handle_put_unlocked - releases reference on user-space handle * @obj: GEM object * * Releases a reference on the GEM buffer object's handle. Possibly releases
@@ -257,14 +268,14 @@ void drm_gem_object_handle_put_unlocked(struct drm_device *dev = obj->dev;bool final = false; -if (WARN_ON (READ_ONCE (obj->handle_count) ==0 )) +if (drm_WARN_ON (dev,READ_ONCE (obj->handle_count) ==0 ))return ;/* -* Must bump handle count first as this may be the last -* ref, in which case the object would disappear before we -* checked for a name -*/ +* Must bump handle count first as this may be the last +* ref, in which case the object would disappear before +* we checked for a name. +*/ mutex_lock (&dev->object_name_lock);if (--obj->handle_count ==0 ) {
@@ -277,7 +288,6 @@ void drm_gem_object_handle_put_unlocked(if (final)drm_gem_object_put (obj); } -EXPORT_SYMBOL (drm_gem_object_handle_put_unlocked);/* * Called at device or object close to release the file's
drivers/gpu/drm/drm_gem_framebuffer_helper.c +7 -9
@@ -99,7 +99,7 @@ void drm_gem_fb_destroy(struct drm_frameunsigned int i;for (i =0 ; i < fb->format->num_planes; i++) -drm_gem_object_handle_put_unlocked (fb->obj[i]); +drm_gem_object_put (fb->obj[i]);drm_framebuffer_cleanup (fb);kfree (fb);
@@ -182,10 +182,8 @@ int drm_gem_fb_init_with_funcs(struct drif (!objs[i]) {drm_dbg_kms (dev,"Failed to lookup GEM object\n" ); ret = -ENOENT ; - goto err_gem_object_handle_put_unlocked; + goto err_gem_object_put; } -drm_gem_object_handle_get_unlocked (objs[i]); -drm_gem_object_put (objs[i]); min_size = (height -1 ) * mode_cmd->pitches[i] +drm_format_info_min_pitch (info, i, width)
@@ -195,22 +193,22 @@ int drm_gem_fb_init_with_funcs(struct drdrm_dbg_kms (dev,"GEM object size (%zu) smaller than minimum size (%u) for plane %d\n" , objs[i]->size, min_size, i); -drm_gem_object_handle_put_unlocked (objs[i]); +drm_gem_object_put (objs[i]); ret = -EINVAL ; - goto err_gem_object_handle_put_unlocked; + goto err_gem_object_put; } } ret =drm_gem_fb_init (dev, fb, mode_cmd, objs, i, funcs);if (ret) - goto err_gem_object_handle_put_unlocked; + goto err_gem_object_put;return 0 ; -err_gem_object_handle_put_unlocked: +err_gem_object_put:while (i >0 ) { --i; -drm_gem_object_handle_put_unlocked (objs[i]); +drm_gem_object_put (objs[i]); }return ret; }
drivers/gpu/drm/drm_internal.h +1 -1
@@ -153,7 +153,7 @@ void drm_sysfs_lease_event(struct drm_de/* drm_gem.c */ int drm_gem_init (struct drm_device *dev); -void drm_gem_object_handle_get_unlocked (struct drm_gem_object *obj); +bool drm_gem_object_handle_get_if_exists_unlocked (struct drm_gem_object *obj);void drm_gem_object_handle_put_unlocked (struct drm_gem_object *obj); int drm_gem_handle_create_tail(struct drm_file *file_priv, struct drm_gem_object *obj,
include/drm/drm_framebuffer.h +7 -0
@@ -23,6 +23,7 @@#ifndef __DRM_FRAMEBUFFER_H__#define __DRM_FRAMEBUFFER_H__ +#include <linux/bits.h> #include <linux/ctype.h> #include <linux/list.h> #include <linux/sched.h>
@@ -100,6 +101,8 @@ struct drm_framebuffer_funcs { unsigned num_clips); }; +#define DRM_FRAMEBUFFER_HAS_HANDLE_REF (_i) BIT(0u + (_i)) +/** * struct drm_framebuffer - frame buffer object *
@@ -189,6 +192,10 @@ struct drm_framebuffer {*/ int flags;/** +* @internal_flags: Framebuffer flags like DRM_FRAMEBUFFER_HAS_HANDLE_REF. +*/ +unsigned int internal_flags; +/** * @filp_head: Placed on &drm_file.fbs, protected by &drm_file.fbs_lock. */ struct list_head filp_head;
Greg Kroah-Hartman
maintainerPATCH 83/163 drm/xe: Allocate PF queue size on pow2 boundary
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Brost <[email protected]>
commit c9a95dbe06102cf01afee4cd83ecb29f8d587a72 upstream.
CIRC_SPACE does not work unless the size argument is a power of 2, allocate PF queue size on power of 2 boundary.
--- drivers/gpu/drm/xe/xe_gt_pagefault.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/xe/xe_gt_pagefault.c +1 -0
@@ -432,6 +432,7 @@ static int xe_alloc_pf_queue(struct xe_g#define PF_MULTIPLIER 8 pf_queue->num_dw = (num_eus +XE_NUM_HW_ENGINES ) *PF_MSG_LEN_DW *PF_MULTIPLIER ; + pf_queue->num_dw =roundup_pow_of_two (pf_queue->num_dw);#undef PF_MULTIPLIER pf_queue->gt = gt;
Greg Kroah-Hartman
maintainerPATCH 84/163 Revert "ACPI: battery: negate current when discharging"
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <[email protected]>
commit de1675de39aa945bad5937d1fde4df3682670639 upstream.
Revert commit 234f71555019 ("ACPI: battery: negate current when discharging") breaks not one but several userspace implementations of battery monitoring: Steam and MangoHud. Perhaps it breaks more, but those are the two that have been tested.
--- drivers/acpi/battery.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-)
drivers/acpi/battery.c +3 -16
@@ -243,23 +243,10 @@ static int acpi_battery_get_property(strbreak ;case POWER_SUPPLY_PROP_CURRENT_NOW :case POWER_SUPPLY_PROP_POWER_NOW : -if (battery->rate_now ==ACPI_BATTERY_VALUE_UNKNOWN ) { +if (battery->rate_now ==ACPI_BATTERY_VALUE_UNKNOWN ) ret = -ENODEV ; -break ; - } - - val->intval = battery->rate_now *1000 ; -/* -* When discharging, the current should be reported as a -* negative number as per the power supply class interface -* definition. -*/ -if (psp ==POWER_SUPPLY_PROP_CURRENT_NOW && - (battery->state &ACPI_BATTERY_STATE_DISCHARGING ) && -acpi_battery_handle_discharging (battery) - ==POWER_SUPPLY_STATUS_DISCHARGING ) - val->intval = -val->intval; - +else + val->intval = battery->rate_now *1000 ;break ;case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN :case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN :
Greg Kroah-Hartman
maintainerPATCH 85/163 Revert "PCI/ACPI: Fix allocated memory release on error in pci_acpi_scan_root()"
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhe Qiao <[email protected]>
commit 2b8be57fa0c88ac824a906f29c04d728f9f6047a upstream.
This reverts commit 631b2af2f357 ("PCI/ACPI: Fix allocated memory release on error in pci_acpi_scan_root()").
The reverted patch causes the 'ri->cfg' and 'root_ops' resources to be released multiple times.
When acpi_pci_root_create() fails, these resources have already been released internally by the __acpi_pci_root_release_info() function.
Releasing them again in pci_acpi_scan_root() leads to incorrect behavior and potential memory issues.
We plan to resolve the issue using a more appropriate fix.
--- drivers/pci/pci-acpi.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
drivers/pci/pci-acpi.c +10 -13
@@ -1676,19 +1676,24 @@ struct pci_bus *pci_acpi_scan_root(strucreturn NULL ; root_ops =kzalloc (sizeof (*root_ops),GFP_KERNEL ); -if (!root_ops) - goto free_ri; +if (!root_ops) { +kfree (ri); +return NULL ; + } ri->cfg =pci_acpi_setup_ecam_mapping (root); -if (!ri->cfg) - goto free_root_ops; +if (!ri->cfg) { +kfree (ri); +kfree (root_ops); +return NULL ; + } root_ops->release_info = pci_acpi_generic_release_info; root_ops->prepare_resources = pci_acpi_root_prepare_resources; root_ops->pci_ops = (struct pci_ops *)&ri->cfg->ops->pci_ops; bus =acpi_pci_root_create (root, root_ops, &ri->common, ri->cfg);if (!bus) - goto free_cfg; +return NULL ;/* If we must preserve the resource configuration, claim now */ host =pci_find_host_bridge (bus);
@@ -1705,14 +1710,6 @@ struct pci_bus *pci_acpi_scan_root(strucpcie_bus_configure_settings (child);return bus; - -free_cfg: -pci_ecam_free (ri->cfg); -free_root_ops: -kfree (root_ops); -free_ri: -kfree (ri); -return NULL ; }void pcibios_add_bus (struct pci_bus *bus)
Greg Kroah-Hartman
maintainerPATCH 86/163 kallsyms: fix build without execinfo
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Achill Gilgenast <[email protected]>
commit a95743b53031b015e8949e845a9f6fdfb2656347 upstream.
Some libc's like musl libc don't provide execinfo.h since it's not part of POSIX. In order to fix compilation on musl, only include execinfo.h if available (HAVE_BACKTRACE_SUPPORT)
This was discovered with c104c16073b7 ("Kunit to check the longest symbol length") which starts to include linux/kallsyms.h with Alpine Linux' configs.
--- tools/include/linux/kallsyms.h | 4 ++++ 1 file changed, 4 insertions(+)
tools/include/linux/kallsyms.h +4 -0
@@ -18,6 +18,7 @@ static inline const char *kallsyms_lookureturn NULL ; } +#ifdef HAVE_BACKTRACE_SUPPORT #include <execinfo.h> #include <stdlib.h> static inline void print_ip_sym (const char *loglvl,unsigned long ip)
@@ -30,5 +31,8 @@ static inline void print_ip_sym(const chfree (name); } +#else +static inline void print_ip_sym (const char *loglvl,unsigned long ip) {} +#endif #endif
Greg Kroah-Hartman
maintainerPATCH 87/163 maple_tree: fix mt_destroy_walk() on root leaf node
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Yang <[email protected]>
commit ea9b77f98d94c4d5c1bd1ac1db078f78b40e8bf5 upstream.
On destroy, we should set each node dead. But current code miss this when the maple tree has only the root node.
The reason is mt_destroy_walk() leverage mte_destroy_descend() to set node dead, but this is skipped since the only root node is a leaf.
Fixes this by setting the node dead if it is a leaf.
--- lib/maple_tree.c | 1 + 1 file changed, 1 insertion(+)
lib/maple_tree.c +1 -0
@@ -5335,6 +5335,7 @@ static void mt_destroy_walk(struct maplestruct maple_enode *start;if (mte_is_leaf (enode)) { +mte_set_node_dead (enode); node->type =mte_node_type (enode); goto free_leaf; }
Greg Kroah-Hartman
maintainerPATCH 88/163 mm: fix the inaccurate memory statistics issue for users
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baolin Wang <[email protected]>
commit 82241a83cd15aaaf28200a40ad1a8b480012edaf upstream.
On some large machines with a high number of CPUs running a 64K pagesize kernel, we found that the 'RES' field is always 0 displayed by the top command for some processes, which will cause a lot of confusion for users.
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
875525 root 20 0 12480 0 0 R 0.3 0.0 0:00.08 top
1 root 20 0 172800 0 0 S 0.0 0.0 0:04.52 systemdThe main reason is that the batch size of the percpu counter is quite large on these machines, caching a significant percpu value, since converting mm's rss stats into percpu_counter by commit f1a7941243c1 ("mm:
convert mm's rss stats into percpu_counter"). Intuitively, the batch number should be optimized, but on some paths, performance may take precedence over statistical accuracy. Therefore, introducing a new interface to add the percpu statistical count and display it to users, which can remove the confusion. In addition, this change is not expected to be on a performance-critical path, so the modification should be acceptable.
In addition, the 'mm->rss_stat' is updated by using add_mm_counter() and dec/inc_mm_counter(), which are all wrappers around percpu_counter_add_batch(). In percpu_counter_add_batch(), there is percpu batch caching to avoid 'fbc->lock' contention. This patch changes task_mem() and task_statm() to get the accurate mm counters under the 'fbc->lock', but this should not exacerbate kernel 'mm->rss_stat' lock contention due to the percpu batch caching of the mm counters. The following test also confirm the theoretical analysis.
I run the stress-ng that stresses anon page faults in 32 threads on my 32 cores machine, while simultaneously running a script that starts 32 threads to busy-loop pread each stress-ng thread's /proc/pid/status interface. From the following data, I did not observe any obvious impact of this patch on the stress-ng tests.
w/o patch:
stress-ng: info: [6848] 4,399,219,085,152 CPU Cycles 67.327 B/sec
stress-ng: info: [6848] 1,616,524,844,832 Instructions 24.740 B/sec (0.367 instr. per cycle)
stress-ng: info: [6848] 39,529,792 Page Faults Total 0.605 M/sec
stress-ng: info: [6848] 39,529,792 Page Faults Minor 0.605 M/sec
w/patch:
stress-ng: info: [2485] 4,462,440,381,856 CPU Cycles 68.382 B/sec
stress-ng: info: [2485] 1,615,101,503,296 Instructions 24.750 B/sec (0.362 instr. per cycle)
stress-ng: info: [2485] 39,439,232 Page Faults Total 0.604 M/sec
stress-ng: info: [2485] 39,439,232 Page Faults Minor 0.604 M/sec
On comparing a very simple app which just allocates & touches some memory against v6.1 (which doesn't have f1a7941243c1) and latest Linus tree (4c06e63b9203) I can see that on latest Linus tree the values for VmRSS, RssAnon and RssFile from /proc/self/status are all zeroes while they do report values on v6.1 and a Linus tree with this patch.
Tested-by Donet Tom <[email protected]>
--- fs/proc/task_mmu.c | 14 +++++++------- include/linux/mm.h | 5 +++++ 2 files changed, 12 insertions(+), 7 deletions(-)
fs/proc/task_mmu.c +7 -7
@@ -36,9 +36,9 @@ void task_mem(struct seq_file *m, structunsigned long text, lib, swap, anon, file, shmem;unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss; - anon =get_mm_counter (mm,MM_ANONPAGES ); - file =get_mm_counter (mm,MM_FILEPAGES ); - shmem =get_mm_counter (mm,MM_SHMEMPAGES ); + anon =get_mm_counter_sum (mm,MM_ANONPAGES ); + file =get_mm_counter_sum (mm,MM_FILEPAGES ); + shmem =get_mm_counter_sum (mm,MM_SHMEMPAGES );/* * Note: to minimize their overhead, mm maintains hiwater_vm and
@@ -59,7 +59,7 @@ void task_mem(struct seq_file *m, struct text =min (text, mm->exec_vm <<PAGE_SHIFT ); lib = (mm->exec_vm <<PAGE_SHIFT ) - text; - swap =get_mm_counter (mm,MM_SWAPENTS ); + swap =get_mm_counter_sum (mm,MM_SWAPENTS );SEQ_PUT_DEC ("VmPeak:\t" , hiwater_vm);SEQ_PUT_DEC (" kB\nVmSize:\t" , total_vm);SEQ_PUT_DEC (" kB\nVmLck:\t" , mm->locked_vm);
@@ -92,12 +92,12 @@ unsigned long task_statm(struct mm_struc unsigned long *shared, unsigned long *text, unsigned long *data, unsigned long *resident) { - *shared =get_mm_counter (mm,MM_FILEPAGES ) + -get_mm_counter (mm,MM_SHMEMPAGES ); + *shared =get_mm_counter_sum (mm,MM_FILEPAGES ) + +get_mm_counter_sum (mm,MM_SHMEMPAGES ); *text = (PAGE_ALIGN (mm->end_code) - (mm->start_code &PAGE_MASK )) >>PAGE_SHIFT ; *data = mm->data_vm + mm->stack_vm; - *resident = *shared +get_mm_counter (mm,MM_ANONPAGES ); + *resident = *shared +get_mm_counter_sum (mm,MM_ANONPAGES );return mm->total_vm; }
include/linux/mm.h +5 -0
@@ -2592,6 +2592,11 @@ static inline unsigned long get_mm_countreturn percpu_counter_read_positive (&mm->rss_stat[member]); } +static inline unsigned long get_mm_counter_sum (struct mm_struct *mm,int member) +{ +return percpu_counter_sum_positive (&mm->rss_stat[member]); +} +void mm_trace_rss_stat (struct mm_struct *mm,int member);static inline void add_mm_counter (struct mm_struct *mm,int member,long value)
Greg Kroah-Hartman
maintainerPATCH 89/163 scripts/gdb: fix interrupts display after MCP on x86
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Fainelli <[email protected]>
commit 7627b459aa0737bdd62a8591a1481cda467f20e3 upstream.
The text line would not be appended to as it should have, it should have been a '+=' but ended up being a '==', fix that.
--- scripts/gdb/linux/interrupts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/gdb/linux/interrupts.py +1 -1
@@ -142,7 +142,7 @@ def x86_show_interupts(prec): if constants.LX_CONFIG_X86_MCE: text += x86_show_mce(prec, "&mce_exception_count", "MCE", "Machine check exceptions") - text == x86_show_mce(prec, "&mce_poll_count", "MCP", "Machine check polls") + text += x86_show_mce(prec, "&mce_poll_count", "MCP", "Machine check polls") text += show_irq_err_count(prec)
Greg Kroah-Hartman
maintainerPATCH 90/163 scripts/gdb: de-reference per-CPU MCE interrupts
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Fainelli <[email protected]>
commit 50f4d2ba26d5c3a4687ae0569be3bbf1c8f0cbed upstream.
The per-CPU MCE interrupts are looked up by reference and need to be de-referenced before printing, otherwise we print the addresses of the variables instead of their contents:
MCE: 18379471554386948492 Machine check exceptions
MCP: 18379471554386948488 Machine check polls
The corrected output looks like this instead now:
MCE: 0 Machine check exceptions MCP: 1 Machine check polls
--- scripts/gdb/linux/interrupts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/gdb/linux/interrupts.py +1 -1
@@ -110,7 +110,7 @@ def x86_show_mce(prec, var, pfx, desc): pvar = gdb.parse_and_eval(var) text = "%*s: " % (prec, pfx) for cpu in cpus.each_online_cpu(): - text += "%10u " % (cpus.per_cpu(pvar, cpu)) + text += "%10u " % (cpus.per_cpu(pvar, cpu).dereference()) text += " %s\n" % (desc) return text
Greg Kroah-Hartman
maintainerPATCH 91/163 scripts/gdb: fix interrupts.py after maple tree conversion
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Fainelli <[email protected]>
commit a02b0cde8ee515ee0c8efd33e7fbe6830c282e69 upstream.
In commit 721255b9826b ("genirq: Use a maple tree for interrupt descriptor management"), the irq_desc_tree was replaced with a sparse_irqs tree using a maple tree structure. Since the script looked for the irq_desc_tree symbol which is no longer available, no interrupts would be printed and the script output would not be useful anymore.
In addition to looking up the correct symbol (sparse_irqs), a new module (mapletree.py) is added whose mtree_load() implementation is largely copied after the C version and uses the same variable and intermediate function names wherever possible to ensure that both the C and Python version be updated in the future.
This restores the scripts' output to match that of /proc/interrupts.
--- scripts/gdb/linux/constants.py.in | 7 + scripts/gdb/linux/interrupts.py | 12 - scripts/gdb/linux/mapletree.py | 252 ++++++++++++++++++++++++++++++++++++++ scripts/gdb/linux/xarray.py | 28 ++++ 4 files changed, 293 insertions(+), 6 deletions(-) create mode 100644 scripts/gdb/linux/mapletree.py create mode 100644 scripts/gdb/linux/xarray.py
scripts/gdb/linux/constants.py.in +7 -0
@@ -20,6 +20,7 @@ #include <linux/of_fdt.h> #include <linux/page_ext.h> #include <linux/radix-tree.h> +#include <linux/maple_tree.h> #include <linux/slab.h> #include <linux/threads.h> #include <linux/vmalloc.h>
@@ -93,6 +94,12 @@ LX_GDBPARSED(RADIX_TREE_MAP_SIZE) LX_GDBPARSED(RADIX_TREE_MAP_SHIFT) LX_GDBPARSED(RADIX_TREE_MAP_MASK) +/* linux/maple_tree.h */ +LX_VALUE(MAPLE_NODE_SLOTS) +LX_VALUE(MAPLE_RANGE64_SLOTS) +LX_VALUE(MAPLE_ARANGE64_SLOTS) +LX_GDBPARSED(MAPLE_NODE_MASK) + /* linux/vmalloc.h */ LX_VALUE(VM_IOREMAP) LX_VALUE(VM_ALLOC)
scripts/gdb/linux/interrupts.py +6 -6
@@ -7,7 +7,7 @@ import gdb from linux import constants from linux import cpus from linux import utils -from linux import radixtree +from linux import mapletree irq_desc_type = utils.CachedType("struct irq_desc")
@@ -23,12 +23,12 @@ def irqd_is_level(desc): def show_irq_desc(prec, irq): text = "" - desc = radixtree.lookup(gdb.parse_and_eval("&irq_desc_tree"), irq) + desc = mapletree.mtree_load(gdb.parse_and_eval("&sparse_irqs"), irq) if desc is None: return text - desc = desc.cast(irq_desc_type.get_type()) - if desc is None: + desc = desc.cast(irq_desc_type.get_type().pointer()) + if desc == 0: return text if irq_settings_is_hidden(desc):
@@ -221,8 +221,8 @@ class LxInterruptList(gdb.Command): gdb.write("CPU%-8d" % cpu) gdb.write("\n") - if utils.gdb_eval_or_none("&irq_desc_tree") is None: - return + if utils.gdb_eval_or_none("&sparse_irqs") is None: + raise gdb.GdbError("Unable to find the sparse IRQ tree, is CONFIG_SPARSE_IRQ enabled?") for irq in range(nr_irqs): gdb.write(show_irq_desc(prec, irq))
scripts/gdb/linux/mapletree.py new file +252 -0
252 lines not on this page · raw message
scripts/gdb/linux/xarray.py new file +28 -0
@@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Xarray helpers +# +# Copyright (c) 2025 Broadcom +# +# Authors: +# Florian Fainelli <[email protected]> + +import gdb + +from linux import utils +from linux import constants + +def xa_is_internal(entry): + ulong_type = utils.get_ulong_type() + return ((entry.cast(ulong_type) & 3) == 2) + +def xa_mk_internal(v): + return ((v << 2) | 2) + +def xa_is_zero(entry): + ulong_type = utils.get_ulong_type() + return entry.cast(ulong_type) == xa_mk_internal(257) + +def xa_is_node(entry): + ulong_type = utils.get_ulong_type() + return xa_is_internal(entry) and (entry.cast(ulong_type) > 4096)
Greg Kroah-Hartman
maintainerPATCH 92/163 mm/vmalloc: leave lazy MMU mode on PTE mapping error
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Gordeev <[email protected]>
commit fea18c686320a53fce7ad62a87a3e1d10ad02f31 upstream.
vmap_pages_pte_range() enters the lazy MMU mode, but fails to leave it in case an error is encountered.
--- mm/vmalloc.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-)
mm/vmalloc.c +15 -7
@@ -487,6 +487,7 @@ static int vmap_pages_pte_range(pmd_t *p unsigned long end, pgprot_t prot, struct page **pages, int *nr, pgtbl_mod_mask *mask) { + int err = 0;pte_t *pte;/*
@@ -500,18 +501,25 @@ static int vmap_pages_pte_range(pmd_t *pdo {struct page *page = pages[*nr]; -if (WARN_ON (!pte_none (ptep_get (pte)))) -return -EBUSY ; -if (WARN_ON (!page)) -return -ENOMEM ; -if (WARN_ON (!pfn_valid (page_to_pfn (page)))) -return -EINVAL ; +if (WARN_ON (!pte_none (ptep_get (pte)))) { + err = -EBUSY ; +break ; + } +if (WARN_ON (!page)) { + err = -ENOMEM ; +break ; + } +if (WARN_ON (!pfn_valid (page_to_pfn (page)))) { + err = -EINVAL ; +break ; + }set_pte_at (&init_mm, addr, pte,mk_pte (page, prot)); (*nr)++; }while (pte++, addr +=PAGE_SIZE , addr != end); *mask |=PGTBL_PTE_MODIFIED ; -return 0 ; + +return err; } static int vmap_pages_pmd_range(pud_t *pud, unsigned long addr,
Greg Kroah-Hartman
maintainerPATCH 93/163 lib/alloc_tag: do not acquire non-existent lock in alloc_tag_top_users()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harry Yoo <[email protected]>
commit 99af22cd34688cc0d535a1919e0bea4cbc6c1ea1 upstream.
alloc_tag_top_users() attempts to lock alloc_tag_cttype->mod_lock even when the alloc_tag_cttype is not allocated because:
1) alloc tagging is disabled because mem profiling is disabled
(!alloc_tag_cttype)
2) alloc tagging is enabled, but not yet initialized (!alloc_tag_cttype)
3) alloc tagging is enabled, but failed initialization (!alloc_tag_cttype or IS_ERR(alloc_tag_cttype))
In all cases, alloc_tag_cttype is not allocated, and therefore alloc_tag_top_users() should not attempt to acquire the semaphore.
This leads to a crash on memory allocation failure by attempting to acquire a non-existent semaphore:
Oops: general protection fault, probably for non-canonical address 0xdffffc000000001b: 0000 [#3] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x00000000000000d8-0x00000000000000df] CPU: 2 UID: 0 PID: 1 Comm: systemd Tainted: G D 6.16.0-rc2 #1 VOLUNTARY Tainted: [D]=DIE Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 RIP: 0010:down_read_trylock+0xaa/0x3b0 Code: d0 7c 08 84 d2 0f 85 a0 02 00 00 8b 0d df 31 dd 04 85 c9 75 29 48 b8 00 00 00 00 00 fc ff df 48 8d 6b 68 48 89 ea 48 c1 ea 03 <80> 3c 02 00 0f 85 88 02 00 00 48 3b 5b 68 0f 85 53 01 00 00 65 ff RSP: 0000:ffff8881002ce9b8 EFLAGS: 00010016 RAX: dffffc0000000000 RBX: 0000000000000070 RCX: 0000000000000000 RDX: 000000000000001b RSI: 000000000000000a RDI: 0000000000000070 RBP: 00000000000000d8 R08: 0000000000000001 R09: ffffed107dde49d1 R10: ffff8883eef24e8b R11: ffff8881002cec20 R12: 1ffff11020059d37 R13: 00000000003fff7b R14: ffff8881002cec20 R15: dffffc0000000000 FS: 00007f963f21d940(0000) GS:ffff888458ca6000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f963f5edf71 CR3: 000000010672c000 CR4: 0000000000350ef0 Call Trace: <TASK> codetag_trylock_module_list+0xd/0x20 alloc_tag_top_users+0x369/0x4b0 __show_mem+0x1cd/0x6e0 warn_alloc+0x2b1/0x390 __alloc_frozen_pages_noprof+0x12b9/0x21a0 alloc_pages_mpol+0x135/0x3e0 alloc_slab_page+0x82/0xe0 new_slab+0x212/0x240 ___slab_alloc+0x82a/0xe00 </TASK>
As David Wang points out, this issue became easier to trigger after commit 780138b12381 ("alloc_tag: check mem_profiling_support in alloc_tag_init").
Before the commit, the issue occurred only when it failed to allocate and initialize alloc_tag_cttype or if a memory allocation fails before alloc_tag_init() is called. After the commit, it can be easily triggered when memory profiling is compiled but disabled at boot.
To properly determine whether alloc_tag_init() has been called and its data structures initialized, verify that alloc_tag_cttype is a valid pointer before acquiring the semaphore. If the variable is NULL or an error value, it has not been properly initialized. In such a case, just skip and do not attempt to acquire the semaphore.
--- lib/alloc_tag.c | 3 +++ 1 file changed, 3 insertions(+)
lib/alloc_tag.c +3 -0
@@ -113,6 +113,9 @@ size_t alloc_tag_top_users(struct codetastruct codetag_bytes n;unsigned int i, nr =0 ; +if (IS_ERR_OR_NULL (alloc_tag_cttype)) +return 0 ; +if (can_sleep)codetag_lock_module_list (alloc_tag_cttype, true);else if (!codetag_trylock_module_list (alloc_tag_cttype))
Greg Kroah-Hartman
maintainerPATCH 94/163 rust: init: allow `dead_code` warnings for Rust >= 1.89.0
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
Starting with Rust 1.89.0 (expected 2025-08-07), the Rust compiler may warn:
error: trait `MustNotImplDrop` is never used
--> rust/kernel/init/macros.rs:927:15
|
927 | trait MustNotImplDrop {}
| ^^^^^^^^^^^^^^^
|
::: rust/kernel/sync/arc.rs:133:1
|
133 | #[pin_data]
| ----------- in this procedural macro expansion
|
= note: `-D dead-code` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(dead_code)]`
= note: this error originates in the macro `$crate::__pin_data`
which comes from the expansion of the attribute macro
`pin_data` (in Nightly builds, run with
-Z macro-backtrace for more info)Thus allow it to clean it up.
This does not happen in mainline nor 6.15.y, because there the macro was moved out of the kernel crate, and dead_code warnings are not emitted if the macro is foreign to the crate. Thus this patch is directly sent to stable and intended for 6.12.y only.
Similarly, it is not needed in previous LTSs, because there the Rust version is pinned.
--- rust/kernel/init/macros.rs | 2 ++ 1 file changed, 2 insertions(+)
rust/kernel/init/macros.rs +2 -0
@@ -924,6 +924,7 @@ macro_rules! __pin_data {// We prevent this by creating a trait that will be implemented for all types implementing // `Drop`. Additionally we will implement this trait for the struct leading to a conflict, // if it also implements `Drop` +#[allow(dead_code)] trait MustNotImplDrop {}#[expect(drop_bounds)] impl <T : ::core::ops::Drop >MustNotImplDrop for T {}
@@ -932,6 +933,7 @@ macro_rules! __pin_data {// We also take care to prevent users from writing a useless `PinnedDrop` implementation. // They might implement `PinnedDrop` correctly for the struct, but forget to give // `PinnedDrop` as the parameter to `#[pin_data]`. +#[allow(dead_code)] #[expect(non_camel_case_types)] trait UselessPinnedDropImpl_you_need_to_specify_PinnedDrop {} impl<T: $crate::init::PinnedDrop>
Greg Kroah-Hartman
maintainerPATCH 95/163 clk: imx: Fix an out-of-bounds access in dispmix_csr_clk_dev_data
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiaolei Wang <[email protected]>
commit aacc875a448d363332b9df0621dde6d3a225ea9f upstream.
When num_parents is 4, __clk_register() occurs an out-of-bounds when accessing parent_names member. Use ARRAY_SIZE() instead of hardcode number here.
BUG: KASAN: global-out-of-bounds in __clk_register+0x1844/0x20d8
Read of size 8 at addr ffff800086988e78 by task kworker/u24:3/59
Hardware name: NXP i.MX95 19X19 board (DT)
Workqueue: events_unbound deferred_probe_work_func
Call trace:
dump_backtrace+0x94/0xec
show_stack+0x18/0x24
dump_stack_lvl+0x8c/0xcc
print_report+0x398/0x5fc
kasan_report+0xd4/0x114
__asan_report_load8_noabort+0x20/0x2c
__clk_register+0x1844/0x20d8
clk_hw_register+0x44/0x110
__clk_hw_register_mux+0x284/0x3a8
imx95_bc_probe+0x4f4/0xa70--- drivers/clk/imx/clk-imx95-blk-ctl.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/clk/imx/clk-imx95-blk-ctl.c +8 -4
@@ -219,11 +219,15 @@ static const struct imx95_blk_ctl_dev_data lvds_csr_dev_data = { .clk_reg_offset = 0, }; +static const char *const disp_engine_parents[] = { +"videopll1" ,"dsi_pll" ,"ldb_pll_div7" +}; +static const struct imx95_blk_ctl_clk_dev_data dispmix_csr_clk_dev_data[] = { [IMX95_CLK_DISPMIX_ENG0_SEL ] = { .name ="disp_engine0_sel" , - .parent_names = (const char *[]){"videopll1" ,"dsi_pll" ,"ldb_pll_div7" , }, - .num_parents =4 , + .parent_names = disp_engine_parents, + .num_parents =ARRAY_SIZE (disp_engine_parents), .reg =0 , .bit_idx =0 , .bit_width =2 ,
@@ -232,8 +236,8 @@ static const struct imx95_blk_ctl_clk_dev_data dispmix_csr_clk_dev_data[] = { }, [IMX95_CLK_DISPMIX_ENG1_SEL] = { .name = "disp_engine1_sel", - .parent_names = (const char *[]){"videopll1", "dsi_pll", "ldb_pll_div7", }, - .num_parents = 4, + .parent_names = disp_engine_parents, + .num_parents = ARRAY_SIZE(disp_engine_parents), .reg = 0, .bit_idx = 2, .bit_width = 2,
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 96/163 x86/rdrand: Disable RDSEED on AMD Cyan Skillfish
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Paulyshka <[email protected]>
commit 5b937a1ed64ebeba8876e398110a5790ad77407c upstream.
AMD Cyan Skillfish (Family 17h, Model 47h, Stepping 0h) has an error that causes RDSEED to always return 0xffffffff, while RDRAND works correctly.
Mask the RDSEED cap for this CPU so that both /proc/cpuinfo and direct CPUID read report RDSEED as unavailable.
[ bp: Move to amd.c, massage. ]
--- arch/x86/include/asm/msr-index.h | 1 + arch/x86/kernel/cpu/amd.c | 7 +++++++ tools/arch/x86/include/asm/msr-index.h | 1 + 3 files changed, 9 insertions(+)
arch/x86/include/asm/msr-index.h +1 -0
@@ -621,6 +621,7 @@#define MSR_AMD64_OSVW_STATUS 0xc0010141#define MSR_AMD_PPIN_CTL 0xc00102f0#define MSR_AMD_PPIN 0xc00102f1 +#define MSR_AMD64_CPUID_FN_7 0xc0011002#define MSR_AMD64_CPUID_FN_1 0xc0011004#define MSR_AMD64_LS_CFG 0xc0011020#define MSR_AMD64_DC_CFG 0xc0011022
arch/x86/kernel/cpu/amd.c +7 -0
@@ -977,6 +977,13 @@ static void init_amd_zen2(struct cpuinfoinit_spectral_chicken (c);fix_erratum_1386 (c);zen2_zenbleed_check (c); + +/* Disable RDSEED on AMD Cyan Skillfish because of an error. */ +if (c->x86_model ==0x47 && c->x86_stepping ==0x0 ) { +clear_cpu_cap (c,X86_FEATURE_RDSEED ); +msr_clear_bit (MSR_AMD64_CPUID_FN_7 ,18 ); +pr_emerg ("RDSEED is not reliable on this platform; disabling.\n" ); + } }static void init_amd_zen3 (struct cpuinfo_x86 *c)
tools/arch/x86/include/asm/msr-index.h +1 -0
@@ -612,6 +612,7 @@#define MSR_AMD64_OSVW_STATUS 0xc0010141#define MSR_AMD_PPIN_CTL 0xc00102f0#define MSR_AMD_PPIN 0xc00102f1 +#define MSR_AMD64_CPUID_FN_7 0xc0011002#define MSR_AMD64_CPUID_FN_1 0xc0011004#define MSR_AMD64_LS_CFG 0xc0011020#define MSR_AMD64_DC_CFG 0xc0011022
Greg Kroah-Hartman
maintainerPATCH 97/163 x86/mm: Disable hugetlb page table sharing on 32-bit
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <[email protected]>
commit 76303ee8d54bff6d9a6d55997acd88a6c2ba63cf upstream.
Only select ARCH_WANT_HUGE_PMD_SHARE on 64-bit x86.
Page table sharing requires at least three levels because it involves shared references to PMD tables; 32-bit x86 has either two-level paging (without PAE) or three-level paging (with PAE), but even with three-level paging, having a dedicated PGD entry for hugetlb is only barely possible (because the PGD only has four entries), and it seems unlikely anyone's actually using PMD sharing on 32-bit.
Having ARCH_WANT_HUGE_PMD_SHARE enabled on non-PAE 32-bit X86 (which has 2-level paging) became particularly problematic after commit 59d9094df3d7 ("mm: hugetlb: independent PMD page table shared count"), since that changes struct ptdesc such that the pt_mm (for PGDs) and the pt_share_count (for PMDs) share the same union storage - and with 2-level paging, PMDs are PGDs.
(For comparison, arm64 also gates ARCH_WANT_HUGE_PMD_SHARE on the configuration of page tables such that it is never enabled with 2-level paging.)
--- arch/x86/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/Kconfig +1 -1
@@ -137,7 +137,7 @@ config X86 select ARCH_WANTS_DYNAMIC_TASK_STRUCT select ARCH_WANTS_NO_INSTR select ARCH_WANT_GENERAL_HUGETLB - select ARCH_WANT_HUGE_PMD_SHARE + select ARCH_WANT_HUGE_PMD_SHARE if X86_64 select ARCH_WANT_LD_ORPHAN_WARN select ARCH_WANT_OPTIMIZE_DAX_VMEMMAP if X86_64 select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP if X86_64
Greg Kroah-Hartman
maintainerPATCH 98/163 clk: scmi: Handle case where child clocks are initialized before their parents
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sascha Hauer <[email protected]>
commit 6306e0c5a0d28e9df2b5902f4a021204bee75173 upstream.
The SCMI clock driver currently assumes that parent clocks are always initialized before their children. However, this assumption can fail if a child clock is encountered before its parent during probe.
This leads to an issue during initialization of the parent_data array:
sclk->parent_data[i].hw = hws[sclk->info->parents[i]];
If the parent clock's hardware structure has not been initialized yet, this assignment results in invalid data.
To resolve this, allocate all struct scmi_clk instances as a contiguous array at the beginning of the probe and populate the hws[] array upfront. This ensures that any parent referenced later is already initialized, regardless of the order in which clocks are processed.
Note that we can no longer free individual scmi_clk instances if scmi_clk_ops_init() fails which shouldn't be a problem if the SCMI platform has proper per-agent clock discovery.
--- drivers/clk/clk-scmi.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-)
drivers/clk/clk-scmi.c +10 -8
@@ -404,6 +404,7 @@ static int scmi_clocks_probe(struct scmiconst struct scmi_handle *handle = sdev->handle;struct scmi_protocol_handle *ph;const struct clk_ops *scmi_clk_ops_db[SCMI_MAX_CLK_OPS ] = {}; +struct scmi_clk *sclks;if (!handle)return -ENODEV ;
@@ -430,18 +431,21 @@ static int scmi_clocks_probe(struct scmi transport_is_atomic = handle->is_transport_atomic (handle, &atomic_threshold_us); + sclks =devm_kcalloc (dev, count,sizeof (*sclks),GFP_KERNEL ); +if (!sclks) +return -ENOMEM ; + +for (idx =0 ; idx < count; idx++) + hws[idx] = &sclks[idx].hw; +for (idx =0 ; idx < count; idx++) { -struct scmi_clk *sclk; +struct scmi_clk *sclk = &sclks[idx];const struct clk_ops *scmi_ops; - sclk =devm_kzalloc (dev,sizeof (*sclk),GFP_KERNEL ); -if (!sclk) -return -ENOMEM ; - sclk->info = scmi_proto_clk_ops->info_get (ph, idx);if (!sclk->info) {dev_dbg (dev,"invalid clock info for idx %d\n" , idx); -devm_kfree (dev, sclk); + hws[idx] =NULL ;continue ; }
@@ -479,13 +483,11 @@ static int scmi_clocks_probe(struct scmiif (err) {dev_err (dev,"failed to register clock %d\n" , idx);devm_kfree (dev, sclk->parent_data); -devm_kfree (dev, sclk); hws[idx] =NULL ; }else {dev_dbg (dev,"Registered clock:%s%s\n" , sclk->info->name, scmi_ops->enable ?" (atomic ops)" :"" ); - hws[idx] = &sclk->hw; } }
Greg Kroah-Hartman
maintainerPATCH 99/163 smb: server: make use of rdma_destroy_qp()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Metzmacher <[email protected]>
commit 0c2b53997e8f5e2ec9e0fbd17ac0436466b65488 upstream.
The qp is created by rdma_create_qp() as t->cm_id->qp and t->qp is just a shortcut.
rdma_destroy_qp() also calls ib_destroy_qp(cm_id->qp) internally, but it is protected by a mutex, clears the cm_id and also calls trace_cm_qp_destroy().
This should make the tracing more useful as both rdma_create_qp() and rdma_destroy_qp() are traces and it makes the code look more sane as functions from the same layer are used for the specific qp object.
trace-cmd stream -e rdma_cma:cm_qp_create -e rdma_cma:cm_qp_destroy shows this now while doing a mount and unmount from a client:
<...>-80 [002] 378.514182: cm_qp_create: cm.id=1 src=172.31.9.167:5445 dst=172.31.9.166:37113 tos=0 pd.id=0 qp_type=RC send_wr=867 recv_wr=255 qp_num=1 rc=0
<...>-6283 [001] 381.686172: cm_qp_destroy: cm.id=1 src=172.31.9.167:5445 dst=172.31.9.166:37113 tos=0 qp_num=1
Before we only saw the first line.
--- fs/smb/server/transport_rdma.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/smb/server/transport_rdma.c +3 -2
@@ -432,7 +432,8 @@ static void free_transport(struct smb_diif (t->qp) {ib_drain_qp (t->qp);ib_mr_pool_destroy (t->qp, &t->qp->rdma_mrs); -ib_destroy_qp (t->qp); + t->qp =NULL ; +rdma_destroy_qp (t->cm_id); }ksmbd_debug (RDMA ,"drain the reassembly queue\n" );
@@ -1939,8 +1940,8 @@ static int smb_direct_create_qpair(strucreturn 0 ; err:if (t->qp) { -ib_destroy_qp (t->qp); t->qp =NULL ; +rdma_destroy_qp (t->cm_id); }if (t->recv_cq) {ib_destroy_cq (t->recv_cq);
Greg Kroah-Hartman
maintainerPATCH 100/163 ksmbd: fix a mount write count leak in ksmbd_vfs_kern_path_locked()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 277627b431a0a6401635c416a21b2a0f77a77347 upstream.
If the call of ksmbd_vfs_lock_parent() fails, we drop the parent_path references and return an error. We need to drop the write access we just got on parent_path->mnt before we drop the mount reference - callers assume that ksmbd_vfs_kern_path_locked() returns with mount write access grabbed if and only if it has returned 0.
--- fs/smb/server/vfs.c | 1 + 1 file changed, 1 insertion(+)
fs/smb/server/vfs.c +1 -0
@@ -1298,6 +1298,7 @@ out1: err =ksmbd_vfs_lock_parent (parent_path->dentry, path->dentry);if (err) { +mnt_drop_write (parent_path->mnt);path_put (path);path_put (parent_path); }
Greg Kroah-Hartman
maintainerPATCH 101/163 erofs: fix to add missing tracepoint in erofs_read_folio()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
commit 99f7619a77a0a2e3e2bcae676d0f301769167754 upstream.
Commit 771c994ea51f ("erofs: convert all uncompressed cases to iomap") converts to use iomap interface, it removed trace_erofs_readpage() tracepoint in the meantime, let's add it back.
--- fs/erofs/data.c | 2 ++ 1 file changed, 2 insertions(+)
fs/erofs/data.c +2 -0
@@ -378,6 +378,8 @@ int erofs_fiemap(struct inode *inode, st*/ static int erofs_read_folio (struct file *file,struct folio *folio) { +trace_erofs_read_folio (folio, true); +return iomap_read_folio (folio, &erofs_iomap_ops); }
Greg Kroah-Hartman
maintainerPATCH 102/163 erofs: address D-cache aliasing
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao Xiang <[email protected]>
commit 27917e8194f91dffd8b4825350c63cb68e98ce58 upstream.
Flush the D-cache before unlocking folios for compressed inodes, as they are dirtied during decompression.
Avoid calling flush_dcache_folio() on every CPU write, since it's more like playing whack-a-mole without real benefit.
It has no impact on x86 and arm64/risc-v: on x86, flush_dcache_folio() is a no-op, and on arm64/risc-v, PG_dcache_clean (PG_arch_1) is clear for new page cache folios. However, certain ARM boards are affected, as reported.
--- fs/erofs/data.c | 16 +++++++++++----- fs/erofs/decompressor.c | 12 ++++-------- fs/erofs/fileio.c | 4 ++-- fs/erofs/internal.h | 2 +- fs/erofs/zdata.c | 6 +++--- 5 files changed, 21 insertions(+), 19 deletions(-)
fs/erofs/data.c +11 -5
@@ -240,9 +240,11 @@ int erofs_map_dev(struct super_block *sb/* * bit 30: I/O error occurred on this folio +* bit 29: CPU has dirty data in D-cache (needs aliasing handling); * bit 0 - 29: remaining parts to complete this folio */ -#define EROFS_ONLINEFOLIO_EIO (1 << 30) +#define EROFS_ONLINEFOLIO_EIO 30 +#define EROFS_ONLINEFOLIO_DIRTY 29void erofs_onlinefolio_init (struct folio *folio) {
@@ -259,19 +261,23 @@ void erofs_onlinefolio_split(struct foliatomic_inc ((atomic_t *)&folio->private); } -void erofs_onlinefolio_end (struct folio *folio,int err) +void erofs_onlinefolio_end (struct folio *folio,int err,bool dirty) {int orig, v;do { orig =atomic_read ((atomic_t *)&folio->private); - v = (orig -1 ) | (err ?EROFS_ONLINEFOLIO_EIO :0 ); +DBG_BUGON (orig <=0 ); + v = dirty <<EROFS_ONLINEFOLIO_DIRTY ; + v |= (orig -1 ) | (!!err <<EROFS_ONLINEFOLIO_EIO ); }while (atomic_cmpxchg ((atomic_t *)&folio->private, orig, v) != orig); -if (v & ~EROFS_ONLINEFOLIO_EIO ) +if (v & (BIT (EROFS_ONLINEFOLIO_DIRTY ) -1 ))return ; folio->private =0 ; -folio_end_read (folio, !(v &EROFS_ONLINEFOLIO_EIO )); +if (v &BIT (EROFS_ONLINEFOLIO_DIRTY )) +flush_dcache_folio (folio); +folio_end_read (folio, !(v &BIT (EROFS_ONLINEFOLIO_EIO ))); } static int erofs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
fs/erofs/decompressor.c +4 -8
@@ -331,13 +331,11 @@ static int z_erofs_transform_plain(struc cur =min (cur, rq->outputsize);if (cur && rq->out[0 ]) { kin =kmap_local_page (rq->in[nrpages_in -1 ]); -if (rq->out[0 ] == rq->in[nrpages_in -1 ]) { +if (rq->out[0 ] == rq->in[nrpages_in -1 ])memmove (kin + rq->pageofs_out, kin + pi, cur); -flush_dcache_page (rq->out[0 ]); - }else { +else memcpy_to_page (rq->out[0 ], rq->pageofs_out, kin + pi, cur); - }kunmap_local (kin); } rq->outputsize -= cur;
@@ -355,14 +353,12 @@ static int z_erofs_transform_plain(struc po = (rq->pageofs_out + cur + pi) & ~PAGE_MASK ;DBG_BUGON (no >= nrpages_out); cnt =min (insz - pi,PAGE_SIZE - po); -if (rq->out[no] == rq->in[ni]) { +if (rq->out[no] == rq->in[ni])memmove (kin + po, kin + rq->pageofs_in + pi, cnt); -flush_dcache_page (rq->out[no]); - }else if (rq->out[no]) { +else if (rq->out[no])memcpy_to_page (rq->out[no], po, kin + rq->pageofs_in + pi, cnt); - } pi += cnt; }while (pi < insz);kunmap_local (kin);
fs/erofs/fileio.c +2 -2
@@ -38,7 +38,7 @@ static void erofs_fileio_ki_complete(str }else {bio_for_each_folio_all (fi, &rq->bio) {DBG_BUGON (folio_test_uptodate (fi.folio)); -erofs_onlinefolio_end (fi.folio, ret); +erofs_onlinefolio_end (fi.folio, ret, false); } }bio_uninit (&rq->bio);
@@ -158,7 +158,7 @@ io_retry: } cur += len; } -erofs_onlinefolio_end (folio, err); +erofs_onlinefolio_end (folio, err, false);return err; }
fs/erofs/internal.h +1 -1
@@ -405,7 +405,7 @@ int erofs_fiemap(struct inode *inode, stint erofs_map_blocks (struct inode *inode,struct erofs_map_blocks *map);void erofs_onlinefolio_init (struct folio *folio);void erofs_onlinefolio_split (struct folio *folio); -void erofs_onlinefolio_end (struct folio *folio,int err); +void erofs_onlinefolio_end (struct folio *folio,int err,bool dirty);struct inode *erofs_iget (struct super_block *sb,erofs_nid_t nid); int erofs_getattr(struct mnt_idmap *idmap, const struct path *path, struct kstat *stat, u32 request_mask,
fs/erofs/zdata.c +3 -3
@@ -1087,7 +1087,7 @@ static int z_erofs_scan_folio(struct z_e tight = (bs ==PAGE_SIZE ); } }while ((end = cur) >0 ); -erofs_onlinefolio_end (folio, err); +erofs_onlinefolio_end (folio, err, false);return err; }
@@ -1193,7 +1193,7 @@ static void z_erofs_fill_other_copies(st cur += len; }kunmap_local (dst); -erofs_onlinefolio_end (page_folio (bvi->bvec.page), err); +erofs_onlinefolio_end (page_folio (bvi->bvec.page), err, true);list_del (p);kfree (bvi); }
@@ -1348,7 +1348,7 @@ static int z_erofs_decompress_pcluster(sDBG_BUGON (z_erofs_page_is_invalidated (page));if (!z_erofs_is_shortlived_page (page)) { -erofs_onlinefolio_end (page_folio (page), err); +erofs_onlinefolio_end (page_folio (page), err, true);continue ; }if (pcl->algorithmformat !=Z_EROFS_COMPRESSION_LZ4 ) {
Greg Kroah-Hartman
maintainerPATCH 103/163 ASoC: Intel: sof-function-topology-lib: Print out the unsupported dmic count
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi <[email protected]>
commit 16ea4666bbb7f5bd1130fa2d75631ccf8b62362e upstream.
It is better to print out the non supported num_dmics than printing that it is not matching with 2 or 4.
--- sound/soc/intel/common/sof-function-topology-lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
sound/soc/intel/common/sof-function-topology-lib.c +2 -1
@@ -73,7 +73,8 @@ int sof_sdw_get_tplg_files(struct snd_sobreak ;default :dev_warn (card->dev, -"only -2ch and -4ch are supported for dmic\n" ); +"unsupported number of dmics: %d\n" , + mach_params.dmic_num);continue ; } tplg_dev =TPLG_DEVICE_INTEL_PCH_DMIC ;
Greg Kroah-Hartman
maintainerPATCH 104/163 netlink: Fix rmem check in netlink_broadcast_deliver().
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
commit a3c4a125ec725cefb40047eb05ff9eafd57830b4 upstream.
We need to allow queuing at least one skb even when skb is larger than sk->sk_rcvbuf.
The cited commit made a mistake while converting a condition in netlink_broadcast_deliver().
Let's correct the rmem check for the allow-one-skb rule.
--- net/netlink/af_netlink.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netlink/af_netlink.c +1 -1
@@ -1398,7 +1398,7 @@ static int netlink_broadcast_deliver(str rmem =atomic_add_return (skb->truesize, &sk->sk_rmem_alloc); rcvbuf =READ_ONCE (sk->sk_rcvbuf); -if ((rmem != skb->truesize || rmem <= rcvbuf) && +if ((rmem == skb->truesize || rmem <= rcvbuf) && !test_bit (NETLINK_S_CONGESTED , &nlk->state)) {netlink_skb_set_owner_r (skb, sk);__netlink_sendskb (sk, skb);
Greg Kroah-Hartman
maintainerPATCH 105/163 netlink: make sure we allow at least one dump skb
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
commit a215b5723922f8099078478122f02100e489cb80 upstream.
Commit under Fixes tightened up the memory accounting for Netlink sockets. Looks like the accounting is too strict for some existing use cases, Marek reported issues with nl80211 / WiFi iw CLI.
To reduce number of iterations Netlink dumps try to allocate messages based on the size of the buffer passed to previous recvmsg() calls. If user space uses a larger buffer in recvmsg() than sk_rcvbuf we will allocate an skb we won't be able to queue.
Make sure we always allow at least one skb to be queued. Same workaround is already present in netlink_attachskb(). Alternative would be to cap the allocation size to
rcvbuf - rmem_alloc
but as I said, the workaround is already present in other places.
--- net/netlink/af_netlink.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/netlink/af_netlink.c +3 -2
@@ -2261,11 +2261,11 @@ static int netlink_dump(struct sock *sk,struct netlink_ext_ack extack = {};struct netlink_callback *cb;struct sk_buff *skb =NULL ; +unsigned int rmem, rcvbuf;size_t max_recvmsg_len;struct module *module;int err = -ENOBUFS ;int alloc_min_size; -unsigned int rmem;int alloc_size;if (!lock_taken)
@@ -2297,8 +2297,9 @@ static int netlink_dump(struct sock *sk,if (!skb) goto errout_skb; + rcvbuf =READ_ONCE (sk->sk_rcvbuf); rmem =atomic_add_return (skb->truesize, &sk->sk_rmem_alloc); -if (rmem >=READ_ONCE (sk->sk_rcvbuf)) { +if (rmem != skb->truesize && rmem >= rcvbuf) {atomic_sub (skb->truesize, &sk->sk_rmem_alloc); goto errout_skb; }
Greg Kroah-Hartman
maintainerPATCH 106/163 netfs: Fix ref leak on inserted extra subreq in write retry
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit 97d8e8e52cb8ab3d7675880a92626d9a4332f7a6 ]
The write-retry algorithm will insert extra subrequests into the list if it can't get sufficient capacity to split the range that needs to be retried into the sequence of subrequests it currently has (for instance, if the cifs credit pool has fewer credits available than it did when the range was originally divided).
However, the allocator furnishes each new subreq with 2 refs and then another is added for resubmission, causing one to be leaked.
Fix this by replacing the ref-getting line with a neutral trace line.
--- fs/netfs/write_collect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/netfs/write_collect.c +1 -1
@@ -285,7 +285,7 @@ static void netfs_retry_write_stream(struct netfs_io_request *wreq,trace_netfs_sreq_ref (wreq->debug_id, subreq->debug_index,refcount_read (&subreq->ref), netfs_sreq_trace_new); -netfs_get_subrequest (subreq, netfs_sreq_trace_get_resubmit); +trace_netfs_sreq (subreq, netfs_sreq_trace_split);list_add (&subreq->rreq_link, &to->rreq_link); to =list_next_entry (to, rreq_link);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 107/163 wifi: cfg80211: fix S1G beacon head validation in nl80211
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lachlan Hodges <[email protected]>
[ Upstream commit 1fe44a86ff0ff483aa1f1332f2b08f431fa51ce8 ]
S1G beacons contain fixed length optional fields that precede the variable length elements, ensure we take this into account when validating the beacon. This particular case was missed in 1e1f706fc2ce ("wifi: cfg80211/mac80211: correctly parse S1G beacon optional elements").
--- net/wireless/nl80211.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/wireless/nl80211.c +5 -2
@@ -229,6 +229,7 @@ static int validate_beacon_head(const struct nlattr *attr,unsigned int len =nla_len (attr);const struct element *elem;const struct ieee80211_mgmt *mgmt = (void *)data; +const struct ieee80211_ext *ext;unsigned int fixedlen, hdrlen;bool s1g_bcn;
@@ -237,8 +238,10 @@ static int validate_beacon_head(const struct nlattr *attr, s1g_bcn =ieee80211_is_s1g_beacon (mgmt->frame_control);if (s1g_bcn) { - fixedlen = offsetof(struct ieee80211_ext , - u.s1g_beacon.variable); + ext = (struct ieee80211_ext *)mgmt; + fixedlen = + offsetof(struct ieee80211_ext, u.s1g_beacon.variable) + +ieee80211_s1g_optional_len (ext->frame_control); hdrlen = offsetof(struct ieee80211_ext, u.s1g_beacon); }else { fixedlen = offsetof(struct ieee80211_mgmt,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 108/163 wifi: zd1211rw: Fix potential NULL pointer dereference in zd_mac_tx_to_dev()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniil Dulov <[email protected]>
[ Upstream commit 74b1ec9f5d627d2bdd5e5b6f3f81c23317657023 ]
There is a potential NULL pointer dereference in zd_mac_tx_to_dev(). For example, the following is possible:
T0 T1
zd_mac_tx_to_dev()
/* len == skb_queue_len(q) */
while (len > ZD_MAC_MAX_ACK_WAITERS) {
filter_ack()
spin_lock_irqsave(&q->lock, flags);
/* position == skb_queue_len(q) */
for (i=1; i<position; i++)
skb = __skb_dequeue(q)
if (mac->type == NL80211_IFTYPE_AP)
skb = __skb_dequeue(q);
spin_unlock_irqrestore(&q->lock, flags);
skb_dequeue() -> NULLSince there is a small gap between checking skb queue length and skb being unconditionally dequeued in zd_mac_tx_to_dev(), skb_dequeue() can return NULL. Then the pointer is passed to zd_mac_tx_status() where it is dereferenced.
In order to avoid potential NULL pointer dereference due to situations like above, check if skb is not NULL before passing it to zd_mac_tx_status().
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/net/wireless/zydas/zd1211rw/zd_mac.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/net/wireless/zydas/zd1211rw/zd_mac.c +5 -1
@@ -583,7 +583,11 @@ void zd_mac_tx_to_dev(struct sk_buff *skb, int error)skb_queue_tail (q, skb);while (skb_queue_len (q) >ZD_MAC_MAX_ACK_WAITERS ) { -zd_mac_tx_status (hw,skb_dequeue (q), + skb =skb_dequeue (q); +if (!skb) +break ; + +zd_mac_tx_status (hw, skb, mac->ack_pending ? mac->ack_signal :0 ,NULL ); mac->ack_pending =0 ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 109/163 drm/tegra: nvdec: Fix dma_alloc_coherent error check
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikko Perttunen <[email protected]>
[ Upstream commit 44306a684cd1699b8562a54945ddc43e2abc9eab ]
Check for NULL return value with dma_alloc_coherent, in line with Robin's fix for vic.c in 'drm/tegra: vic: Fix DMA API misuse'.
--- drivers/gpu/drm/tegra/nvdec.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/gpu/drm/tegra/nvdec.c +2 -4
@@ -261,10 +261,8 @@ static int nvdec_load_falcon_firmware(struct nvdec *nvdec)if (!client->group) { virt =dma_alloc_coherent (nvdec->dev, size, &iova,GFP_KERNEL ); - - err =dma_mapping_error (nvdec->dev, iova); -if (err <0 ) -return err; +if (!virt) +return -ENOMEM ; }else { virt =tegra_drm_alloc (tegra, size, &iova);if (IS_ERR (virt))
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 110/163 md/raid1: Fix stack memory use after return in raid1_reshape
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Jinchao <[email protected]>
[ Upstream commit d67ed2ccd2d1dcfda9292c0ea8697a9d0f2f0d98 ]
In the raid1_reshape function, newpool is allocated on the stack and assigned to conf->r1bio_pool. This results in conf->r1bio_pool.wait.head pointing to a stack address.
Accessing this address later can lead to a kernel panic.
Example access path:
raid1_reshape()
{
// newpool is on the stack
mempool_t newpool, oldpool;
// initialize newpool.wait.head to stack address
mempool_init(&newpool, ...);
conf->r1bio_pool = newpool;
}raid1_read_request() or raid1_write_request()
{
alloc_r1bio()
{
mempool_alloc()
{
// if pool->alloc fails
remove_element()
{
--pool->curr_nr;
}
}
}
}mempool_free()
{
if (pool->curr_nr < pool->min_nr) {
// pool->wait.head is a stack address
// wake_up() will try to access this invalid address
// which leads to a kernel panic
return;
wake_up(&pool->wait);
}
}Fix:
reinit conf->r1bio_pool.wait after assigning newpool.
--- drivers/md/raid1.c | 1 + 1 file changed, 1 insertion(+)
drivers/md/raid1.c +1 -0
@@ -3380,6 +3380,7 @@ static int raid1_reshape(struct mddev *mddev)/* ok, everything is stopped */ oldpool = conf->r1bio_pool; conf->r1bio_pool = newpool; +init_waitqueue_head (&conf->r1bio_pool.wait);for (d = d2 =0 ; d < conf->raid_disks; d++) {struct md_rdev *rdev = conf->mirrors[d].rdev;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 111/163 raid10: cleanup memleak at raid10_make_request
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nigel Croxon <[email protected]>
[ Upstream commit 43806c3d5b9bb7d74ba4e33a6a8a41ac988bde24 ]
If raid10_read_request or raid10_write_request registers a new request and the REQ_NOWAIT flag is set, the code does not free the malloc from the mempool.
unreferenced object 0xffff8884802c3200 (size 192):
comm "fio", pid 9197, jiffies 4298078271 hex dump (first 32 bytes):
00 00 00 00 00 00 00 00 88 41 02 00 00 00 00 00 .........A......
08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
backtrace (crc c1a049a2):
__kmalloc+0x2bb/0x450
mempool_alloc+0x11b/0x320
raid10_make_request+0x19e/0x650 [raid10]
md_handle_request+0x3b3/0x9e0
__submit_bio+0x394/0x560
__submit_bio_noacct+0x145/0x530
submit_bio_noacct_nocheck+0x682/0x830
__blkdev_direct_IO_async+0x4dc/0x6b0
blkdev_read_iter+0x1e5/0x3b0
__io_read+0x230/0x1110
io_read+0x13/0x30
io_issue_sqe+0x134/0x1180
io_submit_sqes+0x48c/0xe90
__do_sys_io_uring_enter+0x574/0x8b0
do_syscall_64+0x5c/0xe0
entry_SYSCALL_64_after_hwframe+0x76/0x7eV4: changing backing tree to see if CKI tests will pass. The patch code has not changed between any versions.
--- drivers/md/raid10.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/md/raid10.c +8 -2
@@ -1181,8 +1181,11 @@ static void raid10_read_request(struct mddev *mddev, struct bio *bio, } } -if (!regular_request_wait (mddev, conf, bio, r10_bio->sectors)) +if (!regular_request_wait (mddev, conf, bio, r10_bio->sectors)) { +raid_end_bio_io (r10_bio);return ; + } + rdev =read_balance (conf, r10_bio, &max_sectors);if (!rdev) {if (err_rdev) {
@@ -1368,8 +1371,11 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio, } sectors = r10_bio->sectors; -if (!regular_request_wait (mddev, conf, bio, sectors)) +if (!regular_request_wait (mddev, conf, bio, sectors)) { +raid_end_bio_io (r10_bio);return ; + } + if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) && (mddev->reshape_backwards ? (bio->bi_iter.bi_sector < conf->reshape_safe &&
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 112/163 wifi: mac80211: correctly identify S1G short beacon
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lachlan Hodges <[email protected]>
[ Upstream commit c5fd399a24c8e2865524361f7dc4d4a6899be4f4 ]
mac80211 identifies a short beacon by the presence of the next TBTT field, however the standard actually doesn't explicitly state that the next TBTT can't be in a long beacon or even that it is required in a short beacon - and as a result this validation does not work for all vendor implementations.
The standard explicitly states that an S1G long beacon shall contain the S1G beacon compatibility element as the first element in a beacon transmitted at a TBTT that is not a TSBTT (Target Short Beacon Transmission Time) as per IEEE80211-2024 11.1.3.10.1. This is validated by 9.3.4.3 Table 9-76 which states that the S1G beacon compatibility element is only allowed in the full set and is not allowed in the minimum set of elements permitted for use within short beacons.
Correctly identify short beacons by the lack of an S1G beacon compatibility element as the first element in an S1G beacon frame.
--- include/linux/ieee80211.h | 45 ++++++++++++++++++++++++++++----------- net/mac80211/mlme.c | 7 ++++-- 2 files changed, 38 insertions(+), 14 deletions(-)
include/linux/ieee80211.h +33 -12
@@ -662,18 +662,6 @@ static inline bool ieee80211_s1g_has_cssid(__le16 fc) (fc &cpu_to_le16 (IEEE80211_S1G_BCN_CSSID )); } -/** -* ieee80211_is_s1g_short_beacon - check if frame is an S1G short beacon -* @fc: frame control bytes in little-endian byteorder -* Return: whether or not the frame is an S1G short beacon, -* i.e. it is an S1G beacon with 'next TBTT' flag set -*/ -static inline bool ieee80211_is_s1g_short_beacon (__le16 fc) -{ -return ieee80211_is_s1g_beacon (fc) && - (fc &cpu_to_le16 (IEEE80211_S1G_BCN_NEXT_TBTT )); -} -/** * ieee80211_is_atim - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ATIM * @fc: frame control bytes in little-endian byteorder
@@ -4863,6 +4851,39 @@ static inline bool ieee80211_is_ftm(struct sk_buff *skb)return false; } +/** +* ieee80211_is_s1g_short_beacon - check if frame is an S1G short beacon +* @fc: frame control bytes in little-endian byteorder +* @variable: pointer to the beacon frame elements +* @variable_len: length of the frame elements +* Return: whether or not the frame is an S1G short beacon. As per +* IEEE80211-2024 11.1.3.10.1, The S1G beacon compatibility element shall +* always be present as the first element in beacon frames generated at a +* TBTT (Target Beacon Transmission Time), so any frame not containing +* this element must have been generated at a TSBTT (Target Short Beacon +* Transmission Time) that is not a TBTT. Additionally, short beacons are +* prohibited from containing the S1G beacon compatibility element as per +* IEEE80211-2024 9.3.4.3 Table 9-76, so if we have an S1G beacon with +* either no elements or the first element is not the beacon compatibility +* element, we have a short beacon. +*/ +static inline bool ieee80211_is_s1g_short_beacon (__le16 fc,const u8 *variable, +size_t variable_len) +{ +if (!ieee80211_is_s1g_beacon (fc)) +return false; + +/* +* If the frame does not contain at least 1 element (this is perfectly +* valid in a short beacon) and is an S1G beacon, we have a short +* beacon. +*/ +if (variable_len <2 ) +return true; + +return variable[0 ] !=WLAN_EID_S1G_BCN_COMPAT ; +} +struct element {u8 id;u8 datalen;
net/mac80211/mlme.c +5 -2
@@ -6702,6 +6702,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,struct ieee80211_bss_conf *bss_conf = link->conf;struct ieee80211_vif_cfg *vif_cfg = &sdata->vif.cfg;struct ieee80211_mgmt *mgmt = (void *) hdr; +struct ieee80211_ext *ext =NULL ;size_t baselen;struct ieee802_11_elems *elems;struct ieee80211_local *local = sdata->local;
@@ -6727,7 +6728,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,/* Process beacon from the current BSS */ bssid =ieee80211_get_bssid (hdr, len, sdata->vif.type);if (ieee80211_is_s1g_beacon (mgmt->frame_control)) { -struct ieee80211_ext *ext = (void *) mgmt; + ext = (void *)mgmt; variable = ext->u.s1g_beacon.variable +ieee80211_s1g_optional_len (ext->frame_control); }
@@ -6914,7 +6915,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link, }if ((ncrc == link->u.mgd.beacon_crc && link->u.mgd.beacon_crc_valid) || -ieee80211_is_s1g_short_beacon (mgmt->frame_control)) + (ext &&ieee80211_is_s1g_short_beacon (ext->frame_control, + parse_params.start, + parse_params.len))) goto free; link->u.mgd.beacon_crc = ncrc; link->u.mgd.beacon_crc_valid = true;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 113/163 wifi: mac80211: fix non-transmitted BSSID profile search
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit e1e6ebf490e55fee1ae573aa443c1d4aea5e4a40 ]
When the non-transmitted BSSID profile is found, immediately return from the search to not return the wrong profile_len when the profile is found in a multiple BSSID element that isn't the last one in the frame.
--- net/mac80211/parse.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
net/mac80211/parse.c +2 -4
@@ -758,7 +758,6 @@ static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len, {const struct element *elem, *sub;size_t profile_len =0 ; -bool found = false;if (!bss || !bss->transmitted_bss)return profile_len;
@@ -809,15 +808,14 @@ static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len, index[2 ], new_bssid);if (ether_addr_equal (new_bssid, bss->bssid)) { - found = true; elems->bssid_index_len = index[1 ]; elems->bssid_index = (void *)&index[2 ]; -break ; +return profile_len; } } } -return found ? profile_len :0 ; +return 0 ; } static void
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 114/163 wifi: rt2x00: fix remove callback type mismatch
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Fietkau <[email protected]>
[ Upstream commit 2ce6ad9262256dd345cb104ba0ac6cf4aeed25a3 ]
The function is used as remove callback for a platform driver. It was missed during the conversion from int to void
--- drivers/net/wireless/ralink/rt2x00/rt2x00soc.c | 4 +--- drivers/net/wireless/ralink/rt2x00/rt2x00soc.h | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-)
drivers/net/wireless/ralink/rt2x00/rt2x00soc.c +1 -3
@@ -108,7 +108,7 @@ int rt2x00soc_probe(struct platform_device *pdev, const struct rt2x00_ops *ops) }EXPORT_SYMBOL_GPL (rt2x00soc_probe); -int rt2x00soc_remove (struct platform_device *pdev) +void rt2x00soc_remove (struct platform_device *pdev) {struct ieee80211_hw *hw =platform_get_drvdata (pdev);struct rt2x00_dev *rt2x00dev = hw->priv;
@@ -119,8 +119,6 @@ int rt2x00soc_remove(struct platform_device *pdev)rt2x00lib_remove_dev (rt2x00dev);rt2x00soc_free_reg (rt2x00dev);ieee80211_free_hw (hw); - -return 0 ; }EXPORT_SYMBOL_GPL (rt2x00soc_remove);
drivers/net/wireless/ralink/rt2x00/rt2x00soc.h +1 -1
@@ -17,7 +17,7 @@* SoC driver handlers. */ int rt2x00soc_probe (struct platform_device *pdev,const struct rt2x00_ops *ops); -int rt2x00soc_remove (struct platform_device *pdev); +void rt2x00soc_remove (struct platform_device *pdev);#ifdef CONFIG_PM int rt2x00soc_suspend (struct platform_device *pdev,pm_message_t state);int rt2x00soc_resume (struct platform_device *pdev);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 115/163 drm/nouveau/gsp: fix potential leak of memory used during acpi init
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Skeggs <[email protected]>
[ Upstream commit d133036a0b23d3ef781d067ccdea6bbfb381e0cf ]
If any of the ACPI calls fail, memory allocated for the input buffer would be leaked. Fix failure paths to free allocated memory.
Also add checks to ensure the allocations succeeded in the first place.
--- .../gpu/drm/nouveau/nvkm/subdev/gsp/r535.c | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c +14 -6
@@ -1454,7 +1454,6 @@ r535_gsp_acpi_caps(acpi_handle handle, CAPS_METHOD_DATA *caps)union acpi_object argv4 = { .buffer.type =ACPI_TYPE_BUFFER , .buffer.length =4 , - .buffer.pointer =kmalloc (argv4.buffer.length,GFP_KERNEL ), }, *obj; caps->status =0xffff ;
@@ -1462,17 +1461,22 @@ r535_gsp_acpi_caps(acpi_handle handle, CAPS_METHOD_DATA *caps)if (!acpi_check_dsm (handle, &NVOP_DSM_GUID ,NVOP_DSM_REV ,BIT_ULL (0x1a )))return ; + argv4.buffer.pointer =kmalloc (argv4.buffer.length,GFP_KERNEL ); +if (!argv4.buffer.pointer) +return ; + obj =acpi_evaluate_dsm (handle, &NVOP_DSM_GUID ,NVOP_DSM_REV ,0x1a , &argv4);if (!obj) -return ; + goto done;if (WARN_ON (obj->type !=ACPI_TYPE_BUFFER ) ||WARN_ON (obj->buffer.length !=4 )) -return ; + goto done; caps->status =0 ; caps->optimusCaps = *(u32 *)obj->buffer.pointer; +done:ACPI_FREE (obj);kfree (argv4.buffer.pointer);
@@ -1489,24 +1493,28 @@ r535_gsp_acpi_jt(acpi_handle handle, JT_METHOD_DATA *jt)union acpi_object argv4 = { .buffer.type =ACPI_TYPE_BUFFER , .buffer.length =sizeof (caps), - .buffer.pointer =kmalloc (argv4.buffer.length,GFP_KERNEL ), }, *obj; jt->status =0xffff ; + argv4.buffer.pointer =kmalloc (argv4.buffer.length,GFP_KERNEL ); +if (!argv4.buffer.pointer) +return ; + obj =acpi_evaluate_dsm (handle, &JT_DSM_GUID ,JT_DSM_REV ,0x1 , &argv4);if (!obj) -return ; + goto done;if (WARN_ON (obj->type !=ACPI_TYPE_BUFFER ) ||WARN_ON (obj->buffer.length !=4 )) -return ; + goto done; jt->status =0 ; jt->jtCaps = *(u32 *)obj->buffer.pointer; jt->jtRevId = (jt->jtCaps &0xfff00000 ) >>20 ; jt->bSBIOSCaps =0 ; +done:ACPI_FREE (obj);kfree (argv4.buffer.pointer);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 116/163 wifi: mt76: mt7925: Fix null-ptr-deref in mt7925_thermal_init()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henry Martin <[email protected]>
[ Upstream commit 03ee8f73801a8f46d83dfc2bf73fb9ffa5a21602 ]
devm_kasprintf() returns NULL on error. Currently, mt7925_thermal_init() does not check for this case, which results in a NULL pointer dereference.
Add NULL check after devm_kasprintf() to prevent this issue.
--- drivers/net/wireless/mediatek/mt76/mt7925/init.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/wireless/mediatek/mt76/mt7925/init.c +2 -0
@@ -52,6 +52,8 @@ static int mt7925_thermal_init(struct mt792x_phy *phy) name =devm_kasprintf (&wiphy->dev,GFP_KERNEL ,"mt7925_%s" ,wiphy_name (wiphy)); +if (!name) +return -ENOMEM ; hwmon =devm_hwmon_device_register_with_groups (&wiphy->dev, name, phy, mt7925_hwmon_groups);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 117/163 nbd: fix uaf in nbd_genl_connect() error path
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zheng Qixing <[email protected]>
[ Upstream commit aa9552438ebf015fc5f9f890dbfe39f0c53cf37e ]
There is a use-after-free issue in nbd:
block nbd6: Receive control failed (result -104)
block nbd6: shutting down sockets
==================================================================
BUG: KASAN: slab-use-after-free in recv_work+0x694/0xa80 drivers/block/nbd.c:1022 Write of size 4 at addr ffff8880295de478 by task kworker/u33:0/67 CPU: 2 UID: 0 PID: 67 Comm: kworker/u33:0 Not tainted 6.15.0-rc5-syzkaller-00123-g2c89c1b655c0 #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 Workqueue: nbd6-recv recv_work Call Trace: <TASK> __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x116/0x1f0 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:408 [inline] print_report+0xc3/0x670 mm/kasan/report.c:521 kasan_report+0xe0/0x110 mm/kasan/report.c:634 check_region_inline mm/kasan/generic.c:183 [inline] kasan_check_range+0xef/0x1a0 mm/kasan/generic.c:189 instrument_atomic_read_write include/linux/instrumented.h:96 [inline] atomic_dec include/linux/atomic/atomic-instrumented.h:592 [inline] recv_work+0x694/0xa80 drivers/block/nbd.c:1022 process_one_work+0x9cc/0x1b70 kernel/workqueue.c:3238 process_scheduled_works kernel/workqueue.c:3319 [inline] worker_thread+0x6c8/0xf10 kernel/workqueue.c:3400 kthread+0x3c2/0x780 kernel/kthread.c:464 ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:153 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 </TASK>
nbd_genl_connect() does not properly stop the device on certain error paths after nbd_start_device() has been called. This causes the error path to put nbd->config while recv_work continue to use the config after putting it, leading to use-after-free in recv_work.
This patch moves nbd_start_device() after the backend file creation.
--- drivers/block/nbd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/block/nbd.c +3 -3
@@ -2136,9 +2136,7 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) goto out; } } - ret =nbd_start_device (nbd); -if (ret) - goto out; +if (info->attrs[NBD_ATTR_BACKEND_IDENTIFIER ]) { nbd->backend =nla_strdup (info->attrs[NBD_ATTR_BACKEND_IDENTIFIER ],GFP_KERNEL );
@@ -2154,6 +2152,8 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) goto out; }set_bit (NBD_RT_HAS_BACKEND_FILE , &config->runtime_flags); + + ret =nbd_start_device (nbd); out:mutex_unlock (&nbd->config_lock);if (!ret) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 118/163 drm/xe/pf: Clear all LMTT pages on alloc
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Wajdeczko <[email protected]>
[ Upstream commit 705a412a367f383430fa34bada387af2e52eb043 ]
Our LMEM buffer objects are not cleared by default on alloc and during VF provisioning we only setup LMTT PTEs for the actually provisioned LMEM range. But beyond that valid range we might leave some stale data that could either point to some other VFs allocations or even to the PF pages.
Explicitly clear all new LMTT page to avoid the risk that a malicious VF would try to exploit that gap.
While around add asserts to catch any undesired PTE overwrites and low-level debug traces to track LMTT PT life-cycle.
--- drivers/gpu/drm/xe/xe_lmtt.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/gpu/drm/xe/xe_lmtt.c +11 -0
@@ -78,6 +78,9 @@ static struct xe_lmtt_pt *lmtt_pt_alloc(struct xe_lmtt *lmtt, unsigned int level }lmtt_assert (lmtt,xe_bo_is_vram (bo)); +lmtt_debug (lmtt,"level=%u addr=%#llx\n" , level, (u64 )xe_bo_main_addr (bo,XE_PAGE_SIZE )); + +xe_map_memset (lmtt_to_xe (lmtt), &bo->vmap,0 ,0 , bo->size); pt->level = level; pt->bo = bo;
@@ -91,6 +94,9 @@ static struct xe_lmtt_pt *lmtt_pt_alloc(struct xe_lmtt *lmtt, unsigned int levelstatic void lmtt_pt_free (struct xe_lmtt_pt *pt) { +lmtt_debug (&pt->bo->tile->sriov.pf.lmtt,"level=%u addr=%llx\n" , + pt->level, (u64 )xe_bo_main_addr (pt->bo,XE_PAGE_SIZE )); +xe_bo_unpin_map_no_vm (pt->bo);kfree (pt); }
@@ -226,9 +232,14 @@ static void lmtt_write_pte(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pt,switch (lmtt->ops->lmtt_pte_size (level)) {case sizeof (u32): +lmtt_assert (lmtt, !overflows_type (pte, u32)); +lmtt_assert (lmtt, !pte || !iosys_map_rd (&pt->bo->vmap, idx *sizeof (u32), u32)); +xe_map_wr (lmtt_to_xe (lmtt), &pt->bo->vmap, idx *sizeof (u32), u32, pte);break ;case sizeof (u64): +lmtt_assert (lmtt, !pte || !iosys_map_rd (&pt->bo->vmap, idx *sizeof (u64), u64)); +xe_map_wr (lmtt_to_xe (lmtt), &pt->bo->vmap, idx *sizeof (u64), u64, pte);break ;default :
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 119/163 erofs: free pclusters if no cached folio is attached
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chunhai Guo <[email protected]>
[ Upstream commit f5ad9f9a603f829d11ca31a0a4049e16091e8c13 ]
Once a pcluster is fully decompressed and there are no attached cached folios, its corresponding struct z_erofs_pcluster will be freed. This will significantly reduce the frequency of calls to erofs_shrink_scan() and the memory allocated for struct z_erofs_pcluster.
The tables below show approximately a 96% reduction in the calls to erofs_shrink_scan() and in the memory allocated for struct z_erofs_pcluster after applying this patch. The results were obtained by performing a test to copy a 4.1GB partition on ARM64 Android devices running the 6.6 kernel with an 8-core CPU and 12GB of memory.
1. The reduction in calls to erofs_shrink_scan():
+-----------------+-----------+----------+---------+ | | w/o patch | w/ patch | diff | +-----------------+-----------+----------+---------+ | Average (times) | 11390 | 390 | -96.57% | +-----------------+-----------+----------+---------+
2. The reduction in memory released by erofs_shrink_scan():
+-----------------+-----------+----------+---------+ | | w/o patch | w/ patch | diff | +-----------------+-----------+----------+---------+ | Average (Byte) | 133612656 | 4434552 | -96.68% | +-----------------+-----------+----------+---------+
Stable-dep-of: d53238b614e0 ("erofs: fix to add missing tracepoint in erofs_readahead()")
--- fs/erofs/zdata.c | 57 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 19 deletions(-)
fs/erofs/zdata.c +38 -19
@@ -882,14 +882,11 @@ static void z_erofs_rcu_callback(struct rcu_head *head) struct z_erofs_pcluster, rcu)); } -static bool erofs_try_to_release_pcluster (struct erofs_sb_info *sbi, +static bool __erofs_try_to_release_pcluster (struct erofs_sb_info *sbi,struct z_erofs_pcluster *pcl) { -int free = false; - -spin_lock (&pcl->lockref.lock);if (pcl->lockref.count) - goto out; +return false;/* * Note that all cached folios should be detached before deleted from
@@ -897,7 +894,7 @@ static bool erofs_try_to_release_pcluster(struct erofs_sb_info *sbi,* orphan old pcluster when the new one is available in the tree. */ if (erofs_try_to_free_all_cached_folios (sbi, pcl)) - goto out; +return false;/* * It's impossible to fail after the pcluster is freezed, but in order
@@ -906,8 +903,16 @@ static bool erofs_try_to_release_pcluster(struct erofs_sb_info *sbi,DBG_BUGON (__xa_erase (&sbi->managed_pslots, pcl->index) != pcl);lockref_mark_dead (&pcl->lockref); - free = true; -out: +return true; +} + +static bool erofs_try_to_release_pcluster (struct erofs_sb_info *sbi, +struct z_erofs_pcluster *pcl) +{ +bool free; + +spin_lock (&pcl->lockref.lock); + free =__erofs_try_to_release_pcluster (sbi, pcl);spin_unlock (&pcl->lockref.lock);if (free) {atomic_long_dec (&erofs_global_shrink_cnt);
@@ -938,16 +943,25 @@ unsigned long z_erofs_shrink_scan(struct erofs_sb_info *sbi,return freed; } -static void z_erofs_put_pcluster (struct z_erofs_pcluster *pcl) +static void z_erofs_put_pcluster (struct erofs_sb_info *sbi, +struct z_erofs_pcluster *pcl,bool try_free) { +bool free = false; +if (lockref_put_or_lock (&pcl->lockref))return ;DBG_BUGON (__lockref_is_dead (&pcl->lockref)); -if (pcl->lockref.count ==1 ) -atomic_long_inc (&erofs_global_shrink_cnt); - --pcl->lockref.count; +if (!--pcl->lockref.count) { +if (try_free &&xa_trylock (&sbi->managed_pslots)) { + free =__erofs_try_to_release_pcluster (sbi, pcl); +xa_unlock (&sbi->managed_pslots); + } +atomic_long_add (!free, &erofs_global_shrink_cnt); + }spin_unlock (&pcl->lockref.lock); +if (free) +call_rcu (&pcl->rcu, z_erofs_rcu_callback); }static void z_erofs_pcluster_end (struct z_erofs_decompress_frontend *fe)
@@ -968,7 +982,7 @@ static void z_erofs_pcluster_end(struct z_erofs_decompress_frontend *fe)* any longer if the pcluster isn't hosted by ourselves. */ if (fe->mode <Z_EROFS_PCLUSTER_FOLLOWED_NOINPLACE ) -z_erofs_put_pcluster (pcl); +z_erofs_put_pcluster (EROFS_I_SB (fe->inode), pcl, false); fe->pcl =NULL ; }
@@ -1271,6 +1285,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be,int i, j, jtop, err2;struct page *page;bool overlapped; +bool try_free = true;mutex_lock (&pcl->lock); be->nr_pages =PAGE_ALIGN (pcl->length + pcl->pageofs_out) >>PAGE_SHIFT ;
@@ -1328,9 +1343,12 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be,/* managed folios are still left in compressed_bvecs[] */ for (i =0 ; i < pclusterpages; ++i) { page = be->compressed_pages[i]; -if (!page || -erofs_folio_is_managed (sbi,page_folio (page))) +if (!page)continue ; +if (erofs_folio_is_managed (sbi,page_folio (page))) { + try_free = false; +continue ; + } (void )z_erofs_put_shortlivedpage (be->pagepool, page);WRITE_ONCE (pcl->compressed_bvecs[i].page,NULL ); }
@@ -1375,6 +1393,11 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be,/* pcluster lock MUST be taken before the following line */ WRITE_ONCE (pcl->next,Z_EROFS_PCLUSTER_NIL );mutex_unlock (&pcl->lock); + +if (z_erofs_is_inline_pcluster (pcl)) +z_erofs_free_pcluster (pcl); +else +z_erofs_put_pcluster (sbi, pcl, try_free);return err; }
@@ -1397,10 +1420,6 @@ static int z_erofs_decompress_queue(const struct z_erofs_decompressqueue *io, owned =READ_ONCE (be.pcl->next); err =z_erofs_decompress_pcluster (&be, err) ?: err; -if (z_erofs_is_inline_pcluster (be.pcl)) -z_erofs_free_pcluster (be.pcl); -else -z_erofs_put_pcluster (be.pcl); }return err; }
Signature · 1 line
2.39.5
Re: [PATCH 6.12 119/163] erofs: free pclusters if no cached folio is attached
Hi Greg,
Quoted 1 line · Greg Kroah-Hartman
6.12-stable review patch. If anyone has any objections, please let me know.
Can we drop this patch?
Since it's a new feature and lack of another fix backport:
commit b10a1e5643e5 ("erofs: fix rare pcluster memory leak after unmounting")
It's not worth to backport those commits in order to backport a simple tracepoint fix.
Thanks,
Gao Xiang
Quoted 176 lines
------------------
From: Chunhai Guo <[email protected]>
[ Upstream commit
f5ad9f9a603f829d11ca31a0a4049e16091e8c13]Once a pcluster is fully decompressed and there are no attached cached folios, its corresponding
struct z_erofs_pclusterwill be freed. This will significantly reduce the frequency of calls toerofs_shrink_scan()and the memory allocated forstruct z_erofs_pcluster.The tables below show approximately a 96% reduction in the calls to
erofs_shrink_scan()and in the memory allocated forstruct z_erofs_pclusterafter applying this patch. The results were obtained by performing a test to copy a 4.1GB partition on ARM64 Android devices running the 6.6 kernel with an 8-core CPU and 12GB of memory.1. The reduction in calls to
erofs_shrink_scan():+-----------------+-----------+----------+---------+ | | w/o patch | w/ patch | diff | +-----------------+-----------+----------+---------+ | Average (times) | 11390 | 390 | -96.57% | +-----------------+-----------+----------+---------+2. The reduction in memory released by
erofs_shrink_scan():+-----------------+-----------+----------+---------+ | | w/o patch | w/ patch | diff | +-----------------+-----------+----------+---------+ | Average (Byte) | 133612656 | 4434552 | -96.68% | +-----------------+-----------+----------+---------+Signed-off-by Chunhai Guo <[email protected]>Reviewed-by Gao Xiang <[email protected]>Signed-off-by Gao Xiang <[email protected]>Stable-dep-of:
d53238b614e0("erofs: fix to add missing tracepoint inerofs_readahead()")Signed-off-by Sasha Levin <[email protected]>--- fs/erofs/zdata.c | 57 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 19 deletions(-)fs/erofs/zdata.c +38
-19@@ -882,14 +882,11 @@ static void z_erofs_rcu_callback(struct rcu_head *head) struct z_erofs_pcluster, rcu)); } -static bool erofs_try_to_release_pcluster (struct erofs_sb_info *sbi, +static bool __erofs_try_to_release_pcluster (struct erofs_sb_info *sbi,struct z_erofs_pcluster *pcl) { -int free = false; - -spin_lock (&pcl->lockref.lock);if (pcl->lockref.count) - goto out; +return false;/* * Note that all cached folios should be detached before deleted from @@ -897,7 +894,7 @@ static bool erofs_try_to_release_pcluster(struct erofs_sb_info *sbi,* orphan old pcluster when the new one is available in the tree. */ if (erofs_try_to_free_all_cached_folios (sbi, pcl)) - goto out; +return false;/* * It's impossible to fail after the pcluster is freezed, but in order @@ -906,8 +903,16 @@ static bool erofs_try_to_release_pcluster(struct erofs_sb_info *sbi,DBG_BUGON (__xa_erase (&sbi->managed_pslots, pcl->index) != pcl);lockref_mark_dead (&pcl->lockref); - free = true; -out: +return true; +} + +static bool erofs_try_to_release_pcluster (struct erofs_sb_info *sbi, +struct z_erofs_pcluster *pcl) +{ +bool free; + +spin_lock (&pcl->lockref.lock); + free =__erofs_try_to_release_pcluster (sbi, pcl);spin_unlock (&pcl->lockref.lock);if (free) {atomic_long_dec (&erofs_global_shrink_cnt);@@ -938,16 +943,25 @@ unsigned long z_erofs_shrink_scan(struct erofs_sb_info *sbi,return freed; } -static void z_erofs_put_pcluster (struct z_erofs_pcluster *pcl) +static void z_erofs_put_pcluster (struct erofs_sb_info *sbi, +struct z_erofs_pcluster *pcl,bool try_free) { +bool free = false; +if (lockref_put_or_lock (&pcl->lockref))return ;DBG_BUGON (__lockref_is_dead (&pcl->lockref)); -if (pcl->lockref.count ==1 ) -atomic_long_inc (&erofs_global_shrink_cnt); - --pcl->lockref.count; +if (!--pcl->lockref.count) { +if (try_free &&xa_trylock (&sbi->managed_pslots)) { + free =__erofs_try_to_release_pcluster (sbi, pcl); +xa_unlock (&sbi->managed_pslots); + } +atomic_long_add (!free, &erofs_global_shrink_cnt); + }spin_unlock (&pcl->lockref.lock); +if (free) +call_rcu (&pcl->rcu, z_erofs_rcu_callback); }static void z_erofs_pcluster_end (struct z_erofs_decompress_frontend *fe)@@ -968,7 +982,7 @@ static void z_erofs_pcluster_end(struct z_erofs_decompress_frontend *fe)* any longer if the pcluster isn't hosted by ourselves. */ if (fe->mode <Z_EROFS_PCLUSTER_FOLLOWED_NOINPLACE ) -z_erofs_put_pcluster (pcl); +z_erofs_put_pcluster (EROFS_I_SB (fe->inode), pcl, false); fe->pcl =NULL ; }@@ -1271,6 +1285,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be,int i, j, jtop, err2;struct page *page;bool overlapped; +bool try_free = true;mutex_lock (&pcl->lock); be->nr_pages =PAGE_ALIGN (pcl->length + pcl->pageofs_out) >>PAGE_SHIFT ;@@ -1328,9 +1343,12 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be,/* managed folios are still left in compressed_bvecs[] */ for (i =0 ; i < pclusterpages; ++i) { page = be->compressed_pages[i]; -if (!page || -erofs_folio_is_managed (sbi,page_folio (page))) +if (!page)continue ; +if (erofs_folio_is_managed (sbi,page_folio (page))) { + try_free = false; +continue ; + } (void )z_erofs_put_shortlivedpage (be->pagepool, page);WRITE_ONCE (pcl->compressed_bvecs[i].page,NULL ); }@@ -1375,6 +1393,11 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be,/* pcluster lock MUST be taken before the following line */ WRITE_ONCE (pcl->next,Z_EROFS_PCLUSTER_NIL );mutex_unlock (&pcl->lock); + +if (z_erofs_is_inline_pcluster (pcl)) +z_erofs_free_pcluster (pcl); +else +z_erofs_put_pcluster (sbi, pcl, try_free);return err; }@@ -1397,10 +1420,6 @@ static int z_erofs_decompress_queue(const struct z_erofs_decompressqueue *io, owned =READ_ONCE (be.pcl->next); err =z_erofs_decompress_pcluster (&be, err) ?: err; -if (z_erofs_is_inline_pcluster (be.pcl)) -z_erofs_free_pcluster (be.pcl); -else -z_erofs_put_pcluster (be.pcl); }return err; }
Re: [PATCH 6.12 119/163] erofs: free pclusters if no cached folio is attached
Quoted 9 lines · Gao Xiang
Hi Greg,
Quoted 1 line · Greg Kroah-Hartman
6.12-stable review patch. If anyone has any objections, please let me know.
Can we drop this patch?
Since it's a new feature and lack of another fix backport:
commitb10a1e5643e5("erofs: fix rare pcluster memory leak after unmounting")
Oh, that fix is included, very sorry about that.
I can live with that then.
Thanks,
Gao Xiang
Quoted 173 lines
It's not worth to backport those commits in order to backport a simple tracepoint fix.
Thanks,
Gao XiangQuoted 165 lines
------------------
From: Chunhai Guo <[email protected]>
[ Upstream commit
f5ad9f9a603f829d11ca31a0a4049e16091e8c13]Once a pcluster is fully decompressed and there are no attached cached folios, its corresponding
struct z_erofs_pclusterwill be freed. This will significantly reduce the frequency of calls toerofs_shrink_scan()and the memory allocated forstruct z_erofs_pcluster.The tables below show approximately a 96% reduction in the calls to
erofs_shrink_scan()and in the memory allocated forstruct z_erofs_pclusterafter applying this patch. The results were obtained by performing a test to copy a 4.1GB partition on ARM64 Android devices running the 6.6 kernel with an 8-core CPU and 12GB of memory.1. The reduction in calls to
erofs_shrink_scan():+-----------------+-----------+----------+---------+ | | w/o patch | w/ patch | diff | +-----------------+-----------+----------+---------+ | Average (times) | 11390 | 390 | -96.57% | +-----------------+-----------+----------+---------+2. The reduction in memory released by
erofs_shrink_scan():+-----------------+-----------+----------+---------+ | | w/o patch | w/ patch | diff | +-----------------+-----------+----------+---------+ | Average (Byte) | 133612656 | 4434552 | -96.68% | +-----------------+-----------+----------+---------+Signed-off-by Chunhai Guo <[email protected]>Reviewed-by Gao Xiang <[email protected]>Signed-off-by Gao Xiang <[email protected]>Stable-dep-of:
d53238b614e0("erofs: fix to add missing tracepoint inerofs_readahead()")Signed-off-by Sasha Levin <[email protected]>---
fs/erofs/zdata.c| 57 ++++++++++++++++++++++++++++++++----------------1 file changed, 38 insertions(+), 19 deletions(-)fs/erofs/zdata.c +38
-19@@ -882,14 +882,11 @@ static void z_erofs_rcu_callback(struct rcu_head *head) struct z_erofs_pcluster, rcu)); } -static bool erofs_try_to_release_pcluster (struct erofs_sb_info *sbi, +static bool __erofs_try_to_release_pcluster (struct erofs_sb_info *sbi, struct z_erofs_pcluster *pcl) { - int free = false; - - spin_lock(&pcl->lockref.lock); if (pcl->lockref.count) - goto out; + return false; /** Note that all cached folios should be detached before deleted from @@ -897,7 +894,7 @@ static bool erofs_try_to_release_pcluster(struct erofs_sb_info *sbi,* orphan old pcluster when the new one is available in the tree. */ if (erofs_try_to_free_all_cached_folios(sbi, pcl)) - goto out; + return false; /** It's impossible to fail after the pcluster is freezed, but in order @@ -906,8 +903,16 @@ static bool erofs_try_to_release_pcluster(struct erofs_sb_info *sbi, DBG_BUGON(__xa_erase(&sbi->managed_pslots, pcl->index) != pcl); lockref_mark_dead(&pcl->lockref); - free = true; -out: + return true; +} + +static bool erofs_try_to_release_pcluster (struct erofs_sb_info *sbi, + struct z_erofs_pcluster *pcl) +{ + bool free; + + spin_lock(&pcl->lockref.lock); + free = __erofs_try_to_release_pcluster(sbi, pcl); spin_unlock(&pcl->lockref.lock); if (free) { atomic_long_dec(&erofs_global_shrink_cnt);@@ -938,16 +943,25 @@ unsigned long z_erofs_shrink_scan(struct erofs_sb_info *sbi, return freed; } -static void z_erofs_put_pcluster (struct z_erofs_pcluster *pcl) +static void z_erofs_put_pcluster (struct erofs_sb_info *sbi, + struct z_erofs_pcluster *pcl, bool try_free) { + bool free = false; + if (lockref_put_or_lock(&pcl->lockref)) return; DBG_BUGON(__lockref_is_dead(&pcl->lockref)); - if (pcl->lockref.count == 1) - atomic_long_inc(&erofs_global_shrink_cnt); - --pcl->lockref.count; + if (!--pcl->lockref.count) { + if (try_free && xa_trylock(&sbi->managed_pslots)) { + free = __erofs_try_to_release_pcluster(sbi, pcl); + xa_unlock(&sbi->managed_pslots); + } + atomic_long_add(!free, &erofs_global_shrink_cnt); + } spin_unlock(&pcl->lockref.lock); + if (free) + call_rcu(&pcl->rcu, z_erofs_rcu_callback); } static void z_erofs_pcluster_end(struct z_erofs_decompress_frontend *fe)@@ -968,7 +982,7 @@ static void z_erofs_pcluster_end(struct z_erofs_decompress_frontend *fe)* any longer if the pcluster isn't hosted by ourselves. */ if (fe->mode < Z_EROFS_PCLUSTER_FOLLOWED_NOINPLACE) - z_erofs_put_pcluster(pcl); + z_erofs_put_pcluster(EROFS_I_SB(fe->inode), pcl, false); fe->pcl = NULL; }@@ -1271,6 +1285,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be, int i, j, jtop, err2; struct page *page; bool overlapped; + bool try_free = true; mutex_lock(&pcl->lock); be->nr_pages = PAGE_ALIGN(pcl->length + pcl->pageofs_out) >> PAGE_SHIFT;@@ -1328,9 +1343,12 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be, /* managed folios are still left in compressed_bvecs[] */ for (i = 0; i < pclusterpages; ++i) { page = be->compressed_pages[i]; - if (!page || - erofs_folio_is_managed(sbi, page_folio(page))) + if (!page) continue; + if (erofs_folio_is_managed(sbi, page_folio(page))) { + try_free = false; + continue; + } (void)z_erofs_put_shortlivedpage(be->pagepool, page); WRITE_ONCE(pcl->compressed_bvecs[i].page, NULL); }@@ -1375,6 +1393,11 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be, /* pcluster lock MUST be taken before the following line */ WRITE_ONCE(pcl->next, Z_EROFS_PCLUSTER_NIL); mutex_unlock(&pcl->lock); + + if (z_erofs_is_inline_pcluster(pcl)) + z_erofs_free_pcluster(pcl); + else + z_erofs_put_pcluster(sbi, pcl, try_free); return err; }@@ -1397,10 +1420,6 @@ static int z_erofs_decompress_queue(const struct z_erofs_decompressqueue *io, owned = READ_ONCE(be.pcl->next); err = z_erofs_decompress_pcluster(&be, err) ?: err; - if (z_erofs_is_inline_pcluster(be.pcl)) - z_erofs_free_pcluster(be.pcl); - else - z_erofs_put_pcluster(be.pcl); } return err; }
Greg Kroah-Hartman
maintainerPATCH 120/163 erofs: get rid of `z_erofs_next_pcluster_t`
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao Xiang <[email protected]>
[ Upstream commit 5514d8478b8ef3f0ba1b77beaa65f05c12825143 ]
It was originally intended for tagged pointer reservation.
Now all encoded data can be represented uniformally with struct z_erofs_pcluster as described in commit bf1aa03980f4 ("erofs: sunset struct erofs_workgroup"), let's drop it too.
Stable-dep-of: d53238b614e0 ("erofs: fix to add missing tracepoint in erofs_readahead()")
--- fs/erofs/zdata.c | 80 ++++++++++++++++++------------------------------ 1 file changed, 29 insertions(+), 51 deletions(-)
fs/erofs/zdata.c +29 -51
@@ -12,12 +12,6 @@#define Z_EROFS_PCLUSTER_MAX_PAGES (Z_EROFS_PCLUSTER_MAX_SIZE / PAGE_SIZE)#define Z_EROFS_INLINE_BVECS 2 -/* -* let's leave a type here in case of introducing -* another tagged pointer later. -*/ -typedef void *z_erofs_next_pcluster_t ; -struct z_erofs_bvec {struct page *page;int offset;
@@ -48,7 +42,7 @@ struct z_erofs_pcluster {struct lockref lockref;/* A: point to next chained pcluster or TAILs */ -z_erofs_next_pcluster_t next; +struct z_erofs_pcluster *next;/* I: start block address of this pcluster */ erofs_off_t index;
@@ -91,12 +85,11 @@ struct z_erofs_pcluster {/* the end of a chain of pclusters */ #define Z_EROFS_PCLUSTER_TAIL ((void *) 0x700 + POISON_POINTER_DELTA) -#define Z_EROFS_PCLUSTER_NIL (NULL)struct z_erofs_decompressqueue {struct super_block *sb; +struct z_erofs_pcluster *head;atomic_t pending_bios; -z_erofs_next_pcluster_t head;union {struct completion done;
@@ -491,8 +484,7 @@ struct z_erofs_decompress_frontend {struct page *pagepool;struct page *candidate_bvpage; -struct z_erofs_pcluster *pcl; -z_erofs_next_pcluster_t owned_head; +struct z_erofs_pcluster *pcl, *head;enum z_erofs_pclustermode mode;erofs_off_t headoffset;
@@ -502,7 +494,7 @@ struct z_erofs_decompress_frontend { };#define DECOMPRESS_FRONTEND_INIT (__i) { \ - .inode = __i, .owned_head = Z_EROFS_PCLUSTER_TAIL, \ + .inode = __i, .head = Z_EROFS_PCLUSTER_TAIL, \ .mode = Z_EROFS_PCLUSTER_FOLLOWED }static bool z_erofs_should_alloc_cache (struct z_erofs_decompress_frontend *fe)
@@ -750,9 +742,7 @@ static int z_erofs_register_pcluster(struct z_erofs_decompress_frontend *fe) pcl->algorithmformat = map->m_algorithmformat; pcl->length =0 ; pcl->partial = true; - -/* new pclusters should be claimed as type 1, primary and followed */ - pcl->next = fe->owned_head; + pcl->next = fe->head; pcl->pageofs_out = map->m_la & ~PAGE_MASK ; fe->mode =Z_EROFS_PCLUSTER_FOLLOWED ;
@@ -788,8 +778,7 @@ static int z_erofs_register_pcluster(struct z_erofs_decompress_frontend *fe) goto err_out; } } - fe->owned_head = &pcl->next; - fe->pcl = pcl; + fe->head = fe->pcl = pcl;return 0 ; err_out:
@@ -808,7 +797,7 @@ static int z_erofs_pcluster_begin(struct z_erofs_decompress_frontend *fe)DBG_BUGON (fe->pcl);/* must be Z_EROFS_PCLUSTER_TAIL or pointed to previous pcluster */ -DBG_BUGON (fe->owned_head ==Z_EROFS_PCLUSTER_NIL ); +DBG_BUGON (!fe->head);if (!(map->m_flags &EROFS_MAP_META )) {while (1 ) {
@@ -836,10 +825,9 @@ static int z_erofs_pcluster_begin(struct z_erofs_decompress_frontend *fe)if (ret == -EEXIST ) {mutex_lock (&fe->pcl->lock);/* check if this pcluster hasn't been linked into any chain. */ -if (cmpxchg (&fe->pcl->next,Z_EROFS_PCLUSTER_NIL , - fe->owned_head) ==Z_EROFS_PCLUSTER_NIL ) { +if (!cmpxchg (&fe->pcl->next,NULL , fe->head)) {/* .. so it can be attached to our submission chain */ - fe->owned_head = &fe->pcl->next; + fe->head = fe->pcl; fe->mode =Z_EROFS_PCLUSTER_FOLLOWED ; }else {/* otherwise, it belongs to an inflight chain */ fe->mode =Z_EROFS_PCLUSTER_INFLIGHT ;
@@ -1391,7 +1379,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be, pcl->vcnt =0 ;/* pcluster lock MUST be taken before the following line */ -WRITE_ONCE (pcl->next,Z_EROFS_PCLUSTER_NIL ); +WRITE_ONCE (pcl->next,NULL );mutex_unlock (&pcl->lock);if (z_erofs_is_inline_pcluster (pcl))
@@ -1409,16 +1397,14 @@ static int z_erofs_decompress_queue(const struct z_erofs_decompressqueue *io, .pagepool = pagepool, .decompressed_secondary_bvecs = LIST_HEAD_INIT(be.decompressed_secondary_bvecs), + .pcl = io->head, }; -z_erofs_next_pcluster_t owned = io->head; +struct z_erofs_pcluster *next;int err = io->eio ? -EIO :0 ; -while (owned !=Z_EROFS_PCLUSTER_TAIL ) { -DBG_BUGON (owned ==Z_EROFS_PCLUSTER_NIL ); - - be.pcl = container_of(owned, struct z_erofs_pcluster, next); - owned =READ_ONCE (be.pcl->next); - +for (; be.pcl !=Z_EROFS_PCLUSTER_TAIL ; be.pcl = next) { +DBG_BUGON (!be.pcl); + next =READ_ONCE (be.pcl->next); err =z_erofs_decompress_pcluster (&be, err) ?: err; }return err;
@@ -1628,18 +1614,13 @@ enum { NR_JOBQUEUES, }; -static void move_to_bypass_jobqueue (struct z_erofs_pcluster *pcl, -z_erofs_next_pcluster_t qtail[], -z_erofs_next_pcluster_t owned_head) +static void z_erofs_move_to_bypass_queue (struct z_erofs_pcluster *pcl, +struct z_erofs_pcluster *next, +struct z_erofs_pcluster **qtail[]) { -z_erofs_next_pcluster_t *const submit_qtail = qtail[JQ_SUBMIT ]; -z_erofs_next_pcluster_t *const bypass_qtail = qtail[JQ_BYPASS ]; -WRITE_ONCE (pcl->next,Z_EROFS_PCLUSTER_TAIL ); - -WRITE_ONCE (*submit_qtail, owned_head); -WRITE_ONCE (*bypass_qtail, &pcl->next); - +WRITE_ONCE (*qtail[JQ_SUBMIT ], next); +WRITE_ONCE (*qtail[JQ_BYPASS ], pcl); qtail[JQ_BYPASS ] = &pcl->next; }
@@ -1674,9 +1655,9 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f, {struct super_block *sb = f->inode->i_sb;struct address_space *mc =MNGD_MAPPING (EROFS_SB (sb)); -z_erofs_next_pcluster_t qtail[NR_JOBQUEUES ]; +struct z_erofs_pcluster **qtail[NR_JOBQUEUES ];struct z_erofs_decompressqueue *q[NR_JOBQUEUES ]; -z_erofs_next_pcluster_t owned_head = f->owned_head; +struct z_erofs_pcluster *pcl, *next;/* bio is NULL initially, so no need to initialize last_{index,bdev} */ erofs_off_t last_pa;unsigned int nr_bios =0 ;
@@ -1692,22 +1673,19 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f, qtail[JQ_SUBMIT ] = &q[JQ_SUBMIT ]->head;/* by default, all need io submission */ - q[JQ_SUBMIT ]->head = owned_head; + q[JQ_SUBMIT ]->head = next = f->head; do { struct erofs_map_dev mdev; - struct z_erofs_pcluster *pcl; erofs_off_t cur, end; struct bio_vec bvec; unsigned int i = 0; bool bypass = true; - DBG_BUGON(owned_head == Z_EROFS_PCLUSTER_NIL); - pcl = container_of(owned_head, struct z_erofs_pcluster, next); - owned_head = READ_ONCE(pcl->next); - + pcl = next; + next = READ_ONCE(pcl->next); if (z_erofs_is_inline_pcluster(pcl)) { - move_to_bypass_jobqueue(pcl, qtail, owned_head); + z_erofs_move_to_bypass_queue(pcl, next, qtail); continue; }
@@ -1779,8 +1757,8 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f,if (!bypass) qtail[JQ_SUBMIT ] = &pcl->next;else -move_to_bypass_jobqueue (pcl, qtail, owned_head); - }while (owned_head !=Z_EROFS_PCLUSTER_TAIL ); +z_erofs_move_to_bypass_queue (pcl, next, qtail); + }while (next !=Z_EROFS_PCLUSTER_TAIL );if (bio) {if (erofs_is_fileio_mode (EROFS_SB (sb)))
@@ -1812,7 +1790,7 @@ static int z_erofs_runqueue(struct z_erofs_decompress_frontend *f,bool force_fg =z_erofs_is_sync_decompress (sbi, ra_folios);int err; -if (f->owned_head ==Z_EROFS_PCLUSTER_TAIL ) +if (f->head ==Z_EROFS_PCLUSTER_TAIL )return 0 ;z_erofs_submit_queue (f, io, &force_fg, !!ra_folios);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 121/163 erofs: tidy up zdata.c
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao Xiang <[email protected]>
[ Upstream commit 6f435e94a19ad25b372bc61443afd0839b8a521c ]
All small code style adjustments, no logic changes:
- z_erofs_decompress_frontend => z_erofs_frontend;
- z_erofs_decompress_backend => z_erofs_backend;
- Use Z_EROFS_DEFINE_FRONTEND() to replace DECOMPRESS_FRONTEND_INIT();
- nr_folios should be nrpages in z_erofs_readahead();
- Refine in-line comments.
Stable-dep-of: d53238b614e0 ("erofs: fix to add missing tracepoint in erofs_readahead()")
--- fs/erofs/zdata.c | 111 ++++++++++++++++++----------------------------- 1 file changed, 43 insertions(+), 68 deletions(-)
fs/erofs/zdata.c +43 -68
@@ -453,31 +453,25 @@ int __init z_erofs_init_subsystem(void) }enum z_erofs_pclustermode { +/* It has previously been linked into another processing chain */ Z_EROFS_PCLUSTER_INFLIGHT ,/* -* a weak form of Z_EROFS_PCLUSTER_FOLLOWED, the difference is that it -* could be dispatched into bypass queue later due to uptodated managed -* pages. All related online pages cannot be reused for inplace I/O (or -* bvpage) since it can be directly decoded without I/O submission. +* A weaker form of Z_EROFS_PCLUSTER_FOLLOWED; the difference is that it +* may be dispatched to the bypass queue later due to uptodated managed +* folios. All file-backed folios related to this pcluster cannot be +* reused for in-place I/O (or bvpage) since the pcluster may be decoded +* in a separate queue (and thus out of order). */ Z_EROFS_PCLUSTER_FOLLOWED_NOINPLACE ,/* -* The pcluster was just linked to a decompression chain by us. It can -* also be linked with the remaining pclusters, which means if the -* processing page is the tail page of a pcluster, this pcluster can -* safely use the whole page (since the previous pcluster is within the -* same chain) for in-place I/O, as illustrated below: -* ___________________________________________________ -* | tail (partial) page | head (partial) page | -* | (of the current pcl) | (of the previous pcl) | -* |___PCLUSTER_FOLLOWED___|_____PCLUSTER_FOLLOWED_____| -* -* [ (*) the page above can be used as inplace I/O. ] +* The pcluster has just been linked to our processing chain. +* File-backed folios (except for the head page) related to it can be +* used for in-place I/O (or bvpage). */ Z_EROFS_PCLUSTER_FOLLOWED , }; -struct z_erofs_decompress_frontend { +struct z_erofs_frontend {struct inode *const inode;struct erofs_map_blocks map;struct z_erofs_bvec_iter biter;
@@ -493,11 +487,11 @@ struct z_erofs_decompress_frontend {unsigned int icur; }; -#define DECOMPRESS_FRONTEND_INIT (__i) { \ - .inode = __i, .head = Z_EROFS_PCLUSTER_TAIL, \ - .mode = Z_EROFS_PCLUSTER_FOLLOWED } +#define Z_EROFS_DEFINE_FRONTEND (fe, i, ho) struct z_erofs_frontend fe = { \ + .inode = i, .head = Z_EROFS_PCLUSTER_TAIL, \ + .mode = Z_EROFS_PCLUSTER_FOLLOWED, .headoffset = ho } -static bool z_erofs_should_alloc_cache (struct z_erofs_decompress_frontend *fe) +static bool z_erofs_should_alloc_cache (struct z_erofs_frontend *fe) {unsigned int cachestrategy =EROFS_I_SB (fe->inode)->opt.cache_strategy;
@@ -514,7 +508,7 @@ static bool z_erofs_should_alloc_cache(struct z_erofs_decompress_frontend *fe)return false; } -static void z_erofs_bind_cache (struct z_erofs_decompress_frontend *fe) +static void z_erofs_bind_cache (struct z_erofs_frontend *fe) {struct address_space *mc =MNGD_MAPPING (EROFS_I_SB (fe->inode));struct z_erofs_pcluster *pcl = fe->pcl;
@@ -671,7 +665,7 @@ int z_erofs_init_super(struct super_block *sb) }/* callers must be with pcluster lock held */ -static int z_erofs_attach_page (struct z_erofs_decompress_frontend *fe, +static int z_erofs_attach_page (struct z_erofs_frontend *fe,struct z_erofs_bvec *bvec,bool exclusive) {struct z_erofs_pcluster *pcl = fe->pcl;
@@ -717,7 +711,7 @@ static bool z_erofs_get_pcluster(struct z_erofs_pcluster *pcl)return true; } -static int z_erofs_register_pcluster (struct z_erofs_decompress_frontend *fe) +static int z_erofs_register_pcluster (struct z_erofs_frontend *fe) {struct erofs_map_blocks *map = &fe->map;struct super_block *sb = fe->inode->i_sb;
@@ -787,7 +781,7 @@ static int z_erofs_register_pcluster(struct z_erofs_decompress_frontend *fe)return err; } -static int z_erofs_pcluster_begin (struct z_erofs_decompress_frontend *fe) +static int z_erofs_pcluster_begin (struct z_erofs_frontend *fe) {struct erofs_map_blocks *map = &fe->map;struct super_block *sb = fe->inode->i_sb;
@@ -860,14 +854,9 @@ static int z_erofs_pcluster_begin(struct z_erofs_decompress_frontend *fe)return 0 ; } -/* -* keep in mind that no referenced pclusters will be freed -* only after a RCU grace period. -*/ static void z_erofs_rcu_callback (struct rcu_head *head) { -z_erofs_free_pcluster (container_of(head , -struct z_erofs_pcluster ,rcu )); +z_erofs_free_pcluster (container_of(head ,struct z_erofs_pcluster ,rcu )); } static bool __erofs_try_to_release_pcluster(struct erofs_sb_info *sbi,
@@ -909,8 +898,7 @@ static bool erofs_try_to_release_pcluster(struct erofs_sb_info *sbi,return free; } -unsigned long z_erofs_shrink_scan (struct erofs_sb_info *sbi, -unsigned long nr_shrink) +unsigned long z_erofs_shrink_scan (struct erofs_sb_info *sbi,unsigned long nr) {struct z_erofs_pcluster *pcl;unsigned long index, freed =0 ;
@@ -923,7 +911,7 @@ unsigned long z_erofs_shrink_scan(struct erofs_sb_info *sbi,xa_unlock (&sbi->managed_pslots); ++freed; -if (!--nr_shrink) +if (!--nr)return freed;xa_lock (&sbi->managed_pslots); }
@@ -952,7 +940,7 @@ static void z_erofs_put_pcluster(struct erofs_sb_info *sbi,call_rcu (&pcl->rcu, z_erofs_rcu_callback); } -static void z_erofs_pcluster_end (struct z_erofs_decompress_frontend *fe) +static void z_erofs_pcluster_end (struct z_erofs_frontend *fe) {struct z_erofs_pcluster *pcl = fe->pcl;
@@ -965,13 +953,9 @@ static void z_erofs_pcluster_end(struct z_erofs_decompress_frontend *fe)if (fe->candidate_bvpage) fe->candidate_bvpage =NULL ; -/* -* if all pending pages are added, don't hold its reference -* any longer if the pcluster isn't hosted by ourselves. -*/ +/* Drop refcount if it doesn't belong to our processing chain */ if (fe->mode <Z_EROFS_PCLUSTER_FOLLOWED_NOINPLACE )z_erofs_put_pcluster (EROFS_I_SB (fe->inode), pcl, false); - fe->pcl =NULL ; }
@@ -1000,7 +984,7 @@ static int z_erofs_read_fragment(struct super_block *sb, struct folio *folio,return 0 ; } -static int z_erofs_scan_folio (struct z_erofs_decompress_frontend *f, +static int z_erofs_scan_folio (struct z_erofs_frontend *f,struct folio *folio,bool ra) {struct inode *const inode = f->inode;
@@ -1113,7 +1097,7 @@ static bool z_erofs_page_is_invalidated(struct page *page)return !page_folio (page)->mapping && !z_erofs_is_shortlived_page (page); } -struct z_erofs_decompress_backend { +struct z_erofs_backend {struct page *onstack_pages[Z_EROFS_ONSTACK_PAGES ];struct super_block *sb;struct z_erofs_pcluster *pcl;
@@ -1134,7 +1118,7 @@ struct z_erofs_bvec_item {struct list_head list; }; -static void z_erofs_do_decompressed_bvec (struct z_erofs_decompress_backend *be, +static void z_erofs_do_decompressed_bvec (struct z_erofs_backend *be,struct z_erofs_bvec *bvec) {int poff = bvec->offset + be->pcl->pageofs_out;
@@ -1159,8 +1143,7 @@ static void z_erofs_do_decompressed_bvec(struct z_erofs_decompress_backend *be,list_add (&item->list, &be->decompressed_secondary_bvecs); } -static void z_erofs_fill_other_copies (struct z_erofs_decompress_backend *be, -int err) +static void z_erofs_fill_other_copies (struct z_erofs_backend *be,int err) {unsigned int off0 = be->pcl->pageofs_out;struct list_head *p, *n;
@@ -1201,7 +1184,7 @@ static void z_erofs_fill_other_copies(struct z_erofs_decompress_backend *be, } } -static void z_erofs_parse_out_bvecs (struct z_erofs_decompress_backend *be) +static void z_erofs_parse_out_bvecs (struct z_erofs_backend *be) {struct z_erofs_pcluster *pcl = be->pcl;struct z_erofs_bvec_iter biter;
@@ -1226,8 +1209,7 @@ static void z_erofs_parse_out_bvecs(struct z_erofs_decompress_backend *be)z_erofs_put_shortlivedpage (be->pagepool, old_bvpage); } -static int z_erofs_parse_in_bvecs (struct z_erofs_decompress_backend *be, -bool *overlapped) +static int z_erofs_parse_in_bvecs (struct z_erofs_backend *be,bool *overlapped) {struct z_erofs_pcluster *pcl = be->pcl;unsigned int pclusterpages =z_erofs_pclusterpages (pcl);
@@ -1262,8 +1244,7 @@ static int z_erofs_parse_in_bvecs(struct z_erofs_decompress_backend *be,return err; } -static int z_erofs_decompress_pcluster (struct z_erofs_decompress_backend *be, -int err) +static int z_erofs_decompress_pcluster (struct z_erofs_backend *be,int err) {struct erofs_sb_info *const sbi =EROFS_SB (be->sb);struct z_erofs_pcluster *pcl = be->pcl;
@@ -1392,7 +1373,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be, static int z_erofs_decompress_queue(const struct z_erofs_decompressqueue *io, struct page **pagepool) { - struct z_erofs_decompress_backend be = { + struct z_erofs_backend be = { .sb = io->sb, .pagepool = pagepool, .decompressed_secondary_bvecs =
@@ -1470,7 +1451,7 @@ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io, }static void z_erofs_fill_bio_vec (struct bio_vec *bvec, -struct z_erofs_decompress_frontend *f, +struct z_erofs_frontend *f,struct z_erofs_pcluster *pcl,unsigned int nr,struct address_space *mc)
@@ -1649,7 +1630,7 @@ static void z_erofs_endio(struct bio *bio)bio_put (bio); } -static void z_erofs_submit_queue (struct z_erofs_decompress_frontend *f, +static void z_erofs_submit_queue (struct z_erofs_frontend *f,struct z_erofs_decompressqueue *fgq,bool *force_fg,bool readahead) {
@@ -1782,17 +1763,16 @@ static void z_erofs_submit_queue(struct z_erofs_decompress_frontend *f,z_erofs_decompress_kickoff (q[JQ_SUBMIT ], nr_bios); } -static int z_erofs_runqueue (struct z_erofs_decompress_frontend *f, -unsigned int ra_folios) +static int z_erofs_runqueue (struct z_erofs_frontend *f,unsigned int rapages) {struct z_erofs_decompressqueue io[NR_JOBQUEUES ];struct erofs_sb_info *sbi =EROFS_I_SB (f->inode); -bool force_fg =z_erofs_is_sync_decompress (sbi, ra_folios); +bool force_fg =z_erofs_is_sync_decompress (sbi, rapages);int err;if (f->head ==Z_EROFS_PCLUSTER_TAIL )return 0 ; -z_erofs_submit_queue (f, io, &force_fg, !!ra_folios); +z_erofs_submit_queue (f, io, &force_fg, !!rapages);/* handle bypass queue (no i/o pclusters) immediately */ err =z_erofs_decompress_queue (&io[JQ_BYPASS ], &f->pagepool);
@@ -1810,7 +1790,7 @@ static int z_erofs_runqueue(struct z_erofs_decompress_frontend *f,* Since partial uptodate is still unimplemented for now, we have to use * approximate readmore strategies as a start. */ -static void z_erofs_pcluster_readmore (struct z_erofs_decompress_frontend *f, +static void z_erofs_pcluster_readmore (struct z_erofs_frontend *f,struct readahead_control *rac,bool backmost) {struct inode *inode = f->inode;
@@ -1865,12 +1845,10 @@ static void z_erofs_pcluster_readmore(struct z_erofs_decompress_frontend *f,static int z_erofs_read_folio (struct file *file,struct folio *folio) {struct inode *const inode = folio->mapping->host; -struct z_erofs_decompress_frontend f =DECOMPRESS_FRONTEND_INIT (inode); +Z_EROFS_DEFINE_FRONTEND (f, inode,folio_pos (folio));int err;trace_erofs_read_folio (folio, false); - f.headoffset = (erofs_off_t )folio->index <<PAGE_SHIFT ; -z_erofs_pcluster_readmore (&f,NULL , true); err =z_erofs_scan_folio (&f, folio, false);z_erofs_pcluster_readmore (&f,NULL , false);
@@ -1890,17 +1868,14 @@ static int z_erofs_read_folio(struct file *file, struct folio *folio)static void z_erofs_readahead (struct readahead_control *rac) {struct inode *const inode = rac->mapping->host; -struct z_erofs_decompress_frontend f =DECOMPRESS_FRONTEND_INIT (inode); +Z_EROFS_DEFINE_FRONTEND (f, inode,readahead_pos (rac));struct folio *head =NULL , *folio; -unsigned int nr_folios; +unsigned int nrpages =readahead_count (rac);int err; - f.headoffset =readahead_pos (rac); -z_erofs_pcluster_readmore (&f, rac, true); - nr_folios =readahead_count (rac); -trace_erofs_readpages (inode,readahead_index (rac), nr_folios, false); - + nrpages =readahead_count (rac); +trace_erofs_readpages (inode,readahead_index (rac), nrpages, false);while ((folio =readahead_folio (rac))) { folio->private = head; head = folio;
@@ -1919,7 +1894,7 @@ static void z_erofs_readahead(struct readahead_control *rac)z_erofs_pcluster_readmore (&f, rac, false);z_erofs_pcluster_end (&f); - (void )z_erofs_runqueue (&f, nr_folios); + (void )z_erofs_runqueue (&f, nrpages);erofs_put_metabuf (&f.map.buf);erofs_release_pages (&f.pagepool); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 122/163 erofs: refine readahead tracepoint
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao Xiang <[email protected]>
[ Upstream commit 4eb56b0761e75034dd35067a81da4c280c178262 ]
- trace_erofs_readpages => trace_erofs_readahead;
- Rename a redundant statement nrpages = readahead_count(rac);;
- Move the tracepoint to the beginning of z_erofs_readahead().
Stable-dep-of: d53238b614e0 ("erofs: fix to add missing tracepoint in erofs_readahead()")
--- fs/erofs/fileio.c | 2 +- fs/erofs/zdata.c | 5 ++--- include/trace/events/erofs.h | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-)
fs/erofs/fileio.c +1 -1
@@ -180,7 +180,7 @@ static void erofs_fileio_readahead(struct readahead_control *rac)struct folio *folio;int err; -trace_erofs_readpages (inode,readahead_index (rac), +trace_erofs_readahead (inode,readahead_index (rac),readahead_count (rac), true);while ((folio =readahead_folio (rac))) { err =erofs_fileio_scan_folio (&io, folio);
fs/erofs/zdata.c +2 -3
@@ -1869,13 +1869,12 @@ static void z_erofs_readahead(struct readahead_control *rac) {struct inode *const inode = rac->mapping->host;Z_EROFS_DEFINE_FRONTEND (f, inode,readahead_pos (rac)); -struct folio *head =NULL , *folio;unsigned int nrpages =readahead_count (rac); +struct folio *head =NULL , *folio;int err; +trace_erofs_readahead (inode,readahead_index (rac), nrpages, false);z_erofs_pcluster_readmore (&f, rac, true); - nrpages =readahead_count (rac); -trace_erofs_readpages (inode,readahead_index (rac), nrpages, false);while ((folio =readahead_folio (rac))) { folio->private = head; head = folio;
include/trace/events/erofs.h +1 -1
@@ -113,7 +113,7 @@ TRACE_EVENT(erofs_read_folio, __entry->raw) ); -TRACE_EVENT(erofs_readpages, +TRACE_EVENT(erofs_readahead, TP_PROTO(struct inode *inode, pgoff_t start, unsigned int nrpage, bool raw),
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 123/163 erofs: fix to add missing tracepoint in erofs_readahead()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <[email protected]>
[ Upstream commit d53238b614e01266a3d36b417b60a502e0698504 ]
Commit 771c994ea51f ("erofs: convert all uncompressed cases to iomap") converts to use iomap interface, it removed trace_erofs_readahead() tracepoint in the meantime, let's add it back.
--- fs/erofs/data.c | 3 +++ 1 file changed, 3 insertions(+)
fs/erofs/data.c +3 -0
@@ -391,6 +391,9 @@ static int erofs_read_folio(struct file *file, struct folio *folio)static void erofs_readahead (struct readahead_control *rac) { +trace_erofs_readahead (rac->mapping->host,readahead_index (rac), +readahead_count (rac), true); +return iomap_readahead (rac, &erofs_iomap_ops); }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 124/163 netfilter: flowtable: account for Ethernet header in nf_flow_pppoe_proto()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 18cdb3d982da8976b28d57691eb256ec5688fad2 ]
syzbot found a potential access to uninit-value in nf_flow_pppoe_proto()
Blamed commit forgot the Ethernet header.
BUG: KMSAN: uninit-value in nf_flow_offload_inet_hook+0x7e4/0x940 net/netfilter/nf_flow_table_inet.c:27 nf_flow_offload_inet_hook+0x7e4/0x940 net/netfilter/nf_flow_table_inet.c:27 nf_hook_entry_hookfn include/linux/netfilter.h:157 [inline] nf_hook_slow+0xe1/0x3d0 net/netfilter/core.c:623 nf_hook_ingress include/linux/netfilter_netdev.h:34 [inline] nf_ingress net/core/dev.c:5742 [inline] __netif_receive_skb_core+0x4aff/0x70c0 net/core/dev.c:5837 __netif_receive_skb_one_core net/core/dev.c:5975 [inline] __netif_receive_skb+0xcc/0xac0 net/core/dev.c:6090 netif_receive_skb_internal net/core/dev.c:6176 [inline] netif_receive_skb+0x57/0x630 net/core/dev.c:6235 tun_rx_batched+0x1df/0x980 drivers/net/tun.c:1485 tun_get_user+0x4ee0/0x6b40 drivers/net/tun.c:1938 tun_chr_write_iter+0x3e9/0x5c0 drivers/net/tun.c:1984 new_sync_write fs/read_write.c:593 [inline] vfs_write+0xb4b/0x1580 fs/read_write.c:686 ksys_write fs/read_write.c:738 [inline] __do_sys_write fs/read_write.c:749 [inline]
--- include/net/netfilter/nf_flow_table.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/net/netfilter/nf_flow_table.h +1 -1
@@ -369,7 +369,7 @@ static inline __be16 __nf_flow_pppoe_proto(const struct sk_buff *skb)static inline bool nf_flow_pppoe_proto (struct sk_buff *skb,__be16 *inner_proto) { -if (!pskb_may_pull (skb,PPPOE_SES_HLEN )) +if (!pskb_may_pull (skb,ETH_HLEN +PPPOE_SES_HLEN ))return false; *inner_proto =__nf_flow_pppoe_proto (skb);
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 125/163 net: appletalk: Fix device refcount leak in atrtr_create()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kito Xu <[email protected]>
[ Upstream commit 711c80f7d8b163d3ecd463cd96f07230f488e750 ]
When updating an existing route entry in atrtr_create(), the old device reference was not being released before assigning the new device, leading to a device refcount leak. Fix this by calling dev_put() to release the old device reference before holding the new one.
--- net/appletalk/ddp.c | 1 + 1 file changed, 1 insertion(+)
net/appletalk/ddp.c +1 -0
@@ -576,6 +576,7 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint)/* Fill in the routing entry */ rt->target = ta->sat_addr; +dev_put (rt->dev);/* Release old device */ dev_hold (devhint); rt->dev = devhint; rt->flags = r->rt_flags;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 126/163 ibmvnic: Fix hardcoded NUM_RX_STATS/NUM_TX_STATS with dynamic sizeof
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mingming Cao <[email protected]>
[ Upstream commit 01b8114b432d7baaa5e51ab229c12c4f36b8e2c6 ]
The previous hardcoded definitions of NUM_RX_STATS and NUM_TX_STATS were not updated when new fields were added to the ibmvnic_{rx,tx}_queue_stats structures. Specifically, commit 2ee73c54a615 ("ibmvnic: Add stat for tx direct vs tx batched") added a fourth TX stat, but NUM_TX_STATS remained 3, leading to a mismatch.
This patch replaces the static defines with dynamic sizeof-based calculations to ensure the stat arrays are correctly sized. This fixes incorrect indexing and prevents incomplete stat reporting in tools like ethtool.
--- drivers/net/ethernet/ibm/ibmvnic.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/ethernet/ibm/ibmvnic.h +6 -2
@@ -211,7 +211,6 @@ struct ibmvnic_statistics {u8 reserved[72 ]; } __packed__aligned(8) ; -#define NUM_TX_STATS 3struct ibmvnic_tx_queue_stats {u64 batched_packets;u64 direct_packets;
@@ -219,13 +218,18 @@ struct ibmvnic_tx_queue_stats {u64 dropped_packets; }; -#define NUM_RX_STATS 3 +#define NUM_TX_STATS \ + (sizeof(struct ibmvnic_tx_queue_stats) / sizeof(u64)) +struct ibmvnic_rx_queue_stats {u64 packets;u64 bytes;u64 interrupts; }; +#define NUM_RX_STATS \ + (sizeof(struct ibmvnic_rx_queue_stats) / sizeof(u64)) +struct ibmvnic_acl_buffer {__be32 len;__be32 version;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 127/163 net: phy: microchip: Use genphy_soft_reset() to purge stale LPA bits
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
[ Upstream commit b4517c363e0e005c7f81ae3be199eec68e87f122 ]
Enable .soft_reset for the LAN88xx PHY driver by assigning genphy_soft_reset() to ensure that the phylib core performs a proper soft reset during reconfiguration.
Previously, the driver left .soft_reset unimplemented, so calls to phy_init_hw() (e.g., from lan88xx_link_change_notify()) did not fully reset the PHY. As a result, stale contents in the Link Partner Ability (LPA) register could persist, causing the PHY to incorrectly report that the link partner advertised autonegotiation even when it did not.
Using genphy_soft_reset() guarantees a clean reset of the PHY and corrects the false autoneg reporting in these scenarios.
--- drivers/net/phy/microchip.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/phy/microchip.c +1 -0
@@ -486,6 +486,7 @@ static struct phy_driver microchip_phy_driver[] = { .config_init = lan88xx_config_init, .config_aneg = lan88xx_config_aneg, .link_change_notify = lan88xx_link_change_notify, + .soft_reset = genphy_soft_reset,/* Interrupt handling is broken, do not define related * functions to force polling.
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 128/163 net: phy: microchip: limit 100M workaround to link-down events on LAN88xx
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
[ Upstream commit dd4360c0e8504f2f7639c7f5d07c93cfd6a98333 ]
Restrict the 100Mbit forced-mode workaround to link-down transitions only, to prevent repeated link reset cycles in certain configurations.
The workaround was originally introduced to improve signal reliability when switching cables between long and short distances. It temporarily forces the PHY into 10 Mbps before returning to 100 Mbps.
However, when used with autonegotiating link partners (e.g., Intel i350), executing this workaround on every link change can confuse the partner and cause constant renegotiation loops. This results in repeated link down/up transitions and the PHY never reaching a stable state.
Limit the workaround to only run during the PHY_NOLINK state. This ensures it is triggered only once per link drop, avoiding disruptive toggling while still preserving its intended effect.
Note: I am not able to reproduce the original issue that this workaround addresses. I can only confirm that 100 Mbit mode works correctly in my test setup. Based on code inspection, I assume the workaround aims to reset some internal state machine or signal block by toggling speeds. However, a PHY reset is already performed earlier in the function via phy_init_hw(), which may achieve a similar effect. Without a reproducer, I conservatively keep the workaround but restrict its conditions.
--- drivers/net/phy/microchip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/phy/microchip.c +1 -1
@@ -332,7 +332,7 @@ static void lan88xx_link_change_notify(struct phy_device *phydev)* As workaround, set to 10 before setting to 100 * at forced 100 F/H mode. */ -if (!phydev->autoneg && phydev->speed ==100 ) { +if (phydev->state ==PHY_NOLINK && !phydev->autoneg && phydev->speed ==100 ) {/* disable phy interrupt */ temp =phy_read (phydev,LAN88XX_INT_MASK ); temp &= ~LAN88XX_INT_MASK_MDINTPIN_EN_ ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 129/163 selftests: net: lib: Move logging from forwarding/lib.sh here
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Machata <[email protected]>
[ Upstream commit b219bcfcc92e9bd50c6277ac68cb75f64b403e5e ]
Many net selftests invent their own logging helpers. These really should be in a library sourced by these tests. Currently forwarding/lib.sh has a suite of perfectly fine logging helpers, but sourcing a forwarding/ library from a higher-level directory smells of layering violation. In this patch, move the logging helpers to net/lib.sh so that every net test can use them.
Together with the logging helpers, it's also necessary to move pause_on_fail(), and EXIT_STATUS and RET.
Existing lib.sh users might be using these same names for their functions or variables. However lib.sh is always sourced near the top of the file (checked), and whatever new definitions will simply override the ones provided by lib.sh.
Stable-dep-of: 47c84997c686 ("selftests: net: lib: fix shift count out of range")
--- tools/testing/selftests/net/forwarding/lib.sh | 113 ----------------- tools/testing/selftests/net/lib.sh | 115 ++++++++++++++++++ 2 files changed, 115 insertions(+), 113 deletions(-)
tools/testing/selftests/net/forwarding/lib.sh +0 -113
@@ -48,7 +48,6 @@ declare -A NETIFS=( : "${WAIT_TIME:=5}" # Whether to pause on, respectively, after a failure and before cleanup. -: "${PAUSE_ON_FAIL:=no}" : "${PAUSE_ON_CLEANUP:=no}" # Whether to create virtual interfaces, and what netdevice type they should be.
@@ -446,22 +445,6 @@ done ############################################################################## # Helpers -# Exit status to return at the end. Set in case one of the tests fails. -EXIT_STATUS=0 -# Per-test return value. Clear at the beginning of each test. -RET=0 - -ret_set_ksft_status() -{ - local ksft_status=$1; shift - local msg=$1; shift - - RET=$(ksft_status_merge $RET $ksft_status) - if (( $? )); then - retmsg=$msg - fi -} - # Whether FAILs should be interpreted as XFAILs. Internal. FAIL_TO_XFAIL=
@@ -535,102 +518,6 @@ xfail_on_veth() fi } -log_test_result() -{ - local test_name=$1; shift - local opt_str=$1; shift - local result=$1; shift - local retmsg=$1; shift - - printf "TEST: %-60s [%s]\n" "$test_name $opt_str" "$result" - if [[ $retmsg ]]; then - printf "\t%s\n" "$retmsg" - fi -} - -pause_on_fail() -{ - if [[ $PAUSE_ON_FAIL == yes ]]; then - echo "Hit enter to continue, 'q' to quit" - read a - [[ $a == q ]] && exit 1 - fi -} - -handle_test_result_pass() -{ - local test_name=$1; shift - local opt_str=$1; shift - - log_test_result "$test_name" "$opt_str" " OK " -} - -handle_test_result_fail() -{ - local test_name=$1; shift - local opt_str=$1; shift - - log_test_result "$test_name" "$opt_str" FAIL "$retmsg" - pause_on_fail -} - -handle_test_result_xfail() -{ - local test_name=$1; shift - local opt_str=$1; shift - - log_test_result "$test_name" "$opt_str" XFAIL "$retmsg" - pause_on_fail -} - -handle_test_result_skip() -{ - local test_name=$1; shift - local opt_str=$1; shift - - log_test_result "$test_name" "$opt_str" SKIP "$retmsg" -} - -log_test() -{ - local test_name=$1 - local opt_str=$2 - - if [[ $# -eq 2 ]]; then - opt_str="($opt_str)" - fi - - if ((RET == ksft_pass)); then - handle_test_result_pass "$test_name" "$opt_str" - elif ((RET == ksft_xfail)); then - handle_test_result_xfail "$test_name" "$opt_str" - elif ((RET == ksft_skip)); then - handle_test_result_skip "$test_name" "$opt_str" - else - handle_test_result_fail "$test_name" "$opt_str" - fi - - EXIT_STATUS=$(ksft_exit_status_merge $EXIT_STATUS $RET) - return $RET -} - -log_test_skip() -{ - RET=$ksft_skip retmsg= log_test "$@" -} - -log_test_xfail() -{ - RET=$ksft_xfail retmsg= log_test "$@" -} - -log_info() -{ - local msg=$1 - - echo "INFO: $msg" -} - not() { "$@"
tools/testing/selftests/net/lib.sh +115 -0
130 lines not on this page · raw message
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 130/163 selftests: net: lib: fix shift count out of range
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hangbin Liu <[email protected]>
[ Upstream commit 47c84997c686b4d43b225521b732492552b84758 ]
I got the following warning when writing other tests:
+ handle_test_result_pass 'bond 802.3ad' '(lacp_active off)'
+ local 'test_name=bond 802.3ad'
+ shift
+ local 'opt_str=(lacp_active off)'
+ shift
+ log_test_result 'bond 802.3ad' '(lacp_active off)' ' OK '
+ local 'test_name=bond 802.3ad'
+ shift
+ local 'opt_str=(lacp_active off)'
+ shift
+ local 'result= OK '
+ shift
+ local retmsg=
+ shift
/net/tools/testing/selftests/net/forwarding/../lib.sh: line 315: shift: shift count out of range
This happens because an extra shift is executed even after all arguments have been consumed. Remove the last shift in log_test_result() to avoid this warning.
--- tools/testing/selftests/net/lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/net/lib.sh +1 -1
@@ -258,7 +258,7 @@ log_test_result() local test_name=$1; shift local opt_str=$1; shift local result=$1; shift - local retmsg=$1; shift + local retmsg=$1 printf "TEST: %-60s [%s]\n" "$test_name $opt_str" "$result" if [[ $retmsg ]]; then
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 131/163 drm/xe/pm: Correct comment of xe_pm_set_vram_threshold()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuicheng Lin <[email protected]>
[ Upstream commit 0539c5eaf81f3f844213bf6b3137a53e5b04b083 ]
The parameter threshold is with size in MiB, not in bits. Correct it to avoid any confusion.
v2: s/mb/MiB, s/vram/VRAM, fix return section. (Michal)
--- drivers/gpu/drm/xe/xe_pm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/gpu/drm/xe/xe_pm.c +5 -3
@@ -682,11 +682,13 @@ void xe_pm_assert_unbounded_bridge(struct xe_device *xe) }/** -* xe_pm_set_vram_threshold - Set a vram threshold for allowing/blocking D3Cold +* xe_pm_set_vram_threshold - Set a VRAM threshold for allowing/blocking D3Cold * @xe: xe device instance -* @threshold: VRAM size in bites for the D3cold threshold +* @threshold: VRAM size in MiB for the D3cold threshold * -* Returns 0 for success, negative error code otherwise. +* Return: +* * 0 - success +* * -EINVAL - invalid argument */ int xe_pm_set_vram_threshold (struct xe_device *xe,u32 threshold) {
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 132/163 can: m_can: m_can_handle_lost_msg(): downgrade msg lost in rx message to debug level
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Nyekjaer <[email protected]>
[ Upstream commit 58805e9cbc6f6a28f35d90e740956e983a0e036e ]
Downgrade the "msg lost in rx" message to debug level, to prevent flooding the kernel log with error messages.
--- drivers/net/can/m_can/m_can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/can/m_can/m_can.c +1 -1
@@ -665,7 +665,7 @@ static int m_can_handle_lost_msg(struct net_device *dev)struct can_frame *frame;u32 timestamp =0 ; -netdev_err (dev,"msg lost in rxf0\n" ); +netdev_dbg (dev,"msg lost in rxf0\n" ); stats->rx_errors++; stats->rx_over_errors++;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 133/163 net/mlx5e: Fix race between DIM disable and net_dim()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carolina Jubran <[email protected]>
[ Upstream commit eb41a264a3a576dc040ee37c3d9d6b7e2d9be968 ]
There's a race between disabling DIM and NAPI callbacks using the dim pointer on the RQ or SQ.
If NAPI checks the DIM state bit and sees it still set, it assumes rq->dim or sq->dim is valid. But if DIM gets disabled right after that check, the pointer might already be set to NULL, leading to a NULL pointer dereference in net_dim().
Fix this by calling synchronize_net() before freeing the DIM context. This ensures all in-progress NAPI callbacks are finished before the pointer is cleared.
Kernel log:
BUG: kernel NULL pointer dereference, address: 0000000000000000 ... RIP: 0010:net_dim+0x23/0x190 ... Call Trace: <TASK> ? __die+0x20/0x60 ? page_fault_oops+0x150/0x3e0 ? common_interrupt+0xf/0xa0 ? sysvec_call_function_single+0xb/0x90 ? exc_page_fault+0x74/0x130 ? asm_exc_page_fault+0x22/0x30 ? net_dim+0x23/0x190 ? mlx5e_poll_ico_cq+0x41/0x6f0 [mlx5_core] ? sysvec_apic_timer_interrupt+0xb/0x90 mlx5e_handle_rx_dim+0x92/0xd0 [mlx5_core] mlx5e_napi_poll+0x2cd/0xac0 [mlx5_core] ? mlx5e_poll_ico_cq+0xe5/0x6f0 [mlx5_core] busy_poll_stop+0xa2/0x200 ? mlx5e_napi_poll+0x1d9/0xac0 [mlx5_core] ? mlx5e_trigger_irq+0x130/0x130 [mlx5_core] __napi_busy_loop+0x345/0x3b0 ? sysvec_call_function_single+0xb/0x90 ? asm_sysvec_call_function_single+0x16/0x20 ? sysvec_apic_timer_interrupt+0xb/0x90 ? pcpu_free_area+0x1e4/0x2e0 napi_busy_loop+0x11/0x20 xsk_recvmsg+0x10c/0x130 sock_recvmsg+0x44/0x70 __sys_recvfrom+0xbc/0x130 ? __schedule+0x398/0x890 __x64_sys_recvfrom+0x20/0x30 do_syscall_64+0x4c/0x100 entry_SYSCALL_64_after_hwframe+0x4b/0x53 ... ---[ end trace 0000000000000000 ]--- ... ---[ end Kernel panic - not syncing: Fatal exception in interrupt ]---
--- drivers/net/ethernet/mellanox/mlx5/core/en_dim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en_dim.c +2 -2
@@ -113,7 +113,7 @@ int mlx5e_dim_rx_change(struct mlx5e_rq *rq, bool enable)__set_bit (MLX5E_RQ_STATE_DIM , &rq->state); }else {__clear_bit (MLX5E_RQ_STATE_DIM , &rq->state); - +synchronize_net ();mlx5e_dim_disable (rq->dim); rq->dim =NULL ; }
@@ -140,7 +140,7 @@ int mlx5e_dim_tx_change(struct mlx5e_txqsq *sq, bool enable)__set_bit (MLX5E_SQ_STATE_DIM , &sq->state); }else {__clear_bit (MLX5E_SQ_STATE_DIM , &sq->state); - +synchronize_net ();mlx5e_dim_disable (sq->dim); sq->dim =NULL ; }
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 134/163 net/mlx5e: Add new prio for promiscuous mode
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianbo Liu <[email protected]>
[ Upstream commit 4c9fce56fa702059bbc5ab737265b68f79cbaac4 ]
An optimization for promiscuous mode adds a high-priority steering table with a single catch-all rule to steer all traffic directly to the TTC table.
However, a gap exists between the creation of this table and the insertion of the catch-all rule. Packets arriving in this brief window would miss as no rule was inserted yet, unnecessarily incrementing the 'rx_steer_missed_packets' counter and dropped.
This patch resolves the issue by introducing a new prio for this table, placing it between MLX5E_TC_PRIO and MLX5E_NIC_PRIO. By doing so, packets arriving during the window now fall through to the next prio (at MLX5E_NIC_PRIO) instead of being dropped.
--- drivers/net/ethernet/mellanox/mlx5/core/en/fs.h | 9 +++++++-- drivers/net/ethernet/mellanox/mlx5/core/en_fs.c | 2 +- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 13 +++++++++---- 3 files changed, 17 insertions(+), 7 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/fs.h +7 -2
@@ -18,7 +18,8 @@ enum {enum {MLX5E_TC_PRIO =0 , -MLX5E_NIC_PRIO +MLX5E_PROMISC_PRIO , +MLX5E_NIC_PRIO , };struct mlx5e_flow_table {
@@ -68,9 +69,13 @@ struct mlx5e_l2_table { MLX5_HASH_FIELD_SEL_DST_IP |\ MLX5_HASH_FIELD_SEL_IPSEC_SPI) -/* NIC prio FTS */ +/* NIC promisc FT level */ enum {MLX5E_PROMISC_FT_LEVEL , +}; + +/* NIC prio FTS */ +enum {MLX5E_VLAN_FT_LEVEL ,MLX5E_L2_FT_LEVEL ,MLX5E_TTC_FT_LEVEL ,
drivers/net/ethernet/mellanox/mlx5/core/en_fs.c +1 -1
@@ -776,7 +776,7 @@ static int mlx5e_create_promisc_table(struct mlx5e_flow_steering *fs) ft_attr.max_fte =MLX5E_PROMISC_TABLE_SIZE ; ft_attr.autogroup.max_num_groups =1 ; ft_attr.level =MLX5E_PROMISC_FT_LEVEL ; - ft_attr.prio =MLX5E_NIC_PRIO ; + ft_attr.prio =MLX5E_PROMISC_PRIO ; ft->t =mlx5_create_auto_grouped_flow_table (fs->ns, &ft_attr);if (IS_ERR (ft->t)) {
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +9 -4
@@ -113,13 +113,16 @@#define ETHTOOL_PRIO_NUM_LEVELS 1#define ETHTOOL_NUM_PRIOS 11#define ETHTOOL_MIN_LEVEL (KERNEL_MIN_LEVEL + ETHTOOL_NUM_PRIOS) -/* Promiscuous, Vlan, mac, ttc, inner ttc, {UDP/ANY/aRFS/accel/{esp, esp_err}}, IPsec policy, +/* Vlan, mac, ttc, inner ttc, {UDP/ANY/aRFS/accel/{esp, esp_err}}, IPsec policy, * {IPsec RoCE MPV,Alias table},IPsec RoCE policy */ -#define KERNEL_NIC_PRIO_NUM_LEVELS 11 +#define KERNEL_NIC_PRIO_NUM_LEVELS 10#define KERNEL_NIC_NUM_PRIOS 1 -/* One more level for tc */ -#define KERNEL_MIN_LEVEL (KERNEL_NIC_PRIO_NUM_LEVELS + 1) +/* One more level for tc, and one more for promisc */ +#define KERNEL_MIN_LEVEL (KERNEL_NIC_PRIO_NUM_LEVELS + 2) + +#define KERNEL_NIC_PROMISC_NUM_PRIOS 1 +#define KERNEL_NIC_PROMISC_NUM_LEVELS 1#define KERNEL_NIC_TC_NUM_PRIOS 1#define KERNEL_NIC_TC_NUM_LEVELS 3
@@ -187,6 +190,8 @@ static struct init_tree_node {ADD_NS (MLX5_FLOW_TABLE_MISS_ACTION_DEF ,ADD_MULTIPLE_PRIO (KERNEL_NIC_TC_NUM_PRIOS ,KERNEL_NIC_TC_NUM_LEVELS ), +ADD_MULTIPLE_PRIO (KERNEL_NIC_PROMISC_NUM_PRIOS , +KERNEL_NIC_PROMISC_NUM_LEVELS ),ADD_MULTIPLE_PRIO (KERNEL_NIC_NUM_PRIOS , KERNEL_NIC_PRIO_NUM_LEVELS))), ADD_PRIO(0, BY_PASS_MIN_LEVEL, 0, FS_CHAINING_CAPS,
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 135/163 net: ll_temac: Fix missing tx_pending check in ethtools_set_ringparam()
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alok Tiwari <[email protected]>
[ Upstream commit e81750b4e3826fedce7362dad839cb40384d60ae ]
The function ll_temac_ethtools_set_ringparam() incorrectly checked rx_pending twice, once correctly for RX and once mistakenly in place of tx_pending. This caused tx_pending to be left unchecked against TX_BD_NUM_MAX.
As a result, invalid TX ring sizes may have been accepted or valid ones wrongly rejected based on the RX limit, leading to potential misconfiguration or unexpected results.
This patch corrects the condition to properly validate tx_pending.
--- drivers/net/ethernet/xilinx/ll_temac_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/xilinx/ll_temac_main.c +1 -1
@@ -1309,7 +1309,7 @@ ll_temac_ethtools_set_ringparam(struct net_device *ndev,if (ering->rx_pending >RX_BD_NUM_MAX || ering->rx_mini_pending || ering->rx_jumbo_pending || - ering->rx_pending >TX_BD_NUM_MAX ) + ering->tx_pending >TX_BD_NUM_MAX )return -EINVAL ;if (netif_running (ndev))
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 136/163 bnxt_en: Fix DCB ETS validation
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shravya KN <[email protected]>
[ Upstream commit b74c2a2e9cc471e847abd87e50a2354c07e02040 ]
In bnxt_ets_validate(), the code incorrectly loops over all possible traffic classes to check and add the ETS settings. Fix it to loop over the configured traffic classes only.
The unconfigured traffic classes will default to TSA_ETS with 0 bandwidth. Looping over these unconfigured traffic classes may cause the validation to fail and trigger this error message:
"rejecting ETS config starving a TC\n"
The .ieee_setets() will then fail.
--- drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c +2 -0
@@ -487,7 +487,9 @@ static int bnxt_ets_validate(struct bnxt *bp, struct ieee_ets *ets, u8 *tc)if ((ets->tc_tx_bw[i] || ets->tc_tsa[i]) && i > bp->max_tc)return -EINVAL ; + } +for (i =0 ; i < max_tc; i++) {switch (ets->tc_tsa[i]) {case IEEE_8021QAZ_TSA_STRICT :break ;
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 137/163 bnxt_en: Set DMA unmap len correctly for XDP_REDIRECT
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Somnath Kotur <[email protected]>
[ Upstream commit 3cdf199d4755d477972ee87110b2aebc88b3cfad ]
When transmitting an XDP_REDIRECT packet, call dma_unmap_len_set() with the proper length instead of 0. This bug triggers this warning on a system with IOMMU enabled:
WARNING: CPU: 36 PID: 0 at drivers/iommu/dma-iommu.c:842 __iommu_dma_unmap+0x159/0x170 RIP: 0010:__iommu_dma_unmap+0x159/0x170 Code: a8 00 00 00 00 48 c7 45 b0 00 00 00 00 48 c7 45 c8 00 00 00 00 48 c7 45 a0 ff ff ff ff 4c 89 45
b8 4c 89 45 c0 e9 77 ff ff ff <0f> 0b e9 60 ff ff ff e8 8b bf 6a 00 66 66 2e 0f 1f 84 00 00 00 00
RSP: 0018:ff22d31181150c88 EFLAGS: 00010206
RAX: 0000000000002000 RBX: 00000000e13a0000 RCX: 0000000000000000
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000
RBP: ff22d31181150cf0 R08: ff22d31181150ca8 R09: 0000000000000000
R10: 0000000000000000 R11: ff22d311d36c9d80 R12: 0000000000001000
R13: ff13544d10645010 R14: ff22d31181150c90 R15: ff13544d0b2bac00
FS: 0000000000000000(0000) GS:ff13550908a00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00005be909dacff8 CR3: 0008000173408003 CR4: 0000000000f71ef0
PKRU: 55555554
Call Trace: <IRQ> ? show_regs+0x6d/0x80 ? __warn+0x89/0x160 ? __iommu_dma_unmap+0x159/0x170 ? report_bug+0x17e/0x1b0 ? handle_bug+0x46/0x90 ? exc_invalid_op+0x18/0x80 ? asm_exc_invalid_op+0x1b/0x20 ? __iommu_dma_unmap+0x159/0x170 ? __iommu_dma_unmap+0xb3/0x170 iommu_dma_unmap_page+0x4f/0x100 dma_unmap_page_attrs+0x52/0x220 ? srso_alias_return_thunk+0x5/0xfbef5 ? xdp_return_frame+0x2e/0xd0 bnxt_tx_int_xdp+0xdf/0x440 [bnxt_en] __bnxt_poll_work_done+0x81/0x1e0 [bnxt_en] bnxt_poll+0xd3/0x1e0 [bnxt_en]
--- drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c +1 -1
@@ -115,7 +115,7 @@ static void __bnxt_xmit_xdp_redirect(struct bnxt *bp, tx_buf->action =XDP_REDIRECT ; tx_buf->xdpf = xdpf;dma_unmap_addr_set (tx_buf, mapping, mapping); -dma_unmap_len_set (tx_buf, len,0 ); +dma_unmap_len_set (tx_buf, len, len); }void bnxt_tx_int_xdp (struct bnxt *bp,struct bnxt_napi *bnapi,int budget)
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 138/163 ublk: sanity check add_dev input for underflow
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ronnie Sahlberg <[email protected]>
[ Upstream commit 969127bf0783a4ac0c8a27e633a9e8ea1738583f ]
Add additional checks that queue depth and number of queues are non-zero.
--- drivers/block/ublk_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/block/ublk_drv.c +2 -1
@@ -2457,7 +2457,8 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd)if (copy_from_user (&info, argp,sizeof (info)))return -EFAULT ; -if (info.queue_depth >UBLK_MAX_QUEUE_DEPTH || info.nr_hw_queues >UBLK_MAX_NR_QUEUES ) +if (info.queue_depth >UBLK_MAX_QUEUE_DEPTH || !info.queue_depth || + info.nr_hw_queues >UBLK_MAX_NR_QUEUES || !info.nr_hw_queues)return -EINVAL ;if (capable (CAP_SYS_ADMIN ))
Signature · 1 line
2.39.5
Greg Kroah-Hartman
maintainerPATCH 139/163 atm: idt77252: Add missing `dma_map_error()`
In reply to Greg Kroah-Hartman6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier <[email protected]>
[ Upstream commit c4890963350dcf4e9a909bae23665921fba4ad27 ]
The DMA map functions can fail and should be tested for errors.
--- drivers/atm/idt77252.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/atm/idt77252.c +5 -0
@@ -852,6 +852,8 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,IDT77252_PRV_PADDR (skb) =dma_map_single (&card->pcidev->dev, skb->data, skb->len,DMA_TO_DEVICE ); +if (dma_mapping_error (&card->pcidev->dev,IDT77252_PRV_PADDR (skb))) +return -ENOMEM ; error = -EINVAL ;
@@ -1857,6 +1859,8 @@ add_rx_skb(struct idt77252_dev *card, int queue, paddr =dma_map_single (&card->pcidev->dev, skb->data,skb_end_pointer (skb) - skb->data,DMA_FROM_DEVICE ); +if (dma_mapping_error (&card->pcidev->dev, paddr)) + goto outpoolrm;IDT77252_PRV_PADDR (skb) = paddr;if (push_rx_skb (card, skb, queue)) {
@@ -1871,6 +1875,7 @@ add_rx_skb(struct idt77252_dev *card, int queue,dma_unmap_single (&card->pcidev->dev,IDT77252_PRV_PADDR (skb),skb_end_pointer (skb) - skb->data,DMA_FROM_DEVICE ); +outpoolrm: handle =IDT77252_PRV_POOL (skb); card->sbpool[POOL_QUEUE (handle)].skb[POOL_INDEX (handle)] =NULL ;
Signature · 1 line
2.39.5