* [PATCH 7.3 000/507] 7.3.5-rc1 review
@ 2026-11-13 15:45 Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 001/507] cxl/features: Ensure that count is set before access to ent[] __counted_by() Greg Kroah-Hartman
` (506 more replies)
0 siblings, 507 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, linux-kernel, torvalds, akpm, linux,
shuah, patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
This is the start of the stable review cycle for the 7.3.5 release.
There are 507 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 Sun, 15 Nov 2026 15:36:17 +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/v7.x/stable-review/patch-7.3.5-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-7.3.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Linux 7.3.5-rc1
Gianluca Balboni <gianluca.balboni06@gmail.com>
ASoC: amd: yc: Add DMI quirk for HP OmniBook 3 Laptop 16-by0xxx
Chao Yu <chao@kernel.org>
f2fs: fix to use bio_in_atomic() in f2fs_write_end_io()
Arnd Bergmann <arnd@arndb.de>
mm/vmscan: avoid false-positive -Wuninitialized warning, again
Kairui Song <kasong@tencent.com>
mm/mglru: use explicit tier range in read_ctrl_pos()
Daeho Jeong <daehojeong@google.com>
f2fs: expose resizable_tail feature via sysfs
Rafael J. Wysocki <rafael.j.wysocki@intel.com>
intel_idle: Adjust state names and descriptions for _LPI states
Andy Shevchenko <andy.shevchenko@gmail.com>
intel_idle: Use 2-argument strscpy()
Ali Ahmet Memiş <aliamemis@disroot.org>
thermal: intel: int340x: Evaluate _TMP exclusively
Andrea Parri <parri.andrea@gmail.com>
iommufd/iova_bitmap: Ensure that iova_bitmap_set() handles the full IOVA
David Carlier <devnexen@gmail.com>
media: ipu6: Fix firmware config leak on stream start
Antti Laakso <antti.laakso@linux.intel.com>
media: ipu6: Rename pointer to firmware context
Daeho Jeong <daehojeong@google.com>
f2fs: release a removed xattr node in roll-forward recovery
Miquel Raynal <miquel.raynal@bootlin.com>
clk: nuvoton: ma35d1: Add missing WDT/WWDT parent clocks
Miquel Raynal <miquel.raynal@bootlin.com>
dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks
Miquel Raynal <miquel.raynal@bootlin.com>
dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define
Miquel Raynal <miquel.raynal@bootlin.com>
clk: nuvoton: ma35d1: Keep the clock count in the driver
Sumit Kumar <sumit.kumar@oss.qualcomm.com>
PCI: dwc: Set DMA_BYPASS bit in outbound IATU CTRL2 register
Ali Ahmet Memiş <aliamemis@disroot.org>
ACPI: battery: Evaluate battery methods exclusively
Ali Ahmet Memiş <aliamemis@disroot.org>
ACPI: utils: Add exclusive AML evaluation helpers
Chao Yu <chao@kernel.org>
f2fs: fix to invalidate curseg if change_curseg() fails
Vladimir Oltean <vladimir.oltean@nxp.com>
PCI: cadence: Preserve all error codes in cdns_plat_pcie_probe()
Linmao Li <lilinmao@kylinos.cn>
PCI: cadence: Store the core controller in platform drvdata
vladimir.oltean@nxp.com <vladimir.oltean@nxp.com>
PCI: cadence: Remove device links to PHY
Hengyu Liang <hengyul@cs.unc.edu>
erofs: fix metadata reads at the end of file-backed images
Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
ASoC: hdac_hda: Restore the codec device type on unbind
Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
ASoC: hdac_hda: Allocate the private data at codec driver bind
Guixin Liu <kanie@linux.alibaba.com>
nvme-tcp: Validate the queue state under the queue lock in the address attribute
Chao Yu <chao@kernel.org>
f2fs: fix to avoid potential reference count leak in do_garbage_collect()
Marc Zyngier <maz@kernel.org>
KVM: arm64: vgic: Stop the target vcpu when disabling LPIs
Arnaldo Carvalho de Melo <acme@redhat.com>
perf evsel: Close the fds opened so far when disabling missing features
Hui Su <sh_def@163.com>
perf evsel: Restrict incremental open error unwind
Kaixuan Li <kaixuanli0131@gmail.com>
f2fs: bound the SIT/NAT bitmaps by the checkpoint pack
Daeho Jeong <daehojeong@google.com>
f2fs: return -EIO for a lost inode block after cp_error
Chao Yu <chao@kernel.org>
f2fs: zone: fix to avoid bio split on sequential zone
Vincent Donnefort <vdonnefort@google.com>
KVM: arm64: Use kvm_s2_fault_vma_info in pkvm_mem_abort()
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
dmaengine: qcom: bam_dma: free interrupt before the clock in error path
Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
dmaengine: qcom: bam_dma: Defer IRQ trigger type to device tree
Salvatore Dipietro <dipiets@amazon.it>
mm/page_alloc: avoid direct reclaim and compaction for costly __GFP_NORETRY allocations
Mehmet Fide <mehmet.fide@screeningeagle.com>
wifi: rtw88: widen the ATIM window while an AP interface is up
Mehmet Fide <mehmet.fide@screeningeagle.com>
wifi: rtw88: usb: only let the frames a dozing station needs use the after-DTIM queue
Mehmet Fide <mehmet.fide@screeningeagle.com>
wifi: rtw88: usb: bound what the driver feeds the after-DTIM queue
Mehmet Fide <mehmet.fide@screeningeagle.com>
wifi: rtw88: usb: route bmc frames via the high queue only for DTIM delivery
Martin Belanger <martin.belanger@dell.com>
nvme-tcp: skip TLS control records while waiting for the ICResp
Chris Mason <mason@kernel.org>
mm/shmem: honour F_SEAL_EXEC when an ACL is set
Lorenzo Stoakes (ARM) <ljs@kernel.org>
mm/vma: avoid spurious write locks when mm->mm_lock_seq overflows
Dave Hansen <dave.hansen@linux.intel.com>
mm: add RCU-based VMA lookup helper that waits for writers
David Hildenbrand (Arm) <david@kernel.org>
mm/userfaultfd: only allocate anon_vma in CoW mappings
James Fairweather <james.a.fairweather@gmail.com>
platform/chrome: cros_usbpd_notify: Only use drvdata when parent is GOOG0004
Hemanth Selam <hemanth.selam@gmail.com>
platform/chrome: Fix typos in comments
Yuejie Shi <syjcnss@gmail.com>
fs/ntfs3: validate the EA value length in ntfs_read_ea()
Jun Yang <junvyyang@tencent.com>
sctp: re-point retained control chunks on association migration
David Lee <david.lee@trailofbits.com>
sctp: hold shkey across socket migration
Jared Wuerzburger <jwuerz@gmail.com>
ALSA: hda/realtek: Fix internal mic on Minisforum V3 and V3 SE
Saim Masood <s.m.saim074@gmail.com>
ALSA: hda/realtek: Fix speakers on ASUS ExpertBook PM3606CHA
Chao Yu <chao@kernel.org>
f2fs: fix to check continuousness in f2fs_sync_meta_pages() correctly
Chao Yu <chao@kernel.org>
f2fs: fix to avoid folio->mapping dereference in is_{meta, node}_folio()
Runyu Xiao <runyu.xiao@seu.edu.cn>
ALSA: usb-audio: Protect Roland control activation
Nicholas Hobson <nicholas.hobson@outlook.com>
ALSA: usb-audio: keep MIDI input running for Roland TD-11
Balakrishnan Sambath <balakrishnan.s@microchip.com>
media: microchip-isc: fix SBGGR10 Bayer pattern
Balakrishnan Sambath <balakrishnan.s@microchip.com>
media: microchip-isc: fix ISC_PFG_CFG0_BPS macro name typo
Fuad Tabba <fuad.tabba@linux.dev>
KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort()
Vincent Donnefort <vdonnefort@google.com>
KVM: arm64: Pass kvm_s2_fault_desc to fault_supports_stage2_huge_mapping()
Balakrishnan Sambath <balakrishnan.s@microchip.com>
media: microchip-isc: fix WB offset and gain register field masking
Balakrishnan Sambath <balakrishnan.s@microchip.com>
media: microchip-isc: store the unshifted PFE_CFG0 BPS value
Cheng Ming Lin <chengminglin@mxic.com.tw>
mtd: spi-nor: macronix: Restore fallback parameters for MX25L12805D
Richard Fitzgerald <rf@opensource.cirrus.com>
ASoC: cs35l56: Wait for firmware timer expiry before system suspend
Jason Gunthorpe <jgg@ziepe.ca>
iommu/arm-smmu-v3: Handle ARM erratum for CONT under invalidation with SVA
Zhao Gongyi <zhaogongyi@bytedance.com>
ata: libata-scsi: reject data-in commands with a data-out buffer
Sven Eckelmann <sven@narfation.org>
batman-adv: tt: only update flags for TT events
Sven Eckelmann <sven@narfation.org>
batman-adv: tt: send ROAM_ADV on each roamed back client
Sven Eckelmann <sven@narfation.org>
batman-adv: tt: clear ROAM flag when re-adding a pending local client
Sven Eckelmann <sven@narfation.org>
batman-adv: tt: only transmit local ROAM flag together with DEL
Ido Schimmel <idosch@nvidia.com>
vxlan: Stop rejecting dynamic FDB entries with a nexthop ID
Guanglei Zhu <zhugl3@xiaopeng.com>
ceph: clamp the inline data length in ceph_fill_inline_data()
Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
iommu/amd: Force device table to maximum size
Chris Mason <mason@kernel.org>
x86/mm: Fix global ASID handed out to two processes
Marco Ziliani <rylos78@gmail.com>
ata: libata-pmp: disable the SEMB port on Marvell 88SM9705
Kiryl Shutsemau (Meta) <kas@kernel.org>
arm64: sdei: Preserve the interrupted context's exception registers
Kiryl Shutsemau (Meta) <kas@kernel.org>
arm64: sdei: Run the event handler on the kernel vectors
Thorsten Blum <blum@kernel.org>
x86/boot: Fix off-by-one error in sme_clear_pgd()
Jinjie Ruan <ruanjinjie@huawei.com>
arm64: kexec_file: Fix elf_headers memory leak in retry loop
Kevin Mitchell <kevmitch@arista.com>
iommu/amd: remove obsolete domain pointer warning on release
Akshay Jindal <Akshay.Jindal@amd.com>
iommu/amd: Skip non-IVMD entries when parsing IVRS memory definitions
Breno Leitao <leitao@debian.org>
x86/nmi: Ignore negative NMI handler durations
Daehyeon Ko <4ncienth@gmail.com>
sched/fair: Clear throttle state when leaving the fair class
Danish Khateeb <danishkhateeb03@gmail.com>
perf/core: Don't send SIGTRAP after exec removed the event
Shao Mingyin <shao.mingyin@zte.com.cn>
nvmet: bound the traddr and trsvcid configfs writes
Qiliang Yuan <odys.yuan@gmail.com>
nvme: wait for SRCU readers before splicing the namespace list
Qiliang Yuan <odys.yuan@gmail.com>
srcu: Add list_splice_init_srcu()
Imre Kaloz <kaloz@kernel.org>
MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses
Imre Kaloz <kaloz@kernel.org>
MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only
Imre Kaloz <kaloz@kernel.org>
MIPS: mm: Fix the cache error vector jump for XKPHYS kernels
Matthias Goergens <matthias.goergens@gmail.com>
udf: don't use eloc after the end of the unallocated space table
Matthias Goergens <matthias.goergens@gmail.com>
udf: fix preallocation discarding before an empty allocation extent
Matthias Goergens <matthias.goergens@gmail.com>
udf: check the unallocated space table when it is loaded
Matthias Goergens <matthias.goergens@gmail.com>
udf: don't let the extent type hide an exhausted free-space table extent
Kyle Zeng <kylebot@openai.com>
mptcp: pm: kernel: use RCU to free endpoint listeners
Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
drm/sched: Adjust run-queue when changing priority at runtime
Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
drm/sched: Fix out of bounds entity priority check
Christian Gmeiner <cgmeiner@igalia.com>
drm/etnaviv: Flush the tile status cache through both the PE and BLT
Christian Gmeiner <cgmeiner@igalia.com>
drm/etnaviv: Fix NULL dereference on unbind without PPU flop reset
James Clark <jjc@jclark.com>
net: ethernet: ti: am65-cpsw-nuss: Enable timestamping of unicast PTP packets
Ray Zhang <sgzhang@google.com>
net: count last skb of each sk_backlog pass in __release_sock()
Bryam Vargas <hexlabsecurity@proton.me>
net/smc: don't spin in smc_rx_recvmsg() while a pipe holds spliced data
Hungyu Lin <dennylin0707@gmail.com>
ext2: preserve IOMAP_F_DIRTY for extending direct writes
Sinan Turunc <enscrpt@pm.me>
ALSA: usx2y: Guard the playback copy
Sinan Turunc <enscrpt@pm.me>
ALSA: usx2y: Require a buffer of two URBs
Wentao Liang <vulab@iscas.ac.cn>
ALSA: caiaq: free the EP4 URB when input setup fails
Sinan Turunc <enscrpt@pm.me>
ALSA: line6: Reject capture buffers smaller than two packets
Mohamed Yassine Jebabli <med.jebabli@gmail.com>
ALSA: hda/tas2781: Only accept CRC-less V1 data if all entries are valid
Alexandr <youdoit@mail.ru>
ALSA: hda/realtek: Enable mute and mic-mute LEDs on HP ENVY 17-cr0xxx
Yuqiang Sun <izaiahsun@gmail.com>
ALSA: usb-audio: qcom: Check the return value of qmi_handle_init()
YuanZhe Liu <25031212351@stu.xidian.edu.cn>
ALSA: usx2y: Refuse a retried DSP load after a failure
YuanZhe Liu <25031212351@stu.xidian.edu.cn>
ALSA: bcd2000: Fix use-after-free of MIDI URBs on file close
Alex Kazinsky <a.kazinsky@ideco.ru>
ALSA: cs46xx: Handle SCB creation failures before dereferencing
Chris Simpson <chris@nilk.net>
ALSA: hda/realtek: Enable bass speakers on Alienware m17 R3
HyeongJun An <sammiee5311@gmail.com>
ALSA: ump: Fix dropped data bytes at UMP System message conversion
Ilia Mirkin <imirkin@alum.mit.edu>
drm/nouveau/devinit/gf100-: try to avoid double-running vbios scripts
Finn Zeruhn <fzeruhn@icloud.com>
drm/dp: keep MOT set between messages when no_zero_sized is set
Rosen Penev <rosenp@gmail.com>
drm/nouveau/nvkm: clear use.enabled when subdev init fails
Hengyu Liang <hengyul@cs.unc.edu>
l2tp: only return sessions of the given tunnel in l2tp_session_get()
Amir Goldstein <amir73il@gmail.com>
selftests/fscontext_ns: expect EINVAL for overlay descendant userns create
Chris Mason <mason@kernel.org>
ovl: look up the index by the decoded origin
Sasha Levin <sashal@kernel.org>
nvme-pci: add NVME_QUIRK_DMAPOOL_ALIGN_512 for KIOXIA XG10d
Zhao Gongyi <zhaogongyi@bytedance.com>
arm64: mm: validate /dev/mem mmap ranges without overflow
Wei Wang <wvw@google.com>
arm64: suspend: Save and restore TPIDR2_EL0 across CPU suspend
Ewan D. Milne <emilne@redhat.com>
nvmet: don't return memory contents beyond valid data when reading ANA log page
Jesse Zhang <Jesse.Zhang@amd.com>
drm/amdgpu: don't drop the gang dependency fence twice
renpanpan <renpanpan@kylinos.cn>
drm/amdgpu: Only enable HDMI audio if display supports it
Jesse Zhang <Jesse.Zhang@amd.com>
drm/amdgpu: don't walk the CS chunks when allocating them failed
Jesse Zhang <Jesse.Zhang@amd.com>
drm/amdgpu: rewrite all PTEs of the BOs after a VM reset
Jesse Zhang <Jesse.Zhang@amd.com>
drm/amdgpu: unlock the VM and BO when attaching a KFD BO fails
Jesse Zhang <Jesse.Zhang@amd.com>
drm/amdgpu: drop the dma-buf reference when a KFD import fails
Hugo Sales <hugo@hsal.es>
drm/amdgpu: Clamp the ATIF backlight curve to its 99 points
Erhan Bilgili <erhan.bilgili@gmail.com>
drm/amdgpu: Report MES ring wait timeouts.
Erhan Bilgili <erhan.bilgili@gmail.com>
drm/amdgpu: Fix duplicate dependency fence releases
Kevin Wang <kevin.wang@amd.com>
drm/amd/pm: populate unique ID for smu 13.0.7
Melissa Wen <mwen@igalia.com>
drm/amd/display: Signal PQ EOTF in FreeSync infopacket for DP HDR
Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
drm/amd/display: set allow_freesync before validating a new stream
Kylie C <kyliepc@proton.me>
drm/amd/display: Don't select zero V_TOTAL_MIN/MAX on seamless boot
Matthew Schwartz <matthew.schwartz@linux.dev>
drm/amd/display: Keep the nominal vtotal while VRR is inactive
Misha Nasledov <misha@nasledov.com>
drm/amd/display: Drop clock requirements on DCN32 when no displays are active
Roman Demidov <roman.demidov.nn@gmail.com>
drm/amd/display: Fix NULL deref in dcn401_update_clocks_update_dtb_dto
Jesse Zhang <Jesse.Zhang@amd.com>
drm/amdgpu/gfx12: disallow GFXOFF while updating the SPM VMID
Roman Li <Roman.Li@amd.com>
drm/amd/display: Reset DET of HUBPs without a plane before outstanding updates
Alex Hung <alex.hung@amd.com>
drm/amd/display: Avoid closing unowned DDC pins
Milan Milicevic <Milan.Milicevic@amd.com>
drm/amdgpu: publish IH enabled before PSP programs IH_RB_CNTL
Kent Russell <kent.russell@amd.com>
drm/amdgpu: Ensure that harvest information gets set
Prike Liang <Prike.Liang@amd.com>
drm/amdgpu: stop the schedulers before preparing the GPU reset
Milan Milicevic <Milan.Milicevic@amd.com>
drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts for navi10_ih
Prike Liang <Prike.Liang@amd.com>
drm/amdgpu: finish GPU recovery callbacks before restarting schedulers
Wayne Lin <Wayne.Lin@amd.com>
drm/amd/display: add missing CRC engine 1 registers
Jesse Zhang <Jesse.Zhang@amd.com>
drm/amdgpu/userq: validate the moved individual BOs on restore
Dariusz Marcinkiewicz <darekm@google.com>
drm/amdgpu: check amdgpu_vm_ready() in dma-buf move notify
Prike Liang <Prike.Liang@amd.com>
drm/amdgpu/userq: wait for GPU reset before mapping or unmapping queues
Jesse Zhang <Jesse.Zhang@amd.com>
drm/amdkfd: use the queue's process info for the WPTR BO eviction fence
Jesse Zhang <Jesse.Zhang@amd.com>
drm/amdgpu: keep the CS user fence BO in GTT
Jesse Zhang <Jesse.Zhang@amd.com>
drm/amdgpu: parse CS IBs at the BO offset their VA mapping starts at
Jesse Zhang <Jesse.Zhang@amd.com>
drm/amdgpu: sign extend the addresses GEM_OP(GET_MAPPING_INFO) returns
Ce Sun <cesun102@amd.com>
drm/amdgpu: skip RAS error count reset in debug mode
Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
drm/amdgpu: Check cs flags.
Jarkko Sakkinen <jarkko@kernel.org>
nvme-keyring: Add a missing key_put() call to nvme_tls_key_lookup()
Yitang Yang <yi1tang.yang@gmail.com>
ublk: add missing DEL_DEV_ASYNC to unprivileged permission check
Yilin Zhang <yilinzhang@moonshot.ai>
mptcp: do not use Fast Open on MP_JOIN subflows
Daehyeon Ko <4ncienth@gmail.com>
vhost/vsock: size receive SKBs from declared payload
Alexei Starovoitov <ast@kernel.org>
net: reject a negative TCP header offset in qdisc_pkt_len_segs_init()
Amir Goldstein <amir73il@gmail.com>
ovl: inherit FMODE_NONOTIFY when opening directory realfiles
Jamal Hadi Salim <jhs@mojatatu.com>
net/sched: clamp skb->queue_mapping before indexing the tx queue
Chris Mason <mason@kernel.org>
ovl: fix whiteout creation in casefolded directories
Chris Mason <mason@kernel.org>
ovl: do not let chattr change the casefold flag
Chris Mason <mason@kernel.org>
ovl: fail the mount if the casefold flag has changed
Xia Yan <yanxia@cmss.chinamobile.com>
ipv6: fix device binding after failed datagram connect
Thomas Gleixner <tglx@kernel.org>
x86/entry: Fix ptrace regression
Samiullah Khawaja <skhawaja@google.com>
mm/gup: check folio->mapping under folio lock in memfd_pin_folios()
Lance Yang <lance.yang@linux.dev>
khugepaged: fix readahead lock inversion in collapse_file()
Ritesh Harjani (IBM) <ritesh.list@gmail.com>
mm/huge_memory: set the mmu_gather page size in zap_huge_pud()
David Hildenbrand (Arm) <david@kernel.org>
mm/memory-tiers: unregister empty tiers outside memory_tier_lock
Rik van Riel <riel@surriel.com>
mm/cma: don't release CMA pages still in use
David Hildenbrand (Arm) <david@kernel.org>
mm/vma: don't leak the charge for stack growth
David Hildenbrand (Arm) <david@kernel.org>
mm/huge_memory: split huge PUDs when adjusting VMA boundaries
Chris Mason <mason@kernel.org>
mm/vma: call ->may_split() before a partial merge
Chris Mason <mason@kernel.org>
mm/ksm: check large swap-cache folios before mapping them
David Hildenbrand (Arm) <david@kernel.org>
mm/ksm: fix use of a freed anon_vma at swap-in
David Hildenbrand (Arm) <david@kernel.org>
mm/ksm: reset the unstable trees of all nodes
Chris Mason <mason@kernel.org>
mm: fix deadlock of mremap() against UFFDIO_MOVE
Chris Mason <mason@kernel.org>
mm: fix unkillable fault loop on MAP_DROPPABLE memory
Josef Bacik <josef@toxicpanda.com>
mm: fix unmap_mapping_range() beyond 4 GiB on 32-bit
Chris Mason <mason@kernel.org>
mm/memory: reject remote COW faults on PFN mappings
David Hildenbrand (Arm) <david@kernel.org>
mm/madvise: fix data loss from MADV_FREE on a KSM page
Josef Bacik <josef@toxicpanda.com>
mm/mremap: fix moving PUD leaves
David Hildenbrand (Arm) <david@kernel.org>
mm/mremap: recheck PUDs under the page table lock
David Hildenbrand (Arm) <david@kernel.org>
mm/mremap: use pudp_huge_get_and_clear() when moving huge PUDs
Chris Mason <mason@kernel.org>
mm/mmu_notifier: set ->mm only after mmgrab()
Josef Bacik <josef@toxicpanda.com>
mm/mmu_notifier: finish non-blocking interval invalidation on error
Josef Bacik <josef@toxicpanda.com>
mm/mmu_gather: fix flushing ranges with 4 GiB or larger
Josef Bacik <josef@toxicpanda.com>
mm/userfaultfd: wake all waiters on unregister
David Hildenbrand (Arm) <david@kernel.org>
mm/userfaultfd: write-lock the VMA before waking waiters when unregistering
David Hildenbrand (Arm) <david@kernel.org>
mm/gup: check for overflow when converting nr_pages to bytes in GUP-fast
Chris Mason <mason@kernel.org>
mm/gup: fix out-of-bounds write for nr_pages == 0 in GUP-fast
Chris Mason <mason@kernel.org>
mm/gup: fix clearing folios in memfd_pin_folios()
David Hildenbrand (Arm) <david@kernel.org>
mm/gup: recheck the PUD under PTL in follow_pud_mask()
Chris Mason <mason@kernel.org>
mm/khugepaged: preserve dirty bits when collapsing PTE-mapped THPs
Josef Bacik <josef@toxicpanda.com>
mm/khugepaged: fix PMD table lock leak in try_collapse_pte_mapped_thp()
Josef Bacik <josef@toxicpanda.com>
mm/khugepaged: always recheck the pmd in try_collapse_pte_mapped_thp()
Chris Mason <mason@kernel.org>
mm/huge_memory: fix zapping migration entries for device-private THPs
Chris Mason <mason@kernel.org>
mm/huge_memory: fix truncate racing with PMD zapping
Liu Changjie <liucj1228@outlook.com>
can: peak_usb: pcan_usb_fd_decode_buf(): accept short uCAN end-of-list records
ChunYuZhiQiang <chunyuzhiqiang@yinhe.ht>
can: dev: can_fill_info(): don't wake up controller if interface is down
Oliver Hartkopp <socketcan@hartkopp.net>
can: proc: skip stats calculation after reset in can_stat_update()
Runyu Xiao <runyu.xiao@seu.edu.cn>
can: proc: reset pkg_stats atomics individually
Oliver Hartkopp <socketcan@hartkopp.net>
can: raw, isotp: copy socket options outside of lock_sock()
Oliver Hartkopp <socketcan@hartkopp.net>
can: protect the receive lists with a per-device lock
Oliver Hartkopp <socketcan@hartkopp.net>
can: isotp: check the return values of can_rx_register() in isotp_bind()
Oliver Hartkopp <socketcan@hartkopp.net>
can: replace ARPHRD_CAN type checks with can_get_ml_priv()
Cunhao Lu <1579567540@qq.com>
can: dev: can_put_echo_skb(): free skb on invalid echo index
Cunhao Lu <1579567540@qq.com>
can: skb: make echo skb freeing safe in any IRQ context
Kaixuan Li <kaixuanli0131@gmail.com>
can: isotp: check the frame type, not just the length
Vincent Mailhol <mailhol@kernel.org>
can: dev: can_dropped_invalid_skb: drop CAN XL frames on non-CAN XL devices
Yingjie Wang <1075151112@qq.com>
nvmet: reject keep-alive timeouts that would overflow
Christoph Hellwig <hch@lst.de>
xfs: fix recovery of partial attr removals
Hyunwoo Kim <imv4bel@gmail.com>
net: restore refcount ordering for lockless socket access
Daejun Park <daejun7.park@samsung.com>
xfs: clamp the pNFS layout range to the maximum file size
Daejun Park <daejun7.park@samsung.com>
xfs: cap the block count of xfs_iomap_write_direct() at one extent
Daejun Park <daejun7.park@samsung.com>
xfs: clamp a pNFS LAYOUTCOMMIT extent before computing its end
Daejun Park <daejun7.park@samsung.com>
xfs: refuse a pNFS LAYOUTCOMMIT of a range without blocks
Daejun Park <daejun7.park@samsung.com>
xfs: add a flag to convert unwritten extents without allocating blocks
Daejun Park <daejun7.park@samsung.com>
xfs: mark the inode preallocated for pNFS write layouts past EOF
Zhe Liu <liuzhe1@kylinos.cn>
blk-iocost: account flush sequence latency only once
Krystian Kaniewski <krystianmkaniewski@gmail.com>
blk-mq: fix out-of-bounds read in blk_mq_free_rqs
Laveesh Bansal <laveeshb@laveeshbansal.com>
block: only serialize elevator switches of the same queue
Reid Downing <skibletz@gmail.com>
xfs: fix wrong compat fields in xfs_ioctl32_bstat_copyin()
Hungyu Lin <dennylin0707@gmail.com>
block: Return the soft block size for compat BLKBSZGET
Cong Zhang <cong.zhang@oss.qualcomm.com>
virtio_blk: use synchronous quiesce in virtblk_freeze_priv()
Josef Bacik <josef@toxicpanda.com>
blk-mq: end the request if getting a keyslot fails
Hungyu Lin <dennylin0707@gmail.com>
inotify: do not coalesce rename events
chenglong.ma <longpareto@gmail.com>
vduse: fix VA/PA confusion in the coherent page fault path
Thorsten Blum <blum@kernel.org>
hwrng: virtio - prevent use-after-free after a failed restore
Esben Haabendal <esben@geanix.com>
drm/bridge: nwl-dsi: Limit LCDIF specific sync override
Esben Haabendal <esben@geanix.com>
drm/bridge: nwl-dsi: Cleanup endpoint mux control selection
Yuho Choi <oss.patchbox@gmail.com>
vdpa/snet: Don't discard the DPU error in snet_send_ctrl_msg()
Yuho Choi <oss.patchbox@gmail.com>
iommu/virtio: Reset device before deleting virtqueues on probe failure
Fang Xieyan <fangxy@xiaopeng.com>
vhost: fix used ring index wrap in vhost_add_used_n_in_order
Shubham Antil <shubham@octane.security>
vhost-scsi: zero misaligned I/O bounce pages
Kyle Zeng <kylebot@openai.com>
net/sched: sch_qfq: prevent aggregate self-replacement
Jianyun Gao <jianyungao89@gmail.com>
xfs: fix temporary cursor leak in btree shift corruption paths
Naman Jain <namjain@linux.microsoft.com>
x86/init: Initialize wall clock in get_rtc_noop()
Cen Zhang <zzzccc427@gmail.com>
ocfs2: cache the mount context for dentry lock callbacks
Cen Zhang <zzzccc427@gmail.com>
ocfs2: wait for filecheck kobject release after a failed add
Cen Zhang <zzzccc427@gmail.com>
ocfs2/cluster: unlink socket containers before releasing resources
Cen Zhang <zzzccc427@gmail.com>
ocfs2: stop recovery before shutting down local allocators
Cen Zhang <zzzccc427@gmail.com>
ocfs2/dlm: serialize migration MLE cleanup on failure
Nickolai Zeldovich <nickolai@csail.mit.edu>
panic: zero the dynamically allocated taint buffer
Cen Zhang <zzzccc427@gmail.com>
ocfs2: keep locking_state within the cluster connection lifetime
Cen Zhang <zzzccc427@gmail.com>
ocfs2: validate move extents against a stable EOF
Matheus Alves de Almeida <matheus.aalmeida@inf.ufrgs.br>
fat: hold truncate_lock in fat_write_failed()
Joseph Qi <joseph.qi@linux.alibaba.com>
ocfs2: do not read the entry array of an empty xattr block
Joseph Qi <joseph.qi@linux.alibaba.com>
ocfs2: do not index before the entry array when dividing an empty bucket
Joseph Qi <joseph.qi@linux.alibaba.com>
ocfs2: do not read the entry array of an empty xattr bucket
Joseph Qi <joseph.qi@linux.alibaba.com>
ocfs2: find the xattr entry again after converting a block to a bucket
Joseph Qi <joseph.qi@linux.alibaba.com>
ocfs2: find the xattr entry again after defragmenting a bucket
Andrew Morton <akpm@linux-foundation.org>
openrisc: export __mulsi3 for modules
Nathan Chancellor <nathan@kernel.org>
lib/base64: silence clang-24 -Wconstant-conversion with diag pragmas
T.J. Mercier <tjmercier@google.com>
mm: memcontrol: fix NULL pointer deref and UAF from high_work_func() on dying memcg
Mike Rapoport (Microsoft) <rppt@kernel.org>
mm/cma: accept memory of CMA areas reserved at a fixed address
Mike Rapoport (Microsoft) <rppt@kernel.org>
mm/cma: accept memory of multi-range CMA areas
Johannes Weiner <hannes@cmpxchg.org>
mm: page_alloc: remove ALLOC_NON_BLOCK from ALLOC_RESERVES
Johannes Weiner <hannes@cmpxchg.org>
mm: page_alloc: do not give all non-blocking requests reserve access
Kiryl Shutsemau (Meta) <kas@kernel.org>
mm/hugetlb_vmemmap: map the shared tail page writable
Lorenzo Stoakes (ARM) <ljs@kernel.org>
mm/vma: update VMA iterator state on error in new VMA merge
Yafang Shao <laoar.shao@gmail.com>
mm/migrate: snapshot the source nid before the misplaced migration
Lance Yang <lance.yang@linux.dev>
mm/ksm: fix userfaultfd protection during merge and unmerge
Hungyu Lin <dennylin0707@gmail.com>
mm/migrate: untag addresses when querying page nodes
Chris Down <chris@chrisdown.name>
mm: make swapoff interruptible when unusing mms/shmem
SJ Park <sj@kernel.org>
mm/damon/core: move static variable rotation to damon_ctx
SJ Park <sj@kernel.org>
mm/damon/core: move static variable last_nr_regions to damon_ctx
SJ Park <sj@kernel.org>
mm/damon/sysfs-schemes: hold damon_sysfs_lock in target_metric_store()
Hengyu Liang <hengyul@cs.unc.edu>
fs/proc/task_mmu: return -ENOTTY for unknown pagemap ioctls
Samarth Narang <samarth.colleges@gmail.com>
mm/ksm: keep soft-dirty when merging a page
David Hildenbrand (Arm) <david@kernel.org>
mm/vma: write lock source VMA before duplicating it in __split_vma()
Zenghui Yu (Huawei) <zenghui.yu@linux.dev>
mm/page_alloc: mark pages freed by __free_pages_core() as not tagged
Li Zhe <lizhe.67@bytedance.com>
mm/hugetlb: fix mremap deadlock when PMD sharing is possible
Li Zhe <lizhe.67@bytedance.com>
mm/hugetlb: fix mremap move length truncation
Gregory Price (Meta) <gourry@gourry.net>
mm/page_alloc: let the highest memory node recover from hopeless state
Hungyu Lin <dennylin0707@gmail.com>
mm/page-writeback: avoid 32-bit overflow in dirty threshold shares
Baolin Wang <baolin.wang@linux.alibaba.com>
mm: memory: fix truncation removing mapped folios
David Hildenbrand (Arm) <david@kernel.org>
mm: fix address wraparound when scanning large folio PTEs
Kyle Zeng <kylebot@openai.com>
mm/khugepaged: flush deferred unmaps before dropping a failed folio
Babu Moger <babu.moger@amd.com>
x86,fs/resctrl: Keep mbm_assign_mode in default mode at boot
Babu Moger <babu.moger@amd.com>
x86/resctrl: Correct ABMC counter ID field width
Mohit Sharma <mohit.sharma@oss.qualcomm.com>
ASoC: qcom: q6apm: Guard callbacks until probe data is ready
Michael McAllister <me@michaelmcallister.org>
Bluetooth: qca: Fix the WCN3950 NVM baud rate offset
Valentin Kindschi <valentin.kindschi@fiveco.ch>
Bluetooth: hci_sync: pause advertising for the scan address update
Valentin Kindschi <valentin.kindschi@fiveco.ch>
Bluetooth: hci_sync: re-enable legacy advertising on resume
Zack Rusin <zack.rusin@broadcom.com>
x86/vmware: Fix i386 high-bandwidth hypercall arguments
Yingjie Wang <1075151112@qq.com>
ipv6: reject wrapped temporary address preferred lifetimes
Eric Dumazet <edumazet@kernel.org>
inet: frags: limit the truesize of a reassembly queue
James Calligeros <jcalligeros99@gmail.com>
ASoC: tas2770: Fix error detection in tas2770_set_dai_tdm_idle
Sean Christopherson <seanjc@google.com>
KVM: x86: Unconditionally reset MMU context when emulating INIT
Sean Christopherson <seanjc@google.com>
KVM: x86/mmu: Cap number of parent PTEs per SP at 1000 (the arbitrary rmap limit)
Sean Christopherson <seanjc@google.com>
KVM: nVMX: Process each host MSR entry at most once when unwinding failed VM-Entry
Sean Christopherson <seanjc@google.com>
KVM: x86: Conditionally resched when restarting REP string emulation
Sean Christopherson <seanjc@google.com>
KVM: x86/mmu: Conditionally resched when retrying gPTE walk on A/D update failure
Yuqiang Sun <izaiahsun@gmail.com>
nvme: Do not drop the cdev reference twice when cdev_device_add() fails
Daejun Park <daejun7.park@samsung.com>
nvme: unregister when pr_register() is given a zero new key
Christian Aurich Zanettini Martins <christian.aurichzm@gmail.com>
nvme-rdma: fix NULL queue->ctrl dereference on reconnect
Joonhoe Kim <26rote@gmail.com>
net: qrtr: announce local services again once our HELLO is sent
Vas Zayarskiy <contact@vasily.cc>
hwmon: (aquacomputer_d5next) Avoid truncating scaled sensor readings
Guenter Roeck <linux@roeck-us.net>
hwmon: (sht4x) Convert update_interval to jiffies in pending data check
Guenter Roeck <linux@roeck-us.net>
hwmon: (coretemp) Set nr_cores only after core_data allocation succeeds
Guenter Roeck <linux@roeck-us.net>
hwmon: (coretemp) Check for NULL platform device in hotplug callbacks
Baek Kyu, Kim <pocj8ur4in@gmail.com>
hwmon: (gpio-fan) Update the speed cache before dropping the PM reference
Guenter Roeck <linux@roeck-us.net>
hwmon: (tmp108) Fix initial conversion delay and wait until ready
Guenter Roeck <linux@roeck-us.net>
hwmon: (lm75) Fix setting polarity mask for chips with 16-bit config register
Guenter Roeck <linux@roeck-us.net>
hwmon: (pmbus) Fix return value check from thermal zone registration
Guenter Roeck <linux@roeck-us.net>
hwmon: (pmbus) Release devres allocated memory after devm_thermal_of_zone_register error
Guenter Roeck <linux@roeck-us.net>
hwmon: (pmbus) Check return value from pmbus_thermal_add_sensor()
Guenter Roeck <linux@roeck-us.net>
hwmon: (pmbus/q54sj108a2) Add missing NULL pointer check
Guenter Roeck <linux@roeck-us.net>
hwmon: (peci/dimmtemp) Fix devres leak and UAF on concurrent unbind
Guenter Roeck <linux@roeck-us.net>
hwmon: (nct6683) Fix incorrect struct cast in show_pwm() and store_pwm()
Guenter Roeck <linux@roeck-us.net>
hwmon: (lm87) Fix drvdata type confusion in vrm_show() and vrm_store()
Guenter Roeck <linux@roeck-us.net>
hwmon: (hp-wmi-sensors) Fix unbounded loops in scale_numeric_sensor()
Guenter Roeck <linux@roeck-us.net>
hwmon: (hp-wmi-sensors) Avoid global struct mutation
Guenter Roeck <linux@roeck-us.net>
hwmon: (asus_wmi_sensors) Avoid global struct mutation
Guenter Roeck <linux@roeck-us.net>
hwmon: (aquacomputer_d5next) Check maxcollection when probing AQUAERO devices
Javier Carrasco <javier.carrasco.cruz@gmail.com>
hwmon: chipcap2: synchronize ready IRQ state
Javier Carrasco <javier.carrasco.cruz@gmail.com>
hwmon: chipcap2: serialize access to the alarm indicators
Javier Carrasco <javier.carrasco.cruz@gmail.com>
hwmon: chipcap2: do not discard pending alarms on disable
Javier Carrasco <javier.carrasco.cruz@gmail.com>
hwmon: chipcap2: balance regulator state
Javier Carrasco <javier.carrasco.cruz@gmail.com>
hwmon: chipcap2: enable IRQ processing when regulator is already enabled
Javier Carrasco <javier.carrasco.cruz@gmail.com>
hwmon: chipcap2: disable device after hwmon teardown
Javier Carrasco <javier.carrasco.cruz@gmail.com>
hwmon: chipcap2: fix IRQ teardown ordering
Javier Carrasco <javier.carrasco.cruz@gmail.com>
hwmon: chipcap2: defer probe when IRQs are unavailable
Javier Carrasco <javier.carrasco.cruz@gmail.com>
hwmon: chipcap2: fix be16 handling
Javier Carrasco <javier.carrasco.cruz@gmail.com>
hwmon: chipcap2: fix off-by-one in command mode retry loop
Javier Carrasco <javier.carrasco.cruz@gmail.com>
hwmon: chipcap2: fix command error diagnostics
Alexei Solcanu <alexei.solcanu@pm.me>
hwmon: (gpd-fan) Reset both fans to automatic on duo boards
Zac Lanzon <lanzonza@gmail.com>
hwmon: (asus_rog_ryujin) Fix pump control source on the Ryujin III
Jiale Yao <yaojiale02@163.com>
hwmon: (aquacomputer_d5next) reject short status reports
Baek Kyu, Kim <pocj8ur4in@gmail.com>
hwmon: (corsair-cpro) Cache fan target only after a successful command
Myeonghun Pak <mhun512@gmail.com>
hwmon: (sht15) Stop deferred work before releasing its resources
Xia Yan <yana06070@163.com>
veth: keep carrier off when resizing channels with a down peer
Fang Xieyan <fangxy@xiaopeng.com>
vringh: reject empty / undersized indirect descriptor tables
Fang Xieyan <fangxy@xiaopeng.com>
vringh: bound top-level re-entry into indirect tables
Tal Zussman <tz2294@columbia.edu>
vhost-vdpa: fix pinned page leak in vhost_vdpa_pa_map() error path
Zhan Xusheng <zhanxusheng@xiaomi.com>
ntfs: don't allow compression on volumes with clusters larger than 4K
Qihang <q.h.hack.winter@gmail.com>
cipso: fix optlen corruption in cipso_v4_delopt()
Maíra Canal <mcanal@igalia.com>
drm/v3d: Widen cache_clean_lock over the whole L2TCACTL sequence
Jose Maria Casanova Crespo <jmcasanova@igalia.com>
drm/v3d: Initialize timedout_batches when running a CSD job
Daejun Park <daejun7.park@samsung.com>
xfs: don't skip free extents of the longest length in a whole-AG FITRIM
Daejun Park <daejun7.park@samsung.com>
xfs: don't skip free extents in later batches of a whole-AG FITRIM
Binbin Deng <18983559317@163.com>
xfs: set healthmon mount cookie before publishing it
Hungyu Lin <dennylin0707@gmail.com>
ext2: preserve completed DIO bytes when buffered fallback fails
David Hildenbrand (Arm) <david@kernel.org>
mm/huge_memory: properly handle refcounted PUD mappings on fork
David Hildenbrand (Arm) <david@kernel.org>
mm/huge_memory: fix list corruption when deferred_split_scan() races with deferred_split_folio()
David Hildenbrand (Arm) <david@kernel.org>
mm/rmap: handle device-exclusive entries in folio_referenced_one()
David Hildenbrand (Arm) <david@kernel.org>
mm/filemap: finish fault cleanup before dropping the fault lock
Josef Bacik <josef@toxicpanda.com>
mm/filemap: don't lose a folio lock wakeup to a signal
Josef Bacik <josef@toxicpanda.com>
mm/filemap: read mapping->a_ops->free_folio under i_lock
David Hildenbrand (Arm) <david@kernel.org>
mm/truncate: look again if a folio left the mapping
Josef Bacik <josef@toxicpanda.com>
mm/memfd: make f_pos accesses atomic
David Hildenbrand (Arm) <david@kernel.org>
mm/shmem: make shmem_file() check the file's inode
David Hildenbrand (Arm) <david@kernel.org>
fork: take mmap_lock before copying mm_struct
Josef Bacik <josef@toxicpanda.com>
mm/mglru: don't use stack pointers when walking PUD and PMD tables
David Hildenbrand (Arm) <david@kernel.org>
mm/shmem: fix truncation of files containing only swapin-error markers
David Hildenbrand (Arm) <david@kernel.org>
mm/shmem: fix accounting of swapin-error markers
David Hildenbrand (Arm) <david@kernel.org>
mm/shmem: fix truncate loop after boundary swapin failure
David Hildenbrand (Arm) <david@kernel.org>
mm/shmem: preserve allocation errors when swapping in large entries
David Hildenbrand (Arm) <david@kernel.org>
mm/shmem: fix truncate hang in large swap entry
David Hildenbrand (Arm) <david@kernel.org>
mm/shmem: rescan after nonuniform folio splitting
David Hildenbrand (Arm) <david@kernel.org>
mm/shmem: discard whole new large folios on fallocate rollback
Chris Mason <mason@kernel.org>
mm/shmem: preserve data in clean folios when splitting fails
Chris Mason <mason@kernel.org>
mm/shmem: stop retrying folios that cannot be split
Josef Bacik <josef@toxicpanda.com>
tmpfs: preserve explicitly disabled quota limits
Josef Bacik <josef@toxicpanda.com>
tmpfs: keep the quota soft limits of an unused id
Chris Mason <mason@kernel.org>
mm/mempolicy: charge shared policy nodes
Ian Bridges <icb@fastmail.org>
ksmbd: let the owner read and change the DACL when no ACE names it
Ian Bridges <icb@fastmail.org>
ksmbd: grant a POSIX ACL group entry only to the group's members
Ian Bridges <icb@fastmail.org>
ksmbd: do not read past the DACL in the access denied debug message
Federico Musto <federico@rimpianto.com>
net: atl1c: drop oversized RX frames instead of panicking
Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
drm/i915/display: Allow port sync on PTL
Vidya Srinivas <vidya.srinivas@intel.com>
drm/i915/display: Disable pipe joiner on WCL
Vidya Srinivas <vidya.srinivas@intel.com>
drm/i915/display: Single scaler per pipe on WCL
Lu Yao <yaolu@kylinos.cn>
drm/i915/gem: Reset err for each fence entry
Werner Sembach <wse@tuxedocomputers.com>
drm/i915/display: Add quirk to force backlight type on some TUXEDO devices
Jouni Högander <jouni.hogander@intel.com>
drm/i915/psr: Don't clip plane state destination rectangle
Jouni Högander <jouni.hogander@intel.com>
drm/i915/psr: Fix SFF and CFF CTL register bit definitions
Jouni Högander <jouni.hogander@intel.com>
drm/i915/psr: Disable linked plane sel fetch as well
Jouni Högander <jouni.hogander@intel.com>
drm/i915/display: Add enabled pipe planes into state for selective fetch
Jouni Högander <jouni.hogander@intel.com>
drm/i915/psr: Clear selective fetch area when duplicating plane state
Rosen Penev <rosenp@gmail.com>
x86/csum: Relax the len and proto constraints in 32-bit csum_ipv6_magic()
Breno Leitao <leitao@debian.org>
x86/bugs: Select the BHI mitigation based on the attack vector properly
Lee Jones <lee@kernel.org>
ASoC: SOF: Intel: hda-sdw-bpt: Stop active DMA before closing BPT streams
Miguel Ojeda <ojeda@kernel.org>
rust: cpufreq: fix `undocumented_unsafe_blocks` in `PolicyCpu::from_cpu()`
Jack Blessed Kimani <jackblessed191@gmail.com>
ksmbd: fix NULL pointer dereference in session_user_name() and session_account_type()
Ian Bridges <icb@fastmail.org>
ksmbd: revert fsids on durable reconnect and replay failure
Ian Bridges <icb@fastmail.org>
ksmbd: enforce the read-only share flag when creating a stream
Ian Bridges <icb@fastmail.org>
ksmbd: require DELETE access for delete-on-close opens
Jamal Hadi Salim <jhs@mojatatu.com>
bpf: Fix skb_pull() BUG in __bpf_redirect_neigh()
YuanZhe Liu <25031212351@stu.xidian.edu.cn>
ALSA: hwdep: Serialize DSP load requests
YuanZhe Liu <25031212351@stu.xidian.edu.cn>
ALSA: usx2y: Initialize idle URBs before submitting streams
YuanZhe Liu <25031212351@stu.xidian.edu.cn>
ALSA: us122l: Fix NULL dereference at hwdep open and release
YuanZhe Liu <25031212351@stu.xidian.edu.cn>
ALSA: us122l: Add missing NULL check in usb_stream_hwdep_mmap()
Evanshenf <archwse@gmail.com>
drm/loongson: Handle buffer mapping failures when clearing a BO
Evanshenf <archwse@gmail.com>
drm/loongson: Fix double free on BO initialization failure
Evanshenf <archwse@gmail.com>
drm/loongson: Fix framebuffer selection in async cursor updates
Shao Mingyin <shao.mingyin@zte.com.cn>
scsi: target: tcmu: Fix divide-by-zero in data_pages_per_blk store
Yuanhe Shu <xiangzao@linux.alibaba.com>
scsi: target: Verify the iSCSI ISID is null-terminated
Yingjie Wang <x-professor@outlook.com>
scsi: bsg: Report io_uring data copyback failures
Yingjie Wang <x-professor@outlook.com>
scsi: bsg: Report synchronous data copyback failures
Yu Zhang <yuz08559@gmail.com>
ptp: fix use-after-free in extts_fifo_show() reading tsevqs unlocked
guolingxing <guolingxing@tju.edu.cn>
btrfs: prevent deleting the wrong subvolume by ID
guolingxing <guolingxing@tju.edu.cn>
btrfs: sysfs: restore NOFS context on early return in btrfs_sysfs_add_block_group_type()
Hengyu Liang <hengyul@cs.unc.edu>
btrfs: fix chattr failing on nodatasum files that have the compress flag
Masafumi Suzuki <shengshilingmu97@gmail.com>
sctp: account for chunk padding in sctp_init_cause()
Lucas Tanure <lucas.tanure@neat.no>
drm/vc4: hdmi: enable scrambling before the TMDS clock starts
Lucas Tanure <lucas.tanure@neat.no>
drm/vc4: hdmi: always cancel the scrambling work synchronously
Dom Cobley <popcornmix@gmail.com>
drm/vc4: hdmi: power down the BCM2712 PHY when the output is disabled
Zhou Qiuyue <n0ps1edzz@gmail.com>
ipv6: raw: fix use-after-free in rawv6_send_hdrinc()
Franck Baur <franck.baur.67@gmail.com>
net: jme: keep RX MAC clock enabled for WoL
Sven Eckelmann <sven@narfation.org>
batman-adv: tt: don't drop local events queued during TVLV update
Sven Eckelmann <sven@narfation.org>
batman-adv: tt: ignore ROAM flag of received ADD changes
Sven Eckelmann <sven@narfation.org>
batman-adv: stop originator purge worker before freeing TT
Sven Eckelmann <sven@narfation.org>
batman-adv: fix skb leak when hard_iface is being released
Sven Eckelmann <sven@narfation.org>
batman-adv: dat: initialize orig_node of unfilled candidate slots
Sven Eckelmann <sven@narfation.org>
batman-adv: tpmeter: fix u32 truncation of reported bytes
Kyle Zeng <kylebot@openai.com>
batman-adv: mcast: validate tracker padding before forwarding
Eric Biggers <ebiggers@kernel.org>
lib/crypto: mldsa: Add __must_check to mldsa_verify()
Eric Biggers <ebiggers@kernel.org>
lib/crypto: mldsa: Explicitly check that 'alg' is a valid value
Eric Biggers <ebiggers@kernel.org>
lib/crypto: mldsa: Check pk_len before doing pointer arithmetic
Chengfeng Ye <nicoyip.dev@gmail.com>
batman-adv: Close OGM aggregation before transmission
Yuanfu Xie <yuanfuxie@stu.pku.edu.cn>
9p: don't decrement a server-owned zero nlink
Yehyeong Lee <yhlee@isslab.korea.ac.kr>
9p/xen: validate the response size from the backend
Yu Zhang <yuz08559@gmail.com>
scsi: target: Fix demo-mode dynamic ACL dev-entry UAF vs LUN teardown
Andrew Luebke <andrew.luebke@gmail.com>
scsi: aic79xx: Fix NULL pointer dereference in device reset
Imre Kaloz <kaloz@kernel.org>
scsi: aic7xxx: Use default settings on the SGI O2 onboard controllers
Fourie Zhang <fouriezhang@tencent.com>
xfrm4: use a full socket for local errors
Toke Høiland-Jørgensen <toke@toke.dk>
wifi: mac80211: reinstate IEEE80211_TX_CTL_AMPDU flag in ieee80211_tx_prep_agg()
Eric Biggers <ebiggers@kernel.org>
lib/crypto: mips: Disable Octeon SHA code on little-endian kernels
Maíra Canal <mcanal@igalia.com>
drm/vc4: Drop the BO reservations outside of job_lock
Maíra Canal <mcanal@igalia.com>
drm/vc4: Publish the output fence outside of job_lock
Zijing Yin <yzjaurora@gmail.com>
wifi: cfg80211: fix out-of-bounds read in valid_rule()
Alex Kazinsky <a.kazinsky@ideco.ru>
wifi: rsi: Skip TX aggregation setup for non-QoS frames
Jason Perlow <jperlow@gmail.com>
wifi: brcmfmac: map msgbuf RX packet IDs bidirectional
Weigang He <geoffreyhe2@gmail.com>
wifi: mac80211: reload TDLS header pointer after skb_linearize()
Yili Zhang <zhangyili01@baidu.com>
dma-buf: Fix IOVA offset when linking phys vecs to sgt
André Draszik <andre.draszik@linaro.org>
drm/drm_crtc: fix race with dma_fence_signal() in ::get_driver_name()
André Draszik <andre.draszik@linaro.org>
drm/drm_crtc: ensure dma_fence_ops remain valid during device unbind
Devin Wittmayer <lucid_duck@justthetip.ca>
drm/panic: Fix kmsg screen hang on a long log line
Sabrina Dubroca <sd@queasysnail.net>
xfrm: espintcp: reorder operations within espintcp_init_sk
Qihang <q.h.hack.winter@gmail.com>
xfrm: interface: validate the IP header on xmit
Hyungjung Joo <jhj140711@gmail.com>
net/9p/usbg: clear stale client pointer on close
Michael Grzeschik <mgr@kernel.org>
net/9p/usbg: remove bogus context initialization in alloc_requests
Michael Grzeschik <mgr@kernel.org>
net/9p/usbg: fix out_req buffer leak in disable_usb9pfs
Michael Grzeschik <mgr@kernel.org>
net/9p/usbg: call disable_usb9pfs() from usb9pfs_disable()
Michael Grzeschik <mgr@kernel.org>
net/9p/usbg: always reset completion when disconnecting
Michael Grzeschik <mgr@kernel.org>
net/9p/usbg: set client to Disconnected on usb9pfs_disable
Michael Grzeschik <mgr@kernel.org>
net/9p/usbg: also disable endpoints on p9_usbg_close
Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
net/9p/usbg: Fix use-after-free in disable_usb9pfs()
Zhao Zhang <zzhan461@ucr.edu>
9p: fix caches_show() out-of-bounds write
Yifei Gao <gyf161023@gmail.com>
9p/xen: fix refcount leak in p9_xen_response() on wrong tag
Michael Bommarito <michael.bommarito@gmail.com>
9p/trans_virtio: reject mount tags longer than NAME_MAX at probe
Chengfeng Ye <nicoyip.dev@gmail.com>
net/9p/usbg: clear stale request context after abort
Chengfeng Ye <nicoyip.dev@gmail.com>
xfrm: retry inexact policy lookup after node reinsertion
Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
net/9p/usbg: fix prefix matching in device lookup
Stefano Garzarella <sgarzare@redhat.com>
9p: fix privport option setting wrong RDMA field
SJ Park <sj@kernel.org>
mm/damon/sysfs-schemes: read sysfs_filter->sz_range only once
Ricardo Ribalda <ribalda@chromium.org>
media: uvcvideo: Force UVC version for Avermedia GC515
Ricardo Ribalda <ribalda@chromium.org>
media: uvcvideo: Add autosuspend quirk for AVerMedia Live Gamer HD 2
Christian Loehle <christian.loehle@arm.com>
cpufreq: CPPC: Select the frequency-invariance callback per CPU
Jeff Layton <jlayton@kernel.org>
nfsd: shorten extack string returned with dodgy listener
Darrick J. Wong <djwong@kernel.org>
xfs: forcibly reset quota timers when upgrading to bigtime during repair
Darrick J. Wong <djwong@kernel.org>
xfs: reinitialize dquot block if non-first dquot can't load
Christian Loehle <christian.loehle@arm.com>
ACPI: CPPC: Accept requests to retain immutable autonomous selection
Christian Loehle <christian.loehle@arm.com>
ACPI: CPPC: Validate FFH register fields before hardware access
Ping-Ke Shih <pkshih@realtek.com>
wifi: rtw88: TX report with long timeout for non-PCIE devices
Andrew Morton <akpm@linux-foundation.org>
block: restore the iterator when rejecting a misaligned bio
SJ Park <sj@kernel.org>
mm/damon/core: remove unreachable damos charge_{target,addr}_from
Yuansheng Yang <0xbeac@gmail.com>
io_uring/rsrc: hold uring_lock across index-alloc put_user
Jens Axboe <axboe@kernel.dk>
io_uring/poll: don't poll a writer for urgent data
Jens Axboe <axboe@kernel.dk>
io_uring/poll: don't poll a writer for a read side hangup
Shang En Sim <sim@shangen.org>
io_uring/poll: cancel all matching requests in one pass
Shang En Sim <sim@shangen.org>
io_uring/cancel: count all requests that a CANCEL_ALL cancels
Shakeel Butt <shakeel.butt@linux.dev>
io_uring/sqpoll: do the return-to-userspace work in the SQPOLL thread
Shuai Liu <847807867@qq.com>
io_uring/sqpoll: don't set IO_SQ_THREAD_SHOULD_STOP on thread exit
Jens Axboe <axboe@kernel.dk>
io_uring/sqpoll: don't attach to a thread that is canceling
Chris Mason <mason@kernel.org>
io_uring/cancel: drop sqd->lock while SQPOLL waits
Janne Grunau <j@jannau.net>
wifi: brcmfmac: cfg80211: Report port_authorized for 4-way HS offload
Gael Blivet <gael.blivet@gmail.com>
ksmbd: look up stream size by exact xattr name
Chuck Lever <cel@kernel.org>
NFSD: Complete a cld upcall when copying its reply fails
Chuck Lever <cel@kernel.org>
NFSD: Complete a cld upcall when the daemon closes the pipe
Chuck Lever <cel@kernel.org>
NFSD: Move the cld upcall message out of the caller's stack frame
Chuck Lever <cel@kernel.org>
NFSD: Send a meaningful CB_RECALL_ANY keep count
Jeff Layton <jlayton@kernel.org>
NFSD: stop registering with rpcbind after a failure in listener_set
Jeff Layton <jlayton@kernel.org>
SUNRPC: report local rpcbind calls that get no answer
Jeff Layton <jlayton@kernel.org>
NFSD: report listener creation failures through extack
Chuck Lever <cel@kernel.org>
NFSD: map fh_verify() status codes for NFS_ACLv2 replies
Chuck Lever <cel@kernel.org>
NFSD: Move version-specific ACCESS maps into per-version code
Chuck Lever <cel@kernel.org>
NFSD: Replace nfsd_write()'s "stable" argument with "iocb_flags"
Darrick J. Wong <djwong@kernel.org>
xfs: improve dirent bounds checking in scrub and repair
Darrick J. Wong <djwong@kernel.org>
xfs: refactor directory data block walking loops in scrub
Darrick J. Wong <djwong@kernel.org>
xfs: check for buffer overruns when examining local/remote xattr entries
Darrick J. Wong <djwong@kernel.org>
xfs: break out xattr entry checks into separate functions
Weiming Shi <bestswngs@gmail.com>
smb/server: prevent file publication after tree disconnect
Jinwang Li <jinwang.li@oss.qualcomm.com>
Bluetooth: L2CAP: Ignore connection responses with wrong ident
Siwei Zhang <oss@fourdim.xyz>
Bluetooth: L2CAP: Only accept connection responses to outstanding requests
Siwei Zhang <oss@fourdim.xyz>
Bluetooth: L2CAP: Reject signalling responses in invalid states
Ashok Raj <ashok.raj@oss.qualcomm.com>
cxl/features: Ensure that count is set before access to ent[] __counted_by()
-------------
Diffstat:
Documentation/ABI/testing/sysfs-fs-f2fs | 2 +-
Documentation/admin-guide/pm/intel_idle.rst | 12 +-
Documentation/arch/arm64/silicon-errata.rst | 3 +-
Documentation/filesystems/overlayfs.rst | 3 +-
Documentation/filesystems/resctrl.rst | 87 ++++---
Documentation/hwmon/asus_rog_ryujin.rst | 6 +
Documentation/mm/process_addrs.rst | 14 +-
Documentation/mm/vmemmap_dedup.rst | 15 +-
Makefile | 4 +-
arch/arm64/include/asm/sdei.h | 3 +-
arch/arm64/include/asm/suspend.h | 2 +-
arch/arm64/kernel/entry-common.c | 40 ++-
arch/arm64/kernel/machine_kexec_file.c | 2 +
arch/arm64/kernel/sdei.c | 59 ++++-
arch/arm64/kernel/topology.c | 12 +-
arch/arm64/kvm/mmu.c | 129 +++++-----
arch/arm64/kvm/pkvm.c | 3 +
arch/arm64/kvm/vgic/vgic-mmio-v3.c | 10 +
arch/arm64/mm/mmap.c | 4 +-
arch/arm64/mm/proc.S | 8 +
arch/mips/mm/cex-gen.S | 16 ++
arch/mips/pci/ops-mace.c | 26 +-
arch/mips/pci/pci-ip32.c | 9 +-
arch/mips/sgi-ip32/ip32-irq.c | 45 +---
arch/openrisc/kernel/or32_ksyms.c | 1 +
arch/x86/boot/startup/sme.c | 2 +-
arch/x86/entry/syscall_32.c | 4 +
arch/x86/entry/syscall_64.c | 26 +-
arch/x86/include/asm/checksum_32.h | 2 +-
arch/x86/include/asm/vmware.h | 24 +-
arch/x86/kernel/acpi/cppc.c | 15 ++
arch/x86/kernel/cpu/bugs.c | 12 +-
arch/x86/kernel/cpu/resctrl/internal.h | 4 +-
arch/x86/kernel/cpu/resctrl/monitor.c | 4 +-
arch/x86/kernel/nmi.c | 8 +
arch/x86/kernel/x86_init.c | 2 +-
arch/x86/kvm/mmu/mmu.c | 10 +
arch/x86/kvm/mmu/paging_tmpl.h | 11 +-
arch/x86/kvm/vmx/nested.c | 1 +
arch/x86/kvm/x86.c | 33 ++-
arch/x86/mm/tlb.c | 16 +-
block/bio.c | 3 +
block/blk-iocost.c | 3 +
block/blk-mq.c | 17 +-
block/elevator.c | 32 +--
block/ioctl.c | 4 +-
drivers/acpi/battery.c | 12 +-
drivers/acpi/cppc_acpi.c | 61 ++++-
drivers/acpi/utils.c | 41 +++
drivers/ata/libata-pmp.c | 14 ++
drivers/ata/libata-scsi.c | 25 ++
drivers/block/ublk_drv.c | 1 +
drivers/block/virtio_blk.c | 2 +-
drivers/bluetooth/btqca.c | 3 +-
drivers/char/hw_random/virtio-rng.c | 7 +
drivers/clk/nuvoton/clk-ma35d1.c | 7 +-
drivers/cpufreq/amd-pstate.c | 25 +-
drivers/cpufreq/cppc_cpufreq.c | 26 +-
drivers/cxl/core/features.c | 2 +-
drivers/dma-buf/dma-buf-mapping.c | 2 +-
drivers/dma/qcom/bam_dma.c | 10 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 6 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 3 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 17 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 21 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 41 +--
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 44 +++-
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 5 +
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 7 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 3 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 4 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 19 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 16 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c | 1 -
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 5 +-
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 5 +-
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 5 +-
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 2 +
drivers/gpu/drm/amd/amdgpu/ih_v6_0.c | 13 +-
drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 4 +-
drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 4 +-
drivers/gpu/drm/amd/amdgpu/navi10_ih.c | 41 ++-
.../gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 3 +-
.../drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c | 27 +-
.../amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c | 3 +
drivers/gpu/drm/amd/display/dc/core/dc.c | 6 +-
.../gpu/drm/amd/display/dc/core/dc_hw_sequencer.c | 31 +++
drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h | 3 +
.../display/dc/link/protocols/link_dp_capability.c | 6 +-
.../gpu/drm/amd/display/dc/optc/dcn20/dcn20_optc.c | 7 +
.../gpu/drm/amd/display/dc/optc/dcn30/dcn30_optc.h | 18 ++
.../gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h | 22 +-
.../drm/amd/display/dc/optc/dcn314/dcn314_optc.h | 18 ++
.../gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h | 11 +
.../gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h | 11 -
.../drm/amd/display/dc/optc/dcn401/dcn401_optc.h | 12 +
.../gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.h | 2 +
.../gpu/drm/amd/display/dc/optc/dcn60/dcn60_optc.h | 2 +
.../amd/display/dc/resource/dcn32/dcn32_resource.c | 15 +-
.../amd/display/dc/resource/dcn32/dcn32_resource.h | 6 +
.../display/dc/resource/dcn401/dcn401_resource.h | 6 +
.../drm/amd/display/modules/freesync/freesync.c | 6 +-
.../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 20 ++
drivers/gpu/drm/bridge/nwl-dsi.c | 17 +-
drivers/gpu/drm/display/drm_dp_helper.c | 3 +-
drivers/gpu/drm/drm_crtc.c | 18 +-
drivers/gpu/drm/drm_panic.c | 7 +-
drivers/gpu/drm/etnaviv/etnaviv_buffer.c | 40 ++-
drivers/gpu/drm/etnaviv/etnaviv_drv.c | 6 +-
drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
.../gpu/drm/i915/display/intel_display_device.c | 5 +-
drivers/gpu/drm/i915/display/intel_dp.c | 4 +-
.../gpu/drm/i915/display/intel_dp_aux_backlight.c | 22 +-
drivers/gpu/drm/i915/display/intel_plane.c | 11 +
drivers/gpu/drm/i915/display/intel_psr.c | 96 ++++----
drivers/gpu/drm/i915/display/intel_psr_regs.h | 4 +-
drivers/gpu/drm/i915/display/intel_quirks.c | 24 ++
drivers/gpu/drm/i915/display/intel_quirks.h | 1 +
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +-
drivers/gpu/drm/loongson/lsdc_gem.c | 14 +-
drivers/gpu/drm/loongson/lsdc_plane.c | 2 +-
drivers/gpu/drm/loongson/lsdc_ttm.c | 14 +-
drivers/gpu/drm/loongson/lsdc_ttm.h | 2 +-
drivers/gpu/drm/nouveau/nvkm/core/subdev.c | 1 +
.../gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c | 20 ++
drivers/gpu/drm/scheduler/sched_entity.c | 29 ++-
drivers/gpu/drm/v3d/v3d_gem.c | 5 +-
drivers/gpu/drm/v3d/v3d_sched.c | 2 +
drivers/gpu/drm/vc4/vc4_gem.c | 14 +-
drivers/gpu/drm/vc4/vc4_hdmi.c | 10 +-
drivers/gpu/drm/vc4/vc4_hdmi_phy.c | 5 +
drivers/hwmon/aquacomputer_d5next.c | 58 ++++-
drivers/hwmon/asus_rog_ryujin.c | 54 +++-
drivers/hwmon/asus_wmi_sensors.c | 13 +-
drivers/hwmon/chipcap2.c | 196 ++++++++++-----
drivers/hwmon/coretemp.c | 13 +-
drivers/hwmon/corsair-cpro.c | 3 +-
drivers/hwmon/gpd-fan.c | 1 +
drivers/hwmon/gpio-fan.c | 7 +-
drivers/hwmon/hp-wmi-sensors.c | 29 ++-
drivers/hwmon/lm75.c | 9 +-
drivers/hwmon/lm87.c | 7 +-
drivers/hwmon/nct6683.c | 4 +-
drivers/hwmon/peci/dimmtemp.c | 21 +-
drivers/hwmon/pmbus/pmbus_core.c | 51 ++--
drivers/hwmon/pmbus/q54sj108a2.c | 2 +
drivers/hwmon/sht15.c | 22 +-
drivers/hwmon/sht4x.c | 4 +-
drivers/hwmon/tmp108.c | 26 +-
drivers/idle/intel_idle.c | 11 +-
drivers/iommu/amd/init.c | 41 ++-
drivers/iommu/amd/iommu.c | 17 +-
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 7 +
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 91 +++++--
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 5 +
drivers/iommu/iommufd/io_pagetable.c | 2 +-
drivers/iommu/iommufd/iova_bitmap.c | 19 +-
drivers/iommu/virtio-iommu.c | 6 +-
drivers/media/pci/intel/ipu6/ipu6-fw-isys.c | 88 ++++---
drivers/media/pci/intel/ipu6/ipu6-isys-video.c | 4 +-
drivers/media/pci/intel/ipu6/ipu6-isys.c | 6 +-
drivers/media/pci/intel/ipu6/ipu6-isys.h | 5 +-
.../media/platform/microchip/microchip-isc-base.c | 20 +-
.../media/platform/microchip/microchip-isc-regs.h | 16 +-
drivers/media/platform/microchip/microchip-isc.h | 4 +-
.../platform/microchip/microchip-sama5d2-isc.c | 20 +-
.../platform/microchip/microchip-sama7g5-isc.c | 20 +-
drivers/media/usb/uvc/uvc_driver.c | 20 ++
drivers/mtd/spi-nor/macronix.c | 2 +
drivers/net/can/dev/netlink.c | 4 +-
drivers/net/can/dev/skb.c | 10 +-
drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 7 +-
drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 33 +++
drivers/net/ethernet/jme.c | 37 ++-
drivers/net/ethernet/jme.h | 1 +
drivers/net/ethernet/ti/am65-cpsw-nuss.c | 4 +-
drivers/net/veth.c | 5 +-
drivers/net/vxlan/vxlan_core.c | 14 +-
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 7 +
.../wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 2 +-
drivers/net/wireless/realtek/rtw88/mac80211.c | 2 +
drivers/net/wireless/realtek/rtw88/reg.h | 2 +
drivers/net/wireless/realtek/rtw88/tx.c | 9 +-
drivers/net/wireless/realtek/rtw88/tx.h | 3 +-
drivers/net/wireless/realtek/rtw88/usb.c | 68 ++++-
drivers/net/wireless/realtek/rtw88/usb.h | 5 +
drivers/net/wireless/rsi/rsi_91x_core.c | 2 +-
drivers/nvme/common/keyring.c | 1 +
drivers/nvme/host/core.c | 21 +-
drivers/nvme/host/multipath.c | 2 -
drivers/nvme/host/pci.c | 2 +
drivers/nvme/host/pr.c | 8 +-
drivers/nvme/host/rdma.c | 7 +-
drivers/nvme/host/tcp.c | 213 +++++++++++++---
drivers/nvme/target/admin-cmd.c | 16 +-
drivers/nvme/target/configfs.c | 4 +-
drivers/nvme/target/core.c | 8 +-
drivers/nvme/target/nvmet.h | 8 +
drivers/pci/controller/cadence/pcie-cadence-plat.c | 33 +--
drivers/pci/controller/cadence/pcie-cadence.c | 16 +-
drivers/pci/controller/cadence/pcie-cadence.h | 2 -
drivers/pci/controller/dwc/pcie-designware.c | 2 +
drivers/pci/controller/dwc/pcie-designware.h | 1 +
drivers/platform/chrome/cros_ec_ishtp.c | 2 +-
drivers/platform/chrome/cros_usbpd_notify.c | 41 +--
drivers/ptp/ptp_sysfs.c | 6 +-
drivers/scsi/aic7xxx/aic79xx_core.c | 4 +-
drivers/scsi/aic7xxx/aic79xx_osm.h | 26 +-
drivers/scsi/aic7xxx/aic7xxx_core.c | 8 +-
drivers/scsi/aic7xxx/aic7xxx_pci.c | 20 +-
drivers/scsi/scsi_bsg.c | 8 +-
drivers/target/target_core_device.c | 18 +-
drivers/target/target_core_fabric_lib.c | 10 +
drivers/target/target_core_tpg.c | 10 +-
drivers/target/target_core_user.c | 5 +
.../intel/int340x_thermal/int3403_thermal.c | 3 +-
.../intel/int340x_thermal/int340x_thermal_zone.c | 6 +-
.../int340x_thermal/processor_thermal_device.c | 2 +-
drivers/vdpa/solidrun/snet_ctrl.c | 3 +-
drivers/vdpa/vdpa_user/iova_domain.c | 11 +-
drivers/vhost/scsi.c | 7 +-
drivers/vhost/vdpa.c | 8 +-
drivers/vhost/vhost.c | 3 +-
drivers/vhost/vringh.c | 27 +-
drivers/vhost/vsock.c | 34 ++-
fs/9p/v9fs.c | 18 +-
fs/9p/vfs_inode.c | 8 +
fs/btrfs/ioctl.c | 24 ++
fs/btrfs/sysfs.c | 1 +
fs/ceph/addr.c | 6 +
fs/erofs/fileio.c | 18 +-
fs/ext2/file.c | 3 +-
fs/ext2/inode.c | 13 +-
fs/f2fs/checkpoint.c | 13 +-
fs/f2fs/data.c | 28 ++-
fs/f2fs/f2fs.h | 10 +-
fs/f2fs/gc.c | 11 +-
fs/f2fs/node.c | 75 +++++-
fs/f2fs/segment.c | 3 +-
fs/f2fs/super.c | 24 ++
fs/f2fs/sysfs.c | 2 +
fs/fat/inode.c | 2 +
fs/nfsd/nfs2acl.c | 64 ++++-
fs/nfsd/nfs3proc.c | 58 ++++-
fs/nfsd/nfs3xdr.c | 2 +
fs/nfsd/nfs4proc.c | 60 ++++-
fs/nfsd/nfs4recover.c | 49 +++-
fs/nfsd/nfs4state.c | 24 +-
fs/nfsd/nfs4xdr.c | 2 +-
fs/nfsd/nfsctl.c | 56 ++++-
fs/nfsd/nfsproc.c | 2 +-
fs/nfsd/state.h | 2 +
fs/nfsd/vfs.c | 108 ++------
fs/nfsd/vfs.h | 21 +-
fs/nfsd/xdr3.h | 2 +-
fs/notify/inotify/inotify_fsnotify.c | 2 +-
fs/ntfs/ea.c | 5 +
fs/ntfs3/xattr.c | 25 +-
fs/ocfs2/cluster/tcp.c | 5 +-
fs/ocfs2/dcache.h | 5 +-
fs/ocfs2/dlm/dlmmaster.c | 70 +++++-
fs/ocfs2/dlmglue.c | 34 +--
fs/ocfs2/filecheck.c | 2 +
fs/ocfs2/journal.c | 15 +-
fs/ocfs2/journal.h | 1 +
fs/ocfs2/move_extents.c | 70 +++---
fs/ocfs2/super.c | 3 +
fs/ocfs2/xattr.c | 120 ++++++++-
fs/open.c | 1 +
fs/overlayfs/dir.c | 46 ++--
fs/overlayfs/export.c | 4 +-
fs/overlayfs/inode.c | 8 +
fs/overlayfs/namei.c | 13 +-
fs/overlayfs/overlayfs.h | 21 +-
fs/overlayfs/readdir.c | 6 +-
fs/overlayfs/super.c | 12 +-
fs/overlayfs/util.c | 13 +-
fs/proc/task_mmu.c | 2 +-
fs/smb/server/mgmt/user_session.c | 4 +
fs/smb/server/smb2pdu.c | 65 +++--
fs/smb/server/smbacl.c | 43 +++-
fs/smb/server/vfs.c | 4 +-
fs/smb/server/vfs.h | 2 +
fs/smb/server/vfs_cache.c | 58 +++--
fs/udf/balloc.c | 11 +-
fs/udf/super.c | 80 +++++-
fs/udf/truncate.c | 7 +-
fs/xfs/libxfs/xfs_attr_leaf.c | 9 +-
fs/xfs/libxfs/xfs_bmap.c | 14 +-
fs/xfs/libxfs/xfs_bmap.h | 10 +-
fs/xfs/libxfs/xfs_btree.c | 4 +-
fs/xfs/scrub/attr.c | 102 ++++++--
fs/xfs/scrub/attr_repair.c | 18 +-
fs/xfs/scrub/dir.c | 110 ++++++++-
fs/xfs/scrub/dir_repair.c | 100 ++++++--
fs/xfs/scrub/quota_repair.c | 33 ++-
fs/xfs/xfs_discard.c | 26 +-
fs/xfs/xfs_file.c | 2 +-
fs/xfs/xfs_healthmon.c | 2 +-
fs/xfs/xfs_ioctl32.c | 4 +-
fs/xfs/xfs_ioend.c | 2 +-
fs/xfs/xfs_iomap.c | 28 ++-
fs/xfs/xfs_iomap.h | 3 +-
fs/xfs/xfs_pnfs.c | 60 +++--
include/acpi/acpi_bus.h | 7 +
include/acpi/cppc_acpi.h | 6 +
include/asm-generic/tlb.h | 3 +-
include/crypto/mldsa.h | 6 +-
include/dt-bindings/clock/nuvoton,ma35d1-clk.h | 3 +-
include/linux/blkdev.h | 4 +-
include/linux/can/can-ml.h | 3 +
include/linux/can/dev.h | 2 +-
include/linux/can/skb.h | 4 +-
include/linux/damon.h | 10 +
include/linux/huge_mm.h | 5 +-
include/linux/hugetlb.h | 15 +-
include/linux/ksm.h | 6 +-
include/linux/memfd.h | 9 +
include/linux/mm_types.h | 12 +-
include/linux/mmap_lock.h | 39 ++-
include/linux/mmu_notifier.h | 3 +-
include/linux/mmzone.h | 2 +
include/linux/nfs4.h | 6 +
include/linux/shmem_fs.h | 15 +-
include/linux/srcu.h | 36 +++
include/linux/sunrpc/clnt.h | 3 +-
include/linux/sunrpc/svc.h | 7 +-
include/linux/userfaultfd_k.h | 2 -
include/net/espintcp.h | 5 +-
include/net/inet_frag.h | 9 +
include/net/netns/can.h | 2 +-
include/net/sctp/sm.h | 1 +
include/sound/cs35l56.h | 4 +
include/sound/hwdep.h | 1 +
include/uapi/linux/iommufd.h | 6 +
io_uring/cancel.c | 26 +-
io_uring/poll.c | 62 ++++-
io_uring/rsrc.c | 21 +-
io_uring/sqpoll.c | 26 +-
kernel/events/core.c | 9 +
kernel/fork.c | 20 +-
kernel/panic.c | 2 +-
kernel/sched/fair.c | 4 +-
lib/base64.c | 3 +
lib/crypto/Kconfig | 6 +-
lib/crypto/mldsa.c | 15 +-
lib/crypto/tests/mldsa_kunit.c | 9 +
mm/cma.c | 14 +-
mm/damon/core.c | 32 ++-
mm/damon/sysfs-schemes.c | 8 +-
mm/filemap.c | 84 +++----
mm/gup.c | 68 +++--
mm/huge_memory.c | 146 ++++++++---
mm/hugetlb.c | 92 ++++---
mm/hugetlb_vmemmap.c | 8 +-
mm/internal.h | 38 ++-
mm/khugepaged.c | 75 ++++--
mm/ksm.c | 66 +++--
mm/madvise.c | 9 +
mm/memcontrol.c | 5 +
mm/memfd.c | 2 +
mm/memory-tiers.c | 29 +--
mm/memory.c | 133 ++++++----
mm/mempolicy.c | 4 +-
mm/migrate.c | 5 +-
mm/mm_init.c | 2 -
mm/mmap.c | 8 +-
mm/mmap_lock.c | 124 +++++++++-
mm/mmu_notifier.c | 24 +-
mm/mremap.c | 103 ++++----
mm/nommu.c | 2 +-
mm/page-writeback.c | 8 +-
mm/page_alloc.c | 30 ++-
mm/page_alloc.h | 14 +-
mm/rmap.c | 23 +-
mm/shmem.c | 141 +++++++----
mm/shmem_quota.c | 28 ++-
mm/swapfile.c | 7 +-
mm/truncate.c | 13 +-
mm/userfaultfd.c | 63 ++---
mm/util.c | 13 +
mm/vma.c | 54 ++--
mm/vma_init.c | 3 +
mm/vmscan.c | 29 ++-
net/9p/trans_usbg.c | 91 +++++--
net/9p/trans_virtio.c | 5 +
net/9p/trans_xen.c | 10 +
net/batman-adv/bat_iv_ogm.c | 5 +
net/batman-adv/distributed-arp-table.c | 1 +
net/batman-adv/main.c | 12 +-
net/batman-adv/multicast_forw.c | 5 +-
net/batman-adv/tp_meter.c | 2 +-
net/batman-adv/translation-table.c | 133 ++++++----
net/batman-adv/types.h | 8 +-
net/bluetooth/hci_sync.c | 25 +-
net/bluetooth/l2cap_core.c | 47 +++-
net/can/af_can.c | 56 +++--
net/can/bcm.c | 50 ++--
net/can/gw.c | 7 +-
net/can/isotp.c | 236 +++++++++++-------
net/can/proc.c | 69 +++---
net/can/raw.c | 274 ++++++++++++---------
net/core/dev.c | 4 +-
net/core/filter.c | 23 +-
net/core/sock.c | 6 +-
net/ipv4/cipso_ipv4.c | 9 +-
net/ipv4/inet_connection_sock.c | 6 +-
net/ipv4/inet_fragment.c | 5 +
net/ipv4/inet_hashtables.c | 2 +-
net/ipv4/inet_timewait_sock.c | 4 +-
net/ipv4/syncookies.c | 2 +-
net/ipv4/tcp_fastopen.c | 2 +-
net/ipv4/xfrm4_output.c | 7 +-
net/ipv6/addrconf.c | 3 +-
net/ipv6/datagram.c | 4 +
net/ipv6/inet6_hashtables.c | 2 +-
net/ipv6/raw.c | 3 +
net/l2tp/l2tp_core.c | 13 +-
net/mac80211/tdls.c | 3 +-
net/mac80211/tx.c | 2 +
net/mptcp/pm_kernel.c | 1 +
net/mptcp/subflow.c | 11 +
net/qrtr/af_qrtr.c | 53 +++-
net/sched/sch_generic.c | 41 ++-
net/sched/sch_qfq.c | 3 +
net/sched/sch_taprio.c | 5 +
net/sctp/sm_make_chunk.c | 14 +-
net/sctp/socket.c | 57 ++++-
net/smc/smc_rx.c | 39 ++-
net/sunrpc/rpcb_clnt.c | 22 +-
net/sunrpc/svc.c | 42 +++-
net/wireless/reg.c | 3 +
net/xfrm/espintcp.c | 43 ++--
net/xfrm/xfrm_interface_core.c | 8 +
net/xfrm/xfrm_policy.c | 11 +-
rust/kernel/cpufreq.rs | 4 +-
sound/core/hwdep.c | 2 +
sound/core/ump_convert.c | 2 +-
sound/hda/codecs/realtek/alc269.c | 45 +++-
sound/hda/codecs/side-codecs/tas2781_hda.c | 27 +-
sound/pci/cs46xx/dsp_spos.c | 2 +
sound/pci/cs46xx/dsp_spos_scb_lib.c | 3 +-
sound/soc/amd/yc/acp6x-mach.c | 7 +
sound/soc/codecs/cs35l56-sdw.c | 27 +-
sound/soc/codecs/cs35l56-shared.c | 38 +++
sound/soc/codecs/cs35l56.c | 17 ++
sound/soc/codecs/cs35l56.h | 1 +
sound/soc/codecs/hdac_hda.c | 25 +-
sound/soc/codecs/tas2770.c | 14 +-
sound/soc/qcom/qdsp6/q6apm.c | 6 +-
sound/soc/qcom/qdsp6/q6prm.c | 3 +
sound/soc/sof/intel/hda-codec.c | 23 +-
sound/soc/sof/intel/hda-sdw-bpt.c | 6 +
sound/usb/bcd2000/bcd2000.c | 20 +-
sound/usb/caiaq/input.c | 2 +
sound/usb/line6/capture.c | 29 +++
sound/usb/midi.c | 64 +++--
sound/usb/qcom/qc_audio_offload.c | 7 +
sound/usb/usx2y/us122l.c | 27 +-
sound/usb/usx2y/usX2Yhwdep.c | 5 +
sound/usb/usx2y/usb_stream.c | 9 +-
sound/usb/usx2y/usbusx2yaudio.c | 43 +++-
tools/perf/tests/tool_pmu.c | 79 ++++++
tools/perf/util/evsel.c | 30 ++-
tools/perf/util/hwmon_pmu.c | 2 +-
tools/perf/util/tool_pmu.c | 2 +-
.../filesystems/fscontext_ns/fscontext_ns_test.c | 2 +-
tools/testing/selftests/net/fib_nexthops.sh | 40 ++-
tools/testing/vma/include/dup.h | 2 +-
tools/testing/vma/shared.c | 8 +-
470 files changed, 7038 insertions(+), 2625 deletions(-)
^ permalink raw reply [flat|nested] 508+ messages in thread
* [PATCH 7.3 001/507] cxl/features: Ensure that count is set before access to ent[] __counted_by()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 002/507] Bluetooth: L2CAP: Reject signalling responses in invalid states Greg Kroah-Hartman
` (505 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ashok Raj, Dave Jiang,
Jonathan Cameron, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ashok Raj <ashok.raj@oss.qualcomm.com>
[ Upstream commit c1031c2474f73261d8d5e4deef2b5dc20fb964f5 ]
get_supported_features() assigns entries->num_features only after the
memcpy() loop that fills entries->ent[] has already run. Since ent[]
is __counted_by(num_features), the compiler's bounds instrumentation
sees a 0-length array during that loop and FORTIFY_SOURCE trips on
the memcpy. Set @num_features right after allocation, before any
write into ent[], so the bound is correct for the whole lifetime of
the array.
This was found via a fortify panic:
memcpy: detected buffer overflow: 384 byte write of buffer size 0
WARNING: lib/string_helpers.c:1035 at __fortify_report+0x54/0xa0
kernel BUG at lib/string_helpers.c:1043!
Call trace:
__fortify_panic+0x10/0x18
get_supported_features.isra.0+0x4a0/0x4d0 [cxl_core]
devm_cxl_setup_features+0x84/0x120 [cxl_core]
cxl_pci_probe+0x254/0x5e0 [cxl_pci]
Same class of bug, same fix shape as commit 6c9d2e87df40
("cxl/fwctl: Fix __fortify_panic"), which fixed the analogous issue
in cxlctl_get_supported_features() but missed this one.
[ dj: Fixed up title typo per Jonathan. ]
Fixes: f0e6a2329bf9 ("cxl: Add Get Supported Features command for kernel usage")
Signed-off-by: Ashok Raj <ashok.raj@oss.qualcomm.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Link: https://patch.msgid.link/20260911215304.1816467-1-ashok.raj@oss.qualcomm.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/cxl/core/features.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/cxl/core/features.c b/drivers/cxl/core/features.c
index ba6d2a5acb74a..754fe5eb4b766 100644
--- a/drivers/cxl/core/features.c
+++ b/drivers/cxl/core/features.c
@@ -97,6 +97,7 @@ get_supported_features(struct cxl_features_state *cxlfs)
kvmalloc_flex(*entries, ent, count);
if (!entries)
return NULL;
+ entries->num_features = count;
struct cxl_mbox_get_sup_feats_out *mbox_out __free(kvfree) =
kvmalloc(cxl_mbox->payload_size, GFP_KERNEL);
@@ -174,7 +175,6 @@ get_supported_features(struct cxl_features_state *cxlfs)
start += num_entries;
} while (remain_feats);
- entries->num_features = count;
entries->num_user_features = user_feats;
return no_free_ptr(entries);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 002/507] Bluetooth: L2CAP: Reject signalling responses in invalid states
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 001/507] cxl/features: Ensure that count is set before access to ent[] __counted_by() Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 003/507] Bluetooth: L2CAP: Only accept connection responses to outstanding requests Greg Kroah-Hartman
` (504 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Siwei Zhang, Luiz Augusto von Dentz,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Siwei Zhang <oss@fourdim.xyz>
commit 6320736af7dcb90da6ee9fd651ecc11c564d45b7 upstream.
Adjusted context as stable does not have the lockdep_assert_held()
calls, and l2cap_get_chan_by_scid() still returns the channel locked,
so l2cap_config_rsp() does not lock it again.
A peer can send configuration messages while an
incoming channel is in BT_CONNECT2, before the
security or deferred accept gate has completed. A
configuration response can then promote the channel
to BT_CONNECTED. Configuration responses can also
act on channels that are closing, and a late connection
response can move a disconnecting channel back to
BT_CONFIG.
Accept connection responses only while waiting in
BT_CONNECT. Answer configuration requests in
BT_CONNECT2, but defer our own request until
BT_CONFIG so configuration cannot complete before
the gate. Ignore configuration responses outside
BT_CONFIG and BT_CONNECTED, and only complete
configuration in BT_CONFIG.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/l2cap_core.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index b86999899f669..3e57c605cf8be 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4311,6 +4311,10 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
l2cap_chan_lock(chan);
+ /* Ignore a late response after the channel has left BT_CONNECT. */
+ if (chan->state != BT_CONNECT)
+ goto done;
+
switch (result) {
case L2CAP_CR_SUCCESS:
if (__l2cap_get_chan_by_dcid(conn, dcid)) {
@@ -4340,6 +4344,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
break;
}
+done:
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
@@ -4472,7 +4477,13 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
goto unlock;
}
- if (!test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
+ /* A channel in BT_CONNECT2 has not passed security or userspace
+ * accept yet. Answer the peer's request, but hold our own until
+ * the channel reaches BT_CONFIG: the CONNECT2 -> CONFIG sites send
+ * it. Connected channels may also need to reconfigure.
+ */
+ if ((chan->state == BT_CONFIG || chan->state == BT_CONNECTED) &&
+ !test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) {
u8 buf[64];
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
l2cap_build_conf_req(chan, buf, sizeof(buf)), buf);
@@ -4520,6 +4531,10 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
if (!chan)
return 0;
+ /* Connected channels may also receive reconfiguration responses. */
+ if (chan->state != BT_CONFIG && chan->state != BT_CONNECTED)
+ goto done;
+
switch (result) {
case L2CAP_CONF_SUCCESS:
l2cap_conf_rfc_get(chan, rsp->data, len);
@@ -4587,6 +4602,9 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) {
set_default_fcs(chan);
+ if (chan->state != BT_CONFIG)
+ goto done;
+
if (chan->mode == L2CAP_MODE_ERTM ||
chan->mode == L2CAP_MODE_STREAMING)
err = l2cap_ertm_init(chan);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 003/507] Bluetooth: L2CAP: Only accept connection responses to outstanding requests
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 001/507] cxl/features: Ensure that count is set before access to ent[] __counted_by() Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 002/507] Bluetooth: L2CAP: Reject signalling responses in invalid states Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 004/507] Bluetooth: L2CAP: Ignore connection responses with wrong ident Greg Kroah-Hartman
` (503 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Siwei Zhang, Luiz Augusto von Dentz,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Siwei Zhang <oss@fourdim.xyz>
commit a518b9a9ef6ee3b18ecdf6ba5360c608aaf969e9 upstream.
Adjusted context as stable does not have the lockdep_assert_held()
call and the __must_hold() context analysis annotations.
An outgoing channel waits in BT_CONNECT until security
and the feature mask exchange complete, and only then
sends its connection request. A peer can answer it
before that with a connection response matching our
source CID. The channel then moves to BT_CONFIG,
completes configuration and becomes connected before
security has completed. If security then fails,
l2cap_security_cfm() leaves the connected channel
alone, so it stays up on a link that did not reach
the required security level.
A connection response with a zero source CID is
matched by identifier. Another channel can hold the
same identifier for a response it still has to send,
so the lookup can pick the wrong channel.
Only accept a connection response while our request
is outstanding, and only look at such channels when
matching by identifier.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/l2cap_core.c | 31 ++++++++++++++++++++++++++++---
1 file changed, 28 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 3e57c605cf8be..01945c55e1b87 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -158,6 +158,28 @@ static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn,
return NULL;
}
+/* Our connection request has been sent and is still outstanding */
+static bool l2cap_chan_connect_pending(struct l2cap_chan *chan)
+{
+ return chan->state == BT_CONNECT &&
+ test_bit(CONF_CONNECT_PEND, &chan->conf_state);
+}
+
+/* Other channels may hold the same ident for a response they still have
+ * to send, so only look at channels waiting for a connection response.
+ */
+static struct l2cap_chan *__l2cap_get_connect_chan_by_ident(struct l2cap_conn *conn,
+ u8 ident)
+{
+ struct l2cap_chan *c;
+
+ list_for_each_entry(c, &conn->chan_l, list) {
+ if (c->ident == ident && l2cap_chan_connect_pending(c))
+ return c;
+ }
+ return NULL;
+}
+
static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src,
u8 src_type)
{
@@ -4298,7 +4320,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
if (!chan)
return -EBADSLT;
} else {
- chan = __l2cap_get_chan_by_ident(conn, cmd->ident);
+ chan = __l2cap_get_connect_chan_by_ident(conn, cmd->ident);
if (!chan)
return -EBADSLT;
}
@@ -4311,8 +4333,11 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
l2cap_chan_lock(chan);
- /* Ignore a late response after the channel has left BT_CONNECT. */
- if (chan->state != BT_CONNECT)
+ /* Only accept a response to a connection request we sent and that
+ * is still outstanding. A channel waiting in BT_CONNECT for security
+ * or the feature mask has not sent one yet.
+ */
+ if (!l2cap_chan_connect_pending(chan))
goto done;
switch (result) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 004/507] Bluetooth: L2CAP: Ignore connection responses with wrong ident
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (2 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 003/507] Bluetooth: L2CAP: Only accept connection responses to outstanding requests Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 005/507] smb/server: prevent file publication after tree disconnect Greg Kroah-Hartman
` (502 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jinwang Li, Luiz Augusto von Dentz,
Siwei Zhang, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinwang Li <jinwang.li@oss.qualcomm.com>
commit a9f9eeb5344fc7dc625e5700ccf09891bc2603b5 upstream.
Adjusted context as stable does not have the lockdep_assert_held()
call in l2cap_connect_create_rsp().
L2CAP/COS/CED/BI-28-C requires the IUT to ignore a Connection Response
that carries an invalid Identifier.
l2cap_connect_create_rsp() only checks that a connection request is
outstanding, not that the response answers it. Add an ident check
against the pending request so that a mismatched response is dropped.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Jinwang Li <jinwang.li@oss.qualcomm.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Siwei Zhang <oss@fourdim.xyz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/l2cap_core.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 01945c55e1b87..47f0449588ea1 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4333,11 +4333,11 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
l2cap_chan_lock(chan);
- /* Only accept a response to a connection request we sent and that
- * is still outstanding. A channel waiting in BT_CONNECT for security
- * or the feature mask has not sent one yet.
+ /* Only accept a response matching a connection request we sent and
+ * that is still outstanding. A channel waiting in BT_CONNECT for
+ * security or the feature mask has not sent one yet.
*/
- if (!l2cap_chan_connect_pending(chan))
+ if (!l2cap_chan_connect_pending(chan) || chan->ident != cmd->ident)
goto done;
switch (result) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 005/507] smb/server: prevent file publication after tree disconnect
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (3 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 004/507] Bluetooth: L2CAP: Ignore connection responses with wrong ident Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 006/507] xfs: break out xattr entry checks into separate functions Greg Kroah-Hartman
` (501 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+d531129f2f9fbf88, Weiming Shi,
Namjae Jeon, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
[ Upstream commit 2ff3730998b015b5b0a3f28330bee16c648dd114 ]
TREE_DISCONNECT closes the tree's published file handles before marking and
removing the tree connection. A concurrent CREATE that already holds a tree
reference can therefore publish its file after the close pass. When CREATE
drops its reference, the tree can be freed while the published file still
points to it.
Mark and remove the tree connection before closing its files, and serialize
both new-open and durable-reconnect volatile ID publication with that state
transition. An opener is then either published in time for the close pass
or rejected after disconnect with STATUS_NETWORK_NAME_DELETED.
Keep a tree reference while a file carries its tree pointer. This protects
asynchronous users that can defer the file's final destruction past tree
disconnect.
The close pass can race the successful FP_NEW to FP_INITED transition.
Take the opening request's file reference atomically with that transition.
This keeps the file alive until request completion even if teardown removes
the ID immediately.
BUG: KASAN: slab-use-after-free in proc_show_files (fs/smb/server/vfs_cache.c:126)
Read of size 4 at addr ff11000101540f80 by task poc/153
Call Trace:
proc_show_files (fs/smb/server/vfs_cache.c:126)
seq_read_iter (fs/seq_file.c:231)
proc_reg_read_iter (fs/proc/inode.c:299)
vfs_read (fs/read_write.c:574)
ksys_read (fs/read_write.c:716)
do_syscall_64 (arch/x86/entry/syscall_64.c:84)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
Allocated by:
ksmbd_tree_conn_connect (fs/smb/server/mgmt/tree_connect.c:35)
smb2_tree_connect (fs/smb/server/smb2pdu.c:2819)
handle_ksmbd_work (fs/smb/server/server.c:368)
Freed by:
kfree (mm/slub.c:6801)
handle_ksmbd_work (fs/smb/server/server.c:332)
Fixes: f44158485826 ("cifsd: add file operations")
Cc: stable@vger.kernel.org
Reported-by: <co+d531129f2f9fbf88@bugs.sh>
Assisted-by: LLM
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
[ sashal: replaced ksmbd_tree_connect_get() calls with equivalent inline atomic_inc() operations ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smb2pdu.c | 27 ++++++++++++++----
fs/smb/server/vfs_cache.c | 58 ++++++++++++++++++++++++++++-----------
2 files changed, 63 insertions(+), 22 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 3f1ab9a203070..418610e05ce95 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -3097,9 +3097,10 @@ int smb2_tree_disconnect(struct ksmbd_work *work)
goto err_out;
}
+ err = ksmbd_tree_conn_disconnect(sess, tcon);
+
ksmbd_close_tree_conn_fds(work);
- err = ksmbd_tree_conn_disconnect(sess, tcon);
if (err) {
rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
goto err_out;
@@ -4439,8 +4440,12 @@ int smb2_open(struct ksmbd_work *work)
goto err_out2;
rc = ksmbd_reopen_durable_fd(work, dh_info.fp);
- if (rc)
+ if (rc) {
+ if (rc == -ENOTCONN)
+ rsp->hdr.Status =
+ STATUS_NETWORK_NAME_DELETED;
goto err_out2;
+ }
fp = dh_info.fp;
@@ -4874,6 +4879,8 @@ int smb2_open(struct ksmbd_work *work)
if (IS_ERR(fp)) {
fput(filp);
rc = PTR_ERR(fp);
+ if (rc == -ENOTCONN)
+ rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
fp = NULL;
goto err_out;
}
@@ -5477,11 +5484,20 @@ int smb2_open(struct ksmbd_work *work)
err_out2:
if (!rc) {
- if (!dh_info.replay)
+ if (!dh_info.replay) {
+ smb2_complete_request_open(work);
rc = ksmbd_update_fstate(&work->sess->file_table, fp,
FP_INITED);
- if (!rc)
+ if (rc == -ENOENT)
+ rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
+ if (!rc) {
+ work->request_open = fp;
+ work->request_open_chseq =
+ smb3_hdr_channel_sequence(&req->hdr);
+ }
+ } else {
rc = smb2_set_request_open(work, fp, &req->hdr, false, false);
+ }
if (!rc)
rc = ksmbd_iov_pin_rsp(work, (void *)rsp, iov_len);
}
@@ -5496,8 +5512,7 @@ int smb2_open(struct ksmbd_work *work)
rsp->hdr.Status = STATUS_PRIVILEGE_NOT_HELD;
else
rsp->hdr.Status = STATUS_ACCESS_DENIED;
- }
- else if (rc == -ENOENT)
+ } else if (rc == -ENOENT && !rsp->hdr.Status)
rsp->hdr.Status = STATUS_OBJECT_NAME_INVALID;
else if (rc == -EPERM)
rsp->hdr.Status = STATUS_SHARING_VIOLATION;
diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c
index 1efa9f8145601..38196befa03a5 100644
--- a/fs/smb/server/vfs_cache.c
+++ b/fs/smb/server/vfs_cache.c
@@ -698,16 +698,18 @@ static void __ksmbd_close_fd(struct ksmbd_file_table *ft, struct ksmbd_file *fp)
}
/*
- * Drop fp's strong reference on conn (taken in ksmbd_open_fd() /
- * ksmbd_reopen_durable_fd()). Durable fps that reached the
- * scavenger have already had fp->conn cleared by session_fd_check(),
- * in which case there is nothing to drop here.
+ * Drop fp's strong connection references. Durable fps that reached
+ * the scavenger have already had these cleared by session_fd_check().
*/
if (fp->conn) {
atomic_dec(&fp->conn->stats.open_files_count);
ksmbd_conn_put(fp->conn);
fp->conn = NULL;
}
+ if (fp->tcon) {
+ ksmbd_tree_connect_put(fp->tcon);
+ fp->tcon = NULL;
+ }
if (ksmbd_stream_fd(fp))
kfree(fp->stream.name);
@@ -1331,14 +1333,14 @@ struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp)
fp->filp = filp;
/*
- * fp owns a strong reference on fp->conn for as long as fp->conn is
- * non-NULL, so session_fd_check() and __ksmbd_close_fd() never
- * dereference a dangling pointer. Paired with ksmbd_conn_put() in
- * session_fd_check() (durable preserve), in __ksmbd_close_fd()
- * (final close), and on the error paths below.
+ * fp owns strong references on fp->conn and fp->tcon for as long as
+ * they are non-NULL. Paired with the puts in session_fd_check()
+ * (durable preserve), in __ksmbd_close_fd() (final close), and on the
+ * error paths below.
*/
fp->conn = ksmbd_conn_get(work->conn);
fp->tcon = work->tcon;
+ atomic_inc(&fp->tcon->refcount);
fp->share_conf = work->tcon->share_conf;
atomic_inc(&fp->share_conf->refcount);
fp->volatile_id = KSMBD_NO_FID;
@@ -1351,7 +1353,13 @@ struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp)
goto err_out;
}
- ret = __open_id(&work->sess->file_table, fp, OPEN_ID_TYPE_VOLATILE_ID);
+ down_read(&work->sess->tree_conns_lock);
+ if (work->tcon->t_state == TREE_CONNECTED)
+ ret = __open_id(&work->sess->file_table, fp,
+ OPEN_ID_TYPE_VOLATILE_ID);
+ else
+ ret = -ENOTCONN;
+ up_read(&work->sess->tree_conns_lock);
if (ret) {
ksmbd_inode_put(fp->f_ci);
goto err_out;
@@ -1361,7 +1369,8 @@ struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp)
return fp;
err_out:
- /* fp->conn was set and refcounted before every branch here. */
+ /* fp->conn and fp->tcon were refcounted before every branch here. */
+ ksmbd_tree_connect_put(fp->tcon);
ksmbd_conn_put(fp->conn);
ksmbd_share_config_put(fp->share_conf);
kmem_cache_free(filp_cache, fp);
@@ -1376,8 +1385,9 @@ struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp)
*
* Return: 0 on success. The FP_NEW -> FP_INITED transition is special:
* -ENOENT if teardown already unpublished @fp by advancing the state or
- * clearing the volatile id. Other state updates preserve the historical
- * fire-and-forget behavior.
+ * clearing the volatile id. On success it also takes a reference for the
+ * opening request, which must be released with ksmbd_fd_put(). Other state
+ * updates preserve the historical fire-and-forget behavior.
*/
int ksmbd_update_fstate(struct ksmbd_file_table *ft, struct ksmbd_file *fp,
unsigned int state)
@@ -1393,6 +1403,8 @@ int ksmbd_update_fstate(struct ksmbd_file_table *ft, struct ksmbd_file *fp,
ret = -ENOENT;
} else {
fp->f_state = state;
+ if (state == FP_INITED)
+ atomic_inc(&fp->refcount);
ret = 0;
}
write_unlock(&ft->lock);
@@ -1813,6 +1825,7 @@ static bool session_fd_check(struct ksmbd_tree_connect *tcon,
struct oplock_info *op;
struct ksmbd_conn *conn;
struct ksmbd_lock *smb_lock, *tmp_lock;
+ struct ksmbd_tree_connect *tree_conn;
if (!is_reconnectable(fp))
return false;
@@ -1834,6 +1847,7 @@ static bool session_fd_check(struct ksmbd_tree_connect *tcon,
ci = fp->f_ci;
down_write(&ci->m_lock);
conn = fp->conn;
+ tree_conn = fp->tcon;
list_for_each_entry_rcu(op, &ci->m_op_list, op_entry,
lockdep_is_held(&ci->m_lock)) {
if (op->o_fp != fp)
@@ -1869,6 +1883,7 @@ static bool session_fd_check(struct ksmbd_tree_connect *tcon,
/* Drop fp's own reference on conn. */
ksmbd_conn_put(conn);
+ ksmbd_tree_connect_put(tree_conn);
return true;
}
@@ -1972,7 +1987,8 @@ int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp)
* concurrent teardown that iterates the table can observe a valid
* volatile_id with fp->conn == NULL and preserve a
* partially-initialized fp. fp owns a strong reference on the new
- * conn (see ksmbd_open_fd()); undo it on __open_id() failure.
+ * conn (see ksmbd_open_fd()); undo it on __open_id() failure. Serialize
+ * publication with tree disconnect just as ksmbd_open_fd() does.
*/
spin_lock(&fp->f_lock);
old_f_state = fp->f_state;
@@ -1982,12 +1998,19 @@ int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp)
atomic_inc(&fp->share_conf->refcount);
fp->conn = ksmbd_conn_get(conn);
fp->tcon = work->tcon;
+ atomic_inc(&fp->tcon->refcount);
spin_unlock(&fp->f_lock);
atomic_inc(&conn->stats.open_files_count);
write_unlock(&global_ft.lock);
- __open_id(&work->sess->file_table, fp, OPEN_ID_TYPE_VOLATILE_ID);
- if (!has_file_id(fp->volatile_id)) {
+ down_read(&work->sess->tree_conns_lock);
+ if (work->tcon->t_state == TREE_CONNECTED)
+ ret = __open_id(&work->sess->file_table, fp,
+ OPEN_ID_TYPE_VOLATILE_ID);
+ else
+ ret = -ENOTCONN;
+ up_read(&work->sess->tree_conns_lock);
+ if (ret) {
write_lock(&global_ft.lock);
spin_lock(&fp->f_lock);
fp->conn = NULL;
@@ -1998,7 +2021,10 @@ int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp)
atomic_dec(&conn->stats.open_files_count);
write_unlock(&global_ft.lock);
ksmbd_conn_put(conn);
+ ksmbd_tree_connect_put(work->tcon);
ksmbd_share_config_put(work->tcon->share_conf);
+ if (ret != -ENOTCONN)
+ ret = -EBADF;
goto out;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 006/507] xfs: break out xattr entry checks into separate functions
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (4 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 005/507] smb/server: prevent file publication after tree disconnect Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 007/507] xfs: check for buffer overruns when examining local/remote xattr entries Greg Kroah-Hartman
` (500 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
[ Upstream commit 9eb04a6d41c7e474d4665118895c3c2d8e5a2741 ]
We're going to add more xattr entry checking code in xchk_xattr_entry so
break these out into separate functions so that we don't go crazy
indenting. There's a slight behavior change here where we skip updating
the usedmap if we've decided the xattr structure is corrupt.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Stable-dep-of: 91c41f952490 ("xfs: check for buffer overruns when examining local/remote xattr entries")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/scrub/attr.c | 90 ++++++++++++++++++++++++++++++++++-----------
1 file changed, 68 insertions(+), 22 deletions(-)
diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
index 842d65834afbc..f7c00ea1af5d3 100644
--- a/fs/xfs/scrub/attr.c
+++ b/fs/xfs/scrub/attr.c
@@ -293,6 +293,66 @@ xchk_xattr_set_map(
return ret;
}
+static unsigned int
+xchk_xattr_local_entry(
+ struct xchk_da_btree *ds,
+ int level,
+ char *buf_end,
+ struct xfs_attr_leafblock *leaf,
+ int idx)
+{
+ struct xfs_attr_leaf_name_local *lentry =
+ xfs_attr3_leaf_name_local(leaf, idx);
+ char *name_end;
+ unsigned int namesize;
+
+ namesize = xfs_attr_leaf_entsize_local(lentry->namelen,
+ be16_to_cpu(lentry->valuelen));
+ name_end = (char *)lentry + namesize;
+ if (lentry->namelen == 0) {
+ xchk_da_set_corrupt(ds, level);
+ return 0;
+ }
+ if (name_end > buf_end) {
+ xchk_da_set_corrupt(ds, level);
+ return 0;
+ }
+
+ return namesize;
+}
+
+static unsigned int
+xchk_xattr_remote_entry(
+ struct xchk_da_btree *ds,
+ int level,
+ char *buf_end,
+ struct xfs_attr_leafblock *leaf,
+ int idx,
+ struct xfs_attr_leaf_entry *ent)
+{
+ struct xfs_attr_leaf_name_remote *rentry =
+ xfs_attr3_leaf_name_remote(leaf, idx);
+ char *name_end;
+ unsigned int namesize;
+
+ namesize = xfs_attr_leaf_entsize_remote(rentry->namelen);
+ name_end = (char *)rentry + namesize;
+ if (rentry->namelen == 0) {
+ xchk_da_set_corrupt(ds, level);
+ return 0;
+ }
+ if (rentry->valueblk == 0 && !(ent->flags & XFS_ATTR_INCOMPLETE)) {
+ xchk_da_set_corrupt(ds, level);
+ return 0;
+ }
+ if (name_end > buf_end) {
+ xchk_da_set_corrupt(ds, level);
+ return 0;
+ }
+
+ return namesize;
+}
+
/*
* Check this leaf entry's relations to everything else.
* Returns the number of bytes used for the name/value data.
@@ -311,9 +371,6 @@ xchk_xattr_entry(
{
struct xfs_mount *mp = ds->state->mp;
struct xchk_xattr_buf *ab = ds->sc->buf;
- char *name_end;
- struct xfs_attr_leaf_name_local *lentry;
- struct xfs_attr_leaf_name_remote *rentry;
unsigned int nameidx;
unsigned int namesize;
@@ -333,25 +390,14 @@ xchk_xattr_entry(
}
/* Check the name information. */
- if (ent->flags & XFS_ATTR_LOCAL) {
- lentry = xfs_attr3_leaf_name_local(leaf, idx);
- namesize = xfs_attr_leaf_entsize_local(lentry->namelen,
- be16_to_cpu(lentry->valuelen));
- name_end = (char *)lentry + namesize;
- if (lentry->namelen == 0)
- xchk_da_set_corrupt(ds, level);
- } else {
- rentry = xfs_attr3_leaf_name_remote(leaf, idx);
- namesize = xfs_attr_leaf_entsize_remote(rentry->namelen);
- name_end = (char *)rentry + namesize;
- if (rentry->namelen == 0)
- xchk_da_set_corrupt(ds, level);
- if (rentry->valueblk == 0 &&
- !(ent->flags & XFS_ATTR_INCOMPLETE))
- xchk_da_set_corrupt(ds, level);
- }
- if (name_end > buf_end)
- xchk_da_set_corrupt(ds, level);
+ if (ent->flags & XFS_ATTR_LOCAL)
+ namesize = xchk_xattr_local_entry(ds, level, buf_end, leaf,
+ idx);
+ else
+ namesize = xchk_xattr_remote_entry(ds, level, buf_end, leaf,
+ idx, ent);
+ if (!namesize)
+ return;
if (!xchk_xattr_set_map(ds->sc, ab->usedmap, nameidx, namesize))
xchk_da_set_corrupt(ds, level);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 007/507] xfs: check for buffer overruns when examining local/remote xattr entries
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (5 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 006/507] xfs: break out xattr entry checks into separate functions Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 008/507] xfs: refactor directory data block walking loops in scrub Greg Kroah-Hartman
` (499 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
[ Upstream commit 91c41f9524906a8ebd2ae68c98a07b4bd5255ddb ]
LOLLM noticed that the xattr scrub and repair code can walk off the end
of the buffer if the xattr entry record starts so close to the end of
the buffer that there's not even space for the entry structure itself.
Strengthen the bounds checking here.
Cc: stable@vger.kernel.org # v4.15
Fixes: 13791d3b833428 ("xfs: scrub extended attribute leaf space")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/scrub/attr.c | 12 ++++++++++++
fs/xfs/scrub/attr_repair.c | 16 +++++++++++++---
2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
index f7c00ea1af5d3..f909e2b25158a 100644
--- a/fs/xfs/scrub/attr.c
+++ b/fs/xfs/scrub/attr.c
@@ -306,6 +306,12 @@ xchk_xattr_local_entry(
char *name_end;
unsigned int namesize;
+ name_end = (char *)lentry + offsetof(typeof(*lentry), nameval[0]);
+ if (name_end > buf_end) {
+ xchk_da_set_corrupt(ds, level);
+ return 0;
+ }
+
namesize = xfs_attr_leaf_entsize_local(lentry->namelen,
be16_to_cpu(lentry->valuelen));
name_end = (char *)lentry + namesize;
@@ -335,6 +341,12 @@ xchk_xattr_remote_entry(
char *name_end;
unsigned int namesize;
+ name_end = (char *)rentry + offsetof(typeof(*rentry), name[0]);
+ if (name_end > buf_end) {
+ xchk_da_set_corrupt(ds, level);
+ return 0;
+ }
+
namesize = xfs_attr_leaf_entsize_remote(rentry->namelen);
name_end = (char *)rentry + namesize;
if (rentry->namelen == 0) {
diff --git a/fs/xfs/scrub/attr_repair.c b/fs/xfs/scrub/attr_repair.c
index c7695d4cc8e7c..ad688f9f7ce94 100644
--- a/fs/xfs/scrub/attr_repair.c
+++ b/fs/xfs/scrub/attr_repair.c
@@ -285,6 +285,7 @@ xrep_xattr_salvage_local_attr(
struct xfs_attr_leaf_name_local *lentry)
{
struct xchk_xattr_buf *ab = rx->sc->buf;
+ char *name_end;
unsigned char *value;
unsigned int valuelen;
unsigned int namesize;
@@ -293,10 +294,14 @@ xrep_xattr_salvage_local_attr(
* Decode the leaf local entry format. If something seems wrong, we
* junk the attribute.
*/
+ name_end = (char *)lentry + offsetof(typeof(*lentry), nameval[0]);
+ if (name_end > buf_end)
+ return 0;
value = &lentry->nameval[lentry->namelen];
valuelen = be16_to_cpu(lentry->valuelen);
namesize = xfs_attr_leaf_entsize_local(lentry->namelen, valuelen);
- if ((char *)lentry + namesize > buf_end)
+ name_end = (char *)lentry + namesize;
+ if (name_end > buf_end)
return 0;
if (!xrep_xattr_want_salvage(rx, ent->flags, lentry->nameval,
lentry->namelen, value, valuelen))
@@ -333,8 +338,8 @@ xrep_xattr_salvage_remote_attr(
.attr_filter = ent->flags & XFS_ATTR_NSP_ONDISK_MASK,
.namelen = rentry->namelen,
.name = rentry->name,
- .valuelen = be32_to_cpu(rentry->valuelen),
};
+ char *name_end;
unsigned int namesize;
int error;
@@ -343,9 +348,14 @@ xrep_xattr_salvage_remote_attr(
* junk the attribute. Note that we should never find a zero-length
* remote attribute value.
*/
+ name_end = (char *)rentry + offsetof(typeof(*rentry), name[0]);
+ if (name_end > buf_end)
+ return 0;
namesize = xfs_attr_leaf_entsize_remote(rentry->namelen);
- if ((char *)rentry + namesize > buf_end)
+ name_end = (char *)rentry + namesize;
+ if (name_end > buf_end)
return 0;
+ args.valuelen = be32_to_cpu(rentry->valuelen);
if (args.valuelen == 0 ||
!xrep_xattr_want_salvage(rx, ent->flags, rentry->name,
rentry->namelen, NULL, args.valuelen))
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 008/507] xfs: refactor directory data block walking loops in scrub
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (6 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 007/507] xfs: check for buffer overruns when examining local/remote xattr entries Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 009/507] xfs: improve dirent bounds checking in scrub and repair Greg Kroah-Hartman
` (498 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
[ Upstream commit 19b5653cc870788df71e7fcf2dd7b6131d8868dc ]
Hoist the inner loop code of the directory data block walking code in
the directory scrub and repair code to separate functions in preparation
for strengthening the validation in a subsequent patch.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Stable-dep-of: 5d470234d04d ("xfs: improve dirent bounds checking in scrub and repair")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/scrub/dir.c | 56 ++++++++++++++++++++++++++----
fs/xfs/scrub/dir_repair.c | 73 ++++++++++++++++++++++++++++-----------
2 files changed, 102 insertions(+), 27 deletions(-)
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index 4ab7e64692482..e35631e00ddec 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -313,6 +313,45 @@ xchk_dir_actor(
return error;
}
+/*
+ * Deal with an unused directory entry. Returns a positive number of bytes to
+ * advance in the directory block, zero to stop processing, or -1 if corruption
+ * was found.
+ */
+static int
+xchk_dir_check_unused(
+ struct xchk_da_btree *ds,
+ struct xfs_buf *bp,
+ unsigned int iter_off,
+ unsigned int end)
+{
+ struct xfs_dir2_data_unused *dup = bp->b_addr + iter_off;
+
+ return be16_to_cpu(dup->length);
+}
+
+/*
+ * Check a directory entry. Returns a positive number of bytes to advance
+ * in the directory block, zero to stop processing, or -1 if corruption was
+ * found.
+ */
+static int
+xchk_dir_check_entry(
+ struct xchk_da_btree *ds,
+ struct xfs_buf *bp,
+ unsigned int iter_off,
+ unsigned int end,
+ struct xfs_dir2_data_entry *dent)
+{
+ struct xfs_dir2_data_entry *dep = bp->b_addr + iter_off;
+ struct xfs_mount *mp = ds->state->mp;
+
+ if (dep == dent)
+ return 0;
+
+ return xfs_dir2_data_entsize(mp, dep->namelen);
+}
+
/* Scrub a directory btree record. */
STATIC int
xchk_dir_rec(
@@ -389,21 +428,24 @@ xchk_dir_rec(
goto out_relse;
}
for (;;) {
- struct xfs_dir2_data_entry *dep = bp->b_addr + iter_off;
struct xfs_dir2_data_unused *dup = bp->b_addr + iter_off;
+ int advance;
if (iter_off >= end) {
xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
goto out_relse;
}
- if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
- iter_off += be16_to_cpu(dup->length);
- continue;
- }
- if (dep == dent)
+ if (dup->freetag == cpu_to_be16(XFS_DIR2_DATA_FREE_TAG))
+ advance = xchk_dir_check_unused(ds, bp, iter_off, end);
+ else
+ advance = xchk_dir_check_entry(ds, bp, iter_off, end,
+ dent);
+ if (advance < 0)
+ goto out_relse;
+ if (!advance)
break;
- iter_off += xfs_dir2_data_entsize(mp, dep->namelen);
+ iter_off += advance;
}
/* Retrieve the entry, sanity check it, and compare hashes. */
diff --git a/fs/xfs/scrub/dir_repair.c b/fs/xfs/scrub/dir_repair.c
index bb3f2f462bde5..1169a2ad26876 100644
--- a/fs/xfs/scrub/dir_repair.c
+++ b/fs/xfs/scrub/dir_repair.c
@@ -462,6 +462,52 @@ xrep_dir_salvage_data_entry(
return xrep_dir_salvage_entry(rd, dep->name, dep->namelen, ino);
}
+/*
+ * Deal with an unused directory entry. Returns a positive number of bytes to
+ * advance in the directory block, or zero to stop processing.
+ */
+static int
+xrep_dir_recover_unused(
+ struct xfs_buf *bp,
+ unsigned int offset,
+ unsigned int end)
+{
+ struct xfs_dir2_data_unused *dup = bp->b_addr + offset;
+
+ return be16_to_cpu(dup->length);
+}
+
+/*
+ * Salvage a directory entry. Returns a positive number of bytes to advance
+ * in the directory block, zero to stop processing, or a negative errno.
+ */
+static int
+xrep_dir_recover_entry(
+ struct xrep_dir *rd,
+ struct xfs_buf *bp,
+ unsigned int offset,
+ unsigned int end)
+{
+ struct xfs_dir2_data_entry *dep = bp->b_addr + offset;
+ unsigned int advance;
+ int error;
+
+ /* Don't walk off the end of the block. */
+ advance = xfs_dir2_data_entsize(rd->sc->mp, dep->namelen);
+ if (!advance)
+ return 0;
+ if (offset + advance > end)
+ return 0;
+
+ /* Ok, let's save this entry. */
+ error = xrep_dir_salvage_data_entry(rd, dep);
+ if (error < 0)
+ return error;
+
+ return advance;
+}
+
+
/* Try to recover block/data format directory entries. */
STATIC int
xrep_dir_recover_data(
@@ -483,33 +529,20 @@ xrep_dir_recover_data(
while (offset < end) {
struct xfs_dir2_data_unused *dup = bp->b_addr + offset;
- struct xfs_dir2_data_entry *dep = bp->b_addr + offset;
- unsigned int advance;
+ int advance;
if (xchk_should_terminate(rd->sc, &error))
return error;
- /* Skip unused entries. */
- if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
- if (!dup->length)
- break;
- offset += be16_to_cpu(dup->length);
- continue;
- }
-
- /* Don't walk off the end of the block. */
- advance = xfs_dir2_data_entsize(rd->sc->mp, dep->namelen);
+ if (dup->freetag == cpu_to_be16(XFS_DIR2_DATA_FREE_TAG))
+ advance = xrep_dir_recover_unused(bp, offset, end);
+ else
+ advance = xrep_dir_recover_entry(rd, bp, offset, end);
+ if (advance < 0)
+ return advance;
if (!advance)
break;
offset += advance;
- if (offset > end)
- break;
-
- /* Ok, let's save this entry. */
- error = xrep_dir_salvage_data_entry(rd, dep);
- if (error)
- return error;
-
}
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 009/507] xfs: improve dirent bounds checking in scrub and repair
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (7 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 008/507] xfs: refactor directory data block walking loops in scrub Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 010/507] NFSD: Replace nfsd_write()s "stable" argument with "iocb_flags" Greg Kroah-Hartman
` (497 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
[ Upstream commit 5d470234d04dae6fe2ca2cf4b9ef277b78c7e05a ]
LOLLM complains that we don't do enough bounds checking of the directory
entries in directory blocks when we're looking for errors or trying to
salvage entries. Let's improve that with more detailed checks.
Cc: stable@vger.kernel.org # v4.16
Fixes: ce92d29ddf9908 ("xfs: directory scrubber must walk through data block to offset")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/scrub/dir.c | 68 +++++++++++++++++++++++++++++++++------
fs/xfs/scrub/dir_repair.c | 37 ++++++++++++++++++---
2 files changed, 91 insertions(+), 14 deletions(-)
diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c
index e35631e00ddec..05fe8bc71427e 100644
--- a/fs/xfs/scrub/dir.c
+++ b/fs/xfs/scrub/dir.c
@@ -323,11 +323,24 @@ xchk_dir_check_unused(
struct xchk_da_btree *ds,
struct xfs_buf *bp,
unsigned int iter_off,
- unsigned int end)
+ unsigned int end,
+ xfs_dablk_t rec_bno)
{
struct xfs_dir2_data_unused *dup = bp->b_addr + iter_off;
+ unsigned int advance;
+
+ if (iter_off + sizeof(*dup) > end) {
+ xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
+ return -1;
+ }
+
+ advance = xfs_dir2_data_unusedsize(be16_to_cpu(dup->length));
+ if (!advance || iter_off + advance > end) {
+ xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
+ return -1;
+ }
- return be16_to_cpu(dup->length);
+ return advance;
}
/*
@@ -341,15 +354,31 @@ xchk_dir_check_entry(
struct xfs_buf *bp,
unsigned int iter_off,
unsigned int end,
- struct xfs_dir2_data_entry *dent)
+ struct xfs_dir2_data_entry *dent,
+ xfs_dablk_t rec_bno)
{
struct xfs_dir2_data_entry *dep = bp->b_addr + iter_off;
struct xfs_mount *mp = ds->state->mp;
+ unsigned int advance;
+
+ /* must have namelen */
+ advance = offsetof(typeof(*dep), name);
+ if (iter_off + advance >= end) {
+ xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
+ return -1;
+ }
+
+ /* Don't walk off the end of the block. */
+ advance = xfs_dir2_data_entsize(mp, dep->namelen);
+ if (!advance || iter_off + advance > end) {
+ xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
+ return -1;
+ }
if (dep == dent)
return 0;
- return xfs_dir2_data_entsize(mp, dep->namelen);
+ return advance;
}
/* Scrub a directory btree record. */
@@ -377,6 +406,7 @@ xchk_dir_rec(
xfs_dahash_t hash;
struct xfs_dir3_icleaf_hdr hdr;
unsigned int tag;
+ bool foundit = false;
int error;
ASSERT(blk->magic == XFS_DIR2_LEAF1_MAGIC ||
@@ -421,33 +451,44 @@ xchk_dir_rec(
dent = bp->b_addr + off;
/* Make sure we got a real directory entry. */
- iter_off = geo->data_entry_offset;
end = xfs_dir3_data_end_offset(geo, bp->b_addr);
if (!end) {
xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
goto out_relse;
}
- for (;;) {
+ iter_off = geo->data_entry_offset;
+ while (iter_off < end) {
struct xfs_dir2_data_unused *dup = bp->b_addr + iter_off;
int advance;
- if (iter_off >= end) {
+ /* must have freetag */
+ advance = offsetof(typeof(*dup), length);
+ if (iter_off + advance >= end) {
xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
goto out_relse;
}
if (dup->freetag == cpu_to_be16(XFS_DIR2_DATA_FREE_TAG))
- advance = xchk_dir_check_unused(ds, bp, iter_off, end);
+ advance = xchk_dir_check_unused(ds, bp, iter_off, end,
+ rec_bno);
else
advance = xchk_dir_check_entry(ds, bp, iter_off, end,
- dent);
+ dent, rec_bno);
if (advance < 0)
goto out_relse;
- if (!advance)
+ if (!advance) {
+ foundit = true;
break;
+ }
iter_off += advance;
}
+ /* Hash tree must point to the exact dirent */
+ if (!foundit) {
+ xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
+ goto out_relse;
+ }
+
/* Retrieve the entry, sanity check it, and compare hashes. */
ino = be64_to_cpu(dent->inumber);
hash = be32_to_cpu(ent->hashval);
@@ -459,6 +500,13 @@ xchk_dir_rec(
goto out_relse;
}
+ /* Name must not overflow end of block */
+ if ((char *)dent->name + dent->namelen >
+ (char *)bp->b_addr + BBTOB(bp->b_length)) {
+ xchk_fblock_set_corrupt(ds->sc, XFS_DATA_FORK, rec_bno);
+ goto out_relse;
+ }
+
/* Does the directory hash match? */
dname.name = dent->name;
dname.len = dent->namelen;
diff --git a/fs/xfs/scrub/dir_repair.c b/fs/xfs/scrub/dir_repair.c
index 1169a2ad26876..84fe3dda0d421 100644
--- a/fs/xfs/scrub/dir_repair.c
+++ b/fs/xfs/scrub/dir_repair.c
@@ -473,8 +473,16 @@ xrep_dir_recover_unused(
unsigned int end)
{
struct xfs_dir2_data_unused *dup = bp->b_addr + offset;
+ unsigned int advance;
+
+ if (offset + sizeof(*dup) > end)
+ return 0;
+
+ advance = xfs_dir2_data_unusedsize(be16_to_cpu(dup->length));
+ if (!advance || offset + advance > end)
+ return 0;
- return be16_to_cpu(dup->length);
+ return advance;
}
/*
@@ -492,11 +500,14 @@ xrep_dir_recover_entry(
unsigned int advance;
int error;
+ /* must have namelen */
+ advance = offsetof(typeof(*dep), name);
+ if (offset + advance >= end)
+ return 0;
+
/* Don't walk off the end of the block. */
advance = xfs_dir2_data_entsize(rd->sc->mp, dep->namelen);
- if (!advance)
- return 0;
- if (offset + advance > end)
+ if (!advance || offset + advance > end)
return 0;
/* Ok, let's save this entry. */
@@ -534,6 +545,11 @@ xrep_dir_recover_data(
if (xchk_should_terminate(rd->sc, &error))
return error;
+ /* must have freetag */
+ advance = offsetof(typeof(*dup), length);
+ if (offset + advance >= end)
+ break;
+
if (dup->freetag == cpu_to_be16(XFS_DIR2_DATA_FREE_TAG))
advance = xrep_dir_recover_unused(bp, offset, end);
else
@@ -565,6 +581,19 @@ xrep_dir_recover_sf(
hdr = ifp->if_data;
end = (unsigned char *)ifp->if_data + ifp->if_bytes;
+ /* sf header must be big enough for count/i8count */
+ if (!hdr || ifp->if_bytes < 2)
+ return 0;
+
+ /* and large enough for the parent inumber */
+ if (hdr->i8count) {
+ if (ifp->if_bytes < offsetof(struct xfs_dir2_sf_hdr, parent[8]))
+ return 0;
+ } else {
+ if (ifp->if_bytes < offsetof(struct xfs_dir2_sf_hdr, parent[4]))
+ return 0;
+ }
+
ino = xfs_dir2_sf_get_parent_ino(hdr);
trace_xrep_dir_salvaged_parent(rd->sc->ip, ino);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 010/507] NFSD: Replace nfsd_write()s "stable" argument with "iocb_flags"
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (8 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 009/507] xfs: improve dirent bounds checking in scrub and repair Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 011/507] NFSD: Move version-specific ACCESS maps into per-version code Greg Kroah-Hartman
` (496 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chuck Lever, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <cel@kernel.org>
[ Upstream commit 7f7dde9a45dfd9b3c9f35cb24aff9e45669071cc ]
The current nfsd_write() API is not NFS version-agnostic, as it
relies on callers to pass an NFSv3 stable_how value to determine
the persistence of the requested WRITE. NFSv2 does not use a
stable-how value on the wire, and NFSv4 has its own stable_how4
(though stable_how and stable_how4 happen to share the same
numeric values).
To remove the dependence on NFSv3-specific XDR values from NFSD's
generic VFS APIs, replace nfsd_write()'s stable argument with an
argument that passes a set of IOCB flags instead of an XDR-defined
value.
The NFSv4 WRITE and COPY paths had been borrowing the NFSv3
stable_how constants for their own on-the-wire stable values,
relying on the numeric coincidence noted above. Convert those
sites to the stable_how4 enumerators so the v4 code expresses
its own protocol's values directly, with no change in behavior.
While here, bound-check the decoded NFSv3 WRITE stable value, as
the NFSv4 WRITE decoder already does, and make the nfsd3_writeargs
stable field unsigned to suit.
The larger benefit is one less NFSv4 dependency on nfs3.h.
Link: https://patch.msgid.link/20260723182043.990391-3-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Stable-dep-of: ccfc4db5ab74 ("NFSD: map fh_verify() status codes for NFS_ACLv2 replies")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfs3proc.c | 17 ++++++++++++++++-
fs/nfsd/nfs3xdr.c | 2 ++
fs/nfsd/nfs4proc.c | 18 ++++++++++++++++--
fs/nfsd/nfs4xdr.c | 2 +-
fs/nfsd/nfsproc.c | 2 +-
fs/nfsd/vfs.c | 30 ++++++++++--------------------
fs/nfsd/vfs.h | 6 ++++--
fs/nfsd/xdr3.h | 2 +-
include/linux/nfs4.h | 6 ++++++
9 files changed, 57 insertions(+), 28 deletions(-)
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 0904d953d10e0..7d8ddb7bfab0c 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -48,6 +48,20 @@ static bool nfsd3_time_in_range(const struct iattr *iap)
return true;
}
+static int nfsd3_iocb_flags(enum nfs3_stable_how how)
+{
+ switch (how) {
+ case NFS_FILE_SYNC:
+ /* persist data and timestamps */
+ return IOCB_DSYNC | IOCB_SYNC;
+ case NFS_DATA_SYNC:
+ /* persist data only */
+ return IOCB_DSYNC;
+ default:
+ return 0;
+ }
+}
+
static __be32 nfsd3_map_status(__be32 status)
{
switch (status) {
@@ -260,7 +274,8 @@ nfsd3_proc_write(struct svc_rqst *rqstp)
resp->committed = argp->stable;
resp->status = nfsd_write(rqstp, &resp->fh, argp->offset,
&argp->payload, &cnt,
- resp->committed, resp->verf);
+ nfsd3_iocb_flags(resp->committed),
+ resp->verf);
resp->count = cnt;
resp->status = nfsd3_map_status(resp->status);
return rpc_success;
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index e481804bb120c..f418cab0bd614 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -556,6 +556,8 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, struct xdr_stream *xdr)
return false;
if (xdr_stream_decode_u32(xdr, &args->stable) < 0)
return false;
+ if (args->stable > NFS_FILE_SYNC)
+ return false;
/* opaque data */
if (xdr_stream_decode_u32(xdr, &args->len) < 0)
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index f3f7f14a93683..9ee02a6d00868 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -69,6 +69,20 @@ MODULE_PARM_DESC(nfsd4_ssc_umount_timeout,
#define NFSDDBG_FACILITY NFSDDBG_PROC
+static int nfsd4_iocb_flags(enum stable_how4 how)
+{
+ switch (how) {
+ case FILE_SYNC4:
+ /* persist data and timestamps */
+ return IOCB_DSYNC | IOCB_SYNC;
+ case DATA_SYNC4:
+ /* persist data only */
+ return IOCB_DSYNC;
+ default:
+ return 0;
+ }
+}
+
static u32 nfsd_attrmask[] = {
NFSD_WRITEABLE_ATTRS_WORD0,
NFSD_WRITEABLE_ATTRS_WORD1,
@@ -1377,7 +1391,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
write->wr_how_written = write->wr_stable_how;
status = nfsd_vfs_write(rqstp, &cstate->current_fh, nf,
write->wr_offset, &write->wr_payload,
- &cnt, write->wr_how_written,
+ &cnt, nfsd4_iocb_flags(write->wr_how_written),
(__be32 *)write->wr_verifier.data);
nfsd_file_put(nf);
@@ -1974,7 +1988,7 @@ static void nfsd4_init_copy_res(struct nfsd4_copy *copy, bool sync)
{
copy->cp_res.wr_stable_how =
test_bit(NFSD4_COPY_F_COMMITTED, ©->cp_flags) ?
- NFS_FILE_SYNC : NFS_UNSTABLE;
+ FILE_SYNC4 : UNSTABLE4;
nfsd4_copy_set_sync(copy, sync);
}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index ebd0dc8f00fca..f7d2884aba44c 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1606,7 +1606,7 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u)
return nfserr_bad_xdr;
if (xdr_stream_decode_u32(argp->xdr, &write->wr_stable_how) < 0)
return nfserr_bad_xdr;
- if (write->wr_stable_how > NFS_FILE_SYNC)
+ if (write->wr_stable_how > FILE_SYNC4)
return nfserr_bad_xdr;
if (xdr_stream_decode_u32(argp->xdr, &write->wr_buflen) < 0)
return nfserr_bad_xdr;
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index aaeb222b62ba1..48182f78d6be9 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -280,7 +280,7 @@ nfsd_proc_write(struct svc_rqst *rqstp)
fh_copy(&resp->fh, &argp->fh);
resp->status = nfsd_write(rqstp, &resp->fh, argp->offset,
- &argp->payload, &cnt, NFS_DATA_SYNC, NULL);
+ &argp->payload, &cnt, IOCB_DSYNC, NULL);
if (resp->status == nfs_ok)
resp->status = fh_getattr(&resp->fh, &resp->stat);
else if (resp->status == nfserr_jukebox)
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 8923a9910a08f..fe27f6b404268 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1424,7 +1424,7 @@ nfsd_direct_write(struct svc_rqst *rqstp, struct svc_fh *fhp,
* @offset: Byte offset of start
* @payload: xdr_buf containing the write payload
* @cnt: IN: number of bytes to write, OUT: number of bytes actually written
- * @stable: An NFS stable_how value
+ * @iocb_flags: VFS IOCB_* flags expressing the requested write stability
* @verf: NFS WRITE verifier
*
* Upon return, caller must invoke fh_put on @fhp.
@@ -1436,7 +1436,7 @@ __be32
nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp,
struct nfsd_file *nf, loff_t offset,
const struct xdr_buf *payload, unsigned long *cnt,
- int stable, __be32 *verf)
+ int iocb_flags, __be32 *verf)
{
struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
struct file *file = nf->nf_file;
@@ -1473,21 +1473,11 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp,
exp = fhp->fh_export;
if (!EX_ISSYNC(exp))
- stable = NFS_UNSTABLE;
+ iocb_flags = 0;
init_sync_kiocb(&kiocb, file);
kiocb.ki_pos = offset;
- if (likely(!fhp->fh_use_wgather)) {
- switch (stable) {
- case NFS_FILE_SYNC:
- /* persist data and timestamps */
- kiocb.ki_flags |= IOCB_DSYNC | IOCB_SYNC;
- break;
- case NFS_DATA_SYNC:
- /* persist data only */
- kiocb.ki_flags |= IOCB_DSYNC;
- break;
- }
- }
+ if (likely(!fhp->fh_use_wgather))
+ kiocb.ki_flags |= iocb_flags;
nvecs = xdr_buf_to_bvec(rqstp->rq_bvec, rqstp->rq_maxpages, payload);
if (nvecs < 0) {
@@ -1528,7 +1518,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp,
goto out_nfserr;
}
- if (stable && fhp->fh_use_wgather) {
+ if (iocb_flags && fhp->fh_use_wgather) {
host_err = wait_for_concurrent_writes(file);
if (host_err < 0)
commit_reset_write_verifier(nn, rqstp, host_err);
@@ -1619,7 +1609,7 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
* @offset: Byte offset of start
* @payload: xdr_buf containing the write payload
* @cnt: IN: number of bytes to write, OUT: number of bytes actually written
- * @stable: An NFS stable_how value
+ * @iocb_flags: VFS IOCB_* flags expressing the requested write stability
* @verf: NFS WRITE verifier
*
* Upon return, caller must invoke fh_put on @fhp.
@@ -1629,8 +1619,8 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
*/
__be32
nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
- const struct xdr_buf *payload, unsigned long *cnt, int stable,
- __be32 *verf)
+ const struct xdr_buf *payload, unsigned long *cnt,
+ int iocb_flags, __be32 *verf)
{
struct nfsd_file *nf;
__be32 err;
@@ -1642,7 +1632,7 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
goto out;
err = nfsd_vfs_write(rqstp, fhp, nf, offset, payload, cnt,
- stable, verf);
+ iocb_flags, verf);
nfsd_file_put(nf);
out:
trace_nfsd_write_done(rqstp, fhp, offset, *cnt);
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index 4af2ff9e9dfee..5937bd78d4291 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -135,11 +135,13 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
u32 *eof);
__be32 nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp,
loff_t offset, const struct xdr_buf *payload,
- unsigned long *cnt, int stable, __be32 *verf);
+ unsigned long *cnt, int iocb_flags,
+ __be32 *verf);
__be32 nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp,
struct nfsd_file *nf, loff_t offset,
const struct xdr_buf *payload,
- unsigned long *cnt, int stable, __be32 *verf);
+ unsigned long *cnt, int iocb_flags,
+ __be32 *verf);
__be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *,
char *, int *);
__be32 nfsd_symlink(struct svc_rqst *, struct svc_fh *,
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index 344203874b4c4..cad875d142313 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -39,7 +39,7 @@ struct nfsd3_writeargs {
svc_fh fh;
__u64 offset;
__u32 count;
- int stable;
+ __u32 stable;
__u32 len;
struct xdr_buf payload;
};
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 1a3981c26b23b..41b7cdcc674f1 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -263,6 +263,12 @@ enum why_no_delegation4 { /* new to v4.1 */
WND4_IS_DIR = 8,
};
+enum stable_how4 {
+ UNSTABLE4 = 0,
+ DATA_SYNC4 = 1,
+ FILE_SYNC4 = 2,
+};
+
enum lock_type4 {
NFS4_UNLOCK_LT = 0,
NFS4_READ_LT = 1,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 011/507] NFSD: Move version-specific ACCESS maps into per-version code
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (9 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 010/507] NFSD: Replace nfsd_write()s "stable" argument with "iocb_flags" Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 012/507] NFSD: map fh_verify() status codes for NFS_ACLv2 replies Greg Kroah-Hartman
` (495 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <cel@kernel.org>
[ Upstream commit 3423b5f91d80d3a76424e1c9f1d0f95d4dd80101 ]
nfsd_access() owns three static tables that map on-the-wire ACCESS
bits to NFSD_MAY flags, and every NFS version shares them. That puts
protocol-version specifics in the version-agnostic VFS layer. The
NFSv4.2 extended-attribute bits are wedged into the NFSv3 tables
under CONFIG_NFSD_V4.
Give each version its own tables in its proc code and pass the
matching set into nfsd_access() as a new argument.
Splitting the tables also stops the NFSv2-ACL and NFSv3 ACCESS paths
from answering for the NFSv4.2 extended-attribute bits. Both use the
NFSv4-augmented table whenever CONFIG_NFSD_V4 is set, so an NFSv3
request that sets an xattr bit has it echoed back in the reply even
though those bits are undefined for v3.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260810141900.33846-2-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Stable-dep-of: ccfc4db5ab74 ("NFSD: map fh_verify() status codes for NFS_ACLv2 replies")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfs2acl.c | 46 ++++++++++++++++++++++++++-
fs/nfsd/nfs3proc.c | 41 +++++++++++++++++++++++-
fs/nfsd/nfs4proc.c | 42 +++++++++++++++++++++++--
fs/nfsd/vfs.c | 78 ++++++++++------------------------------------
fs/nfsd/vfs.h | 15 ++++++++-
5 files changed, 155 insertions(+), 67 deletions(-)
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index 190f5a0019009..f978aa2be36aa 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -15,6 +15,48 @@
#define NFSDDBG_FACILITY NFSDDBG_PROC
+/*
+ * These maps are identical to the NFSv3 maps (nfs3proc.c). This enables
+ * the behavior of the two versions to diverge if needed.
+ */
+static const struct nfsd_access_map nfsd2_regaccess[] = {
+ { NFS3_ACCESS_READ, NFSD_MAY_READ },
+ { NFS3_ACCESS_EXECUTE, NFSD_MAY_EXEC },
+ { NFS3_ACCESS_MODIFY, NFSD_MAY_WRITE|NFSD_MAY_TRUNC },
+ { NFS3_ACCESS_EXTEND, NFSD_MAY_WRITE },
+ { 0, 0 }
+};
+
+static const struct nfsd_access_map nfsd2_diraccess[] = {
+ { NFS3_ACCESS_READ, NFSD_MAY_READ },
+ { NFS3_ACCESS_LOOKUP, NFSD_MAY_EXEC },
+ { NFS3_ACCESS_MODIFY, NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC },
+ { NFS3_ACCESS_EXTEND, NFSD_MAY_EXEC|NFSD_MAY_WRITE },
+ { NFS3_ACCESS_DELETE, NFSD_MAY_REMOVE },
+ { 0, 0 }
+};
+
+/*
+ * Some clients - Solaris 2.6 at least, make an access call to the NFS
+ * server to check for access for things like /dev/null (which really,
+ * NFSD doesn't care about). So NFSD provides simple access checking
+ * for those objects, looking mainly at mode bits, ignoring read-only
+ * filesystem checks.
+ */
+static const struct nfsd_access_map nfsd2_otheraccess[] = {
+ { NFS3_ACCESS_READ, NFSD_MAY_READ },
+ { NFS3_ACCESS_EXECUTE, NFSD_MAY_EXEC },
+ { NFS3_ACCESS_MODIFY, NFSD_MAY_WRITE|NFSD_MAY_LOCAL_ACCESS },
+ { NFS3_ACCESS_EXTEND, NFSD_MAY_WRITE|NFSD_MAY_LOCAL_ACCESS },
+ { 0, 0 }
+};
+
+static const struct nfsd_access_maps nfsd2_access_maps = {
+ .regular = nfsd2_regaccess,
+ .directory = nfsd2_diraccess,
+ .other = nfsd2_otheraccess,
+};
+
/*
* NULL call.
*/
@@ -180,7 +222,9 @@ static __be32 nfsacld_proc_access(struct svc_rqst *rqstp)
fh_copy(&resp->fh, &argp->fh);
resp->access = argp->access;
- resp->status = nfsd_access(rqstp, &resp->fh, &resp->access, NULL);
+
+ resp->status = nfsd_access(rqstp, &resp->fh, &nfsd2_access_maps,
+ &resp->access, NULL);
if (resp->status != nfs_ok)
goto out;
resp->status = fh_getattr(&resp->fh, &resp->stat);
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 7d8ddb7bfab0c..b3c6341907018 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -48,6 +48,44 @@ static bool nfsd3_time_in_range(const struct iattr *iap)
return true;
}
+static const struct nfsd_access_map nfsd3_regaccess[] = {
+ { NFS3_ACCESS_READ, NFSD_MAY_READ },
+ { NFS3_ACCESS_EXECUTE, NFSD_MAY_EXEC },
+ { NFS3_ACCESS_MODIFY, NFSD_MAY_WRITE|NFSD_MAY_TRUNC },
+ { NFS3_ACCESS_EXTEND, NFSD_MAY_WRITE },
+ { 0, 0 }
+};
+
+static const struct nfsd_access_map nfsd3_diraccess[] = {
+ { NFS3_ACCESS_READ, NFSD_MAY_READ },
+ { NFS3_ACCESS_LOOKUP, NFSD_MAY_EXEC },
+ { NFS3_ACCESS_MODIFY, NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC },
+ { NFS3_ACCESS_EXTEND, NFSD_MAY_EXEC|NFSD_MAY_WRITE },
+ { NFS3_ACCESS_DELETE, NFSD_MAY_REMOVE },
+ { 0, 0 }
+};
+
+/*
+ * Some clients - Solaris 2.6 at least, make an access call to the NFS
+ * server to check for access for things like /dev/null (which really,
+ * NFSD doesn't care about). So NFSD provides simple access checking
+ * for those objects, looking mainly at mode bits, ignoring read-only
+ * filesystem checks.
+ */
+static const struct nfsd_access_map nfsd3_otheraccess[] = {
+ { NFS3_ACCESS_READ, NFSD_MAY_READ },
+ { NFS3_ACCESS_EXECUTE, NFSD_MAY_EXEC },
+ { NFS3_ACCESS_MODIFY, NFSD_MAY_WRITE|NFSD_MAY_LOCAL_ACCESS },
+ { NFS3_ACCESS_EXTEND, NFSD_MAY_WRITE|NFSD_MAY_LOCAL_ACCESS },
+ { 0, 0 }
+};
+
+static const struct nfsd_access_maps nfsd3_access_maps = {
+ .regular = nfsd3_regaccess,
+ .directory = nfsd3_diraccess,
+ .other = nfsd3_otheraccess,
+};
+
static int nfsd3_iocb_flags(enum nfs3_stable_how how)
{
switch (how) {
@@ -185,7 +223,8 @@ nfsd3_proc_access(struct svc_rqst *rqstp)
fh_copy(&resp->fh, &argp->fh);
resp->access = argp->access;
- resp->status = nfsd_access(rqstp, &resp->fh, &resp->access, NULL);
+ resp->status = nfsd_access(rqstp, &resp->fh, &nfsd3_access_maps,
+ &resp->access, NULL);
resp->status = nfsd3_map_status(resp->status);
return rpc_success;
}
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 9ee02a6d00868..f19d8ed80a9dd 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -69,6 +69,43 @@ MODULE_PARM_DESC(nfsd4_ssc_umount_timeout,
#define NFSDDBG_FACILITY NFSDDBG_PROC
+static const struct nfsd_access_map nfsd4_regaccess[] = {
+ { NFS4_ACCESS_READ, NFSD_MAY_READ },
+ { NFS4_ACCESS_EXECUTE, NFSD_MAY_EXEC },
+ { NFS4_ACCESS_MODIFY, NFSD_MAY_WRITE|NFSD_MAY_TRUNC },
+ { NFS4_ACCESS_EXTEND, NFSD_MAY_WRITE },
+ { NFS4_ACCESS_XAREAD, NFSD_MAY_READ },
+ { NFS4_ACCESS_XAWRITE, NFSD_MAY_WRITE },
+ { NFS4_ACCESS_XALIST, NFSD_MAY_READ },
+ { 0, 0 }
+};
+
+static const struct nfsd_access_map nfsd4_diraccess[] = {
+ { NFS4_ACCESS_READ, NFSD_MAY_READ },
+ { NFS4_ACCESS_LOOKUP, NFSD_MAY_EXEC },
+ { NFS4_ACCESS_MODIFY, NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC },
+ { NFS4_ACCESS_EXTEND, NFSD_MAY_EXEC|NFSD_MAY_WRITE },
+ { NFS4_ACCESS_DELETE, NFSD_MAY_REMOVE },
+ { NFS4_ACCESS_XAREAD, NFSD_MAY_READ },
+ { NFS4_ACCESS_XAWRITE, NFSD_MAY_WRITE },
+ { NFS4_ACCESS_XALIST, NFSD_MAY_READ },
+ { 0, 0 }
+};
+
+static const struct nfsd_access_map nfsd4_otheraccess[] = {
+ { NFS4_ACCESS_READ, NFSD_MAY_READ },
+ { NFS4_ACCESS_EXECUTE, NFSD_MAY_EXEC },
+ { NFS4_ACCESS_MODIFY, NFSD_MAY_WRITE|NFSD_MAY_LOCAL_ACCESS },
+ { NFS4_ACCESS_EXTEND, NFSD_MAY_WRITE|NFSD_MAY_LOCAL_ACCESS },
+ { 0, 0 }
+};
+
+static const struct nfsd_access_maps nfsd4_access_maps = {
+ .regular = nfsd4_regaccess,
+ .directory = nfsd4_diraccess,
+ .other = nfsd4_otheraccess,
+};
+
static int nfsd4_iocb_flags(enum stable_how4 how)
{
switch (how) {
@@ -809,10 +846,9 @@ nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (access->ac_req_access & ~access_full)
return nfserr_inval;
-
access->ac_resp_access = access->ac_req_access;
- return nfsd_access(rqstp, &cstate->current_fh, &access->ac_resp_access,
- &access->ac_supported);
+ return nfsd_access(rqstp, &cstate->current_fh, &nfsd4_access_maps,
+ &access->ac_resp_access, &access->ac_supported);
}
static __be32
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index fe27f6b404268..792c0b327755f 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -773,64 +773,21 @@ __be32 nfsd4_vfs_fallocate(struct svc_rqst *rqstp, struct svc_fh *fhp,
}
#endif /* defined(CONFIG_NFSD_V4) */
-/*
- * Check server access rights to a file system object
+/**
+ * nfsd_access - Check caller's access rights to a file system object
+ * @rqstp: RPC transaction context
+ * @fhp: target NFS filehandle
+ * @maps: tables mapping on-the-wire access bits to NFSD_MAY flags
+ * @access: requested access bits on entry, permitted bits on return
+ * @supported: optional output of the access bits the server supports
+ *
+ * Return: nfs_ok on success, otherwise an nfserr status code
*/
-struct accessmap {
- u32 access;
- int how;
-};
-static struct accessmap nfs3_regaccess[] = {
- { NFS3_ACCESS_READ, NFSD_MAY_READ },
- { NFS3_ACCESS_EXECUTE, NFSD_MAY_EXEC },
- { NFS3_ACCESS_MODIFY, NFSD_MAY_WRITE|NFSD_MAY_TRUNC },
- { NFS3_ACCESS_EXTEND, NFSD_MAY_WRITE },
-
-#ifdef CONFIG_NFSD_V4
- { NFS4_ACCESS_XAREAD, NFSD_MAY_READ },
- { NFS4_ACCESS_XAWRITE, NFSD_MAY_WRITE },
- { NFS4_ACCESS_XALIST, NFSD_MAY_READ },
-#endif
-
- { 0, 0 }
-};
-
-static struct accessmap nfs3_diraccess[] = {
- { NFS3_ACCESS_READ, NFSD_MAY_READ },
- { NFS3_ACCESS_LOOKUP, NFSD_MAY_EXEC },
- { NFS3_ACCESS_MODIFY, NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC},
- { NFS3_ACCESS_EXTEND, NFSD_MAY_EXEC|NFSD_MAY_WRITE },
- { NFS3_ACCESS_DELETE, NFSD_MAY_REMOVE },
-
-#ifdef CONFIG_NFSD_V4
- { NFS4_ACCESS_XAREAD, NFSD_MAY_READ },
- { NFS4_ACCESS_XAWRITE, NFSD_MAY_WRITE },
- { NFS4_ACCESS_XALIST, NFSD_MAY_READ },
-#endif
-
- { 0, 0 }
-};
-
-static struct accessmap nfs3_anyaccess[] = {
- /* Some clients - Solaris 2.6 at least, make an access call
- * to the server to check for access for things like /dev/null
- * (which really, the server doesn't care about). So
- * We provide simple access checking for them, looking
- * mainly at mode bits, and we make sure to ignore read-only
- * filesystem checks
- */
- { NFS3_ACCESS_READ, NFSD_MAY_READ },
- { NFS3_ACCESS_EXECUTE, NFSD_MAY_EXEC },
- { NFS3_ACCESS_MODIFY, NFSD_MAY_WRITE|NFSD_MAY_LOCAL_ACCESS },
- { NFS3_ACCESS_EXTEND, NFSD_MAY_WRITE|NFSD_MAY_LOCAL_ACCESS },
-
- { 0, 0 }
-};
-
-__be32
-nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *supported)
+__be32 nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp,
+ const struct nfsd_access_maps *maps,
+ u32 *access, u32 *supported)
{
- struct accessmap *map;
+ const struct nfsd_access_map *map;
struct svc_export *export;
struct dentry *dentry;
u32 query, result = 0, sresult = 0;
@@ -844,12 +801,11 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor
dentry = fhp->fh_dentry;
if (d_is_reg(dentry))
- map = nfs3_regaccess;
+ map = maps->regular;
else if (d_is_dir(dentry))
- map = nfs3_diraccess;
+ map = maps->directory;
else
- map = nfs3_anyaccess;
-
+ map = maps->other;
query = *access;
for (; map->access; map++) {
@@ -859,7 +815,7 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor
sresult |= map->access;
err2 = nfsd_permission(&rqstp->rq_cred, export,
- dentry, map->how);
+ dentry, map->may);
switch (err2) {
case nfs_ok:
result |= map->access;
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index 5937bd78d4291..bdb58422a3fbd 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -37,6 +37,17 @@
#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE)
#define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC)
+struct nfsd_access_map {
+ u32 access;
+ int may;
+};
+
+struct nfsd_access_maps {
+ const struct nfsd_access_map *regular;
+ const struct nfsd_access_map *directory;
+ const struct nfsd_access_map *other;
+};
+
struct nfsd_file;
/*
@@ -100,7 +111,9 @@ __be32 nfsd_create_locked(struct svc_rqst *, struct svc_fh *,
__be32 nfsd_create(struct svc_rqst *, struct svc_fh *,
char *name, int len, struct nfsd_attrs *attrs,
int type, dev_t rdev, struct svc_fh *res);
-__be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *);
+__be32 nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp,
+ const struct nfsd_access_maps *maps,
+ u32 *access, u32 *supported);
__be32 nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp,
struct svc_fh *resfhp, struct nfsd_attrs *iap);
__be32 nfsd_commit(struct svc_rqst *rqst, struct svc_fh *fhp,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 012/507] NFSD: map fh_verify() status codes for NFS_ACLv2 replies
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (10 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 011/507] NFSD: Move version-specific ACCESS maps into per-version code Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 013/507] NFSD: report listener creation failures through extack Greg Kroah-Hartman
` (494 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <cel@kernel.org>
[ Upstream commit ccfc4db5ab740175b9958ea0cf5986957bf4e659 ]
The NFS_ACL v2 protocol shares its status code space with NFSv2,
which has no NFSERR_BADHANDLE and no NFSERR_NOFILEHANDLE. An
NFS_ACLv2 GETACL, SETACL, GETATTR, or ACCESS request that carries a
malformed or empty file handle gets a reply with status 10001 or
10020, values the client cannot interpret.
Commit 1459ad57673b ("nfsd: Move error code mapping to per-version
proc code.") removed the version check from fh_verify() that turned
those codes into NFSERR_STALE for any version 2 program. The NFSv2
procedures gained nfsd_map_status() in exchange, but the NFS_ACL v2
procedures did not, so the unmapped status reaches the encoder.
Add the same mapping to the NFS_ACL v2 procedures.
Fixes: 1459ad57673b ("nfsd: Move error code mapping to per-version proc code.")
Cc: stable@vger.kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260916004240.141975-1-cel@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfs2acl.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index f978aa2be36aa..113ec827ae061 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -57,6 +57,20 @@ static const struct nfsd_access_maps nfsd2_access_maps = {
.other = nfsd2_otheraccess,
};
+static __be32 nfsacld_map_status(__be32 status)
+{
+ switch (status) {
+ case nfserr_nofilehandle:
+ case nfserr_badhandle:
+ status = nfserr_stale;
+ break;
+ case nfserr_wrongsec:
+ status = nfserr_acces;
+ break;
+ }
+ return status;
+}
+
/*
* NULL call.
*/
@@ -121,6 +135,7 @@ static __be32 nfsacld_proc_getacl(struct svc_rqst *rqstp)
/* resp->acl_{access,default} are released in nfssvc_release_getacl. */
out:
+ resp->status = nfsacld_map_status(resp->status);
return rpc_success;
fail:
@@ -179,6 +194,7 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst *rqstp)
out:
/* argp->acl_{access,default} are released in nfsaclsvc_release_setacl. */
+ resp->status = nfsacld_map_status(resp->status);
return rpc_success;
out_drop_lock:
@@ -205,6 +221,7 @@ static __be32 nfsacld_proc_getattr(struct svc_rqst *rqstp)
goto out;
resp->status = fh_getattr(&resp->fh, &resp->stat);
out:
+ resp->status = nfsacld_map_status(resp->status);
return rpc_success;
}
@@ -229,6 +246,7 @@ static __be32 nfsacld_proc_access(struct svc_rqst *rqstp)
goto out;
resp->status = fh_getattr(&resp->fh, &resp->stat);
out:
+ resp->status = nfsacld_map_status(resp->status);
return rpc_success;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 013/507] NFSD: report listener creation failures through extack
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (11 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 012/507] NFSD: map fh_verify() status codes for NFS_ACLv2 replies Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 014/507] SUNRPC: report local rpcbind calls that get no answer Greg Kroah-Hartman
` (493 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <jlayton@kernel.org>
[ Upstream commit 8e590a16853fedd2697a3b0c32b3cbf1a444f7b2 ]
nfsd_nl_listener_set_doit() returns the raw errno from
svc_xprt_create_from_sa() and sets no extack. A failed LISTENER_SET
therefore tells userland only "Address already in use", or whatever else
the transport returned. It never tells userland which entry failed.
Record the attribute and the transport name of the entry whose errno the
call returns, and report both after the loop. NL_SET_BAD_ATTR() names the
entry, which the message alone cannot do: a request can carry several
entries with the same transport name.
The rejections in nfsd_nl_validate_listeners() other than -E2BIG and the
unsupported transport name still carry no extack. This patch does not
change them.
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260901-nfsd-nl-hang-v5-5-a540d86668b0@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Stable-dep-of: bf0f3a37e6cc ("NFSD: stop registering with rpcbind after a failure in listener_set")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfsctl.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 86aa8d202b4b1..714c73ddd9dc1 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -2086,7 +2086,9 @@ static int nfsd_nl_validate_listeners(struct genl_info *info)
int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
{
struct net *net = genl_info_net(info);
+ const struct nlattr *bad_attr = NULL;
struct svc_xprt *xprt, *tmp;
+ const char *bad_xprt = NULL;
const struct nlattr *attr;
struct svc_serv *serv;
LIST_HEAD(permsocks);
@@ -2205,8 +2207,22 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
ret = svc_xprt_create_from_sa(serv, xcl_name, net, sa, 0,
current_cred());
/* always save the latest error */
- if (ret < 0)
+ if (ret < 0) {
+ bad_attr = attr;
+ bad_xprt = xcl_name;
err = ret;
+ }
+ }
+
+ /*
+ * The ack carries the errno of the last entry that failed. Point at
+ * that entry as well, since several entries can share a transport
+ * name and the errno alone cannot tell them apart.
+ */
+ if (err) {
+ NL_SET_BAD_ATTR(info->extack, bad_attr);
+ NL_SET_ERR_MSG_FMT(info->extack, "cannot create %s listener",
+ bad_xprt);
}
if (!serv->sv_nrthreads && list_empty(&nn->nfsd_serv->sv_permsocks))
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 014/507] SUNRPC: report local rpcbind calls that get no answer
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (12 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 013/507] NFSD: report listener creation failures through extack Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 015/507] NFSD: stop registering with rpcbind after a failure in listener_set Greg Kroah-Hartman
` (492 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <jlayton@kernel.org>
[ Upstream commit 202a557d0c8e65c7fd7fcff2ad2756468d1ab711 ]
A caller that creates many listeners in one operation calls svc_register()
once for each of them. Every call waits for the local rpcbind on its own,
so a rpcbind that never answers costs the caller one timeout per listener.
The caller has no way to learn that the first call already failed.
Split rpcb_register_call() failures by whether rpcbind answered:
- answered: a FALSE reply, or an RPC-level rejection that
rpc_decode_header() derives from the reply. -EACCES (FALSE reply or
AUTH_ERROR), -EPROTONOSUPPORT, -EPFNOSUPPORT, -EOPNOTSUPP.
- never sent: -ENOMEM, -EMSGSIZE, -ERESTARTSYS.
- no answer: everything else, i.e. transport errors.
Any no-answer error gets represented by -EIO, which is already what the
RPC layer reports for most of it: rpc_check_timeout() returns -EIO for a
soft timeout without RPC_TASK_TIMEOUT, and call_status() documents -EIO
as "shutdown or soft timeout".
Keep a count of the number of rpcbind failures in the serv. Later
patches will use that to watch for hard rpcbind failures, and alter
their behavior accordingly.
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260901-nfsd-nl-hang-v5-6-a540d86668b0@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Stable-dep-of: bf0f3a37e6cc ("NFSD: stop registering with rpcbind after a failure in listener_set")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/sunrpc/clnt.h | 3 ++-
include/linux/sunrpc/svc.h | 7 +++++--
net/sunrpc/rpcb_clnt.c | 22 ++++++++++++++++---
net/sunrpc/svc.c | 42 ++++++++++++++++++++++++++++++++++++-
4 files changed, 67 insertions(+), 7 deletions(-)
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 3c2b8c355ab3a..30344c0d6a9d7 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -199,7 +199,8 @@ struct rpc_xprt *rpc_task_get_xprt(struct rpc_clnt *clnt,
int rpcb_create_local(struct net *);
void rpcb_put_local(struct net *);
-int rpcb_register(struct net *, u32, u32, int, unsigned short);
+int rpcb_register(struct net *net, u32 prog, u32 vers, int prot,
+ unsigned short port);
int rpcb_v4_register(struct net *net, const u32 program,
const u32 version,
const struct sockaddr *address,
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 2db1b9ec5658d..5fa9417e034d7 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -78,6 +78,7 @@ struct svc_serv {
unsigned int sv_max_payload; /* datagram payload size */
unsigned int sv_max_mesg; /* max_payload + 1 page for overheads */
unsigned int sv_xdrsize; /* XDR buffer size */
+ atomic_t sv_rpcb_failures; /* unanswered rpcbind calls */
struct list_head sv_permsocks; /* all permanent sockets */
struct list_head sv_tempsocks; /* all temporary sockets */
int sv_tmpcnt; /* count of temporary "valid" sockets */
@@ -451,6 +452,7 @@ int sunrpc_set_pool_mode(const char *val);
int sunrpc_get_pool_mode(char *val, size_t size);
void svc_rpcb_cleanup(struct svc_serv *serv, struct net *net);
int svc_bind(struct svc_serv *serv, struct net *net);
+unsigned int svc_rpcb_failure_count(struct svc_serv *serv);
struct svc_serv *svc_create(struct svc_program *, unsigned int,
int (*threadfn)(void *data));
bool svc_rqst_replace_page(struct svc_rqst *rqstp,
@@ -471,8 +473,9 @@ unsigned int svc_serv_maxthreads(const struct svc_serv *serv);
int svc_pool_stats_open(struct svc_info *si, struct file *file);
void svc_process(struct svc_rqst *rqstp);
void svc_process_bc(struct rpc_rqst *req, struct svc_rqst *rqstp);
-int svc_register(const struct svc_serv *, struct net *, const int,
- const unsigned short, const unsigned short);
+int svc_register(struct svc_serv *serv, struct net *net,
+ const int family, const unsigned short proto,
+ const unsigned short port);
void svc_wake_up(struct svc_serv *);
void svc_reserve(struct svc_rqst *rqstp, int space);
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 4c0b7fefee4e2..84c06f99e1c72 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -400,7 +400,8 @@ static struct rpc_clnt *rpcb_create(struct net *net, const char *nodename,
return rpc_create(&args);
}
-static int rpcb_register_call(struct sunrpc_net *sn, struct rpc_clnt *clnt, struct rpc_message *msg, bool is_set)
+static int rpcb_register_call(struct sunrpc_net *sn, struct rpc_clnt *clnt,
+ struct rpc_message *msg, bool is_set)
{
int flags = RPC_TASK_NOCONNECT;
int error, result = 0;
@@ -410,8 +411,23 @@ static int rpcb_register_call(struct sunrpc_net *sn, struct rpc_clnt *clnt, stru
msg->rpc_resp = &result;
error = rpc_call_sync(clnt, msg, flags);
- if (error < 0)
- return error;
+ if (error < 0) {
+ switch (error) {
+ /* rpcbind answered; the reply itself carries the error */
+ case -EPROTONOSUPPORT:
+ case -EPFNOSUPPORT:
+ case -EOPNOTSUPP:
+ case -EACCES:
+ /* the call never made it onto the wire */
+ case -ENOMEM:
+ case -EMSGSIZE:
+ /* the caller is going away; this says nothing about rpcbind */
+ case -ERESTARTSYS:
+ return error;
+ }
+ /* anything else, we assume that rpcbind isn't functional */
+ return -EIO;
+ }
if (!result)
return -EACCES;
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 4f402bbf97baa..ca6f90653327c 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1179,10 +1179,40 @@ int svc_generic_rpcbind_set(struct net *net,
error = svc_rpcbind_set_version(net, progp, version,
family, proto, port);
+ /* -EIO means no answer, not a refusal, so vs_rpcb_optnl must keep it. */
+ if (error == -EIO)
+ return error;
+
return (vers->vs_rpcb_optnl) ? 0 : error;
}
EXPORT_SYMBOL_GPL(svc_generic_rpcbind_set);
+/**
+ * svc_rpcb_failure_count - local rpcbind calls for @serv that got no answer
+ * @serv: RPC service to query
+ *
+ * svc_register() adds one for each of its calls that got no answer. A reply
+ * that refuses one entry does not count, because rpcbind answered and the
+ * next entry may still succeed.
+ *
+ * The count is kept per serv rather than per net. The local rpcbind client
+ * is per-net and lockd shares it, but a count that another service can move
+ * says nothing about this serv's own calls.
+ *
+ * This is for callers that cannot see the svc_register() return, because a
+ * transport class sits in between. Such a caller reads the count before it
+ * starts and compares as it goes, so there is no state to reset between
+ * operations. The count never resets, and callers must not attach meaning
+ * to the value itself.
+ *
+ * Return: the number of unanswered calls since this serv was created.
+ */
+unsigned int svc_rpcb_failure_count(struct svc_serv *serv)
+{
+ return atomic_read(&serv->sv_rpcb_failures);
+}
+EXPORT_SYMBOL_GPL(svc_rpcb_failure_count);
+
/**
* svc_register - register an RPC service with the local portmapper
* @serv: svc_serv struct for the service to register
@@ -1193,10 +1223,11 @@ EXPORT_SYMBOL_GPL(svc_generic_rpcbind_set);
*
* Service is registered for any address in the passed-in protocol family
*/
-int svc_register(const struct svc_serv *serv, struct net *net,
+int svc_register(struct svc_serv *serv, struct net *net,
const int family, const unsigned short proto,
const unsigned short port)
{
+ bool noanswer = false;
unsigned int p, i;
int error = 0;
@@ -1208,10 +1239,16 @@ int svc_register(const struct svc_serv *serv, struct net *net,
struct svc_program *progp = &serv->sv_programs[p];
for (i = 0; i < progp->pg_nvers; i++) {
+ const struct svc_version *vers = progp->pg_vers[i];
int ret;
ret = progp->pg_rpcbind_set(net, progp, i,
family, proto, port);
+ if (ret == -EIO) {
+ noanswer = true;
+ if (vers && vers->vs_rpcb_optnl)
+ ret = 0;
+ }
if (ret < 0) {
printk(KERN_WARNING "svc: failed to register "
"%sv%u RPC service (errno %d).\n",
@@ -1223,6 +1260,9 @@ int svc_register(const struct svc_serv *serv, struct net *net,
}
}
+ if (noanswer)
+ atomic_inc(&serv->sv_rpcb_failures);
+
return error;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 015/507] NFSD: stop registering with rpcbind after a failure in listener_set
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (13 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 014/507] SUNRPC: report local rpcbind calls that get no answer Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 016/507] NFSD: Send a meaningful CB_RECALL_ANY keep count Greg Kroah-Hartman
` (491 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Olga Kornievskaia, Jeff Layton,
Chuck Lever, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <jlayton@kernel.org>
[ Upstream commit bf0f3a37e6ccb78ae80cc6eb2edde4f033c7574c ]
nfsd_nl_listener_set_doit() calls svc_xprt_create_from_sa() once for each
requested listener and passes flags of 0, so every listener registers with
rpcbind on its own. A rpcbind that accepts the connection and never replies
therefore costs one timeout for each entry. With the cap of 1024 entries
the request can hold nfsd_mutex for about 34 minutes, which is roughly 17
times the hung-task threshold.
One failure is enough to know that the next call will not fare better.
Read svc_rpcb_failure_count() before the create loop, and pass
SVC_SOCK_ANONYMOUS for the rest of the request once the count moves.
Fixes: 16a471177496 ("NFSD: add listener-{set,get} netlink command")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Link: https://syzkaller.appspot.com/bug?extid=c7eae0eb80858a2dba0f
Suggested-by: Olga Kornievskaia <okorniev@redhat.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260901-nfsd-nl-hang-v5-10-a540d86668b0@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfsctl.c | 42 ++++++++++++++++++++++++++++++++++++++----
1 file changed, 38 insertions(+), 4 deletions(-)
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 714c73ddd9dc1..d5effeae4b792 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -2089,7 +2089,10 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
const struct nlattr *bad_attr = NULL;
struct svc_xprt *xprt, *tmp;
const char *bad_xprt = NULL;
+ unsigned int rpcb_failures;
const struct nlattr *attr;
+ bool skipped_rpcb = false;
+ bool bad_rpcb = false;
struct svc_serv *serv;
LIST_HEAD(permsocks);
struct nfsd_net *nn;
@@ -2179,13 +2182,16 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
if (delete)
svc_xprt_destroy_all(serv, net, false);
+ rpcb_failures = svc_rpcb_failure_count(serv);
+
/* walk list of addrs again, open any that still don't exist */
nlmsg_for_each_attr_type(attr, NFSD_A_SERVER_SOCK_ADDR, info->nlhdr,
GENL_HDRLEN, rem) {
struct nlattr *tb[NFSD_A_SOCK_MAX + 1];
const char *xcl_name;
struct sockaddr *sa;
- int ret;
+ bool hit_rpcb;
+ int flags, ret;
/* validated up front in nfsd_nl_validate_listeners() */
if (nla_parse_nested(tb, NFSD_A_SOCK_MAX, attr,
@@ -2204,12 +2210,27 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
continue;
}
- ret = svc_xprt_create_from_sa(serv, xcl_name, net, sa, 0,
+ flags = skipped_rpcb ? SVC_SOCK_ANONYMOUS : 0;
+ ret = svc_xprt_create_from_sa(serv, xcl_name, net, sa, flags,
current_cred());
+
+ hit_rpcb = false;
+ if (!skipped_rpcb &&
+ svc_rpcb_failure_count(serv) != rpcb_failures) {
+ skipped_rpcb = true;
+ hit_rpcb = true;
+ if (ret < 0)
+ ret = svc_xprt_create_from_sa(serv, xcl_name,
+ net, sa,
+ SVC_SOCK_ANONYMOUS,
+ current_cred());
+ }
+
/* always save the latest error */
if (ret < 0) {
bad_attr = attr;
bad_xprt = xcl_name;
+ bad_rpcb = hit_rpcb;
err = ret;
}
}
@@ -2221,8 +2242,21 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
*/
if (err) {
NL_SET_BAD_ATTR(info->extack, bad_attr);
- NL_SET_ERR_MSG_FMT(info->extack, "cannot create %s listener",
- bad_xprt);
+ if (bad_rpcb)
+ NL_SET_ERR_MSG_FMT(info->extack,
+ "cannot create %s listener; rpcbind did not answer",
+ bad_xprt);
+ else if (skipped_rpcb)
+ NL_SET_ERR_MSG_FMT(info->extack,
+ "cannot create %s listener; rpcbind did not answer earlier, so some listeners are not registered",
+ bad_xprt);
+ else
+ NL_SET_ERR_MSG_FMT(info->extack,
+ "cannot create %s listener",
+ bad_xprt);
+ } else if (skipped_rpcb) {
+ NL_SET_ERR_MSG(info->extack,
+ "rpcbind did not answer, some listeners are not registered");
}
if (!serv->sv_nrthreads && list_empty(&nn->nfsd_serv->sv_permsocks))
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 016/507] NFSD: Send a meaningful CB_RECALL_ANY keep count
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (14 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 015/507] NFSD: stop registering with rpcbind after a failure in listener_set Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 017/507] NFSD: Move the cld upcall message out of the callers stack frame Greg Kroah-Hartman
` (490 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <cel@kernel.org>
[ Upstream commit 9af39c0773ef956039e1ebe9c235532fe6ee1e50 ]
deleg_reaper() sets craa_objects_to_keep to zero on every
CB_RECALL_ANY. RFC 8881 Section 20.6.3 defines that field as the
number of objects the client may keep, leaving the client to choose
which of the excess to return, because the server cannot read lack
of recent use as lack of usefulness. Zero asks for every delegation
the client holds, including the ones backing files an application
still has open.
There is also no reason NFSD has to reclaim the entire delegation
working set on the first sign of memory pressure.
Derive the keep count from cl_deleg_count so that each callback
asks for one delegation. Both the shrinker and the laundromat re-arm
while their condition lasts, so a client with more to give is asked
again on the next pass.
The Linux client ignores craa_objects_to_keep and returns unused
delegations selected from the type mask alone, so the count changes
nothing for it.
Fixes: 44df6f439a17 ("NFSD: add delegation reaper to react to low memory condition")
Cc: stable@vger.kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260817-recall-any-keep-count-v5-4-3b2cffce701e@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
[ sashal: Added missing prerequisites for per-client delegation counting and the directory-delegation callback mask. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfs4state.c | 24 ++++++++++++++++++++----
fs/nfsd/state.h | 2 ++
2 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 3bdde4c1bb8eb..f0a7959401370 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1517,6 +1517,7 @@ hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp)
dp->dl_stid.sc_type = SC_TYPE_DELEG;
list_add(&dp->dl_perfile, &fp->fi_delegations);
list_add(&dp->dl_perclnt, &clp->cl_delegations);
+ clp->cl_deleg_count++;
return 0;
}
@@ -1548,6 +1549,7 @@ unhash_delegation_locked(struct nfs4_delegation *dp, unsigned short statusmask)
++dp->dl_time;
spin_lock(&fp->fi_lock);
list_del_init(&dp->dl_perclnt);
+ dp->dl_stid.sc_client->cl_deleg_count--;
list_del_init(&dp->dl_recall_lru);
list_del_init(&dp->dl_perfile);
spin_unlock(&fp->fi_lock);
@@ -7938,6 +7940,7 @@ deleg_reaper(struct nfsd_net *nn)
{
struct list_head *pos, *next;
struct nfs4_client *clp;
+ unsigned int count;
spin_lock(&nn->client_lock);
list_for_each_safe(pos, next, &nn->client_lru) {
@@ -7947,23 +7950,36 @@ deleg_reaper(struct nfsd_net *nn)
continue;
if (clp->cl_state != NFSD4_ACTIVE)
continue;
- if (list_empty(&clp->cl_delegations))
- continue;
if (atomic_read(&clp->cl_delegs_in_recall))
continue;
if (ktime_get_boottime_seconds() - clp->cl_ra_time < 5)
continue;
if (clp->cl_cb_state != NFSD4_CB_UP)
continue;
+ /*
+ * This read races with hash_delegation_locked() and
+ * unhash_delegation_locked() on other CPUs. A stale
+ * count only skews the keep value; the next
+ * laundromat pass sees a more current one.
+ */
+ count = data_race(READ_ONCE(clp->cl_deleg_count));
+ if (!count)
+ continue;
if (test_and_set_bit(NFSD4_CALLBACK_RUNNING, &clp->cl_ra->ra_cb.cb_flags))
continue;
/* release in nfsd4_cb_recall_any_release */
kref_get(&clp->cl_nfsdfs.cl_ref);
clp->cl_ra_time = ktime_get_boottime_seconds();
- clp->cl_ra->ra_keep = 0;
+ /*
+ * Ask for a single delegation. Recalling one before it
+ * is needed costs the client an OPEN when it next
+ * touches the file.
+ */
+ clp->cl_ra->ra_keep = count - 1;
clp->cl_ra->ra_bmval[0] = BIT(RCA4_TYPE_MASK_RDATA_DLG) |
- BIT(RCA4_TYPE_MASK_WDATA_DLG);
+ BIT(RCA4_TYPE_MASK_WDATA_DLG) |
+ BIT(RCA4_TYPE_MASK_DIR_DLG);
trace_nfsd_cb_recall_any(clp->cl_ra);
nfsd4_run_cb(&clp->cl_ra->ra_cb);
}
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 9661c08b879e8..df35c35890d48 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -610,6 +610,8 @@ struct nfs4_client {
unsigned int cl_state;
atomic_t cl_delegs_in_recall;
+ /* Length of cl_delegations, updated under nn->deleg_lock */
+ unsigned int cl_deleg_count;
struct nfsd4_cb_recall_any *cl_ra;
time64_t cl_ra_time;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 017/507] NFSD: Move the cld upcall message out of the callers stack frame
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (15 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 016/507] NFSD: Send a meaningful CB_RECALL_ANY keep count Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 018/507] NFSD: Complete a cld upcall when the daemon closes the pipe Greg Kroah-Hartman
` (489 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+d5c77cabf7a3492aa650,
Chuck Lever, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <cel@kernel.org>
[ Upstream commit c559b05610557fa3c6c30259261f6dae523b3f23 ]
__cld_pipe_upcall() builds its struct rpc_pipe_msg on the stack and
hands it to rpc_queue_upcall(), which links it into a list the pipe
owns until the message is released. Only the completion rules keep that
frame alive for as long as the pipe refers to it, and the peer that
drives those rules is an untrusted userspace daemon. The gss and idmap
upcalls do not take that on: each keeps the message in the object it
already allocates.
Do the same here and put the message in struct cld_upcall, beside the
reply buffer it carries. cld_pipe_destroy_msg() then reaches the upcall
from the message directly rather than through msg->data.
Reported-by: syzbot+d5c77cabf7a3492aa650@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=d5c77cabf7a3492aa650
Link: https://patch.msgid.link/20260901-alemi-v2-2-e163f94a3a6e@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Stable-dep-of: 2a83fcb50f3c ("NFSD: Complete a cld upcall when the daemon closes the pipe")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfs4recover.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 6441e54283a35..6b0c51b8938b5 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -649,6 +649,7 @@ struct cld_upcall {
struct completion cu_done;
/* daemon has read the whole upcall; protected by cn_lock */
bool cu_inflight;
+ struct rpc_pipe_msg cu_pipe_msg;
union {
struct cld_msg_hdr cu_hdr;
struct cld_msg cu_msg;
@@ -660,22 +661,22 @@ static int
__cld_pipe_upcall(struct rpc_pipe *pipe, void *cmsg, struct nfsd_net *nn)
{
int ret;
- struct rpc_pipe_msg msg;
struct cld_upcall *cup = container_of(cmsg, struct cld_upcall, cu_u);
+ struct rpc_pipe_msg *msg = &cup->cu_pipe_msg;
- memset(&msg, 0, sizeof(msg));
- msg.data = cmsg;
- msg.len = nn->client_tracking_ops->msglen;
+ memset(msg, 0, sizeof(*msg));
+ msg->data = cmsg;
+ msg->len = nn->client_tracking_ops->msglen;
- ret = rpc_queue_upcall(pipe, &msg);
+ ret = rpc_queue_upcall(pipe, msg);
if (ret < 0) {
goto out;
}
wait_for_completion(&cup->cu_done);
- if (msg.errno < 0)
- ret = msg.errno;
+ if (msg->errno < 0)
+ ret = msg->errno;
out:
return ret;
}
@@ -848,9 +849,8 @@ cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
static void
cld_pipe_destroy_msg(struct rpc_pipe_msg *msg)
{
- struct cld_msg *cmsg = msg->data;
- struct cld_upcall *cup = container_of(cmsg, struct cld_upcall,
- cu_u.cu_msg);
+ struct cld_upcall *cup = container_of(msg, struct cld_upcall,
+ cu_pipe_msg);
struct cld_net *cn = cup->cu_net;
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 018/507] NFSD: Complete a cld upcall when the daemon closes the pipe
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (16 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 017/507] NFSD: Move the cld upcall message out of the callers stack frame Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 019/507] NFSD: Complete a cld upcall when copying its reply fails Greg Kroah-Hartman
` (488 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+edbebd898142ee5e24ce,
Chuck Lever, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <cel@kernel.org>
[ Upstream commit 2a83fcb50f3c25c493cc4389619340fefe9d6ac4 ]
Once nfsdcld has read a whole upcall, rpc_pipe_read() unlinks the
message from every pipe list, so the purges in rpc_pipe_release()
and rpc_close_pipes() no longer reach it. cld_upcall_ops supplies no
.release_pipe callback, and cld_pipe_destroy_msg() returns without
completing the upcall because a downcall is expected to follow. A
daemon that exits between the read and the write therefore strands
its waiter: the nfsd thread sleeps in TASK_UNINTERRUPTIBLE in
__cld_pipe_upcall() and never returns, hung task warnings follow,
and the server cannot be shut down.
Add a .release_pipe that completes every upcall the daemon has
consumed. cu_inflight distinguishes those from upcalls still queued
on the pipe, which the framework purges before it calls this
callback; cld_pipe_downcall() removes an upcall it accepts from
cn_list under the same lock. Neither can be completed twice.
Fail the stranded upcall with -EPIPE rather than the -EAGAIN that
makes cld_pipe_upcall() retry. The daemon consumed the request, so
whether it acted on it before exiting is unknown.
Fixes: f3f8014862d8 ("nfsd: add the infrastructure to handle the cld upcall")
Reported-by: syzbot+edbebd898142ee5e24ce@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/linux-nfs/6a99f6f0.2e567484.299ffc.000c.GAE@google.com/
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260901-alemi-v2-7-e163f94a3a6e@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfs4recover.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 6b0c51b8938b5..0b033688aa0b5 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -867,10 +867,34 @@ cld_pipe_destroy_msg(struct rpc_pipe_msg *msg)
complete(&cup->cu_done);
}
+/*
+ * An upcall the daemon has consumed is off every pipe list, so the
+ * purge in rpc_pipe_release() and rpc_close_pipes() cannot reach it.
+ * Release its waiter here instead; no downcall can arrive now.
+ */
+static void
+cld_release_pipe(struct inode *inode)
+{
+ struct nfsd_net *nn = net_generic(inode->i_sb->s_fs_info, nfsd_net_id);
+ struct cld_net *cn = nn->cld_net;
+ struct cld_upcall *cup;
+
+ spin_lock(&cn->cn_lock);
+ list_for_each_entry(cup, &cn->cn_list, cu_list) {
+ if (!cup->cu_inflight)
+ continue;
+ cup->cu_inflight = false;
+ cup->cu_pipe_msg.errno = -EPIPE;
+ complete(&cup->cu_done);
+ }
+ spin_unlock(&cn->cn_lock);
+}
+
static const struct rpc_pipe_ops cld_upcall_ops = {
.upcall = rpc_pipe_generic_upcall,
.downcall = cld_pipe_downcall,
.destroy_msg = cld_pipe_destroy_msg,
+ .release_pipe = cld_release_pipe,
};
static int
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 019/507] NFSD: Complete a cld upcall when copying its reply fails
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (17 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 018/507] NFSD: Complete a cld upcall when the daemon closes the pipe Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 020/507] ksmbd: look up stream size by exact xattr name Greg Kroah-Hartman
` (487 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chuck Lever, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <cel@kernel.org>
[ Upstream commit 8cef2b0a01d28647facc57501a3df7ccd8d13ccd ]
cld_pipe_downcall() removes the matching upcall from cn_list before
copying the daemon's reply. When that copy_from_user() faults, the
downcall returns -EFAULT without completing the upcall, and a
retried write cannot reach it because its xid is no longer on the
list. __cld_pipe_upcall() waits on cu_done uninterruptibly, so the
nfsd thread that sent the upcall is stuck, and nfsd shutdown hangs
behind it. The pipe is mode 0600, so only a broken or hostile
nfsdcld can trigger the fault.
Record the fault in the upcall's pipe message and complete it, so
the waiter returns the error to its client tracking operation.
Fixes: f3f8014862d8 ("nfsd: add the infrastructure to handle the cld upcall")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260901-alemi-v2-3-e163f94a3a6e@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfs4recover.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 0b033688aa0b5..907a914b04cd1 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -839,8 +839,11 @@ cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
if (status == -EINPROGRESS)
return __cld_pipe_inprogress_downcall(cmsg, nn);
- if (copy_from_user(&cup->cu_u.cu_msg_v2, src, mlen) != 0)
+ if (copy_from_user(&cup->cu_u.cu_msg_v2, src, mlen) != 0) {
+ cup->cu_pipe_msg.errno = -EFAULT;
+ complete(&cup->cu_done);
return -EFAULT;
+ }
complete(&cup->cu_done);
return mlen;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 020/507] ksmbd: look up stream size by exact xattr name
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (18 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 019/507] NFSD: Complete a cld upcall when copying its reply fails Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 021/507] wifi: brcmfmac: cfg80211: Report port_authorized for 4-way HS offload Greg Kroah-Hartman
` (486 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Gael Blivet, Namjae Jeon,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gael Blivet <gael.blivet@gmail.com>
[ Upstream commit 10ea20d6584ecdaf2f7505855412a856a88d8934 ]
get_file_stream_info() walks the xattr list from a single
ksmbd_vfs_listxattr() and sizes each stream it finds with
ksmbd_vfs_casexattr_len(), which matches with strncasecmp(). Linux
xattr names are case-sensitive, so two streams differing only in case
report each other's size.
The loop already holds the exact name, so query it directly with
ksmbd_vfs_xattr_len(), which is what casexattr_len() calls once its
search succeeds. Make it non-static and declare it in vfs.h, and drop
the comment above it, which describes a different bug and no longer
matches the code.
This also drops a full listing per stream: casexattr_len() runs its own
listxattr on every call, so enumerating a file with N xattrs cost N
listings instead of one.
Fixes: 689f1eb3719d ("ksmbd: report actual xattr value length in stream enumeration")
Signed-off-by: Gael Blivet <gael.blivet@gmail.com>
Assisted-by: Claude:claude-opus-5
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
[ sashal: retained non-const struct mnt_idmap pointers to match the existing vfs_getxattr() API ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smb2pdu.c | 13 ++-----------
fs/smb/server/vfs.c | 4 ++--
fs/smb/server/vfs.h | 2 ++
3 files changed, 6 insertions(+), 13 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 418610e05ce95..30549a02ccfb2 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -7097,17 +7097,8 @@ static int get_file_stream_info(struct ksmbd_work *work,
streamlen *= 2;
kfree(stream_buf);
file_info->StreamNameLength = cpu_to_le32(streamlen);
- /*
- * stream_name_len is the byte length of the xattr's *name*,
- * not its value -- same class of bug ksmbd_stream_eof()
- * (smb2pdu.c) already fixes for EndOfFile/AllocationSize on
- * a stream handle; this enumeration path needs the same
- * real xattr value length, not the name length reused as a
- * size.
- */
- slen = ksmbd_vfs_casexattr_len(file_mnt_idmap(fp->filp),
- path->dentry, stream_name,
- strlen(stream_name) + 1, NULL);
+ slen = ksmbd_vfs_xattr_len(file_mnt_idmap(fp->filp),
+ path->dentry, stream_name);
ssize = slen < 0 ? 0 : (loff_t)slen;
file_info->StreamSize = cpu_to_le64(ssize);
file_info->StreamAllocationSize = cpu_to_le64(ssize);
diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c
index 7453b6e72bd4d..674e4fcd80cb2 100644
--- a/fs/smb/server/vfs.c
+++ b/fs/smb/server/vfs.c
@@ -902,8 +902,8 @@ ssize_t ksmbd_vfs_listxattr(struct dentry *dentry, char **list)
return size;
}
-static ssize_t ksmbd_vfs_xattr_len(struct mnt_idmap *idmap,
- struct dentry *dentry, char *xattr_name)
+ssize_t ksmbd_vfs_xattr_len(struct mnt_idmap *idmap,
+ struct dentry *dentry, char *xattr_name)
{
return vfs_getxattr(idmap, dentry, xattr_name, NULL, 0);
}
diff --git a/fs/smb/server/vfs.h b/fs/smb/server/vfs.h
index 53044549571ab..7cdd496786674 100644
--- a/fs/smb/server/vfs.h
+++ b/fs/smb/server/vfs.h
@@ -109,6 +109,8 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap,
struct dentry *dentry,
char *xattr_name,
char **xattr_buf);
+ssize_t ksmbd_vfs_xattr_len(struct mnt_idmap *idmap,
+ struct dentry *dentry, char *xattr_name);
ssize_t ksmbd_vfs_casexattr_len(struct mnt_idmap *idmap,
struct dentry *dentry, char *attr_name,
int attr_name_len, char *actual_name);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 021/507] wifi: brcmfmac: cfg80211: Report port_authorized for 4-way HS offload
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (19 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 020/507] ksmbd: look up stream size by exact xattr name Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 022/507] io_uring/cancel: drop sqd->lock while SQPOLL waits Greg Kroah-Hartman
` (485 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Janne Grunau, Neal Gompa,
Arend van Spriel, Johannes Berg, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Janne Grunau <j@jannau.net>
[ Upstream commit 6fff9de5c5b425817588eeed42bd56d665751c13 ]
Since commit 416386060 ("Mark authorization completed on driver
indication during 4-way HS offload") [0] wpa_supplicant expects
NL80211_CMD_PORT_AUTHORIZED to complete the authentication when the
driver supports 4-way handshake offload.
This was apparently never tested with the upstream brcmfmac driver as it
does not report this. This broke authentication on Apple silicon devices
(BRCM4378, BRMC4387, BRMC4388) and other devices when wpa_supplicant
2.11 was released [1]. This was initially dealt with by reverting the
commit in Fedora [2] and other Linux distributions.
Instead of carrying the revert over to wpa_supplicant 2.12 add the
expected NL80211_CMD_PORT_AUTHORIZED when the connection is established.
The "Fixes:" tag is not fully accurate as this has only became an issue
after userspace changes years after the change. Since the change is
expected to be required in all active stable branches for wpa_supplicant
2.11 / 2.12 compatibility it is helpful even though
BRCMF_PROFILE_FWSUP_SAE did not exists then.
Link: https://github.com/zephyrproject-rtos/hostap/commit/41638606054a09867fe3f9a2b5523aa4678cbfa5 [0]
Link: https://lists.infradead.org/pipermail/hostap/2024-August/042893.html [1]
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2302577 [2]
Link: https://lore.kernel.org/linux-wireless/20260911065656.1269623-5-Jason.Huang2@infineon.com/ [3]
Cc: stable@vger.kernel.org
Fixes: b8a64f0e96c2 ("brcmfmac: support 4-way handshake offloading for WPA/WPA2-PSK")
Signed-off-by: Janne Grunau <j@jannau.net>
Reviewed-by: Neal Gompa <neal@gompa.dev>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20260915-brcmfmac-4way-handshake-offload-authenticated-event-v2-1-fbb9cc7ac177@jannau.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Janne Grunau <j@jannau.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 872c48806d091..62d072b6369ef 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -6504,6 +6504,7 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
struct cfg80211_connect_resp_params conn_params;
+ bool authorized;
brcmf_dbg(TRACE, "Enter\n");
@@ -6528,7 +6529,13 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
conn_params.req_ie_len = conn_info->req_ie_len;
conn_params.resp_ie = conn_info->resp_ie;
conn_params.resp_ie_len = conn_info->resp_ie_len;
+ authorized = completed &&
+ ((profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE) ||
+ (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK));
cfg80211_connect_done(ndev, &conn_params, GFP_KERNEL);
+ if (authorized)
+ cfg80211_port_authorized(ndev, profile->bssid, NULL, 0,
+ GFP_KERNEL);
brcmf_dbg(CONN, "Report connect result - connection %s\n",
completed ? "succeeded" : "failed");
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 022/507] io_uring/cancel: drop sqd->lock while SQPOLL waits
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (20 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 021/507] wifi: brcmfmac: cfg80211: Report port_authorized for 4-way HS offload Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 023/507] io_uring/sqpoll: dont attach to a thread that is canceling Greg Kroah-Hartman
` (484 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chris Mason, Jens Axboe, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
Commit cb0306c52ffae083a86fb283de67875ae7a9500e upstream.
An exiting SQPOLL thread calls io_uring_cancel_generic() with sqd->lock
held, and keeps it across cond_resched() and the sleep until nothing is
in flight anymore. A zero-copy send notification can't be canceled and
stays pending as long as the peer doesn't read, so the lock is held for
as long as a user cares to. io_ring_exit_work() needs it to park the
thread, and so do IORING_REGISTER_IOWQ_AFF and IOWQ_MAX_WORKERS. With
64 such rings sharing the thread, every iou_exit slot sleeps on the lock
and no ring gets freed for anyone.
Drop the lock around cond_resched() and the sleep, like the main loop of
the thread does. Each walk of ctx_list is still under one hold, and
nothing is kept across the unlock. The thread drops its io-wq, frees its
tctx and clears sqd->thread under one hold after the loop, so whoever
holds the lock and finds sqd->thread set can still use them.
Fixes: 63809137ebb5 ("io_uring: flush notifiers after sendzc")
Signed-off-by: Chris Mason <mason@kernel.org>
[axboe: adapted to the schedule_timeout() based loop]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
[axboe: adapted to the schedule() based wait loop]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
io_uring/cancel.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/io_uring/cancel.c b/io_uring/cancel.c
index 75a21ecfe69c8..c7ed51377dea2 100644
--- a/io_uring/cancel.c
+++ b/io_uring/cancel.c
@@ -650,7 +650,16 @@ __cold void io_uring_cancel_generic(bool cancel_all, struct io_sq_data *sqd)
}
if (loop) {
+ /*
+ * A request that runs in io-wq and doesn't end makes
+ * each round come here. Don't hold sqd->lock for that
+ * long either.
+ */
+ if (sqd)
+ mutex_unlock(&sqd->lock);
cond_resched();
+ if (sqd)
+ mutex_lock(&sqd->lock);
continue;
}
@@ -678,8 +687,20 @@ __cold void io_uring_cancel_generic(bool cancel_all, struct io_sq_data *sqd)
* avoids a race where a completion comes in before we did
* prepare_to_wait().
*/
- if (inflight == tctx_inflight(tctx, !cancel_all))
+ if (inflight == tctx_inflight(tctx, !cancel_all)) {
+ /*
+ * A zero-copy notification can't be canceled, and a
+ * peer that doesn't read keeps it pending. Don't hold
+ * sqd->lock while waiting for it, or whoever wants the
+ * lock sleeps as long. No ring is used across this,
+ * the next round walks ->ctx_list anew.
+ */
+ if (sqd)
+ mutex_unlock(&sqd->lock);
schedule();
+ if (sqd)
+ mutex_lock(&sqd->lock);
+ }
end_wait:
finish_wait(&tctx->wait, &wait);
} while (1);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 023/507] io_uring/sqpoll: dont attach to a thread that is canceling
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (21 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 022/507] io_uring/cancel: drop sqd->lock while SQPOLL waits Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 024/507] io_uring/sqpoll: dont set IO_SQ_THREAD_SHOULD_STOP on thread exit Greg Kroah-Hartman
` (483 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Jens Axboe,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <axboe@kernel.dk>
Commit 22d9db9fd64a493525d692b32c556875b7254665 upstream.
io_sq_offload_create() refuses to attach a ring to an SQPOLL thread
that has already gone, by checking sqd->thread under sqd->lock. Since
the thread drops the lock while io_uring_cancel_generic() waits for its
requests, that check can run while the thread is on its way out and
still see it. The new ring is then added to ctx_list, io_uring_setup()
succeeds, the thread finishes canceling and exits without ever having
looked at the ring, and io_uring_enter() fails with -EOWNERDEAD.
Only a thread that exits on a fatal signal can be caught like this, as
the stop bit is set once the last ring has let go of the sqd, when no fd
is left to attach through. A fatal signal is group wide and attaching
needs the same thread group, so the attacher is on its way out as well.
Still, make the check see it: set the stop bit before canceling,
whatever the reason for the exit, and test it when attaching.
Reported-by: Karl Mehltretter <kmehltretter@gmail.com>
Fixes: cb0306c52ffa ("io_uring/cancel: drop sqd->lock while SQPOLL waits")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
io_uring/sqpoll.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/io_uring/sqpoll.c b/io_uring/sqpoll.c
index 49c52284ecdde..c833e776320d4 100644
--- a/io_uring/sqpoll.c
+++ b/io_uring/sqpoll.c
@@ -433,6 +433,12 @@ static int io_sq_thread(void *data)
if (io_sq_tw_pending())
io_sq_tw(UINT_MAX);
+ /*
+ * Cancelation drops sqd->lock while it waits, and a ring could attach
+ * to a thread that is on its way out. A fatal signal doesn't set the
+ * bit, so set it here for io_sq_offload_create() to see.
+ */
+ set_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state);
io_uring_cancel_generic(true, sqd);
rcu_assign_pointer(sqd->thread, NULL);
put_task_struct(current);
@@ -502,7 +508,10 @@ __cold int io_sq_offload_create(struct io_ring_ctx *ctx,
list_add(&ctx->sqd_list, &sqd->ctx_list);
io_sqd_update_thread_idle(sqd);
/* don't attach to a dying SQPOLL thread, would be racy */
- ret = (attached && !sqd->thread) ? -ENXIO : 0;
+ ret = 0;
+ if (attached && (!sqd->thread ||
+ test_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state)))
+ ret = -ENXIO;
io_sq_thread_unpark(sqd);
if (ret < 0)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 024/507] io_uring/sqpoll: dont set IO_SQ_THREAD_SHOULD_STOP on thread exit
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (22 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 023/507] io_uring/sqpoll: dont attach to a thread that is canceling Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 025/507] io_uring/sqpoll: do the return-to-userspace work in the SQPOLL thread Greg Kroah-Hartman
` (482 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+675af112519ca34f5502,
Shuai Liu, Jens Axboe, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuai Liu <847807867@qq.com>
Commit fca3ff9e2eee7d285585daf51942e0b5e2be354a upstream.
io_sq_thread_stop() carries a WARN_ON_ONCE() asserting that
IO_SQ_THREAD_SHOULD_STOP isn't set yet, i.e. that stopping the SQPOLL
thread is never attempted twice. Since commit 22d9db9fd64a
("io_uring/sqpoll: don't attach to a thread that is canceling"), the
SQPOLL thread itself sets that bit on its way out, so that
io_sq_offload_create() won't attach a new ring to a thread that is
canceling.
When the thread exits on a fatal signal, the bit is thus set before the
ring teardown gets to io_sq_thread_stop(), which now triggers the
warning on every such exit:
WARNING: io_uring/sqpoll.c:88 at io_sq_thread_stop
Workqueue: iou_exit io_ring_exit_work
Call Trace:
io_put_sq_data
io_sq_thread_finish
io_ring_ctx_free
io_ring_exit_work
Introduce a separate IO_SQ_THREAD_EXITING bit for the thread marking
itself as on its way out, and check it in io_sq_offload_create() along
with IO_SQ_THREAD_SHOULD_STOP. IO_SQ_THREAD_SHOULD_STOP regains its
original meaning, "a stop has been requested", and the WARN_ON_ONCE()
holds again.
Reproduced with an SQPOLL ring and an immediate fatal signal: the
warning fires on v7.3.0+ (22d9db9fd64a present) and is gone with this
change.
Reported-by: syzbot+675af112519ca34f5502@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=675af112519ca34f5502
Fixes: 22d9db9fd64a ("io_uring/sqpoll: don't attach to a thread that is canceling")
Signed-off-by: Shuai Liu <847807867@qq.com>
Link: https://patch.msgid.link/tencent_BB08960D79E0261B5C1EB1E589787734E907@qq.com
[axboe: trim excessive comment]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
io_uring/sqpoll.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/io_uring/sqpoll.c b/io_uring/sqpoll.c
index c833e776320d4..e86658ede44be 100644
--- a/io_uring/sqpoll.c
+++ b/io_uring/sqpoll.c
@@ -29,6 +29,7 @@
enum {
IO_SQ_THREAD_SHOULD_STOP = 0,
IO_SQ_THREAD_SHOULD_PARK,
+ IO_SQ_THREAD_EXITING,
};
void io_sq_thread_unpark(struct io_sq_data *sqd)
@@ -436,9 +437,10 @@ static int io_sq_thread(void *data)
/*
* Cancelation drops sqd->lock while it waits, and a ring could attach
* to a thread that is on its way out. A fatal signal doesn't set the
- * bit, so set it here for io_sq_offload_create() to see.
+ * stop bit, so mark the thread as exiting here for
+ * io_sq_offload_create() to see.
*/
- set_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state);
+ set_bit(IO_SQ_THREAD_EXITING, &sqd->state);
io_uring_cancel_generic(true, sqd);
rcu_assign_pointer(sqd->thread, NULL);
put_task_struct(current);
@@ -510,7 +512,8 @@ __cold int io_sq_offload_create(struct io_ring_ctx *ctx,
/* don't attach to a dying SQPOLL thread, would be racy */
ret = 0;
if (attached && (!sqd->thread ||
- test_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state)))
+ test_bit(IO_SQ_THREAD_SHOULD_STOP, &sqd->state) ||
+ test_bit(IO_SQ_THREAD_EXITING, &sqd->state)))
ret = -ENXIO;
io_sq_thread_unpark(sqd);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 025/507] io_uring/sqpoll: do the return-to-userspace work in the SQPOLL thread
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (23 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 024/507] io_uring/sqpoll: dont set IO_SQ_THREAD_SHOULD_STOP on thread exit Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 026/507] io_uring/cancel: count all requests that a CANCEL_ALL cancels Greg Kroah-Hartman
` (481 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Shakeel Butt, Jens Axboe,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shakeel Butt <shakeel.butt@linux.dev>
Commit f013b695506491c5202a412a6568313549c81f50 upstream.
The SQPOLL thread never returns to userspace. io_sq_tw() runs its
task_work, but the rest of resume_user_mode_work(), like memory.high
reclaim and block cgroup throttling, only runs when the thread exits.
So memory.high reclaim only happens inside a charge, with sqd->lock and
ctx->uring_lock held, and not at all if the charges can't block.
This used to work. The loop called io_run_task_work(), which does this
work since commit b5d3ae202fbf ("io_uring: handle TIF_NOTIFY_RESUME
when checking for task_work"). Commit af5d68f8892f ("io_uring/sqpoll:
manage task_work privately") replaced that call with io_sq_tw().
Call resume_user_mode_work() at the top of the loop when
TIF_NOTIFY_RESUME is set, with sqd->lock dropped. It runs once per pass,
so a pass that charges two or more batches still reclaims inside the
charge, as before.
Tested in a VM with memory.high=64M and swap on zram. An SQPOLL ring
reads 256M from /dev/zero into untouched memory, 64K at a time. Before,
the thread made 337 calls to __mem_cgroup_handle_over_high(), all from
inside the charge. After, it makes 704, all from the top of the loop.
memory.peak stays at 64M. With 1M reads, 296 of its 385 calls still come
from inside the charge. Both runs take about 50% longer, and the extra
time is in the handler, which now runs more often. Without memory.high
pressure, the test never calls resume_user_mode_work() and the times
do not change. Lockdep showed no warnings, also with io_uring_register()
racing for sqd->lock.
Fixes: af5d68f8892f ("io_uring/sqpoll: manage task_work privately")
Cc: stable@vger.kernel.org
Signed-off-by: Shakeel Butt <shakeel.butt@linux.dev>
Link: https://patch.msgid.link/20261101022146.309201-1-shakeel.butt@linux.dev
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
io_uring/sqpoll.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/io_uring/sqpoll.c b/io_uring/sqpoll.c
index e86658ede44be..d387488db2dec 100644
--- a/io_uring/sqpoll.c
+++ b/io_uring/sqpoll.c
@@ -349,6 +349,18 @@ static int io_sq_thread(void *data)
timeout = jiffies + sqd->sq_thread_idle;
}
+ /*
+ * The SQPOLL thread never returns to userspace, so do the
+ * return-to-userspace work, like memory.high reclaim, here.
+ * It can sleep for a long time, so drop sqd->lock.
+ */
+ if (test_thread_flag(TIF_NOTIFY_RESUME)) {
+ mutex_unlock(&sqd->lock);
+ resume_user_mode_work(NULL);
+ mutex_lock(&sqd->lock);
+ sqd->sq_cpu = raw_smp_processor_id();
+ }
+
cap_entries = !list_is_singular(&sqd->ctx_list);
list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) {
int ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 026/507] io_uring/cancel: count all requests that a CANCEL_ALL cancels
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (24 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 025/507] io_uring/sqpoll: do the return-to-userspace work in the SQPOLL thread Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 027/507] io_uring/poll: cancel all matching requests in one pass Greg Kroah-Hartman
` (480 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Shang En Sim, Jens Axboe,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shang En Sim <sim@shangen.org>
Commit 21ddbb14f7c3baab50a2a6c13ee375edc2bbe031 upstream.
With IORING_ASYNC_CANCEL_ALL, __io_async_cancel() counts one for each
io_try_cancel() call that cancels something. io_futex_cancel() and
io_waitid_cancel() cancel every match in one call and return how many,
so four futex waits cancelled with CANCEL_ALL give a result of 1.
Add the number that they return.
Cc: stable@vger.kernel.org
Fixes: 194bb58c6090 ("io_uring: add support for futex wake and wait")
Fixes: f31ecf671ddc ("io_uring: add IORING_OP_WAITID support")
Signed-off-by: Shang En Sim <sim@shangen.org>
Link: https://patch.msgid.link/20261030050319.1448530-2-sim@shangen.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
io_uring/cancel.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/io_uring/cancel.c b/io_uring/cancel.c
index c7ed51377dea2..a34543cb423cd 100644
--- a/io_uring/cancel.c
+++ b/io_uring/cancel.c
@@ -198,7 +198,8 @@ static int __io_async_cancel(struct io_cancel_data *cd,
break;
if (!all)
return ret;
- nr++;
+ /* futex and waitid return how many they cancelled */
+ nr += max(ret, 1);
} while (1);
/* slow path, try all io-wq's */
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 027/507] io_uring/poll: cancel all matching requests in one pass
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (25 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 026/507] io_uring/cancel: count all requests that a CANCEL_ALL cancels Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 028/507] io_uring/poll: dont poll a writer for a read side hangup Greg Kroah-Hartman
` (479 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Shang En Sim, Jens Axboe,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shang En Sim <sim@shangen.org>
Commit 9eff9c07e927dcd9c57150cd6fb3d4ec76f00480 upstream.
With IORING_ASYNC_CANCEL_ALL, __io_async_cancel() calls io_try_cancel()
until nothing is found, and io_poll_cancel() cancels one request per
call, starting each lookup at the beginning of the hash. A cancelled
request stays hashed until its task work runs, so every lookup walks
past the ones already cancelled. Cancelling K of N pending polls visits
about K*N/2 requests in one io_uring_enter(), with uring_lock held.
A single CANCEL_FD|ALL on 80000 polls on one eventfd takes 17.06s,
0.02s with this change. With voluntary preemption the soft lockup
watchdog fires:
watchdog: BUG: soft lockup - CPU#1 stuck for 26s! [repro:100]
RIP: 0010:io_cancel_req_match+0x19/0xa0
io_poll_cancel+0x73/0x170
io_try_cancel+0x7b/0xf0
__io_async_cancel+0x41/0x110
Walk the hash once and cancel every match, as io_cancel_remove() does
for futex and waitid. Cancel by user_data only needs its own bucket.
__io_async_cancel() still loops until nothing is found, so a request
that io-wq parks in the poll hash meanwhile is still cancelled.
A cancel that matches one request now walks the whole hash twice instead
of stopping at the match.
Cc: stable@vger.kernel.org
Fixes: 8e29da69fead ("io_uring: add support for IORING_ASYNC_CANCEL_ALL")
Signed-off-by: Shang En Sim <sim@shangen.org>
Link: https://patch.msgid.link/20261030050319.1448530-3-sim@shangen.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
io_uring/cancel.c | 2 +-
io_uring/poll.c | 39 +++++++++++++++++++++++++++++++++++++--
2 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/io_uring/cancel.c b/io_uring/cancel.c
index a34543cb423cd..6be224ab53dc9 100644
--- a/io_uring/cancel.c
+++ b/io_uring/cancel.c
@@ -198,7 +198,7 @@ static int __io_async_cancel(struct io_cancel_data *cd,
break;
if (!all)
return ret;
- /* futex and waitid return how many they cancelled */
+ /* poll, futex and waitid return how many they cancelled */
nr += max(ret, 1);
} while (1);
diff --git a/io_uring/poll.c b/io_uring/poll.c
index 4f04bda42f7ff..9b73b0d88a0ee 100644
--- a/io_uring/poll.c
+++ b/io_uring/poll.c
@@ -827,12 +827,47 @@ static int io_poll_disarm(struct io_kiocb *req)
return 0;
}
+/*
+ * Cancel every request matching @cd in one pass. Cancelled requests stay
+ * hashed until their task work runs, so finding them one at a time would
+ * walk past all the earlier ones on each lookup.
+ */
+static int io_poll_cancel_all(struct io_ring_ctx *ctx, struct io_cancel_data *cd)
+{
+ unsigned int nr_buckets = 1U << ctx->cancel_table.hash_bits;
+ unsigned int i = 0;
+ struct hlist_node *tmp;
+ struct io_kiocb *req;
+ int nr = 0;
+
+ if (!(cd->flags & (IORING_ASYNC_CANCEL_FD | IORING_ASYNC_CANCEL_OP |
+ IORING_ASYNC_CANCEL_ANY))) {
+ /* keyed by user_data, so only one bucket can match */
+ i = hash_long(cd->data, ctx->cancel_table.hash_bits);
+ nr_buckets = i + 1;
+ }
+
+ for (; i < nr_buckets; i++) {
+ struct io_hash_bucket *hb = &ctx->cancel_table.hbs[i];
+
+ hlist_for_each_entry_safe(req, tmp, &hb->list, hash_node) {
+ if (!io_cancel_req_match(req, cd))
+ continue;
+ io_poll_cancel_req(req);
+ nr++;
+ }
+ }
+ return nr ?: -ENOENT;
+}
+
static int __io_poll_cancel(struct io_ring_ctx *ctx, struct io_cancel_data *cd)
{
struct io_kiocb *req;
- if (cd->flags & (IORING_ASYNC_CANCEL_FD | IORING_ASYNC_CANCEL_OP |
- IORING_ASYNC_CANCEL_ANY))
+ if (cd->flags & (IORING_ASYNC_CANCEL_ALL | IORING_ASYNC_CANCEL_ANY))
+ return io_poll_cancel_all(ctx, cd);
+
+ if (cd->flags & (IORING_ASYNC_CANCEL_FD | IORING_ASYNC_CANCEL_OP))
req = io_poll_file_find(ctx, cd);
else
req = io_poll_find(ctx, false, cd);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 028/507] io_uring/poll: dont poll a writer for a read side hangup
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (26 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 027/507] io_uring/poll: cancel all matching requests in one pass Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 029/507] io_uring/poll: dont poll a writer for urgent data Greg Kroah-Hartman
` (478 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lukáš Lalinský,
Jens Axboe, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <axboe@kernel.dk>
Commit 74c1f1048e4401d6a953ab2299b14ace1ad6a899 upstream.
io_init_poll_iocb() adds EPOLLRDHUP to every poll, including the async
poll of a send that waits for buffer space. Once the peer has shut down
its sending side, the socket keeps reporting EPOLLRDHUP, so each re-arm
in __io_arm_poll_handler() finds a ready mask and the request is issued
again. The send still can't make progress, the request burns through
APOLL_MAX_RETRY in a few milliseconds and ends up in io-wq.
A send in io-wq blocks until the peer reads, but sendmsg and writev go
through ____sys_sendmsg() and sock_write_iter(), which turn O_NONBLOCK
into MSG_DONTWAIT, and the application gets -EAGAIN for a request that
never asked for a non-blocking send.
Only add EPOLLRDHUP for polls that want to read. A peer that stopped
sending is no event for a writer, and a poll that asks for it explicitly
still gets it.
Fixes: 464dca612bc6 ("io_uring: mask in error/nval/hangup consistently for poll")
Reported-by: Lukáš Lalinský <lukas@lalinsky.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
io_uring/poll.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/io_uring/poll.c b/io_uring/poll.c
index 9b73b0d88a0ee..9703a2fdfb44a 100644
--- a/io_uring/poll.c
+++ b/io_uring/poll.c
@@ -128,12 +128,24 @@ static void io_poll_req_insert(struct io_kiocb *req)
hlist_add_head(&req->hash_node, &table->hbs[index].list);
}
+#define IO_POLL_UNMASK (EPOLLERR|EPOLLHUP|EPOLLNVAL)
+
+static __poll_t io_poll_unmask(__poll_t events)
+{
+ /*
+ * A peer that stopped sending is an event for a reader, but a write
+ * only poll must stay armed until the file is writable again.
+ */
+ if (events & (EPOLLIN | EPOLLRDNORM | EPOLLRDBAND))
+ return IO_POLL_UNMASK | EPOLLRDHUP;
+ return IO_POLL_UNMASK;
+}
+
static void io_init_poll_iocb(struct io_poll *poll, __poll_t events)
{
poll->head = NULL;
-#define IO_POLL_UNMASK (EPOLLERR|EPOLLHUP|EPOLLNVAL|EPOLLRDHUP)
/* mask in events that we always want/need */
- poll->events = events | IO_POLL_UNMASK;
+ poll->events = events | io_poll_unmask(events);
INIT_LIST_HEAD(&poll->wait.entry);
init_waitqueue_func_entry(&poll->wait, io_poll_wake);
}
@@ -1006,7 +1018,7 @@ int io_poll_remove(struct io_kiocb *req, unsigned int issue_flags)
poll->events &= ~0xffff;
poll->events |= poll_update->events & 0xffff;
- poll->events |= IO_POLL_UNMASK;
+ poll->events |= io_poll_unmask(poll->events);
}
if (poll_update->update_user_data)
preq->cqe.user_data = poll_update->new_user_data;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 029/507] io_uring/poll: dont poll a writer for urgent data
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (27 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 028/507] io_uring/poll: dont poll a writer for a read side hangup Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 030/507] io_uring/rsrc: hold uring_lock across index-alloc put_user Greg Kroah-Hartman
` (477 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lukáš Lalinský,
Jens Axboe, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <axboe@kernel.dk>
Commit edeac4546a71b6c1db4ba006a2dbf7c863f54e9a upstream.
io_arm_poll_handler() starts the mask of every async poll with EPOLLPRI,
for a reader and a writer alike. A TCP socket reports EPOLLPRI for as
long as urgent data sits unread, so once the peer has sent a byte with
MSG_OOB, the async poll of a send that waits for buffer space is ready
on every re-arm. The request spins through task_work and
__io_arm_poll_handler() until APOLL_MAX_RETRY is used up and io-wq takes
it, the same spin that EPOLLRDHUP caused for a half-closed peer.
While it spins, the request is neither in the poll hash nor in io-wq. A
cancel issued right after the send gets -ENOENT and the send stays
pending, until a later cancel finds it in io-wq.
Only add EPOLLPRI for polls that want to read. Urgent data is an event
for a recv, not for a writer.
Fixes: d7718a9d25a6 ("io_uring: use poll driven retry for files that support it")
Reported-by: Lukáš Lalinský <lukas@lalinsky.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
io_uring/poll.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/io_uring/poll.c b/io_uring/poll.c
index 9703a2fdfb44a..fc1800c7097b5 100644
--- a/io_uring/poll.c
+++ b/io_uring/poll.c
@@ -739,7 +739,7 @@ int io_arm_apoll(struct io_kiocb *req, unsigned issue_flags, __poll_t mask)
int io_arm_poll_handler(struct io_kiocb *req, unsigned issue_flags)
{
const struct io_issue_def *def = &io_issue_defs[req->opcode];
- __poll_t mask = POLLPRI | POLLERR;
+ __poll_t mask = EPOLLERR;
if (!def->pollin && !def->pollout)
return IO_APOLL_ABORTED;
@@ -747,7 +747,8 @@ int io_arm_poll_handler(struct io_kiocb *req, unsigned issue_flags)
return IO_APOLL_ABORTED;
if (def->pollin) {
- mask |= EPOLLIN | EPOLLRDNORM;
+ /* urgent data is an event for a reader only */
+ mask |= EPOLLIN | EPOLLRDNORM | EPOLLPRI;
/* If reading from MSG_ERRQUEUE using recvmsg, ignore POLLIN */
if (req->flags & REQ_F_CLEAR_POLLIN)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 030/507] io_uring/rsrc: hold uring_lock across index-alloc put_user
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (28 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 029/507] io_uring/poll: dont poll a writer for urgent data Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 031/507] mm/damon/core: remove unreachable damos charge_{target,addr}_from Greg Kroah-Hartman
` (476 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yuansheng Yang, Jens Axboe,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuansheng Yang <0xbeac@gmail.com>
Commit d7c7037253f6935af243570635d71b4920b5a4ea upstream.
io_files_update_with_index_alloc() installs a fixed file via
io_fixed_fd_install(), which drops ->uring_lock when the request runs on
io-wq, then put_user()s the allocated slot back to userspace. If that
faults, the error path calls __io_close_fixed() by slot index after
re-taking the lock.
The slot can be closed and reused between the install and that cleanup:
another fixed CLOSE plus open/accept/pipe/socket, or a FILES_UPDATE, can
put an unrelated file into the same slot. The error path then removes
that file instead of the one this request installed, ending an unrelated
file's fixed-table reference early. This is a correctness/DoS issue, not
a use-after-free: fixed-file requests hold an io_rsrc_node reference, so
the node and file stay alive until they are done.
Hold ->uring_lock across __io_fixed_fd_install() and put_user(), and do
the failure cleanup with io_fixed_fd_remove() under the same lock. This
is the same class as the io_pipe_fixed() fix in a3d7ee11289f. Faulting
while holding ->uring_lock is fine, the registration paths already do
it.
Fixes: a7c41b4687f5 ("io_uring: let IORING_OP_FILES_UPDATE support choosing fixed file slots")
Signed-off-by: Yuansheng Yang <0xbeac@gmail.com>
Link: https://patch.msgid.link/20261104154655.81876-1-0xbeac@gmail.com
[axboe: various touch-ups]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
io_uring/rsrc.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c
index d69baa47c7e75..c1ab760c4591c 100644
--- a/io_uring/rsrc.c
+++ b/io_uring/rsrc.c
@@ -521,11 +521,12 @@ static int io_files_update_with_index_alloc(struct io_kiocb *req,
{
struct io_rsrc_update *up = io_kiocb_to_cmd(req, struct io_rsrc_update);
__s32 __user *fds = u64_to_user_ptr(up->arg);
+ struct io_ring_ctx *ctx = req->ctx;
unsigned int done;
struct file *file;
int ret, fd;
- if (!req->ctx->file_table.data.nr)
+ if (!ctx->file_table.data.nr)
return -ENXIO;
for (done = 0; done < up->nr_args; done++) {
@@ -539,15 +540,25 @@ static int io_files_update_with_index_alloc(struct io_kiocb *req,
ret = -EBADF;
break;
}
- ret = io_fixed_fd_install(req, issue_flags, file,
- IORING_FILE_INDEX_ALLOC);
- if (ret < 0)
+ /*
+ * Hold the lock across the put_user(), if it's dropped the
+ * slot can be closed and reused before the error path runs.
+ */
+ io_ring_submit_lock(ctx, issue_flags);
+ ret = __io_fixed_fd_install(ctx, file,
+ IORING_FILE_INDEX_ALLOC);
+ if (ret < 0) {
+ io_ring_submit_unlock(ctx, issue_flags);
+ fput(file);
break;
+ }
if (put_user(ret, &fds[done])) {
- __io_close_fixed(req->ctx, issue_flags, ret);
+ io_fixed_fd_remove(ctx, ret);
+ io_ring_submit_unlock(ctx, issue_flags);
ret = -EFAULT;
break;
}
+ io_ring_submit_unlock(ctx, issue_flags);
}
if (done)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 031/507] mm/damon/core: remove unreachable damos charge_{target,addr}_from
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (29 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 030/507] io_uring/rsrc: hold uring_lock across index-alloc put_user Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 032/507] block: restore the iterator when rejecting a misaligned bio Greg Kroah-Hartman
` (475 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, SJ Park, Andrew Morton, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: SJ Park <sj@kernel.org>
[ Upstream commit 5695abc4e742b947f586bfb6a080a80ad9957e5d ]
damos_quota->charge_{target,addr}_from saves the target and region the
scheme's quota limit is reached. damos_skip_charged_region() skips the
target and regions before the point. The target that was assigned to
charge_target_from could be dynamically removed from the context by the
runtime parameters update (aka commit) feature. In this case,
damos_skip_charged_region() cannot find if the point is passed or not,
so the scheme is effectively disabled.
Similarly, the user could also remove all the regions of the target
using the runtime parameters update feature. It would be uncommon to do
that, but it is a supported feature. Because the skip pointer detection
logic (damos_skip_charged_region()) works for each region of targets,
this result in the logic is entirely skipped and the scheme is
effectively disabled again.
The user impact is that the DAMOS scheme could suddenly stop working
under certain uses of the runtime parameters update feature. It could
surprise users. No crash or leak happens though. Users could also
simply work around by re-installing the scheme.
Catch the corner cases in damos_adjust_quota() and reset the pointers.
Link: https://lore.kernel.org/20261020023958.108276-1-sj@kernel.org
Fixes: da87878010e5 ("mm/damon/sysfs: support online inputs update")
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Closes: https://sashiko.dev/#/bug/linux-cd0c55fc-0cc8-45d8-9637-3334811c49b8
Cc: <stable@vger.kernel.org> # 5.19.x
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/damon/core.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/mm/damon/core.c b/mm/damon/core.c
index e018635774be5..229ab1674b4c1 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -3200,6 +3200,26 @@ static void damos_trace_esz(struct damon_ctx *c, struct damos *s,
trace_damos_esz(cidx, sidx, quota->esz);
}
+static void damos_fix_stale_charge_pointers(struct damon_ctx *c,
+ struct damos *s)
+{
+ struct damos_quota *quota;
+ struct damon_target *t;
+
+ quota = &s->quota;
+ if (!quota->charge_target_from)
+ return;
+ damon_for_each_target(t, c) {
+ if (t == quota->charge_target_from) {
+ if (damon_nr_regions(t) > 0)
+ return;
+ break;
+ }
+ }
+ quota->charge_target_from = NULL;
+ quota->charge_addr_from = 0;
+}
+
static void damos_adjust_quota(struct damon_ctx *c, struct damos *s)
{
struct damos_quota *quota = &s->quota;
@@ -3235,6 +3255,8 @@ static void damos_adjust_quota(struct damon_ctx *c, struct damos *s)
damos_trace_esz(c, s, quota);
}
+ damos_fix_stale_charge_pointers(c, s);
+
if (!c->ops.get_scheme_score)
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 032/507] block: restore the iterator when rejecting a misaligned bio
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (30 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 031/507] mm/damon/core: remove unreachable damos charge_{target,addr}_from Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 033/507] wifi: rtw88: TX report with long timeout for non-PCIE devices Greg Kroah-Hartman
` (474 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andrew Morton, Haocheng Yu,
Jens Axboe, Keith Busch, Christoph Hellwig, Tal Zussman,
Daehyeon Ko, Al Viro, Hannes Reinecke, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Morton <akpm@linux-foundation.org>
commit 40d070cbb1906896d6fd65c39722d2411830ed9f upstream.
bio_iov_iter_get_pages() can extract some iovecs before encountering a
misaligned one. It releases the pages and rejects the entire bio, but
leaves the supplied iterator advanced.
An iomap direct-I/O caller may subsequently reexpand the iterator's
byte count and fall back to buffered I/O. The reexpanded count then
includes bytes before the iterator's current segment, potentially
causing iterate_iovec() to read beyond the imported iovec array.
In a reproducer using an initial empty iovec followed by 10-byte and
1015-byte segments, writev() returned 1015 instead of 1025 and KASAN
reported an 8-byte read beyond the nine-element iovec allocation.
Saving and restoring the iterator on the rejected-bio path makes
writev() return 1025 and eliminates the KASAN report.
Restore the entire iterator rather than reverting a byte count:
advancing past an empty segment changes its position without consuming
any bytes.
Leave successful and partially accepted bio paths unchanged.
[ Backport to 7.3.y: restore the iterator in the existing inline
-EINVAL cleanup, as this tree lacks out_release_pages. ]
Fixes: 14b007e17881 ("block: validate user space vectors during extraction")
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: Haocheng Yu <l1za0.sec@gmail.com>
Closes: https://lore.kernel.org/20261018081203.2431035-1-l1za0.sec@gmail.com
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Keith Busch <kbusch@kernel.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Tal Zussman <tz2294@columbia.edu>
Cc: Daehyeon Ko <4ncienth@gmail.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Hannes Reinecke <hare@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261020170250.014BD1F000C9@smtp.kernel.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Haocheng Yu <l1za0.sec@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
block/bio.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/block/bio.c b/block/bio.c
index f95b63c0604af..90104e6abbcf2 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1285,6 +1285,7 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter,
unsigned mem_align_mask, unsigned len_align_mask)
{
iov_iter_extraction_t flags = 0;
+ struct iov_iter saved_iter;
if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
return -EIO;
@@ -1303,6 +1304,7 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter,
if (bio->bi_bdev && blk_queue_pci_p2pdma(bio->bi_bdev->bd_disk->queue))
flags |= ITER_ALLOW_P2PDMA;
+ saved_iter = *iter;
do {
ssize_t ret;
@@ -1320,6 +1322,7 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter,
bio_release_pages(bio, false);
bio_clear_flag(bio, BIO_PAGE_PINNED);
bio->bi_vcnt = 0;
+ *iter = saved_iter;
}
if (!bio->bi_vcnt)
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 033/507] wifi: rtw88: TX report with long timeout for non-PCIE devices
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (31 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 032/507] block: restore the iterator when rejecting a misaligned bio Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 034/507] ACPI: CPPC: Validate FFH register fields before hardware access Greg Kroah-Hartman
` (473 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ping-Ke Shih, Luka Gejak,
Josef Schlehofer, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ping-Ke Shih <pkshih@realtek.com>
[ Upstream commit 7cde94dab0e74434ccc0a387d7ad373fb3becda0 ]
Many USB and SDIO devices can't report TX status within 500 ms, and
extending to 2500 ms as tested USB/SDIO devices can fix the problem [1].
To avoid adding chip ID one by one, and this change looks harmless.
Keep PCIE using short timeout, and others use long timeout.
[1] https://lore.kernel.org/linux-wireless/20260921165343.8131-1-pepe.schlehofer@gmail.com/
Cc: stable@vger.kernel.org
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Reviewed-by: Luka Gejak <luka.gejak@linux.dev>
Tested-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
Link: https://patch.msgid.link/20260924004637.9958-1-pkshih@realtek.com
[ Adjust the removed condition. This tree has no RTL8723BS support and
lacks commit 4d688f22ebbf ("wifi: rtw88: tx: extend the TX report purge
timeout to RTL8723BS"), so the old check has no rtw_is_8723bs() part.
The resulting code is the same as upstream. ]
Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/realtek/rtw88/tx.c | 9 +++++----
drivers/net/wireless/realtek/rtw88/tx.h | 3 ++-
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c
index 8786bbb421c2b..701ed7c4f3f75 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.c
+++ b/drivers/net/wireless/realtek/rtw88/tx.c
@@ -196,7 +196,7 @@ void rtw_tx_report_purge_timer(struct timer_list *t)
void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn)
{
struct rtw_tx_report *tx_report = &rtwdev->tx_report;
- unsigned long timeout = RTW_TX_PROBE_TIMEOUT;
+ unsigned long timeout;
unsigned long flags;
u8 *drv_data;
@@ -208,9 +208,10 @@ void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn)
__skb_queue_tail(&tx_report->queue, skb);
spin_unlock_irqrestore(&tx_report->q_lock, flags);
- if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D &&
- rtwdev->hci.type == RTW_HCI_TYPE_USB)
- timeout = msecs_to_jiffies(2500);
+ if (rtwdev->hci.type == RTW_HCI_TYPE_PCIE)
+ timeout = RTW_TX_PROBE_TIMEOUT_SHORT;
+ else
+ timeout = RTW_TX_PROBE_TIMEOUT_LONG;
mod_timer(&tx_report->purge_timer, jiffies + timeout);
}
diff --git a/drivers/net/wireless/realtek/rtw88/tx.h b/drivers/net/wireless/realtek/rtw88/tx.h
index d34cdeca16f19..168f48e87853d 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.h
+++ b/drivers/net/wireless/realtek/rtw88/tx.h
@@ -7,7 +7,8 @@
#define RTK_TX_MAX_AGG_NUM_MASK 0x1f
-#define RTW_TX_PROBE_TIMEOUT msecs_to_jiffies(500)
+#define RTW_TX_PROBE_TIMEOUT_SHORT msecs_to_jiffies(500)
+#define RTW_TX_PROBE_TIMEOUT_LONG msecs_to_jiffies(2500)
struct rtw_tx_desc {
__le32 w0;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 034/507] ACPI: CPPC: Validate FFH register fields before hardware access
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (32 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 033/507] wifi: rtw88: TX report with long timeout for non-PCIE devices Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 035/507] ACPI: CPPC: Accept requests to retain immutable autonomous selection Greg Kroah-Hartman
` (472 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Loehle, Sumit Gupta,
Rafael J. Wysocki, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Loehle <christian.loehle@arm.com>
commit 6b016c5c96448c0a5f09328d37f66562d154a5e5 upstream.
The x86 CPPC FFH accessors construct masks and shift values using the
firmware's Bit Width and Bit Offset without checking that the field fits
in an MSR. A zero-width field or a field extending beyond bit 63 can
therefore cause an invalid shift. The safe MSR accessors only handle an
access fault, not invalid field arithmetic after a successful read.
Also, the 64-bit GAS address is implicitly narrowed to the 32-bit MSR
number. A descriptor with nonzero upper address bits can access a different
MSR from the one described by firmware.
The arm64 AMU counter readers have the same unchecked field arithmetic.
Validate the field bounds before reading a counter, including both
descriptors in the paired counter path.
Dispatch FFH accesses before decoding the GAS Access Size in the common
read and write paths. Otherwise, a large access_width can trigger an
invalid shift in GET_BIT_WIDTH() before the architecture validates its
register. That field has architecture-specific FFH semantics and is not
needed by the generic memory/port accessor on this path.
Validate x86 MSR addresses and share the field-bounds checks between
related accessors within each architecture.
Fixes: a6cbcdd5ab5f ("ACPI / CPPC: Add support for functional fixed hardware address")
Fixes: 68c5debcc06d ("arm64: implement CPPC FFH support using AMUs")
Fixes: f489c948028b ("ACPI: CPPC: Fix access width used for PCC registers")
Cc: All applicable <stable@vger.kernel.org>
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
Tested-by: Sumit Gupta <sumitg@nvidia.com>
Link: https://patch.msgid.link/20260916162805.1039247-17-christian.loehle@arm.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kernel/topology.c | 12 +++++++++++-
arch/x86/kernel/acpi/cppc.c | 15 +++++++++++++++
drivers/acpi/cppc_acpi.c | 10 ++++++----
3 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index b8baba2811666..44305b997a026 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -470,6 +470,12 @@ static void amu_read_core_const_ctrs(void *val)
cpu_read_corecnt(&ctrs->corecnt);
}
+static bool cpc_ffh_reg_valid(const struct cpc_reg *reg)
+{
+ return reg->bit_width && reg->bit_width <= 64 &&
+ reg->bit_offset <= 64 - reg->bit_width;
+}
+
static u64 cpc_ffh_extract_bits(const struct cpc_reg *reg, u64 val)
{
val &= GENMASK_ULL(reg->bit_offset + reg->bit_width - 1,
@@ -506,7 +512,8 @@ int cpc_read_ffh_fb_ctrs(int cpu, struct cpc_reg *reg1, u64 *val1,
struct amu_ffh_ctrs ctrs;
int ret;
- if (!is_amu_ctr_reg(reg1) || !is_amu_ctr_reg(reg2))
+ if (!is_amu_ctr_reg(reg1) || !is_amu_ctr_reg(reg2) ||
+ !cpc_ffh_reg_valid(reg1) || !cpc_ffh_reg_valid(reg2))
return -EINVAL;
ret = counters_read_on_cpu(cpu, amu_read_core_const_ctrs, &ctrs);
@@ -530,6 +537,9 @@ int cpc_read_ffh(int cpu, struct cpc_reg *reg, u64 *val)
{
int ret = -EOPNOTSUPP;
+ if (!cpc_ffh_reg_valid(reg))
+ return -EINVAL;
+
switch ((u64)reg->address) {
case CPC_FFH_CTR_CORE:
ret = counters_read_on_cpu(cpu, cpu_read_corecnt, val);
diff --git a/arch/x86/kernel/acpi/cppc.c b/arch/x86/kernel/acpi/cppc.c
index bbade0da5130f..174b734e82614 100644
--- a/arch/x86/kernel/acpi/cppc.c
+++ b/arch/x86/kernel/acpi/cppc.c
@@ -6,6 +6,8 @@
#include <linux/bitfield.h>
+#include <linux/limits.h>
+
#include <acpi/cppc_acpi.h>
#include <asm/msr.h>
#include <asm/processor.h>
@@ -45,10 +47,20 @@ bool cpc_ffh_supported(void)
return true;
}
+static bool cpc_ffh_reg_valid(const struct cpc_reg *reg)
+{
+ return reg->address <= U32_MAX && reg->bit_width &&
+ reg->bit_width <= 64 &&
+ reg->bit_offset <= 64 - reg->bit_width;
+}
+
int cpc_read_ffh(int cpunum, struct cpc_reg *reg, u64 *val)
{
int err;
+ if (!cpc_ffh_reg_valid(reg))
+ return -EINVAL;
+
err = rdmsrq_safe_on_cpu(cpunum, reg->address, val);
if (!err) {
u64 mask = GENMASK_ULL(reg->bit_offset + reg->bit_width - 1,
@@ -65,6 +77,9 @@ int cpc_write_ffh(int cpunum, struct cpc_reg *reg, u64 val)
u64 rd_val;
int err;
+ if (!cpc_ffh_reg_valid(reg))
+ return -EINVAL;
+
err = rdmsrq_safe_on_cpu(cpunum, reg->address, &rd_val);
if (!err) {
u64 mask = GENMASK_ULL(reg->bit_offset + reg->bit_width - 1,
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index fef54fcd00b78..dc9e1c1fb071e 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -1133,6 +1133,9 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val)
}
*val = 0;
+ if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE)
+ return cpc_read_ffh(cpu, reg, val);
+
size = GET_BIT_WIDTH(reg);
if (IS_ENABLED(CONFIG_HAS_IOPORT) &&
@@ -1160,8 +1163,6 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val)
}
else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
vaddr = reg_res->sys_mem_vaddr;
- else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE)
- return cpc_read_ffh(cpu, reg, val);
else
return acpi_os_read_memory((acpi_physical_address)reg->address,
val, size);
@@ -1208,6 +1209,9 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
unsigned long flags;
bool locked = false;
+ if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE)
+ return cpc_write_ffh(cpu, reg, val);
+
size = GET_BIT_WIDTH(reg);
if (IS_ENABLED(CONFIG_HAS_IOPORT) &&
@@ -1233,8 +1237,6 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
}
else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
vaddr = reg_res->sys_mem_vaddr;
- else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE)
- return cpc_write_ffh(cpu, reg, val);
else
return acpi_os_write_memory((acpi_physical_address)reg->address,
val, size);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 035/507] ACPI: CPPC: Accept requests to retain immutable autonomous selection
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (33 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 034/507] ACPI: CPPC: Validate FFH register fields before hardware access Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 036/507] xfs: reinitialize dquot block if non-first dquot cant load Greg Kroah-Hartman
` (471 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Loehle, Sumit Gupta,
Rafael J. Wysocki, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Loehle <christian.loehle@arm.com>
commit 4bcc60d326c5acaa28c5913259decb22a33a83a1 upstream.
ACPI permits Autonomous Selection Enable to be Integer 1 when the platform
always selects performance autonomously. cppc_get_auto_sel() returns that
value, but cppc_set_auto_sel() rejects the Integer even when asked to keep
autonomous selection enabled. AMD shared-memory initialization consequently
fails in active or guided mode after successfully reading the capability.
Accept a request to keep this immutable field enabled without issuing a
register access. Expose the immutable encoding to callers, separately from
the current value of a writable register.
Before an AMD shared-memory transition to passive mode, reject immutable
autonomous selection on any present CPU. Otherwise a guided-to-passive
transition ignores the failed disable and reports the wrong mode, while
active-to-passive unregisters the working driver before passive policy
initialization fails. Check under the driver mode lock before invoking
either transition, including known offline CPUs.
Serialize this capability query with descriptor publication and removal.
ACPI processor removal drops the descriptor before taking the CPU hotplug
write lock, so the caller's cpus_read_lock() alone cannot protect the
lookup. Unpublish under the same mutex before releasing a descriptor,
including when adding its kobject fails.
The cppc-cpufreq auto_select attribute can also request one while
autonomous selection is already enabled. If the subsequent bounds update
fails, its rollback requests zero and clears the cached mode regardless
of the previous state. For an immutable field the disable request fails,
leaving the cached mode wrong. Save and restore the previous mode instead.
This also avoids disabling an already-enabled writable control on that
error path.
Fixes: c984f5d5d45b ("ACPI: CPPC: Add auto select register read/write support")
Fixes: ea3db45ae476 ("cpufreq: cppc: Update MIN_PERF/MAX_PERF in target callbacks")
Cc: All applicable <stable@vger.kernel.org>
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
Tested-by: Sumit Gupta <sumitg@nvidia.com>
Link: https://patch.msgid.link/20260916162805.1039247-19-christian.loehle@arm.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/acpi/cppc_acpi.c | 48 ++++++++++++++++++++++++++++++++--
drivers/cpufreq/amd-pstate.c | 25 ++++++++++++++----
drivers/cpufreq/cppc_cpufreq.c | 5 ++--
include/acpi/cppc_acpi.h | 6 +++++
4 files changed, 75 insertions(+), 9 deletions(-)
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index dc9e1c1fb071e..9079ddf2ead1c 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -36,6 +36,7 @@
#include <linux/delay.h>
#include <linux/iopoll.h>
#include <linux/ktime.h>
+#include <linux/mutex.h>
#include <linux/rwsem.h>
#include <linux/wait.h>
#include <linux/topology.h>
@@ -93,6 +94,16 @@ static DEFINE_PER_CPU(int, cpu_pcc_subspace_idx);
*/
static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr);
+/* Protect immutable capability queries against descriptor removal. */
+static DEFINE_MUTEX(cpc_desc_lock);
+
+static void cpc_set_desc(unsigned int cpu, struct cpc_desc *desc)
+{
+ mutex_lock(&cpc_desc_lock);
+ per_cpu(cpc_desc_ptr, cpu) = desc;
+ mutex_unlock(&cpc_desc_lock);
+}
+
/* pcc mapped address + header size + offset within PCC subspace */
#define GET_PCC_VADDR(offs, pcc_ss_id) (pcc_data[pcc_ss_id]->pcc_channel->shmem + \
0x8 + (offs))
@@ -999,12 +1010,12 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
}
/* Plug PSD data into this CPU's CPC descriptor. */
- per_cpu(cpc_desc_ptr, pr->id) = cpc_ptr;
+ cpc_set_desc(pr->id, cpc_ptr);
ret = kobject_init_and_add(&cpc_ptr->kobj, &cppc_ktype, &cpu_dev->kobj,
"acpi_cppc");
if (ret) {
- per_cpu(cpc_desc_ptr, pr->id) = NULL;
+ cpc_set_desc(pr->id, NULL);
kobject_put(&cpc_ptr->kobj);
goto out_free;
}
@@ -1056,6 +1067,8 @@ void acpi_cppc_processor_exit(struct acpi_processor *pr)
if (!cpc_ptr)
return;
+ cpc_set_desc(pr->id, NULL);
+
/* Free all the mapped sys mem areas for this CPU */
for (i = 2; i < cpc_ptr->num_entries; i++) {
addr = cpc_ptr->cpc_regs[i-2].sys_mem_vaddr;
@@ -1402,6 +1415,11 @@ static int cppc_set_reg_val(int cpu, enum cppc_regs reg_idx, u64 val)
reg = &cpc_desc->cpc_regs[reg_idx];
+ /* Integer 1 describes autonomous selection that is always enabled. */
+ if (reg_idx == AUTO_SEL_ENABLE && reg->type == ACPI_TYPE_INTEGER &&
+ reg->cpc_entry.int_value == 1)
+ return val == 1 ? 0 : -EOPNOTSUPP;
+
/* if a register is writeable, it must be a buffer and not null */
if ((reg->type != ACPI_TYPE_BUFFER) || IS_NULL_REG(®->cpc_entry.reg)) {
pr_debug("CPC register is not supported\n");
@@ -1926,6 +1944,32 @@ int cppc_get_auto_sel(int cpu, bool *enable)
}
EXPORT_SYMBOL_GPL(cppc_get_auto_sel);
+/**
+ * cppc_auto_sel_is_immutable - Check for always-enabled autonomous selection.
+ * @cpu: CPU whose _CPC descriptor to check.
+ *
+ * Context: Process context.
+ * Return: true for Integer 1, false for a register or an absent descriptor.
+ */
+bool cppc_auto_sel_is_immutable(int cpu)
+{
+ struct cpc_desc *cpc_desc;
+ struct cpc_register_resource *reg;
+ bool immutable = false;
+
+ mutex_lock(&cpc_desc_lock);
+ cpc_desc = per_cpu(cpc_desc_ptr, cpu);
+ if (cpc_desc) {
+ reg = &cpc_desc->cpc_regs[AUTO_SEL_ENABLE];
+ immutable = reg->type == ACPI_TYPE_INTEGER &&
+ reg->cpc_entry.int_value == 1;
+ }
+ mutex_unlock(&cpc_desc_lock);
+
+ return immutable;
+}
+EXPORT_SYMBOL_GPL(cppc_auto_sel_is_immutable);
+
/**
* cppc_set_auto_sel - Write autonomous selection register.
* @cpu : CPU to which to write register.
diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c
index 6e00d200920aa..28b9d4d062b98 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -1796,7 +1796,7 @@ EXPORT_SYMBOL_FOR_PSTATE_UT(amd_pstate_get_status);
int amd_pstate_update_status(const char *buf, size_t size)
{
- int mode_idx;
+ int cpu, mode_idx, ret = 0;
if (size > strlen("passive") || size < strlen("active"))
return -EINVAL;
@@ -1805,12 +1805,27 @@ int amd_pstate_update_status(const char *buf, size_t size)
if (mode_idx < 0)
return mode_idx;
- if (mode_state_machine[cppc_state][mode_idx]) {
- guard(mutex)(&amd_pstate_driver_lock);
- return mode_state_machine[cppc_state][mode_idx](mode_idx);
+ guard(mutex)(&amd_pstate_driver_lock);
+
+ if (!mode_state_machine[cppc_state][mode_idx])
+ return 0;
+
+ if (mode_idx == AMD_PSTATE_PASSIVE &&
+ !cpu_feature_enabled(X86_FEATURE_CPPC)) {
+ cpus_read_lock();
+ /* Check offline CPUs too, before changing or removing the driver. */
+ for_each_present_cpu(cpu) {
+ if (cppc_auto_sel_is_immutable(cpu)) {
+ ret = -EOPNOTSUPP;
+ break;
+ }
+ }
+ cpus_read_unlock();
+ if (ret)
+ return ret;
}
- return 0;
+ return mode_state_machine[cppc_state][mode_idx](mode_idx);
}
EXPORT_SYMBOL_FOR_PSTATE_UT(amd_pstate_update_status);
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index 5f20c4a7ba2f2..951db2a6afb58 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -890,6 +890,7 @@ static ssize_t store_auto_select(struct cpufreq_policy *policy,
const char *buf, size_t count)
{
struct cppc_cpudata *cpu_data = policy->driver_data;
+ bool old_auto_sel = cpu_data->perf_ctrls.auto_sel;
bool val;
int ret;
@@ -918,8 +919,8 @@ static ssize_t store_auto_select(struct cpufreq_policy *policy,
if (ret) {
cpu_data->perf_ctrls.min_perf = old_min_perf;
cpu_data->perf_ctrls.max_perf = old_max_perf;
- cppc_set_auto_sel(policy->cpu, false);
- cpu_data->perf_ctrls.auto_sel = false;
+ cppc_set_auto_sel(policy->cpu, old_auto_sel);
+ cpu_data->perf_ctrls.auto_sel = old_auto_sel;
return ret;
}
}
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
index 94a6277edab27..a32b09ec33948 100644
--- a/include/acpi/cppc_acpi.h
+++ b/include/acpi/cppc_acpi.h
@@ -188,6 +188,7 @@ extern int cppc_set_epp(int cpu, u64 epp_val);
extern int cppc_get_auto_act_window(int cpu, u64 *auto_act_window);
extern int cppc_set_auto_act_window(int cpu, u64 auto_act_window);
extern int cppc_get_auto_sel(int cpu, bool *enable);
+bool cppc_auto_sel_is_immutable(int cpu);
extern int cppc_set_auto_sel(int cpu, bool enable);
extern int cppc_get_perf_limited(int cpu, u64 *perf_limited);
extern int cppc_set_perf_limited(int cpu, u64 bits_to_clear);
@@ -289,6 +290,11 @@ static inline int cppc_get_auto_sel(int cpu, bool *enable)
{
return -EOPNOTSUPP;
}
+static inline bool cppc_auto_sel_is_immutable(int cpu)
+{
+ return false;
+}
+
static inline int cppc_set_auto_sel(int cpu, bool enable)
{
return -EOPNOTSUPP;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 036/507] xfs: reinitialize dquot block if non-first dquot cant load
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (34 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 035/507] ACPI: CPPC: Accept requests to retain immutable autonomous selection Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 037/507] xfs: forcibly reset quota timers when upgrading to bigtime during repair Greg Kroah-Hartman
` (470 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
[ Upstream commit faa9aa9e846332aaad78096a2cebfeafe68a7776 ]
LOLLM noticed that the early exit logic in xrep_quota_block is defective
because it only looks in the first ondisk dquot for corruption that
would prevent dquots from loading. We need to scan all the dquots in
the block, not just the first one.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Stable-dep-of: 780212c8d810 ("xfs: forcibly reset quota timers when upgrading to bigtime during repair")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/scrub/quota_repair.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/fs/xfs/scrub/quota_repair.c b/fs/xfs/scrub/quota_repair.c
index b4f33f432b12a..b6a270010b8b6 100644
--- a/fs/xfs/scrub/quota_repair.c
+++ b/fs/xfs/scrub/quota_repair.c
@@ -297,7 +297,6 @@ xrep_quota_block(
xfs_dqid_t id)
{
struct xfs_dqblk *dqblk;
- struct xfs_disk_dquot *ddq;
struct xfs_quotainfo *qi = sc->mp->m_quotainfo;
struct xfs_def_quota *defq = xfs_get_defquota(qi, dqtype);
struct xfs_buf *bp = NULL;
@@ -319,14 +318,21 @@ xrep_quota_block(
break;
case 0:
dqblk = bp->b_addr;
- ddq = &dqblk[0].dd_diskdq;
+ error = 0;
/*
* If there's nothing that would impede a dqiterate, we're
* done.
*/
- if ((ddq->d_type & XFS_DQTYPE_REC_MASK) == dqtype &&
- id == be32_to_cpu(ddq->d_id)) {
+ for (i = 0; i < qi->qi_dqperchunk; i++, dqblk++) {
+ struct xfs_disk_dquot *ddq = &dqblk->dd_diskdq;
+
+ if ((ddq->d_type & XFS_DQTYPE_REC_MASK) != dqtype ||
+ id + i != be32_to_cpu(ddq->d_id))
+ error++;
+ }
+
+ if (!error) {
xfs_trans_brelse(sc->tp, bp);
return 0;
}
@@ -339,7 +345,7 @@ xrep_quota_block(
dqblk = bp->b_addr;
bp->b_ops = &xfs_dquot_buf_ops;
for (i = 0; i < qi->qi_dqperchunk; i++, dqblk++) {
- ddq = &dqblk->dd_diskdq;
+ struct xfs_disk_dquot *ddq = &dqblk->dd_diskdq;
trace_xrep_disk_dquot(sc->mp, dqtype, id + i);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 037/507] xfs: forcibly reset quota timers when upgrading to bigtime during repair
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (35 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 036/507] xfs: reinitialize dquot block if non-first dquot cant load Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 038/507] nfsd: shorten extack string returned with dodgy listener Greg Kroah-Hartman
` (469 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
[ Upstream commit 780212c8d8105eadb5f56b4c7aafb94937755582 ]
If we decide to upgrade a dquot to BIGTIME as part of repairing it, we
should zero out the timer fields so that they are re-evaluated and reset
in bigtime format instead of letting through whatever was in there
before.
Cc: stable@vger.kernel.org # v6.8
Fixes: a5b91555403e3a ("xfs: repair quotas")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/scrub/quota_repair.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/scrub/quota_repair.c b/fs/xfs/scrub/quota_repair.c
index b6a270010b8b6..3be56d73dd665 100644
--- a/fs/xfs/scrub/quota_repair.c
+++ b/fs/xfs/scrub/quota_repair.c
@@ -346,6 +346,8 @@ xrep_quota_block(
bp->b_ops = &xfs_dquot_buf_ops;
for (i = 0; i < qi->qi_dqperchunk; i++, dqblk++) {
struct xfs_disk_dquot *ddq = &dqblk->dd_diskdq;
+ bool was_bigtime =
+ !!(ddq->d_type & XFS_DQTYPE_BIGTIME);
trace_xrep_disk_dquot(sc->mp, dqtype, id + i);
@@ -354,8 +356,21 @@ xrep_quota_block(
ddq->d_type = dqtype;
ddq->d_id = cpu_to_be32(id + i);
- if (xfs_has_bigtime(sc->mp) && ddq->d_id)
+ if (xfs_has_bigtime(sc->mp) && ddq->d_id) {
+ /*
+ * If something was broken with this dquot and it was a
+ * non-bigtime dquot, we'll grant everyone a fresh
+ * grace period by zeroing the timer field rather than
+ * try to interpret what might be garbage.
+ */
+ if (!was_bigtime) {
+ ddq->d_btimer = 0;
+ ddq->d_itimer = 0;
+ ddq->d_rtbtimer = 0;
+ }
+
ddq->d_type |= XFS_DQTYPE_BIGTIME;
+ }
xrep_quota_fix_timer(sc->mp, ddq, ddq->d_blk_softlimit,
ddq->d_bcount, &ddq->d_btimer,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 038/507] nfsd: shorten extack string returned with dodgy listener
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (36 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 037/507] xfs: forcibly reset quota timers when upgrading to bigtime during repair Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 039/507] cpufreq: CPPC: Select the frequency-invariance callback per CPU Greg Kroah-Hartman
` (468 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <jlayton@kernel.org>
[ Upstream commit 8d7859d165dbdf6e8d77b76500fc990f26c8310d ]
The kernel test robot reports:
>> fs/nfsd/nfsctl.c:2253:4: warning: 'snprintf' will always be truncated; specified size is 80, but format string expands to at least 94 [-Wformat-truncation]
Shorten the extack string in this case so that it will fit in 80 chars.
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260904-nfsd-nl-hang-v1-1-8c8035b6294d@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfsctl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index d5effeae4b792..3a5d0f5cc0fc9 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -2248,7 +2248,7 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info)
bad_xprt);
else if (skipped_rpcb)
NL_SET_ERR_MSG_FMT(info->extack,
- "cannot create %s listener; rpcbind did not answer earlier, so some listeners are not registered",
+ "cannot create %s listener; rpcbind did not answer earlier",
bad_xprt);
else
NL_SET_ERR_MSG_FMT(info->extack,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 039/507] cpufreq: CPPC: Select the frequency-invariance callback per CPU
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (37 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 038/507] nfsd: shorten extack string returned with dodgy listener Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 040/507] media: uvcvideo: Add autosuspend quirk for AVerMedia Live Gamer HD 2 Greg Kroah-Hartman
` (467 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Loehle, Sumit Gupta,
Rafael J. Wysocki, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Loehle <christian.loehle@arm.com>
commit 21e018235d99bc86249b034c06646df8757b2852 upstream.
cppc_cpufreq_cpu_fie_init() initializes deferred work only for CPUs whose
feedback counters use PCC. However, if any CPU in a shared policy uses PCC,
it installs the PCC tick callback for the entire policy. With FIE enabled,
a non-PCC CPU then queues an uninitialized irq_work and can call a NULL
function pointer when that work runs.
Choose the frequency-invariance callback separately for each CPU using
the recorded work-initialization state. Processor removal can unpublish
the CPC descriptor before callback registration, so querying its counter
transport again can incorrectly select direct reads for a PCC CPU.
Register the callbacks after all counter initialization has completed, so
a failed initial read for an online CPU cannot leave a partially
registered policy. PCC CPUs use their initialized deferred work, while
non-PCC CPUs read their own counters directly from the tick.
Fixes: 997c021abc6e ("cpufreq: CPPC: Update FIE arch_freq_scale in ticks for non-PCC regs")
Cc: All applicable <stable@vger.kernel.org>
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
Tested-by: Sumit Gupta <sumitg@nvidia.com>
Link: https://patch.msgid.link/20260916162805.1039247-20-christian.loehle@arm.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Christian Loehle <christian.loehle@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/acpi/cppc_acpi.c | 3 +++
drivers/cpufreq/cppc_cpufreq.c | 21 +++++++++++++++------
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index 9079ddf2ead1c..8aa0ce556863a 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -1633,6 +1633,9 @@ bool cppc_perf_ctrs_in_pcc_cpu(unsigned int cpu)
{
struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
+ if (!cpc_desc)
+ return false;
+
return CPC_IN_PCC(&cpc_desc->cpc_regs[DELIVERED_CTR]) ||
CPC_IN_PCC(&cpc_desc->cpc_regs[REFERENCE_CTR]) ||
CPC_IN_PCC(&cpc_desc->cpc_regs[CTR_WRAP_TIME]);
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c
index 951db2a6afb58..782b97acf5dcd 100644
--- a/drivers/cpufreq/cppc_cpufreq.c
+++ b/drivers/cpufreq/cppc_cpufreq.c
@@ -42,6 +42,7 @@ MODULE_PARM_DESC(fie_disabled, "Disable Frequency Invariance Engine (FIE)");
/* Frequency invariance support */
struct cppc_freq_invariance {
int cpu;
+ bool pcc_work_initialized;
struct irq_work irq_work;
struct kthread_work work;
struct cppc_perf_fb_ctrs prev_perf_fb_ctrs;
@@ -152,7 +153,7 @@ static struct scale_freq_data cppc_sftd_pcc = {
static void cppc_cpufreq_cpu_fie_init(struct cpufreq_policy *policy)
{
- struct scale_freq_data *sftd = &cppc_sftd;
+ struct scale_freq_data *sftd;
struct cppc_freq_invariance *cppc_fi;
int cpu, ret;
@@ -169,7 +170,7 @@ static void cppc_cpufreq_cpu_fie_init(struct cpufreq_policy *policy)
kthread_init_work(&cppc_fi->work, cppc_scale_freq_workfn);
init_irq_work(&cppc_fi->irq_work, cppc_irq_work);
- sftd = &cppc_sftd_pcc;
+ cppc_fi->pcc_work_initialized = true;
}
ret = cppc_get_perf_ctrs(cpu, &cppc_fi->prev_perf_fb_ctrs);
@@ -185,8 +186,15 @@ static void cppc_cpufreq_cpu_fie_init(struct cpufreq_policy *policy)
}
}
- /* Register for freq-invariance */
- topology_set_scale_freq_source(sftd, policy->cpus);
+ /* A shared policy may contain both PCC and non-PCC counters. */
+ for_each_cpu(cpu, policy->cpus) {
+ cppc_fi = &per_cpu(cppc_freq_inv, cpu);
+ if (cppc_fi->pcc_work_initialized)
+ sftd = &cppc_sftd_pcc;
+ else
+ sftd = &cppc_sftd;
+ topology_set_scale_freq_source(sftd, cpumask_of(cpu));
+ }
}
/*
@@ -209,11 +217,12 @@ static void cppc_cpufreq_cpu_fie_exit(struct cpufreq_policy *policy)
topology_clear_scale_freq_source(SCALE_FREQ_SOURCE_CPPC, policy->related_cpus);
for_each_cpu(cpu, policy->related_cpus) {
- if (!cppc_perf_ctrs_in_pcc_cpu(cpu))
- continue;
cppc_fi = &per_cpu(cppc_freq_inv, cpu);
+ if (!cppc_fi->pcc_work_initialized)
+ continue;
irq_work_sync(&cppc_fi->irq_work);
kthread_cancel_work_sync(&cppc_fi->work);
+ cppc_fi->pcc_work_initialized = false;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 040/507] media: uvcvideo: Add autosuspend quirk for AVerMedia Live Gamer HD 2
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (38 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 039/507] cpufreq: CPPC: Select the frequency-invariance callback per CPU Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 041/507] media: uvcvideo: Force UVC version for Avermedia GC515 Greg Kroah-Hartman
` (466 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sean Baggaley, Ricardo Ribalda,
Hans de Goede, Laurent Pinchart, Hans Verkuil, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <ribalda@chromium.org>
[ Upstream commit b79251c881bb39f70c6f6fb30ad5d454b78c9f4a ]
A user has reported that this device gets stuck in a loop where every
few seconds it will turn off and turn back on, causing audio devices
to disappear and reappear, its LED to flash, spamming dmesg, etc.
This only happens when not in use; everything is fine when the video
device is actually being used.
They also reported that using the AUTOSUSPEND quirk via module parameters
fixes the issue.
Add the device to the quirk list.
ID 07ca:1570 AVerMedia Technologies, Inc. AVerMedia USB Device
Negotiated speed: High Speed (480Mbps)
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.10
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 [unknown]
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x07ca AVerMedia Technologies, Inc.
idProduct 0x1570 AVerMedia USB Device
bcdDevice 1.00
iManufacturer 6 AVerMedia
iProduct 7 AVerMedia USB Device
iSerial 3 53106326013650
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x01d6
bNumInterfaces 4
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xa0
(Bus Powered)
Remote Wakeup
MaxPower 150mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 2
bFunctionClass 14 Video
bFunctionSubClass 3 Video Interface Collection
bFunctionProtocol 0
iFunction 8 AVerMedia Live Gamer HD 2
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 14 Video
bInterfaceSubClass 1 Video Control
bInterfaceProtocol 0
iInterface 8 AVerMedia Live Gamer HD 2
VideoControl Interface Descriptor:
bLength 13
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdUVC 1.00
wTotalLength 0x004d
dwClockFrequency 120.000000MHz
bInCollection 1
baInterfaceNr( 0) 1
VideoControl Interface Descriptor:
bLength 18
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Camera Sensor
bAssocTerminal 0
iTerminal 0
wObjectiveFocalLengthMin 0
wObjectiveFocalLengthMax 0
wOcularFocalLength 0
bControlSize 3
bmControls 0x00000000
VideoControl Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 5 (PROCESSING_UNIT)
Warning: Descriptor too short
bUnitID 3
bSourceID 1
wMaxMultiplier 0
bControlSize 2
bmControls 0x0000000f
Brightness
Contrast
Hue
Saturation
iProcessing 0
bmVideoStandards 0x09
None
SECAM - 625/50
VideoControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bSourceID 4
iTerminal 0
VideoControl Interface Descriptor:
bLength 28
bDescriptorType 36
bDescriptorSubtype 6 (EXTENSION_UNIT)
bUnitID 4
guidExtensionCode {c66d125b-0480-0844-8c26-b8363a84de63}
bNumControls 17
bNrInPins 1
baSourceID( 0) 3
bControlSize 3
bmControls( 0) 0x07
bmControls( 1) 0xfe
bmControls( 2) 0x01
iExtension 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 8 AVerMedia Live Gamer HD 2
VideoStreaming Interface Descriptor:
bLength 14
bDescriptorType 36
bDescriptorSubtype 1 (INPUT_HEADER)
bNumFormats 1
wTotalLength 0x00bd
bEndpointAddress 0x89 EP 9 IN
bmInfo 0
bTerminalLink 2
bStillCaptureMethod 0
bTriggerSupport 0
bTriggerUsage 0
bControlSize 1
bmaControls( 0) 0
VideoStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 6 (FORMAT_MJPEG)
bFormatIndex 1
bNumFrameDescriptors 5
bFlags 0
Fixed-size samples: No
bDefaultFrameIndex 1
bAspectRatioX 0
bAspectRatioY 0
bmInterlaceFlags 0x00
Interlaced stream or variable: No
Fields per frame: 1 fields
Field 1 first: No
Field pattern: Field 1 only
bCopyProtect 0
VideoStreaming Interface Descriptor:
bLength 34
bDescriptorType 36
bDescriptorSubtype 7 (FRAME_MJPEG)
bFrameIndex 1
bmCapabilities 0x00
Still image unsupported
wWidth 640
wHeight 480
dwMinBitRate 294617088
dwMaxBitRate 294912000
dwMaxVideoFrameBufferSize 614400
dwDefaultFrameInterval 166833
bFrameIntervalType 2
dwFrameInterval( 0) 166666
dwFrameInterval( 1) 166833
VideoStreaming Interface Descriptor:
bLength 34
bDescriptorType 36
bDescriptorSubtype 7 (FRAME_MJPEG)
bFrameIndex 2
bmCapabilities 0x00
Still image unsupported
wWidth 720
wHeight 480
dwMinBitRate 331444224
dwMaxBitRate 331776000
dwMaxVideoFrameBufferSize 691200
dwDefaultFrameInterval 166833
bFrameIntervalType 2
dwFrameInterval( 0) 166666
dwFrameInterval( 1) 166833
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 7 (FRAME_MJPEG)
bFrameIndex 3
bmCapabilities 0x00
Still image unsupported
wWidth 720
wHeight 576
dwMinBitRate 331776000
dwMaxBitRate 331776000
dwMaxVideoFrameBufferSize 829440
dwDefaultFrameInterval 200000
bFrameIntervalType 1
dwFrameInterval( 0) 200000
VideoStreaming Interface Descriptor:
bLength 38
bDescriptorType 36
bDescriptorSubtype 7 (FRAME_MJPEG)
bFrameIndex 4
bmCapabilities 0x00
Still image unsupported
wWidth 1280
wHeight 720
dwMinBitRate 737280000
dwMaxBitRate 884736000
dwMaxVideoFrameBufferSize 1843200
dwDefaultFrameInterval 166666
bFrameIntervalType 3
dwFrameInterval( 0) 166666
dwFrameInterval( 1) 166833
dwFrameInterval( 2) 200000
VideoStreaming Interface Descriptor:
bLength 46
bDescriptorType 36
bDescriptorSubtype 7 (FRAME_MJPEG)
bFrameIndex 5
bmCapabilities 0x00
Still image unsupported
wWidth 1920
wHeight 1080
dwMinBitRate 994332672
dwMaxBitRate 1990656000
dwMaxVideoFrameBufferSize 4147200
dwDefaultFrameInterval 166666
bFrameIntervalType 5
dwFrameInterval( 0) 166666
dwFrameInterval( 1) 166833
dwFrameInterval( 2) 200000
dwFrameInterval( 3) 333333
dwFrameInterval( 4) 333667
VideoStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 13 (COLORFORMAT)
bColorPrimaries 1 (BT.709,sRGB)
bTransferCharacteristics 1 (BT.709)
bMatrixCoefficients 4 (SMPTE 170M (BT.601))
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 0
iInterface 8 AVerMedia Live Gamer HD 2
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x89 EP 9 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x1400 3x 1024 bytes
bInterval 1
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 2
bInterfaceCount 2
bFunctionClass 1 Audio
bFunctionSubClass 2 Streaming
bFunctionProtocol 0
iFunction 9 AVerMedia Live Gamer HD 2
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 9 AVerMedia Live Gamer HD 2
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 0x003a
bInCollection 1
baInterfaceNr(0) 3
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0602 Digital Audio Interface
bAssocTerminal 0
bNrChannels 1
wChannelConfig 0x0000
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 5
wTerminalType 0x0603 Line Connector
bAssocTerminal 0
bNrChannels 1
wChannelConfig 0x0000
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bSourceID 3
iTerminal 0
AudioControl Interface Descriptor:
bLength 8
bDescriptorType 36
bDescriptorSubtype 6 (FEATURE_UNIT)
bUnitID 3
bSourceID 4
bControlSize 1
bmaControls(0) 0x01
Mute Control
iFeature 0
AudioControl Interface Descriptor:
bLength 8
bDescriptorType 36
bDescriptorSubtype 5 (SELECTOR_UNIT)
bUnitID 4
bNrInPins 2
baSourceID(0) 1
baSourceID(1) 5
iSelector 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 9 AVerMedia Live Gamer HD 2
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 9 AVerMedia Live Gamer HD 2
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 2
bDelay 1 frames
wFormatTag 0x0001 PCM
AudioStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 2
bSubframeSize 2
bBitResolution 16
bSamFreqType 1 Discrete
tSamFreq[ 0] 48000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x8a EP 10 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x00c0 1x 192 bytes
bInterval 4
bRefresh 0
bSynchAddress 0
AudioStreaming Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x01
Sampling Frequency
bLockDelayUnits 0 Undefined
wLockDelay 0x0000
Binary Object Store Descriptor:
bLength 5
bDescriptorType 15
wTotalLength 0x0016
bNumDeviceCaps 2
USB 2.0 Extension Device Capability:
bLength 7
bDescriptorType 16
bDevCapabilityType 2
bmAttributes 0x00000006
BESL Link Power Management (LPM) Supported
SuperSpeed USB Device Capability:
bLength 10
bDescriptorType 16
bDevCapabilityType 3
bmAttributes 0x00
wSpeedsSupported 0x000e
Device can operate at Full Speed (12Mbps)
Device can operate at High Speed (480Mbps)
Device can operate at SuperSpeed (5Gbps)
bFunctionalitySupport 1
Lowest fully-functional device speed is Full Speed (12Mbps)
bU1DevExitLat 4 micro seconds
bU2DevExitLat 4 micro seconds
Device Status: 0x0000
(Bus Powered)
Reported-by: Sean Baggaley <me@drinkybird.net>
Closes: https://lore.kernel.org/linux-media/5ef59031-0853-41a7-8d11-c345fe535daf@drinkybird.net/
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Link: https://patch.msgid.link/20260730-uvc-avermedia-v1-1-7272dd394d83@chromium.org
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index e289cc71ba986..30adde5a8bc93 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -2851,6 +2851,15 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
+ /* AVerMedia Live Gamer HD 2 capture card */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x07ca,
+ .idProduct = 0x1570,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_DISABLE_AUTOSUSPEND) },
/* ViMicro Vega */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 041/507] media: uvcvideo: Force UVC version for Avermedia GC515
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (39 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 040/507] media: uvcvideo: Add autosuspend quirk for AVerMedia Live Gamer HD 2 Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 042/507] mm/damon/sysfs-schemes: read sysfs_filter->sz_range only once Greg Kroah-Hartman
` (465 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Edwin Gatier, Laurent Pinchart,
Hans de Goede, Ricardo Ribalda, Hans Verkuil, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda <ribalda@chromium.org>
[ Upstream commit 65444446f0c595c0e250368cde88735b59ccc446 ]
The device announces itself as UVC 1.5, but it only accepts UVC 1.1
controls.
The camera can probably be handled by the automatic uvc_version handler,
but it is more correct to add a quirk and keep some tracking of what
vendors are more or less compliant. Also it might be more robust if we
introduce more UVC version-dependent code.
Bus 003 Device 021: ID 07ca:1515 AVerMedia Technologies, Inc. X'tra Go GC515
Negotiated speed: High Speed (480Mbps)
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 [unknown]
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x07ca AVerMedia Technologies, Inc.
idProduct 0x1515 X'tra Go GC515
bcdDevice 0.10
iManufacturer 1 AVerMedia
iProduct 2 X'tra Go GC515
iSerial 3 5313180000221
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x03fd
bNumInterfaces 4
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 500mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 2
bFunctionClass 14 Video
bFunctionSubClass 3 Video Interface Collection
bFunctionProtocol 0
iFunction 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 1 Video Control
bInterfaceProtocol 1
iInterface 0
VideoControl Interface Descriptor:
bLength 13
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdUVC 1.50
wTotalLength 0x0059
dwClockFrequency 30.000000MHz
bInCollection 1
baInterfaceNr( 0) 1
VideoControl Interface Descriptor:
bLength 18
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Camera Sensor
bAssocTerminal 0
iTerminal 0
wObjectiveFocalLengthMin 0
wObjectiveFocalLengthMax 0
wOcularFocalLength 0
bControlSize 3
bmControls 0x00000000
VideoControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bSourceID 4
iTerminal 0
VideoControl Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 4 (SELECTOR_UNIT)
bUnitID 3
bNrInPins 1
baSource( 0) 1
iSelector 0
VideoControl Interface Descriptor:
bLength 13
bDescriptorType 36
bDescriptorSubtype 5 (PROCESSING_UNIT)
bUnitID 4
bSourceID 3
wMaxMultiplier 0
bControlSize 3
bmControls 0x00000000
iProcessing 0
bmVideoStandards 0x00
VideoControl Interface Descriptor:
bLength 29
bDescriptorType 36
bDescriptorSubtype 6 (EXTENSION_UNIT)
bUnitID 5
guidExtensionCode {55be8e1c-2fdb-4f7a-bd8d-b9b1108d20c3}
bNumControls 24
bNrInPins 1
baSourceID( 0) 4
bControlSize 4
bmControls( 0) 0xff
bmControls( 1) 0xff
bmControls( 2) 0xff
bmControls( 3) 0x00
iExtension 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x85 EP 5 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
VideoControl Endpoint Descriptor:
bLength 5
bDescriptorType 37
bDescriptorSubtype 3 (EP_INTERRUPT)
wMaxTransferSize 64
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 1
iInterface 0
VideoStreaming Interface Descriptor:
bLength 16
bDescriptorType 36
bDescriptorSubtype 1 (INPUT_HEADER)
bNumFormats 3
wTotalLength 0x0303
bEndpointAddress 0x81 EP 1 IN
bmInfo 0
bTerminalLink 2
bStillCaptureMethod 1
bTriggerSupport 0
bTriggerUsage 0
bControlSize 1
bmaControls( 0) 4
bmaControls( 1) 4
bmaControls( 2) 0
VideoStreaming Interface Descriptor:
bLength 28
bDescriptorType 36
bDescriptorSubtype 16 (FORMAT_FRAME_BASED)
bFormatIndex 1
bNumFrameDescriptors 8
guidFormat {34363248-0000-0010-8000-00aa00389b71}
bBitsPerPixel 24
bDefaultFrameIndex 1
bAspectRatioX 0
bAspectRatioY 0
bmInterlaceFlags 0x00
Interlaced stream or variable: No
Fields per frame: 2 fields
Field 1 first: No
Field pattern: Field 1 only
bCopyProtect 1
bVariableSize 1
VideoStreaming Interface Descriptor:
bLength 62
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 1
bmCapabilities 0x01
Still image supported
wWidth 1920
wHeight 1080
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 166666
bFrameIntervalType 9
dwBytesPerLine 0
dwFrameInterval( 0) 83333
dwFrameInterval( 1) 83416
dwFrameInterval( 2) 166666
dwFrameInterval( 3) 166833
dwFrameInterval( 4) 200000
dwFrameInterval( 5) 333333
dwFrameInterval( 6) 333667
dwFrameInterval( 7) 400000
dwFrameInterval( 8) 416666
VideoStreaming Interface Descriptor:
bLength 42
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 2
bmCapabilities 0x01
Still image supported
wWidth 3840
wHeight 2160
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 333333
bFrameIntervalType 4
dwBytesPerLine 0
dwFrameInterval( 0) 333333
dwFrameInterval( 1) 333667
dwFrameInterval( 2) 400000
dwFrameInterval( 3) 416666
VideoStreaming Interface Descriptor:
bLength 34
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 3
bmCapabilities 0x01
Still image supported
wWidth 2560
wHeight 1440
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 166666
bFrameIntervalType 2
dwBytesPerLine 0
dwFrameInterval( 0) 166666
dwFrameInterval( 1) 166833
VideoStreaming Interface Descriptor:
bLength 34
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 4
bmCapabilities 0x01
Still image supported
wWidth 1280
wHeight 800
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 166666
bFrameIntervalType 2
dwBytesPerLine 0
dwFrameInterval( 0) 166666
dwFrameInterval( 1) 166833
VideoStreaming Interface Descriptor:
bLength 38
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 5
bmCapabilities 0x01
Still image supported
wWidth 1280
wHeight 720
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 166666
bFrameIntervalType 3
dwBytesPerLine 0
dwFrameInterval( 0) 166666
dwFrameInterval( 1) 166833
dwFrameInterval( 2) 200000
VideoStreaming Interface Descriptor:
bLength 34
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 6
bmCapabilities 0x01
Still image supported
wWidth 720
wHeight 576
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 200000
bFrameIntervalType 2
dwBytesPerLine 0
dwFrameInterval( 0) 200000
dwFrameInterval( 1) 400000
VideoStreaming Interface Descriptor:
bLength 42
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 7
bmCapabilities 0x01
Still image supported
wWidth 720
wHeight 480
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 166666
bFrameIntervalType 4
dwBytesPerLine 0
dwFrameInterval( 0) 166666
dwFrameInterval( 1) 166833
dwFrameInterval( 2) 333333
dwFrameInterval( 3) 333667
VideoStreaming Interface Descriptor:
bLength 34
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 8
bmCapabilities 0x01
Still image supported
wWidth 640
wHeight 480
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 166666
bFrameIntervalType 2
dwBytesPerLine 0
dwFrameInterval( 0) 166666
dwFrameInterval( 1) 166833
VideoStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 13 (COLORFORMAT)
bColorPrimaries 0 (Unspecified)
bTransferCharacteristics 0 (Unspecified)
bMatrixCoefficients 0 (Unspecified)
VideoStreaming Interface Descriptor:
bLength 28
bDescriptorType 36
bDescriptorSubtype 16 (FORMAT_FRAME_BASED)
bFormatIndex 2
bNumFrameDescriptors 8
guidFormat {43564548-0000-0010-8000-00aa00389b71}
bBitsPerPixel 24
bDefaultFrameIndex 1
bAspectRatioX 0
bAspectRatioY 0
bmInterlaceFlags 0x00
Interlaced stream or variable: No
Fields per frame: 2 fields
Field 1 first: No
Field pattern: Field 1 only
bCopyProtect 1
bVariableSize 1
VideoStreaming Interface Descriptor:
bLength 62
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 1
bmCapabilities 0x01
Still image supported
wWidth 1920
wHeight 1080
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 166666
bFrameIntervalType 9
dwBytesPerLine 0
dwFrameInterval( 0) 83333
dwFrameInterval( 1) 83416
dwFrameInterval( 2) 166666
dwFrameInterval( 3) 166833
dwFrameInterval( 4) 200000
dwFrameInterval( 5) 333333
dwFrameInterval( 6) 333667
dwFrameInterval( 7) 400000
dwFrameInterval( 8) 416666
VideoStreaming Interface Descriptor:
bLength 42
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 2
bmCapabilities 0x01
Still image supported
wWidth 3840
wHeight 2160
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 333333
bFrameIntervalType 4
dwBytesPerLine 0
dwFrameInterval( 0) 333333
dwFrameInterval( 1) 333667
dwFrameInterval( 2) 400000
dwFrameInterval( 3) 416666
VideoStreaming Interface Descriptor:
bLength 34
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 3
bmCapabilities 0x01
Still image supported
wWidth 2560
wHeight 1440
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 166666
bFrameIntervalType 2
dwBytesPerLine 0
dwFrameInterval( 0) 166666
dwFrameInterval( 1) 166833
VideoStreaming Interface Descriptor:
bLength 34
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 4
bmCapabilities 0x01
Still image supported
wWidth 1280
wHeight 800
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 166666
bFrameIntervalType 2
dwBytesPerLine 0
dwFrameInterval( 0) 166666
dwFrameInterval( 1) 166833
VideoStreaming Interface Descriptor:
bLength 38
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 5
bmCapabilities 0x01
Still image supported
wWidth 1280
wHeight 720
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 166666
bFrameIntervalType 3
dwBytesPerLine 0
dwFrameInterval( 0) 166666
dwFrameInterval( 1) 166833
dwFrameInterval( 2) 200000
VideoStreaming Interface Descriptor:
bLength 34
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 6
bmCapabilities 0x01
Still image supported
wWidth 720
wHeight 576
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 200000
bFrameIntervalType 2
dwBytesPerLine 0
dwFrameInterval( 0) 200000
dwFrameInterval( 1) 400000
VideoStreaming Interface Descriptor:
bLength 42
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 7
bmCapabilities 0x01
Still image supported
wWidth 720
wHeight 480
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 166666
bFrameIntervalType 4
dwBytesPerLine 0
dwFrameInterval( 0) 166666
dwFrameInterval( 1) 166833
dwFrameInterval( 2) 333333
dwFrameInterval( 3) 333667
VideoStreaming Interface Descriptor:
bLength 34
bDescriptorType 36
bDescriptorSubtype 17 (FRAME_FRAME_BASED)
bFrameIndex 8
bmCapabilities 0x01
Still image supported
wWidth 640
wHeight 480
dwMinBitRate 33554432
dwMaxBitRate 268435456
dwDefaultFrameInterval 166666
bFrameIntervalType 2
dwBytesPerLine 0
dwFrameInterval( 0) 166666
dwFrameInterval( 1) 166833
VideoStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 13 (COLORFORMAT)
bColorPrimaries 0 (Unspecified)
bTransferCharacteristics 0 (Unspecified)
bMatrixCoefficients 0 (Unspecified)
VideoStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 6 (FORMAT_MJPEG)
bFormatIndex 3
bNumFrameDescriptors 1
bFlags 0
Fixed-size samples: No
bDefaultFrameIndex 1
bAspectRatioX 0
bAspectRatioY 0
bmInterlaceFlags 0x00
Interlaced stream or variable: No
Fields per frame: 1 fields
Field 1 first: No
Field pattern: Field 1 only
bCopyProtect 1
VideoStreaming Interface Descriptor:
bLength 30
bDescriptorType 36
bDescriptorSubtype 7 (FRAME_MJPEG)
bFrameIndex 1
bmCapabilities 0x01
Still image supported
wWidth 1920
wHeight 1080
dwMinBitRate 314572800
dwMaxBitRate 314572800
dwMaxVideoFrameBufferSize 4147200
dwDefaultFrameInterval 166666
bFrameIntervalType 1
dwFrameInterval( 0) 166666
VideoStreaming Interface Descriptor:
bLength 6
bDescriptorType 36
bDescriptorSubtype 13 (COLORFORMAT)
bColorPrimaries 0 (Unspecified)
bTransferCharacteristics 0 (Unspecified)
bMatrixCoefficients 0 (Unspecified)
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 2
bInterfaceCount 2
bFunctionClass 1 Audio
bFunctionSubClass 2 Streaming
bFunctionProtocol 0
iFunction 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 0x0026
bInCollection 1
baInterfaceNr(0) 3
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0602 Digital Audio Interface
bAssocTerminal 0
bNrChannels 2
wChannelConfig 0x0003
Left Front (L)
Right Front (R)
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0101 USB Streaming
bAssocTerminal 0
bSourceID 3
iTerminal 0
AudioControl Interface Descriptor:
bLength 8
bDescriptorType 36
bDescriptorSubtype 6 (FEATURE_UNIT)
bUnitID 3
bSourceID 1
bControlSize 1
bmaControls(0) 0x03
Mute Control
Volume Control
iFeature 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 2
bDelay 1 frames
wFormatTag 0x0001 PCM
AudioStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 2
bSubframeSize 2
bBitResolution 16
bSamFreqType 1 Discrete
tSamFreq[ 0] 48000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x00c4 1x 196 bytes
bInterval 4
bRefresh 0
bSynchAddress 0
AudioStreaming Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x01
Sampling Frequency
bLockDelayUnits 0 Undefined
wLockDelay 0x0000
Cc: stable@vger.kernel.org # 5.12.x
Reported-by: Edwin Gatier <edwin.gatier@protonmail.com>
Closes: https://lore.kernel.org/linux-media/CANiDSCu4AW=JZ9FS+Ny=DK_+LqqytGvSe+V6aVncRiGRiyDMfA@mail.gmail.com/T/#me584c35c4b523ac455925a1590a3de8efc354349
Tested-by: Edwin Gatier <edwin.gatier@protonmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Link: https://patch.msgid.link/20260928-uvc-version-v4-5-da0e983fcb95@chromium.org
Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/usb/uvc/uvc_driver.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index 30adde5a8bc93..73b97ec578ec3 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -2851,6 +2851,17 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
+ /* Avermedia GC515 */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x07ca,
+ .idProduct = 0x1515,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = UVC_PC_PROTOCOL_15,
+ .driver_info = (kernel_ulong_t)&(const struct uvc_device_info){
+ .uvc_version = 0x0110,
+ } },
/* AVerMedia Live Gamer HD 2 capture card */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 042/507] mm/damon/sysfs-schemes: read sysfs_filter->sz_range only once
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (40 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 041/507] media: uvcvideo: Force UVC version for Avermedia GC515 Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 043/507] 9p: fix privport option setting wrong RDMA field Greg Kroah-Hartman
` (464 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, SJ Park, Andrew Morton,
Brendan Higgins, David Gow, Usama Arif, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: SJ Park <sj@kernel.org>
[ Upstream commit af19aff38d6faea35b10f26cca32d0e54f8aea5e ]
DAMON sysfs interface reads the user-provided size range arguments for
hugepage_size type DAMOS filter twice. Once for validation, and once
again for assignments to the variable that will be passed to the core
layer. If the user updates the arguments in parallel, an invalid size
range could be passed to the core layer. Avoid it by doing the
assignments first, and then validating the assigned variables before
passing those to the core layer.
User impact of the bug should be trivial. From the core layer's
perspective, the invalid size range is not really invalid. It just works
as having a weird size range. No critical issues such as a crash or a
leak could happen. And sane users ain't do such parallel arguments update
anyway. If they do, such racy behavior is arguably somewhat expected and
deserved. That said, there is no reason to keep such races.
Link: https://lore.kernel.org/20260914142327.92510-3-sj@kernel.org
Fixes: ea1f204ba29a ("mm/damon/sysfs-schemes: add files for setting damos_filter->sz_range")
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Brendan Higgins <brendan.higgins@linux.dev>
Cc: David Gow <davidgow@davidgow.net>
Cc: Usama Arif <usamaarif642@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/damon/sysfs-schemes.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c
index 974c456a9e099..4ffc13ab95e65 100644
--- a/mm/damon/sysfs-schemes.c
+++ b/mm/damon/sysfs-schemes.c
@@ -2831,12 +2831,11 @@ static int damon_sysfs_add_scheme_filters(struct damos *scheme,
} else if (filter->type == DAMOS_FILTER_TYPE_TARGET) {
filter->target_idx = sysfs_filter->target_idx;
} else if (filter->type == DAMOS_FILTER_TYPE_HUGEPAGE_SIZE) {
- if (sysfs_filter->sz_range.min >
- sysfs_filter->sz_range.max) {
+ filter->sz_range = sysfs_filter->sz_range;
+ if (filter->sz_range.min > filter->sz_range.max) {
damos_destroy_filter(filter);
return -EINVAL;
}
- filter->sz_range = sysfs_filter->sz_range;
}
damos_add_filter(scheme, filter);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 043/507] 9p: fix privport option setting wrong RDMA field
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (41 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 042/507] mm/damon/sysfs-schemes: read sysfs_filter->sz_range only once Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 044/507] net/9p/usbg: fix prefix matching in device lookup Greg Kroah-Hartman
` (463 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, sandeen, Stefano Garzarella,
Dominique Martinet, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefano Garzarella <sgarzare@redhat.com>
[ Upstream commit 7fb9bd3659051ff74a29387de0023bb8300e4aa7 ]
While reviewing a patch adding vsock transport to 9p, I noticed that
since commit 1f3e4142c0eb ("9p: convert to the new mount API"), the
Opt_privport case incorrectly sets rdma_opts->port instead of
rdma_opts->privport, so mounting with the privport option overwrites
the RDMA port number instead of enabling privileged port usage.
Fixes: 1f3e4142c0eb ("9p: convert to the new mount API")
Cc: stable@vger.kernel.org
Cc: sandeen@redhat.com
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
Acked-by: Eric Sandeen <sandeen@redhat.com>
Message-ID: <20260703102254.114446-1-sgarzare@redhat.com>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/9p/v9fs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 274c5157135da..f426cee374148 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -406,7 +406,7 @@ int v9fs_parse_param(struct fs_context *fc, struct fs_parameter *param)
break;
case Opt_privport:
fd_opts->privport = true;
- rdma_opts->port = true;
+ rdma_opts->privport = true;
break;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 044/507] net/9p/usbg: fix prefix matching in device lookup
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (42 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 043/507] 9p: fix privport option setting wrong RDMA field Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 045/507] xfrm: retry inexact policy lookup after node reinsertion Greg Kroah-Hartman
` (462 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yizhou Zhao, Yuxiang Yang, Ao Wang,
Xuewei Feng, Qi Li, Ke Xu, Jackie Liu, Dominique Martinet,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
[ Upstream commit 9ee83ef8d24f11feb55fd0d222c0ec19f09dbd3f ]
p9_usbg_create() matches the mount source against registered usb9pfs
instance tags with strncmp() and the length of the caller supplied source.
That accepts any prefix of the registered tag.
For example, a gadget instance tagged "secret_channel" can be selected with
"s", "sec", or any other non-empty prefix. Once selected, the instance is
marked in use and the client is attached to that transport. This differs
from the configfs tag lookup path, which uses strcmp() and therefore
requires an exact tag match.
Require an exact tag match in p9_usbg_create() as well.
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Cc: stable@vger.kernel.org
Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
Reported-by: Ao Wang <wangao@seu.edu.cn>
Reported-by: Xuewei Feng <fengxw06@126.com>
Reported-by: Qi Li <qli01@tsinghua.edu.cn>
Reported-by: Ke Xu <xuke@tsinghua.edu.cn>
Assisted-by: GLM:GLM-5.1
Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Co-developed-by: Jackie Liu <liuyun01@kylinos.cn>
Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
Message-ID: <20260607121907.12588-1-zhaoyz24@mails.tsinghua.edu.cn>
Message-ID: <20260719040346.88295-1-liu.yun@linux.dev>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/9p/trans_usbg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index 419cda13a7b56..884d6f4af50c0 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -391,7 +391,7 @@ static int p9_usbg_create(struct p9_client *client, struct fs_context *fc)
guard(mutex)(&usb9pfs_lock);
list_for_each_entry(dev, &usbg_instance_list, usb9pfs_instance) {
- if (!strncmp(devname, dev->tag, strlen(devname))) {
+ if (!strcmp(devname, dev->tag)) {
if (!dev->inuse) {
dev->inuse = true;
found = 1;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 045/507] xfrm: retry inexact policy lookup after node reinsertion
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (43 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 044/507] net/9p/usbg: fix prefix matching in device lookup Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 046/507] net/9p/usbg: clear stale request context after abort Greg Kroah-Hartman
` (461 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Steffen Klassert,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
[ Upstream commit 868f63c8bfafa9b827168c9126f85264c39c02ec ]
An inexact policy lookup first records pointers to candidate hlist heads
and then traverses the lists. A concurrent policy insertion can merge
inexact tree nodes between those operations:
lookup policy insertion
------ ----------------
find inexact candidates
save obsolete hlist head
write_seqcount_begin(&bin->count)
merge inexact tree nodes
hlist_del_rcu(&policy->bydst)
reinsert policy->bydst in survivor
write_seqcount_end(&bin->count)
evaluate saved candidate list
miss the moved policy
The merge immediately reinserts the same hlist node into the surviving
tree node. RCU keeps the policy alive, but it does not provide a
consistent view while its list node is moved. A lookup that selected the
obsolete list can observe it empty. A lookup already traversing a moved
policy can instead follow the next pointer rewritten by the reinsertion.
Either case can return an incorrect IPsec policy result.
The per-bin sequence counter already brackets calls to
xfrm_policy_inexact_insert_node(), including node merges. The read side,
however, currently validates the counter only while searching an
individual rb-tree. A successful search returns without validation, and
the later candidate-list traversal is outside that read-side section.
Snapshot the per-bin sequence before discovering candidate heads and
validate it after evaluating all candidate lists. Retry the lookup if
the inexact policy tree changes while it is being searched.
Fixes: 9cf545ebd591 ("xfrm: policy: store inexact policies in a tree ordered by destination address")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/xfrm/xfrm_policy.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 513c9f2283347..f6f40ba713d5a 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2157,6 +2157,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type,
struct xfrm_pol_inexact_bin *bin;
struct xfrm_policy *pol, *ret;
struct hlist_head *chain;
+ unsigned int inexact_sequence;
unsigned int sequence;
int err;
@@ -2191,12 +2192,18 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type,
goto skip_inexact;
bin = xfrm_policy_inexact_lookup_rcu(net, type, family, dir, if_id);
- if (!bin || !xfrm_policy_find_inexact_candidates(&cand, bin, saddr,
- daddr))
+ if (!bin)
+ goto skip_inexact;
+
+ inexact_sequence = read_seqcount_begin(&bin->count);
+ if (!xfrm_policy_find_inexact_candidates(&cand, bin, saddr, daddr))
goto skip_inexact;
pol = xfrm_policy_eval_candidates(&cand, ret, fl, type,
family, if_id);
+ if (read_seqcount_retry(&bin->count, inexact_sequence))
+ goto retry;
+
if (pol) {
ret = pol;
if (IS_ERR(pol))
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 046/507] net/9p/usbg: clear stale request context after abort
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (44 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 045/507] xfrm: retry inexact policy lookup after node reinsertion Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 047/507] 9p/trans_virtio: reject mount tags longer than NAME_MAX at probe Greg Kroah-Hartman
` (460 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Qi Zhang,
Michael Grzeschik, Dominique Martinet, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
[ Upstream commit b58943dd690eb9b76c652e735789937a03f3d30c ]
usb9pfs_clear_tx() serializes access to the active TX request with
usb9pfs->lock, but leaves in_req->context pointing at the request after
p9_client_cb() drops the transport reference. A later teardown path can
therefore retrieve the same request after it has been freed:
CPU 0 (p9_usbg_close) CPU 1 (usb9pfs_disable)
lock(usb9pfs->lock)
req = in_req->context
p9_client_cb(client, req)
p9_req_put(client, req)
unlock(usb9pfs->lock)
request reaches zero refs
kmem_cache_free(req)
lock(usb9pfs->lock)
req = in_req->context
read req->t_err
The lock orders the two callbacks, but cannot protect a pointer that
remains published after its reference has been released. KASAN reported:
BUG: KASAN: slab-use-after-free in usb9pfs_clear_tx+0x166/0x1b0
Read of size 4 at addr ffff88810e7420f4 by task poc/94
Call Trace:
usb9pfs_clear_tx+0x166/0x1b0
usb9pfs_disable+0x1d/0x30
reset_config+0x9d/0x200
__composite_disconnect+0xa7/0x140
Allocated by task 93:
kmem_cache_alloc_noprof+0x141/0x370
p9_tag_alloc+0x8f/0x5b0
p9_client_prepare_req+0xff/0x350
p9_client_rpc+0x1a5/0xac0
Freed by task 0:
slab_free_after_rcu_debug+0xa6/0x1e0
rcu_core+0x50a/0x1850
Last potentially related work creation:
kmem_cache_free+0x1db/0x3d0
p9_req_put+0x164/0x1f0
usb9pfs_clear_tx+0x120/0x1b0
p9_usbg_close+0x7e/0x150
Clear in_req->context after the callback while still holding the lock.
This matches the consume-and-clear pattern in usb9pfs_tx_complete(), so
subsequent teardown calls return without touching the released request.
The existing callback and error ordering remain unchanged.
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Qi Zhang <marsy12010123@gmail.com>
Message-ID: <20260802152148.810390-1-marsy12010123@gmail.com>
Acked-by: Michael Grzeschik <mgr@kernel.org>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/9p/trans_usbg.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index 884d6f4af50c0..f2619e8465d23 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -439,6 +439,7 @@ static void usb9pfs_clear_tx(struct f_usb9pfs *usb9pfs)
req->t_err = -ECONNRESET;
p9_client_cb(usb9pfs->client, req, REQ_STATUS_ERROR);
+ usb9pfs->in_req->context = NULL;
}
static void p9_usbg_close(struct p9_client *client)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 047/507] 9p/trans_virtio: reject mount tags longer than NAME_MAX at probe
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (45 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 046/507] net/9p/usbg: clear stale request context after abort Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 048/507] 9p/xen: fix refcount leak in p9_xen_response() on wrong tag Greg Kroah-Hartman
` (459 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Schoenebeck,
Michael Bommarito, Dominique Martinet, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <michael.bommarito@gmail.com>
[ Upstream commit 5bfef2b6dafe83fe2d8d210d54093a8f48cfc97e ]
p9_virtio_probe() reads a 16-bit mount tag length (tag_len) from the
device config and kzalloc()s tag_len + 1 bytes for chan->tag with no
upper bound. A malicious or compromised host can present a tag of up to
65535 bytes; that tag is later copied into the single-page sysfs buffer
by p9_mount_tag_show() (memcpy(buf, chan->tag, tag_len + 1)), a
host-controlled out-of-bounds write of up to ~64 KiB past the PAGE_SIZE
attribute buffer.
Reject an overlong tag at probe time. A 9p mount tag is a name-like
identifier, so bound it by NAME_MAX (255): that limit is independent of
the sysfs/seq_file page size and is far above any legitimate mount tag,
which keeps p9_mount_tag_show() safe at the root without hard-coding a
seq_file implementation detail.
Fixes: 179a5bc4b8cb ("net/9p: use memcpy() instead of snprintf() in p9_mount_tag_show()")
Cc: stable@vger.kernel.org
Suggested-by: Christian Schoenebeck <linux_oss@crudebyte.com>
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Christian Schoenebeck <linux_oss@crudebyte.com>
Message-ID: <20260627211012.4042372-1-michael.bommarito@gmail.com>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/9p/trans_virtio.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index b0d0094ec8e2c..9fa63e3ebf673 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -633,6 +633,11 @@ static int p9_virtio_probe(struct virtio_device *vdev)
err = -EINVAL;
goto out_free_vq;
}
+ if (tag_len > NAME_MAX) {
+ dev_err(&vdev->dev, "mount tag too long (%u bytes)\n", tag_len);
+ err = -EINVAL;
+ goto out_free_vq;
+ }
tag = kzalloc(tag_len + 1, GFP_KERNEL);
if (!tag) {
err = -ENOMEM;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 048/507] 9p/xen: fix refcount leak in p9_xen_response() on wrong tag
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (46 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 047/507] 9p/trans_virtio: reject mount tags longer than NAME_MAX at probe Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 049/507] 9p: fix caches_show() out-of-bounds write Greg Kroah-Hartman
` (458 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yifei Gao, Stefano Stabellini,
Dominique Martinet, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yifei Gao <gyf161023@gmail.com>
[ Upstream commit 4d183e6f153245aca2534e372152583b868dd925 ]
p9_xen_response() looks up the request for an incoming reply with
p9_tag_lookup(), which takes a reference on the returned p9_req_t. When
the tag does not resolve to a request in REQ_STATUS_SENT, the function
warns and continues the loop without dropping that reference, permanently
leaking the p9_req_t and its msize buffers. The reply header, including
the tag, is supplied by the backend, so a malicious or buggy 9P backend
can leak kernel memory on every crafted response.
Drop the reference before continuing.
Fixes: 728356dedeff ("9p: Add refcount to p9_req_t")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Yifei Gao <gyf161023@gmail.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Message-ID: <20260806144255.4167019-1-gyf161023@gmail.com>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/9p/trans_xen.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
index f9fb2db7a0663..8eea0da8797f4 100644
--- a/net/9p/trans_xen.c
+++ b/net/9p/trans_xen.c
@@ -203,6 +203,8 @@ static void p9_xen_response(struct work_struct *work)
req = p9_tag_lookup(priv->client, h.tag);
if (!req || req->status != REQ_STATUS_SENT) {
dev_warn(&priv->dev->dev, "Wrong req tag=%x\n", h.tag);
+ if (req)
+ p9_req_put(priv->client, req);
cons += h.size;
virt_mb();
ring->intf->in_cons = cons;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 049/507] 9p: fix caches_show() out-of-bounds write
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (47 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 048/507] 9p/xen: fix refcount leak in p9_xen_response() on wrong tag Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 050/507] net/9p/usbg: Fix use-after-free in disable_usb9pfs() Greg Kroah-Hartman
` (457 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuan Tan, Zhengchuan Liang, Xin Liu,
Zhao Zhang, Ren Wei, Dominique Martinet, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Zhang <zzhan461@ucr.edu>
[ Upstream commit 2acd800de8827b7cdce8cb5c2c63b8e8608ec8e3 ]
The sysfs show handler for /sys/fs/9p/caches appends cache tags with
snprintf(buf + count, limit, ...) and then advances count and limit by
the return value. This is incorrect for truncation because snprintf()
returns the full would-have-been length, not the number of bytes stored.
Once the accumulated output exceeds PAGE_SIZE, count can advance past
the sysfs buffer and limit can become negative. A later iteration then
passes an out-of-bounds destination pointer and an oversized size_t
into snprintf(), leading to an out-of-bounds write.
Use sysfs_emit_at() for the append instead. It follows the sysfs buffer
contract and returns the number of bytes actually stored, so the offset
remains bounded even when the output is truncated.
Fixes: 86db0c32f16c ("9p: fix /sys/fs/9p/caches overwriting itself")
Cc: stable@vger.kernel.org
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Zhengchuan Liang <zcliangcn@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Assisted-by: Codex:GPT-5.4
Signed-off-by: Zhao Zhang <zzhan461@ucr.edu>
Co-authored-by: Ren Wei <n05ec@lzu.edu.cn>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
Message-ID: <abfb65f4800634dafb08238bba20cb48797e796f.1781908090.git.zzhan461@ucr.edu>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/9p/v9fs.c | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index f426cee374148..b30ca5145faef 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -17,6 +17,7 @@
#include <linux/fs_context.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
+#include <linux/sysfs.h>
#include <net/9p/9p.h>
#include <net/9p/client.h>
#include <net/9p/transport.h>
@@ -617,21 +618,14 @@ static ssize_t caches_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf)
{
- ssize_t n = 0, count = 0, limit = PAGE_SIZE;
+ ssize_t count = 0;
struct v9fs_session_info *v9ses;
spin_lock(&v9fs_sessionlist_lock);
list_for_each_entry(v9ses, &v9fs_sessionlist, slist) {
- if (v9ses->cachetag) {
- n = snprintf(buf + count, limit, "%s\n", v9ses->cachetag);
- if (n < 0) {
- count = n;
- break;
- }
-
- count += n;
- limit -= n;
- }
+ if (v9ses->cachetag)
+ count += sysfs_emit_at(buf, count, "%s\n",
+ v9ses->cachetag);
}
spin_unlock(&v9fs_sessionlist_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 050/507] net/9p/usbg: Fix use-after-free in disable_usb9pfs()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (48 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 049/507] 9p: fix caches_show() out-of-bounds write Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 051/507] net/9p/usbg: also disable endpoints on p9_usbg_close Greg Kroah-Hartman
` (456 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yizhou Zhao, Yuxiang Yang, Ao Wang,
Xuewei Feng, Qi Li, Ke Xu, Michael Grzeschik, Dominique Martinet,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
[ Upstream commit 6f401e350939442b2ac905f7e5ac952e3802a5d8 ]
disable_usb9pfs() frees the IN and OUT usb_request objects before it
disables the corresponding endpoints. If either request is still queued,
the later usb_ep_disable() call cancels the endpoint queue and the UDC
driver can still access the already freed request.
With dummy_hcd and KASAN, this is reproducible by queueing the OUT
request and then disconnecting the configfs gadget:
BUG: KASAN: slab-use-after-free in dummy_disable+0x2b4/0x300
Read of size 8 at addr ffff888009702400 by task sh/1
usb_ep_disable+0x8e/0x1f0
usb9pfs_func_unbind+0x193/0x350
gadget_dev_desc_UDC_store+0x135/0x280
dummy_free_request() also warns because the request is freed while its
queue entry is still linked.
Disable both endpoints before freeing the request objects. This lets
usb_ep_disable() cancel any queued transfers and invoke the completion
callback while the request storage is still valid. The request objects
are then freed only after they have been removed from the endpoint
queues.
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Cc: stable@vger.kernel.org
Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
Reported-by: Ao Wang <wangao@seu.edu.cn>
Reported-by: Xuewei Feng <fengxw06@126.com>
Reported-by: Qi Li <qli01@tsinghua.edu.cn>
Reported-by: Ke Xu <xuke@tsinghua.edu.cn>
Assisted-by: GLM:GLM-5.1
Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
Acked-by: Michael Grzeschik <mgr@kernel.org>
Message-ID: <20260607130118.16579-1-zhaoyz24@mails.tsinghua.edu.cn>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/9p/trans_usbg.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index f2619e8465d23..e2309500a8c74 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -278,6 +278,9 @@ static void disable_usb9pfs(struct f_usb9pfs *usb9pfs)
struct usb_composite_dev *cdev =
usb9pfs->function.config->cdev;
+ disable_ep(cdev, usb9pfs->in_ep);
+ disable_ep(cdev, usb9pfs->out_ep);
+
if (usb9pfs->in_req) {
usb_ep_free_request(usb9pfs->in_ep, usb9pfs->in_req);
usb9pfs->in_req = NULL;
@@ -287,9 +290,6 @@ static void disable_usb9pfs(struct f_usb9pfs *usb9pfs)
usb_ep_free_request(usb9pfs->out_ep, usb9pfs->out_req);
usb9pfs->out_req = NULL;
}
-
- disable_ep(cdev, usb9pfs->in_ep);
- disable_ep(cdev, usb9pfs->out_ep);
dev_dbg(&cdev->gadget->dev, "%s disabled\n",
usb9pfs->function.name);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 051/507] net/9p/usbg: also disable endpoints on p9_usbg_close
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (49 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 050/507] net/9p/usbg: Fix use-after-free in disable_usb9pfs() Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 052/507] net/9p/usbg: set client to Disconnected on usb9pfs_disable Greg Kroah-Hartman
` (455 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Grzeschik,
Dominique Martinet, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Grzeschik <mgr@kernel.org>
[ Upstream commit f81cdb9164806eb2df1e1c6df402e03bff7dde31 ]
The close function has to fully reverse the state change of 9p_create
(mount) and the potential call of set_alt(1). This includes to ensure
that the usage of the endpoints is not active any more.
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Cc: stable@vger.kernel.org
Signed-off-by: Michael Grzeschik <mgr@kernel.org>
Message-ID: <20260922-usb9pfsfixes-v1-1-9d8dcc52904c@kernel.org>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/9p/trans_usbg.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index e2309500a8c74..0b7fcba4a2262 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -467,6 +467,8 @@ static void p9_usbg_close(struct p9_client *client)
mutex_lock(&usb9pfs_lock);
dev->inuse = false;
mutex_unlock(&usb9pfs_lock);
+
+ disable_usb9pfs(usb9pfs);
}
static int p9_usbg_request(struct p9_client *client, struct p9_req_t *p9_req)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 052/507] net/9p/usbg: set client to Disconnected on usb9pfs_disable
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (50 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 051/507] net/9p/usbg: also disable endpoints on p9_usbg_close Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 053/507] net/9p/usbg: always reset completion when disconnecting Greg Kroah-Hartman
` (454 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Grzeschik,
Dominique Martinet, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Grzeschik <mgr@kernel.org>
[ Upstream commit 795f8eeca01d1c9ca3d9a450385b7745ace4e53a ]
This patch is setting the client status to Disconnected, when the
client is still in use. Otherwise a disconnected usb cable would run
any use of the mount to faults.
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Cc: stable@vger.kernel.org
Signed-off-by: Michael Grzeschik <mgr@kernel.org>
Message-ID: <20260922-usb9pfsfixes-v1-2-9d8dcc52904c@kernel.org>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/9p/trans_usbg.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index 0b7fcba4a2262..a06d0ac163b0d 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -751,7 +751,12 @@ static int usb9pfs_set_alt(struct usb_function *f,
static void usb9pfs_disable(struct usb_function *f)
{
struct f_usb9pfs *usb9pfs = func_to_usb9pfs(f);
+ unsigned long flags;
+ spin_lock_irqsave(&usb9pfs->lock, flags);
+ if (usb9pfs->client)
+ usb9pfs->client->status = Disconnected;
+ spin_unlock_irqrestore(&usb9pfs->lock, flags);
usb9pfs_clear_tx(usb9pfs);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 053/507] net/9p/usbg: always reset completion when disconnecting
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (51 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 052/507] net/9p/usbg: set client to Disconnected on usb9pfs_disable Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 054/507] net/9p/usbg: call disable_usb9pfs() from usb9pfs_disable() Greg Kroah-Hartman
` (453 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Grzeschik,
Dominique Martinet, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Grzeschik <mgr@kernel.org>
[ Upstream commit 08c6b9f484a406d9d87c5b2580725d2e0597f3b9 ]
When some tx or rx transfers were pending while closing the connection,
the completion handler could catch one pending completion call. To
ensure a normal start when mounting again, we have to reset the
completion and flush any pending completions.
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Cc: stable@vger.kernel.org
Signed-off-by: Michael Grzeschik <mgr@kernel.org>
Message-ID: <20260922-usb9pfsfixes-v1-3-9d8dcc52904c@kernel.org>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/9p/trans_usbg.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index a06d0ac163b0d..ce952a5de4260 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -469,6 +469,7 @@ static void p9_usbg_close(struct p9_client *client)
mutex_unlock(&usb9pfs_lock);
disable_usb9pfs(usb9pfs);
+ reinit_completion(&usb9pfs->send);
}
static int p9_usbg_request(struct p9_client *client, struct p9_req_t *p9_req)
@@ -758,6 +759,7 @@ static void usb9pfs_disable(struct usb_function *f)
usb9pfs->client->status = Disconnected;
spin_unlock_irqrestore(&usb9pfs->lock, flags);
usb9pfs_clear_tx(usb9pfs);
+ reinit_completion(&usb9pfs->send);
}
static struct usb_function *usb9pfs_alloc(struct usb_function_instance *fi)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 054/507] net/9p/usbg: call disable_usb9pfs() from usb9pfs_disable()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (52 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 053/507] net/9p/usbg: always reset completion when disconnecting Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 055/507] net/9p/usbg: fix out_req buffer leak in disable_usb9pfs Greg Kroah-Hartman
` (452 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Grzeschik,
Dominique Martinet, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Grzeschik <mgr@kernel.org>
[ Upstream commit cd1988cf723c2eae87112b198bf90b0aebfeaf31 ]
usb9pfs_disable() is the usb_function ->disable callback, invoked by
the composite gadget core whenever the host resets or unconfigures
the gadget. The gadget function API requires this callback to disable
its endpoints; every other in-tree function driver does so from its
->disable hook.
usb9pfs_disable() never called disable_usb9pfs(), so the IN/OUT
endpoints and their usb_request objects were left active and
allocated across a host-driven disable. When the host later
reconfigures the device, enable_usb9pfs() calls alloc_requests() again
and unconditionally overwrites usb9pfs->in_req/out_req, permanently
leaking the previous allocations, while the endpoints themselves are
left enabled underneath the function's own idea of being disabled.
Call disable_usb9pfs() before reinit_completion(&usb9pfs->send),
mirroring the same sequence already used in p9_usbg_close(). Placing
it before the reinit_completion() also ensures usb_ep_disable() has
synchronously flushed any requests still queued in hardware before the
completion is reset, closing the same race that motivated resetting
the completion here in the first place.
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Assisted-by: Claude:claude-opus-4.8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Grzeschik <mgr@kernel.org>
Message-ID: <20260922-usb9pfsfixes-v1-4-9d8dcc52904c@kernel.org>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/9p/trans_usbg.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index ce952a5de4260..e215d047de16c 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -759,6 +759,10 @@ static void usb9pfs_disable(struct usb_function *f)
usb9pfs->client->status = Disconnected;
spin_unlock_irqrestore(&usb9pfs->lock, flags);
usb9pfs_clear_tx(usb9pfs);
+
+ if (usb9pfs->in_ep->enabled)
+ disable_usb9pfs(usb9pfs);
+
reinit_completion(&usb9pfs->send);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 055/507] net/9p/usbg: fix out_req buffer leak in disable_usb9pfs
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (53 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 054/507] net/9p/usbg: call disable_usb9pfs() from usb9pfs_disable() Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 056/507] net/9p/usbg: remove bogus context initialization in alloc_requests Greg Kroah-Hartman
` (451 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Grzeschik,
Dominique Martinet, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Grzeschik <mgr@kernel.org>
[ Upstream commit 5f9807270c7bda8f86b312ed1a8acd7716600555 ]
usb9pfs->out_req is allocated with alloc_ep_req(), which also
allocates the request's data buffer (req->buf). disable_usb9pfs()
frees it with plain usb_ep_free_request(), which only frees the
usb_request structure itself and leaks req->buf on every close.
Use free_ep_req() instead, matching the allocator, as documented by
its own comment ("Requests allocated via alloc_ep_req() *must* be
freed by free_ep_req()").
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4.8
Signed-off-by: Michael Grzeschik <mgr@kernel.org>
Message-ID: <20260922-usb9pfsfixes-v1-5-9d8dcc52904c@kernel.org>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/9p/trans_usbg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index e215d047de16c..af01323db69c0 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -287,7 +287,7 @@ static void disable_usb9pfs(struct f_usb9pfs *usb9pfs)
}
if (usb9pfs->out_req) {
- usb_ep_free_request(usb9pfs->out_ep, usb9pfs->out_req);
+ free_ep_req(usb9pfs->out_ep, usb9pfs->out_req);
usb9pfs->out_req = NULL;
}
dev_dbg(&cdev->gadget->dev, "%s disabled\n",
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 056/507] net/9p/usbg: remove bogus context initialization in alloc_requests
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (54 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 7.3 055/507] net/9p/usbg: fix out_req buffer leak in disable_usb9pfs Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 057/507] net/9p/usbg: clear stale client pointer on close Greg Kroah-Hartman
` (450 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Grzeschik,
Dominique Martinet, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Grzeschik <mgr@kernel.org>
[ Upstream commit bbdb38b2e543ffa72dca5450f2535cf998ef1cdd ]
alloc_requests() initializes usb9pfs->in_req->context to point at the
struct f_usb9pfs instance itself. usb9pfs_queue_tx() later overwrites
this with the real struct p9_req_t pointer before every transmit, and
usb9pfs_tx_complete() clears it back to NULL after each completion, so
in_req->context only ever holds a valid p9_req_t once a request has
actually been queued.
usb9pfs_clear_tx(), however, can run at any time (mount close, gadget
disable) independent of whether a request was ever queued. If it runs
before the first usb9pfs_transmit(), it reads the leftover sentinel
value, type-confuses the struct f_usb9pfs pointer as a struct
p9_req_t, and both writes through it (req->t_err = -ECONNRESET) and
hands it to p9_client_cb(), which manipulates req->wq and req->refcount
at bogus offsets inside f_usb9pfs. This reliably corrupts memory or
panics whenever the transport is torn down before any 9p request has
been transmitted, e.g. mounting and immediately unmounting, or a cable
disconnect racing the very first request.
usb9pfs->out_req->context is set the same way but is never read by
this transport (usb9pfs_rx_complete() identifies the instance via
ep->driver_data instead), so it serves no purpose either.
Both endpoints' ->driver_data are already set to usb9pfs in
enable_endpoint(), which is what the completion handlers actually use
to recover the f_usb9pfs instance. Just drop the leftover
->context assignments; usb_ep_alloc_request()/alloc_ep_req() already
return zeroed requests, so in_req->context correctly starts out NULL.
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4.8
Signed-off-by: Michael Grzeschik <mgr@kernel.org>
Message-ID: <20260922-usb9pfsfixes-v1-6-9d8dcc52904c@kernel.org>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/9p/trans_usbg.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index af01323db69c0..2be5abae03aea 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -314,10 +314,6 @@ static int alloc_requests(struct usb_composite_dev *cdev,
usb9pfs->in_req->complete = usb9pfs_tx_complete;
usb9pfs->out_req->complete = usb9pfs_rx_complete;
- /* length will be set in complete routine */
- usb9pfs->in_req->context = usb9pfs;
- usb9pfs->out_req->context = usb9pfs;
-
return 0;
fail_in:
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 057/507] net/9p/usbg: clear stale client pointer on close
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (55 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 056/507] net/9p/usbg: remove bogus context initialization in alloc_requests Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 058/507] xfrm: interface: validate the IP header on xmit Greg Kroah-Hartman
` (449 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hyungjung Joo, Michael Grzeschik,
Dominique Martinet, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hyungjung Joo <jhj140711@gmail.com>
[ Upstream commit a478958f4c1181ff3362f8857b489c2d069f9c7d ]
p9_usbg_close() tears down the client transport, but usb9pfs keeps
using usb9pfs->client from asynchronous TX and RX completion handlers.
A late completion can therefore dereference a client that has already
been freed during mount teardown.
Clear usb9pfs->client under usb9pfs->lock when closing the transport,
detach any pending TX request from in_req->context, and make the TX/RX
completion handlers bail out once the transport has been detached. This
keeps late completions from touching a freed or rebound p9_client.
Fixes: a3be076dc174 ("net/9p/usbg: Add new usb gadget function transport")
Cc: stable@vger.kernel.org
Signed-off-by: Hyungjung Joo <jhj140711@gmail.com>
Signed-off-by: Michael Grzeschik <mgr@kernel.org>
Message-ID: <20260922-usb9pfsfixes-v1-7-9d8dcc52904c@kernel.org>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/9p/trans_usbg.c | 61 +++++++++++++++++++++++++++++++++------------
1 file changed, 45 insertions(+), 16 deletions(-)
diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c
index 2be5abae03aea..7d600e1288a30 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -149,7 +149,8 @@ static void usb9pfs_tx_complete(struct usb_ep *ep, struct usb_request *req)
{
struct f_usb9pfs *usb9pfs = ep->driver_data;
struct usb_composite_dev *cdev = usb9pfs->function.config->cdev;
- struct p9_req_t *p9_tx_req = req->context;
+ struct p9_client *client;
+ struct p9_req_t *p9_tx_req;
unsigned long flags;
/* reset zero packages */
@@ -165,18 +166,25 @@ static void usb9pfs_tx_complete(struct usb_ep *ep, struct usb_request *req)
ep->name, req->status, req->actual, req->length);
spin_lock_irqsave(&usb9pfs->lock, flags);
- WRITE_ONCE(p9_tx_req->status, REQ_STATUS_SENT);
+ client = usb9pfs->client;
+ p9_tx_req = req->context;
+ req->context = NULL;
- p9_req_put(usb9pfs->client, p9_tx_req);
+ if (!client || !p9_tx_req)
+ goto unlock_complete;
- req->context = NULL;
+ WRITE_ONCE(p9_tx_req->status, REQ_STATUS_SENT);
+ p9_req_put(client, p9_tx_req);
+
+unlock_complete:
spin_unlock_irqrestore(&usb9pfs->lock, flags);
complete(&usb9pfs->send);
}
-static struct p9_req_t *usb9pfs_rx_header(struct f_usb9pfs *usb9pfs, void *buf)
+static struct p9_req_t *usb9pfs_rx_header(struct f_usb9pfs *usb9pfs,
+ struct p9_client *client, void *buf)
{
struct p9_req_t *p9_rx_req;
struct p9_fcall rc;
@@ -202,7 +210,7 @@ static struct p9_req_t *usb9pfs_rx_header(struct f_usb9pfs *usb9pfs, void *buf)
"mux %p pkt: size: %d bytes tag: %d\n",
usb9pfs, rc.size, rc.tag);
- p9_rx_req = p9_tag_lookup(usb9pfs->client, rc.tag);
+ p9_rx_req = p9_tag_lookup(client, rc.tag);
if (!p9_rx_req || p9_rx_req->status != REQ_STATUS_SENT) {
p9_debug(P9_DEBUG_ERROR, "Unexpected packet tag %d\n", rc.tag);
return NULL;
@@ -212,7 +220,7 @@ static struct p9_req_t *usb9pfs_rx_header(struct f_usb9pfs *usb9pfs, void *buf)
p9_debug(P9_DEBUG_ERROR,
"requested packet size too big: %d for tag %d with capacity %zd\n",
rc.size, rc.tag, p9_rx_req->rc.capacity);
- p9_req_put(usb9pfs->client, p9_rx_req);
+ p9_req_put(client, p9_rx_req);
return NULL;
}
@@ -220,7 +228,7 @@ static struct p9_req_t *usb9pfs_rx_header(struct f_usb9pfs *usb9pfs, void *buf)
p9_debug(P9_DEBUG_ERROR,
"No recv fcall for tag %d (req %p), disconnecting!\n",
rc.tag, p9_rx_req);
- p9_req_put(usb9pfs->client, p9_rx_req);
+ p9_req_put(client, p9_rx_req);
return NULL;
}
@@ -231,8 +239,10 @@ static void usb9pfs_rx_complete(struct usb_ep *ep, struct usb_request *req)
{
struct f_usb9pfs *usb9pfs = ep->driver_data;
struct usb_composite_dev *cdev = usb9pfs->function.config->cdev;
+ struct p9_client *client;
struct p9_req_t *p9_rx_req;
unsigned int req_size = req->actual;
+ unsigned long flags;
int status = REQ_STATUS_RCVD;
if (req->status) {
@@ -241,9 +251,16 @@ static void usb9pfs_rx_complete(struct usb_ep *ep, struct usb_request *req)
return;
}
- p9_rx_req = usb9pfs_rx_header(usb9pfs, req->buf);
- if (!p9_rx_req)
+ spin_lock_irqsave(&usb9pfs->lock, flags);
+ client = usb9pfs->client;
+ if (!client) {
+ spin_unlock_irqrestore(&usb9pfs->lock, flags);
return;
+ }
+
+ p9_rx_req = usb9pfs_rx_header(usb9pfs, client, req->buf);
+ if (!p9_rx_req)
+ goto out_unlock;
if (req_size > p9_rx_req->rc.capacity) {
dev_err(&cdev->gadget->dev,
@@ -257,8 +274,11 @@ static void usb9pfs_rx_complete(struct usb_ep *ep, struct usb_request *req)
p9_rx_req->rc.size = req_size;
- p9_client_cb(usb9pfs->client, p9_rx_req, status);
- p9_req_put(usb9pfs->client, p9_rx_req);
+ p9_client_cb(client, p9_rx_req, status);
+ p9_req_put(client, p9_rx_req);
+
+out_unlock:
+ spin_unlock_irqrestore(&usb9pfs->lock, flags);
complete(&usb9pfs->received);
}
@@ -412,7 +432,9 @@ static int p9_usbg_create(struct p9_client *client, struct fs_context *fc)
client->status = Disconnected;
else
client->status = Connected;
+ spin_lock_irq(&usb9pfs->lock);
usb9pfs->client = client;
+ spin_unlock_irq(&usb9pfs->lock);
client->trans_mod->maxsize = usb9pfs->buflen;
@@ -423,18 +445,25 @@ static int p9_usbg_create(struct p9_client *client, struct fs_context *fc)
static void usb9pfs_clear_tx(struct f_usb9pfs *usb9pfs)
{
+ struct p9_client *client;
struct p9_req_t *req;
+ unsigned long flags;
- guard(spinlock_irqsave)(&usb9pfs->lock);
+ spin_lock_irqsave(&usb9pfs->lock, flags);
+ client = usb9pfs->client;
+ usb9pfs->client = NULL;
+ req = usb9pfs->in_req ? usb9pfs->in_req->context : NULL;
+ if (usb9pfs->in_req)
+ usb9pfs->in_req->context = NULL;
+ spin_unlock_irqrestore(&usb9pfs->lock, flags);
- req = usb9pfs->in_req->context;
- if (!req)
+ if (!req || !client)
return;
if (!req->t_err)
req->t_err = -ECONNRESET;
- p9_client_cb(usb9pfs->client, req, REQ_STATUS_ERROR);
+ p9_client_cb(client, req, REQ_STATUS_ERROR);
usb9pfs->in_req->context = NULL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 058/507] xfrm: interface: validate the IP header on xmit
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (56 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 057/507] net/9p/usbg: clear stale client pointer on close Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 059/507] xfrm: espintcp: reorder operations within espintcp_init_sk Greg Kroah-Hartman
` (448 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Qihang, Steffen Klassert,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qihang <q.h.hack.winter@gmail.com>
[ Upstream commit 86de3a1118a16dbbbe5fabe9aa20ffb93c072ed5 ]
Packets injected into an xfrm interface (e.g. AF_PACKET on an xfrmi
device) reach the xfrm output path without IP header validation, but
xfrm4_transport_output() uses iph->ihl for __skb_pull() and memmove()
and expects the header to be valid.
vti_tunnel_xmit() already calls pskb_inet_may_pull() before handing
packets to the xfrm output path. Do the same in xfrmi_xmit() and
perform the header checks ip_rcv_core()/ip6_rcv_core() do on entry
to the IP stack: reject wrong IP versions and malformed IPv4 header
lengths.
Fixes: f203b76d7809 ("xfrm: Add virtual xfrm interfaces")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Qihang <q.h.hack.winter@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/xfrm/xfrm_interface_core.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/net/xfrm/xfrm_interface_core.c b/net/xfrm/xfrm_interface_core.c
index 688306bf62c5a..9835fbe63ccb8 100644
--- a/net/xfrm/xfrm_interface_core.c
+++ b/net/xfrm/xfrm_interface_core.c
@@ -531,8 +531,13 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
memset(&fl, 0, sizeof(fl));
+ if (!pskb_inet_may_pull(skb))
+ goto tx_err;
+
switch (skb->protocol) {
case htons(ETH_P_IPV6):
+ if (ipv6_hdr(skb)->version != 6)
+ goto tx_err;
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
xfrm_decode_session(dev_net(dev), skb, &fl, AF_INET6);
if (!dst) {
@@ -548,6 +553,9 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
}
break;
case htons(ETH_P_IP):
+ if (ip_hdr(skb)->version != 4 || ip_hdr(skb)->ihl < 5 ||
+ !pskb_network_may_pull(skb, ip_hdr(skb)->ihl * 4))
+ goto tx_err;
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
xfrm_decode_session(dev_net(dev), skb, &fl, AF_INET);
if (!dst) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 059/507] xfrm: espintcp: reorder operations within espintcp_init_sk
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (57 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 058/507] xfrm: interface: validate the IP header on xmit Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 060/507] drm/panic: Fix kmsg screen hang on a long log line Greg Kroah-Hartman
` (447 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuan Tan, Yifan Wu, Juefei Pu,
Xin Liu, Peihan Liu, Yilin Zhu, Ren Wei, Eulgyu Kim,
Jaeyoung Chung, Sabrina Dubroca, Steffen Klassert, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sabrina Dubroca <sd@queasysnail.net>
[ Upstream commit f9a11716c8445b496e9fafeec7e8412d384d02e2 ]
When enabled on a socket, espintcp sets the socket callbacks to its
own before it has finished setting up its context and published it as
icsk_ulp_data. Any one of those callbacks that gets called before will
dereference a NULL icsk_ulp_data.
Fix this by reording the operations, and add memory barriers to ensure
callers will have a struct espintcp_ctx available. Add a few
WRITE_ONCE/READ_ONCE too while we're there.
Fixes: e27cca96cd68 ("xfrm: add espintcp (RFC 8229)")
Cc: stable@vger.kernel.org
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Reported-by: Peihan Liu <ronbogo@outlook.com>
Reported-by: Yilin Zhu <zylzyl2333@gmail.com>
Reported-by: Ren Wei <n05ec@lzu.edu.cn>
Reported-by: Eulgyu Kim <eulgyukim@snu.ac.kr>
Reported-by: Jaeyoung Chung <jjy600901@snu.ac.kr>
Link: https://lore.kernel.org/all/c30b645074a1b379e0f7fe297f917c66137d9964.1778464688.git.zylzyl2333@gmail.com/
Link: https://lore.kernel.org/all/20260819155349.3555804-1-jjy600901@snu.ac.kr
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/espintcp.h | 5 +++--
net/xfrm/espintcp.c | 43 +++++++++++++++++++++++++-----------------
2 files changed, 29 insertions(+), 19 deletions(-)
diff --git a/include/net/espintcp.h b/include/net/espintcp.h
index c70efd704b6d5..7cad3c6822df9 100644
--- a/include/net/espintcp.h
+++ b/include/net/espintcp.h
@@ -34,7 +34,8 @@ static inline struct espintcp_ctx *espintcp_getctx(const struct sock *sk)
{
const struct inet_connection_sock *icsk = inet_csk(sk);
- /* RCU is only needed for diag */
- return (__force void *)icsk->icsk_ulp_data;
+ /* pairs with smp_wmb() in espintcp_init_sk() */
+ smp_rmb();
+ return (__force void *)READ_ONCE(icsk->icsk_ulp_data);
}
#endif
diff --git a/net/xfrm/espintcp.c b/net/xfrm/espintcp.c
index 3e72b9f067b9b..4052ae5bbb2ea 100644
--- a/net/xfrm/espintcp.c
+++ b/net/xfrm/espintcp.c
@@ -434,7 +434,9 @@ static void espintcp_destruct(struct sock *sk)
bool tcp_is_ulp_esp(struct sock *sk)
{
- return sk->sk_prot == &espintcp_prot || sk->sk_prot == &espintcp6_prot;
+ const struct proto *prot = READ_ONCE(sk->sk_prot);
+
+ return prot == &espintcp_prot || prot == &espintcp6_prot;
}
EXPORT_SYMBOL_GPL(tcp_is_ulp_esp);
@@ -466,34 +468,41 @@ static int espintcp_init_sk(struct sock *sk)
__sk_dst_reset(sk);
- strp_check_rcv(&ctx->strp);
skb_queue_head_init(&ctx->ike_queue);
skb_queue_head_init(&ctx->out_queue);
+ INIT_WORK(&ctx->work, espintcp_tx_work);
+
+ ctx->saved_data_ready = sk->sk_data_ready;
+ ctx->saved_write_space = sk->sk_write_space;
+ ctx->saved_destruct = sk->sk_destruct;
+
+ /* avoid using task_frag */
+ sk->sk_allocation = GFP_ATOMIC;
+ sk->sk_use_task_frag = false;
+
+ rcu_assign_pointer(icsk->icsk_ulp_data, ctx);
+
+ /* pairs with smp_rmb() in espintcp_getctx() */
+ smp_wmb();
+
+ WRITE_ONCE(sk->sk_data_ready, espintcp_data_ready);
+ WRITE_ONCE(sk->sk_write_space, espintcp_write_space);
+ sk->sk_destruct = espintcp_destruct;
if (sk->sk_family == AF_INET) {
- sk->sk_prot = &espintcp_prot;
- sk->sk_socket->ops = &espintcp_ops;
+ WRITE_ONCE(sk->sk_prot, &espintcp_prot);
+ WRITE_ONCE(sk->sk_socket->ops, &espintcp_ops);
} else {
mutex_lock(&tcpv6_prot_mutex);
if (!espintcp6_prot.recvmsg)
build_protos(&espintcp6_prot, &espintcp6_ops, sk->sk_prot, sk->sk_socket->ops);
mutex_unlock(&tcpv6_prot_mutex);
- sk->sk_prot = &espintcp6_prot;
- sk->sk_socket->ops = &espintcp6_ops;
+ WRITE_ONCE(sk->sk_prot, &espintcp6_prot);
+ WRITE_ONCE(sk->sk_socket->ops, &espintcp6_ops);
}
- ctx->saved_data_ready = sk->sk_data_ready;
- ctx->saved_write_space = sk->sk_write_space;
- ctx->saved_destruct = sk->sk_destruct;
- sk->sk_data_ready = espintcp_data_ready;
- sk->sk_write_space = espintcp_write_space;
- sk->sk_destruct = espintcp_destruct;
- rcu_assign_pointer(icsk->icsk_ulp_data, ctx);
- INIT_WORK(&ctx->work, espintcp_tx_work);
- /* avoid using task_frag */
- sk->sk_allocation = GFP_ATOMIC;
- sk->sk_use_task_frag = false;
+ strp_check_rcv(&ctx->strp);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 060/507] drm/panic: Fix kmsg screen hang on a long log line
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (58 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 059/507] xfrm: espintcp: reorder operations within espintcp_init_sk Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 061/507] drm/drm_crtc: ensure dma_fence_ops remain valid during device unbind Greg Kroah-Hartman
` (446 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Devin Wittmayer, Jocelyn Falempe,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Devin Wittmayer <lucid_duck@justthetip.ca>
[ Upstream commit 1ba6405638439a4214783965538b0196c8de8a5b ]
The kmsg panic screen reads the log back one chunk at a time. A record
that does not fit in a chunk comes back empty without moving on, so the
screen asks for it again forever and the panic never finishes. Every
oops logs the list of loaded modules, and on my machine that list does
not fit.
Read into a buffer the size printk formats one record into, and stop if
a read still comes back empty.
Fixes: 54034bebb22f ("drm/panic: Add a kmsg panic screen")
Cc: stable@vger.kernel.org
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20261016052722.60051-1-lucid_duck@justthetip.ca
Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/drm_panic.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c
index d28ce8878e055..fef47625c5268 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -558,7 +558,8 @@ static void draw_panic_screen_kmsg(struct drm_scanout_buffer *sb)
const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL);
struct drm_rect r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height);
struct kmsg_dump_iter iter;
- char kmsg_buf[512];
+ /* the size printk formats one record into, too big for the stack */
+ static char kmsg_buf[2048];
size_t kmsg_len;
struct drm_panic_line line;
int yoffset;
@@ -576,6 +577,10 @@ static void draw_panic_screen_kmsg(struct drm_scanout_buffer *sb)
char *start;
char *end;
+ /* a record that does not fit comes back empty, every time */
+ if (!kmsg_len)
+ break;
+
/* ignore terminating NUL and newline */
start = kmsg_buf + kmsg_len - 2;
end = kmsg_buf + kmsg_len - 1;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 061/507] drm/drm_crtc: ensure dma_fence_ops remain valid during device unbind
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (59 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 060/507] drm/panic: Fix kmsg screen hang on a long log line Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 062/507] drm/drm_crtc: fix race with dma_fence_signal() in ::get_driver_name() Greg Kroah-Hartman
` (445 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, André Draszik, Philipp Stanner,
Christian König, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Draszik <andre.draszik@linaro.org>
[ Upstream commit 3be436cbd3d265fe4fcfbb5b650edad7b2108443 ]
In [1], sashiko reported the following issue:
=== snip ===
Looking at how these fences are managed, drm_crtc_create_fence()
creates a dma_fence without taking a reference to the drm_device or
drm_crtc. Because the sync_file framework exposes this fence to
userspace, the fence can outlive the CRTC.
The dma_fence contract requires that data accessed by dma_fence_ops
(like get_driver_name) must remain valid for an RCU grace period after
the fence is signaled. However, drm_crtc_cleanup() and the subsequent
freeing of the device do not wait for an RCU grace period via
synchronize_rcu().
If userspace calls ioctl(SYNC_IOC_FILE_INFO) concurrently with a device
hot-unplug:
CPU1 (Userspace)
sync_file_get_name()
ops = rcu_dereference(fence->ops);
if (!dma_fence_test_signaled_flag())
// Preempted or delayed here
CPU2 (Driver Teardown)
Signals the fence (setting fence->ops = NULL)
Destroys and frees the CRTC without waiting for an RCU grace period
CPU1 (Resumes)
ops->get_driver_name(fence) -> drm_crtc_fence_get_driver_name()
crtc = fence_to_crtc(fence); // Casts to the freed CRTC
return crtc->dev->driver->name; // Use-after-free
...
Does the CRTC or DRM device need to be kept alive for the RCU grace
period, or should the fence hold a proper reference to prevent the
use-after-free when get_driver_name() and get_timeline_name() access
the freed CRTC structure?
=== snap ===
I believe this to be a correct observation and this patch implements
the suggestion of waiting for an RCU grace period before proceeding
with destruction of the drm_crtc, so that get_driver_name() and
get_timeline_name() can still work.
Link: https://sashiko.dev/#/patchset/20260618-linux-drm_crtc_fix2-v1-1-c03e77b36f34@linaro.org?part=1
Fixes: 6d6003c4b613 ("drm/fence: add fence timeline to drm_crtc")
Cc: stable@vger.kernel.org
Signed-off-by: André Draszik <andre.draszik@linaro.org>
Reviewed-by: Philipp Stanner <phasta@kernel.org>
Reviewed-by: Christian König <christian.koenig@amd.com>
Link: https://lore.kernel.org/r/20260721-linux-drm_crtc_fix2-v3-1-afa8c71506e6@linaro.org
Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/drm_crtc.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 63ead8ba67564..e8e80c9368529 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -493,14 +493,23 @@ EXPORT_SYMBOL(__drmm_crtc_alloc_with_planes);
* drm_crtc_cleanup - Clean up the core crtc usage
* @crtc: CRTC to cleanup
*
- * This function cleans up @crtc and removes it from the DRM mode setting
- * core. Note that the function does *not* free the crtc structure itself,
- * this is the responsibility of the caller.
+ * This function cleans up @crtc and removes it from the DRM mode setting core,
+ * after first waiting an RCU grace period to ensure @crtc->dev can safely be
+ * dereferenced by our dma_fence_ops.
+ *
+ * Note that the function does *not* free the crtc structure itself, this is the
+ * responsibility of the caller.
*/
void drm_crtc_cleanup(struct drm_crtc *crtc)
{
struct drm_device *dev = crtc->dev;
+ /* Ensure our dma_fence_ops remain valid for an RCU grace period after
+ * the fence is signaled. This is necessary because our dma_fence_ops
+ * dereference crtc->dev.
+ */
+ synchronize_rcu();
+
/* Note that the crtc_list is considered to be static; should we
* remove the drm_crtc at runtime we would have to decrement all
* the indices on the drm_crtc after us in the crtc_list.
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 062/507] drm/drm_crtc: fix race with dma_fence_signal() in ::get_driver_name()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (60 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 061/507] drm/drm_crtc: ensure dma_fence_ops remain valid during device unbind Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 063/507] dma-buf: Fix IOVA offset when linking phys vecs to sgt Greg Kroah-Hartman
` (444 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, André Draszik, Philipp Stanner,
Christian König, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Draszik <andre.draszik@linaro.org>
[ Upstream commit cb104d395da48d965665fefe8502f71b6e7e3733 ]
Since commit 541c8f2468b9 ("dma-buf: detach fence ops on signal v3"),
I'm seeing the BUG_ON() triggering in drm_crtc's fence_to_crtc() via
drm_crtc_fence_get_driver_name() regularly:
Call trace:
panic+0x58/0x5c
die+0x160/0x178
bug_brk_handler+0x70/0xa4
call_el1_break_hook+0x3c/0x1a0
do_el1_brk64+0x24/0x74
el1_brk64+0x34/0x54
el1h_64_sync_handler+0x80/0xfc
el1h_64_sync+0x84/0x88
drm_crtc_fence_get_driver_name+0x60/0x68 (P)
sync_file_get_name+0x184/0x45c
sync_file_ioctl+0x404/0xf70
__arm64_sys_ioctl+0x124/0x1dc
This looks to be caused by a code flow similar to the following:
+++ snip +++
thread A thread B
ioctl(SYNC_IOC_FILE_INFO)
sync_file_ioctl()
sync_file_get_name()
dma_fence_signal_timestamp_locked() dma_fence_driver_name()
ops = rcu_dereference(fence->ops)
if (!dma_fence_test_signaled_flag())
ops->get_driver_name(fence) i.e.
drm_crtc_fence_get_driver_name()
test_and_set_bit(SIGNALED)
RCU_INIT_POINTER(fence->ops, NULL)
drm_crtc_fence_get_driver_name()
BUG_ON(rcu_access_pointer(fence->ops)
!= &drm_crtc_fence_ops)
+++ snap +++
In other words, a fence's ops pointer can now change to NULL on signal,
which wasn't the case before the culprit commit and hence the BUG_ON()
triggers.
Simply drop the BUG_ON() as it's usage of fence ops is invalid now, and
because using BUG_ON() and friends to take down the system is an
unacceptable way to handle a failure.
Note that the adjacent drm_crtc_fence_get_timeline_name() has the same
problem and is fixed by this patch as well.
Fixes: 541c8f2468b9 ("dma-buf: detach fence ops on signal v3")
Cc: stable@vger.kernel.org
Signed-off-by: André Draszik <andre.draszik@linaro.org>
Reviewed-by: Philipp Stanner <phasta@kernel.org>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Christian König <christian.koenig@amd.com>
Link: https://lore.kernel.org/r/20260721-linux-drm_crtc_fix2-v3-2-afa8c71506e6@linaro.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/drm_crtc.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index e8e80c9368529..5295ec122e0d1 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -154,11 +154,8 @@ static void drm_crtc_crc_fini(struct drm_crtc *crtc)
#endif
}
-static const struct dma_fence_ops drm_crtc_fence_ops;
-
static struct drm_crtc *fence_to_crtc(struct dma_fence *fence)
{
- BUG_ON(rcu_access_pointer(fence->ops) != &drm_crtc_fence_ops);
return container_of(fence->extern_lock, struct drm_crtc, fence_lock);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 063/507] dma-buf: Fix IOVA offset when linking phys vecs to sgt
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (61 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 062/507] drm/drm_crtc: fix race with dma_fence_signal() in ::get_driver_name() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 064/507] wifi: mac80211: reload TDLS header pointer after skb_linearize() Greg Kroah-Hartman
` (443 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yili Zhang, Dawid Osuchowski,
Leon Romanovsky, Christian König, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yili Zhang <zhangyili01@baidu.com>
[ Upstream commit d57e3a7d880d783c64aa29457d78b0e3c5a40e3c ]
The dma_buf_phys_vec_to_sgt() routine links every physical range into
the allocated IOVA space at offset zero instead of advancing the offset
by the already mapped length. This breaks the THRU_HOST_BRIDGE flow
whenever phys_vec contains more than one entry: the second and
subsequent dma_iova_link() calls try to install mappings on top of
PTEs that already exist, which fails and makes the whole conversion
return an error.
Fix it by passing the accumulated mapped_len as the IOVA offset. This
matches the pattern used by all other dma_iova_link() callers and is
consistent with the rest of the function: dma_iova_sync() and the
error path in dma_iova_destroy() both operate on the [0, mapped_len)
prefix of the IOVA space, which assumes that the ranges were linked
contiguously starting at offset 0.
Fixes: 3aa31a8bb11e ("dma-buf: provide phys_vec to scatter-gather mapping routine")
Cc: stable@vger.kernel.org
Signed-off-by: Yili Zhang <zhangyili01@baidu.com>
Reviewed-by: Dawid Osuchowski <dawid.osuchowski@linux.intel.com>
Reviewed-by: Leon Romanovsky <leon@kernel.org>
Link: https://lore.kernel.org/r/20260924065508.27245-1-zhangyili01@baidu.com
Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma-buf/dma-buf-mapping.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma-buf/dma-buf-mapping.c b/drivers/dma-buf/dma-buf-mapping.c
index 833be519e1e6a..ef0f22854d018 100644
--- a/drivers/dma-buf/dma-buf-mapping.c
+++ b/drivers/dma-buf/dma-buf-mapping.c
@@ -156,7 +156,7 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach,
phys_vec[i].paddr);
} else if (dma_use_iova(dma->state)) {
ret = dma_iova_link(attach->dev, dma->state,
- phys_vec[i].paddr, 0,
+ phys_vec[i].paddr, mapped_len,
phys_vec[i].len, dir,
DMA_ATTR_MMIO);
if (ret)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 064/507] wifi: mac80211: reload TDLS header pointer after skb_linearize()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (62 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 063/507] dma-buf: Fix IOVA offset when linking phys vecs to sgt Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 065/507] wifi: brcmfmac: map msgbuf RX packet IDs bidirectional Greg Kroah-Hartman
` (442 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Weigang He, Johannes Berg,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weigang He <geoffreyhe2@gmail.com>
[ Upstream commit 35c5a5ea4418571997a7e7af3e7e8922b136f6e6 ]
ieee80211_process_tdls_channel_switch() sets tf = skb->data before it
calls skb_linearize(), and reads tf->action_code afterwards.
ieee80211_rx_h_data() queues TDLS channel switch requests and
responses to the interface after pulling only
offsetof(struct ieee80211_tdls_data, u) bytes, so the skb can still be
non-linear when the interface work handles it. Drivers that build
paged RX skbs do this for every frame that does not fit into the skb
head, e.g. iwlwifi (mvm), which is also the only mac80211 driver
that sets NL80211_FEATURE_TDLS_CHANNEL_SWITCH. If the remaining data
does not fit into the tailroom, skb_linearize() moves the data to a
new head and frees the old one, and the action code is then read from
freed memory. Depending on what that memory holds by then, the frame
is handled as before or ends in the WARN_ON_ONCE() of the default
case.
The frame only has to be a data frame with the TDLS ethertype from an
authorized peer, e.g. relayed by the AP from another station in the
BSS; the read happens before the sender is checked to be a TDLS peer.
Load tf after skb_linearize(), as the request and response handlers
already do.
Found by static analysis tool CodeQL.
Fixes: 8a4d32f30d11 ("mac80211: add TDLS channel-switch Rx flow")
Cc: stable@vger.kernel.org
Assisted-by: LLM codeql
Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
Link: https://patch.msgid.link/20261021145807.3018338-1-geoffreyhe2@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/tdls.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index f663d28d9209c..71db07aa301b7 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -2021,7 +2021,7 @@ void
ieee80211_process_tdls_channel_switch(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb)
{
- struct ieee80211_tdls_data *tf = (void *)skb->data;
+ struct ieee80211_tdls_data *tf;
struct wiphy *wiphy = sdata->local->hw.wiphy;
lockdep_assert_wiphy(wiphy);
@@ -2037,6 +2037,7 @@ ieee80211_process_tdls_channel_switch(struct ieee80211_sub_if_data *sdata,
* The packet/size was already validated by mac80211 Rx path, only look
* at the action type.
*/
+ tf = (void *)skb->data;
switch (tf->action_code) {
case WLAN_TDLS_CHANNEL_SWITCH_REQUEST:
ieee80211_process_tdls_channel_switch_req(sdata, skb);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 065/507] wifi: brcmfmac: map msgbuf RX packet IDs bidirectional
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (63 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 064/507] wifi: mac80211: reload TDLS header pointer after skb_linearize() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 066/507] wifi: rsi: Skip TX aggregation setup for non-QoS frames Greg Kroah-Hartman
` (441 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jason Perlow, Aditya Garg,
Arend van Spriel, Johannes Berg, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Perlow <jperlow@gmail.com>
[ Upstream commit 7ed5dce55fa8393972b1bf2bf5af1c818c5e7dc2 ]
Commit f0ba5fd51ff2 ("wifi: brcmfmac: Set DMA direction for msgbuf
packet IDs") maps the RX packet ID buffers DMA_FROM_DEVICE. The
BCM4364 firmware also reads posted RX buffers, so with VT-d
translation enabled every such read faults ("PTE Read access is not
set") and the firmware crashes and resets in a loop.
Map the RX pool DMA_BIDIRECTIONAL again, as before that commit. TX
keeps DMA_TO_DEVICE.
Fixes: f0ba5fd51ff2 ("wifi: brcmfmac: Set DMA direction for msgbuf packet IDs")
Cc: stable@vger.kernel.org
Signed-off-by: Jason Perlow <jperlow@gmail.com>
Signed-off-by: Aditya Garg <aditya.garg@linux.dev>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Link: https://patch.msgid.link/20261021172238.10004-1-aditya.garg@linux.dev
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index 069ba7016654e..ff47d4827722e 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -1639,7 +1639,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
if (!msgbuf->tx_pktids)
goto fail;
msgbuf->rx_pktids = brcmf_msgbuf_init_pktids(NR_RX_PKTIDS,
- DMA_FROM_DEVICE);
+ DMA_BIDIRECTIONAL);
if (!msgbuf->rx_pktids)
goto fail;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 066/507] wifi: rsi: Skip TX aggregation setup for non-QoS frames
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (64 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 065/507] wifi: brcmfmac: map msgbuf RX packet IDs bidirectional Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 067/507] wifi: cfg80211: fix out-of-bounds read in valid_rule() Greg Kroah-Hartman
` (440 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Kazinsky, Johannes Berg,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Kazinsky <a.kazinsky@ideco.ru>
[ Upstream commit 71f756a4c064b0312f46617c20893ecc17c332e4 ]
When transmitting a non-QoS unicast frame to a station in AP mode,
rsi_core_xmit() assigns IEEE80211_NONQOS_TID (16) to tid. The station
lookup succeeds, allowing tid to index start_tx_aggr[], which has only
IEEE80211_NUM_TIDS (16) elements. This causes an out-of-bounds read and,
if the value read is zero, an out-of-bounds write.
Only access the aggregation state for tids below IEEE80211_NUM_TIDS,
excluding the non-QoS sentinel from TX aggregation setup.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: 19844c0a9a19 ("rsi: data and managemet path changes for AP mode")
Cc: stable@vger.kernel.org
Signed-off-by: Alex Kazinsky <a.kazinsky@ideco.ru>
Link: https://patch.msgid.link/20261015072010.742369-1-a.kazinsky@ideco.ru
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/rsi/rsi_91x_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c
index ead4d4e043280..3281fc94e1078 100644
--- a/drivers/net/wireless/rsi/rsi_91x_core.c
+++ b/drivers/net/wireless/rsi/rsi_91x_core.c
@@ -458,7 +458,7 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
tx_params->sta_id = 0;
}
- if (rsta) {
+ if (rsta && tid < IEEE80211_NUM_TIDS) {
/* Start aggregation if not done for this tid */
if (!rsta->start_tx_aggr[tid]) {
rsta->start_tx_aggr[tid] = true;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 067/507] wifi: cfg80211: fix out-of-bounds read in valid_rule()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (65 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 066/507] wifi: rsi: Skip TX aggregation setup for non-QoS frames Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 068/507] drm/vc4: Publish the output fence outside of job_lock Greg Kroah-Hartman
` (439 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Zijing Yin, Johannes Berg,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijing Yin <yzjaurora@gmail.com>
[ Upstream commit 9d8ec0b5b5295bd23d979d1b2b905de25c36fff2 ]
valid_rule() validates a struct fwdb_rule from the regulatory database
firmware file, but bounds checks only the first byte of the structure,
the length field itself.
It then uses that length, which comes straight out of the file, to
decide whether the optional fields are present, and reads rule->wmm_ptr
at offset 18 of the 20-byte structure once the length claims 20 bytes or
more.
A rule placed in the last bytes of the file therefore makes the parser
read up to 19 bytes past the end of the firmware image. The image comes
from vmalloc() in kernel_read_file(), so with the rule at the end of a
page the read falls into the guard page and oopses, with no memory
debugging enabled.
A length of at least offsetofend(max_bw) but below offsetofend(wmm_ptr)
takes the other branch, so valid_rule() returns true having read nothing
out of bounds, and the database is accepted. regdb_query_country() does
not re-check the rule, and reads rule->start, rule->end, rule->max_bw
and rule->cac_timeout off the end of the kmemdup()ed copy.
A malformed regulatory.db is parsed by cfg80211's own
request_firmware_nowait() at init time, and on demand from user space
through NL80211_CMD_RELOAD_REGDB, which needs CAP_NET_ADMIN but no
wireless hardware. Both paths require write access to the firmware
search path and CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=n.
Bound the whole declared rule, not just its length field. The existing
check on sizeof(rule->len) is still needed, since rule->len has to be
shown to be inside the file before it can be read, so the new test goes
after it. A rule reaching past the end of the file is now rejected,
which fails the database rather than reading out of bounds. That also
gives regdb_query_country() the bound it already assumes.
Fixes: 230ebaa189af ("cfg80211: read wmm rules from regulatory database")
Cc: stable@vger.kernel.org
Signed-off-by: Zijing Yin <yzjaurora@gmail.com>
Link: https://patch.msgid.link/20261015133159.1499728-1-yzjaurora@gmail.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/wireless/reg.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 11665e0a7efc8..44226687349e5 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -679,6 +679,9 @@ static bool valid_rule(const u8 *data, unsigned int size, u16 rule_ptr)
/* mandatory fields */
if (rule->len < offsetofend(struct fwdb_rule, max_bw))
return false;
+ /* the rule must lie entirely within the database */
+ if ((u8 *)rule + rule->len > data + size)
+ return false;
if (rule->len >= offsetofend(struct fwdb_rule, wmm_ptr)) {
u32 wmm_ptr = be16_to_cpu(rule->wmm_ptr) << 2;
struct fwdb_wmm_rule *wmm;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 068/507] drm/vc4: Publish the output fence outside of job_lock
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (66 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 067/507] wifi: cfg80211: fix out-of-bounds read in valid_rule() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 069/507] drm/vc4: Drop the BO reservations " Greg Kroah-Hartman
` (438 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Iago Toral Quiroga, Maíra Canal,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maíra Canal <mcanal@igalia.com>
[ Upstream commit 9ee552a42c3905b4547e83173d46413137ec329a ]
job_lock is taken by the V3D interrupt handler, so nesting an IRQ-unsafe
lock under it creates an inversion. drm_syncobj_replace_fence() takes
drm_syncobj::lock, which other paths acquire with interrupts enabled. For
example, a thread interrupted while holding it blocks the handler on
job_lock, and the handler can only make progress once the submit path
releases job_lock, which it cannot do while waiting for drm_syncobj::lock.
This is reported by lockdep:
[ 188.139076] ========================================================
[ 188.139086] WARNING: possible irq lock inversion dependency detected
[ 188.139096] 7.3.0-rc3-00067-gc4f3feeaf60f #67 Tainted: G C
[ 188.139108] --------------------------------------------------------
[ 188.139116] swapper/0/0 just changed the state of lock:
[ 188.139125] ffff0000054f8ff8 (&vc4->job_lock){-...}-{3:3}, at: vc4_irq+0xa8/0x28c [vc4]
[ 188.139234] but this lock took another, HARDIRQ-unsafe lock in the past:
[ 188.139242] (&syncobj->lock){+.+.}-{3:3}
[ 188.139256] and interrupts could create inverse lock ordering between them.
[ 188.139267] other info that might help us debug this:
[ 188.139275] Possible interrupt unsafe locking scenario:
[ 188.139284] CPU0 CPU1
[ 188.139291] ---- ----
[ 188.139299] lock(&syncobj->lock);
[ 188.139312] local_irq_disable();
[ 188.139320] lock(&vc4->job_lock);
[ 188.139335] lock(&syncobj->lock);
[ 188.139350] <Interrupt>
[ 188.139358] lock(&vc4->job_lock);
[ 188.139372] *** DEADLOCK ***
Hand the fence over after job_lock is dropped. The job can complete and
drop exec->fence in that window, so take a reference first and publish
through the local pointer, as exec may already be gone.
Cc: stable@vger.kernel.org
Fixes: e84fcb95e074 ("drm/vc4: Export fence through syncobj")
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Link: https://patch.msgid.link/20261004-vc4-misc-fixes-v1-1-b763df9e33e1@igalia.com
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/vc4/vc4_gem.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index 6ee4bd77d4331..f4be154d4eb0c 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -639,8 +639,11 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec,
fence->seqno = exec->seqno;
exec->fence = &fence->base;
+ /* The job can complete and drop exec->fence as soon as job_lock is
+ * released, so hold our own reference.
+ */
if (out_sync)
- drm_syncobj_replace_fence(out_sync, exec->fence);
+ dma_fence_get(&fence->base);
vc4_attach_fences(exec);
@@ -662,6 +665,11 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec,
spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+ if (out_sync) {
+ drm_syncobj_replace_fence(out_sync, &fence->base);
+ dma_fence_put(&fence->base);
+ }
+
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 069/507] drm/vc4: Drop the BO reservations outside of job_lock
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (67 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 068/507] drm/vc4: Publish the output fence outside of job_lock Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 070/507] lib/crypto: mips: Disable Octeon SHA code on little-endian kernels Greg Kroah-Hartman
` (437 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Iago Toral Quiroga, Maíra Canal,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maíra Canal <mcanal@igalia.com>
[ Upstream commit 8ef66514d7b993c9fb96a5886f001e3556610c1c ]
vc4_queue_submit() calls drm_exec_fini() with job_lock held and interrupts
disabled. Besides unlocking the reservations, drm_exec_fini() frees the
object array with kvfree(), which asks for preemptible task context or a
non-NMI interrupt, and may reach might_sleep() through vfree().
Considering that an array that exceeds a page can take the vmalloc
fallback, call drm_exec_fini() once job_lock is dropped. The reservations
are then held across the job kick, which is harmless as nothing in the
completion path takes a BO reservation.
Note that vc4_attach_fences() has to stay inside the critical section, as
it walks exec, which the job done worker is free to release as soon as
job_lock is dropped.
Cc: stable@vger.kernel.org
Fixes: 04630796c437 ("drm/vc4: Use DRM Execution Contexts")
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Link: https://patch.msgid.link/20261004-vc4-misc-fixes-v1-2-b763df9e33e1@igalia.com
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/vc4/vc4_gem.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
index f4be154d4eb0c..0fef9b48d3c68 100644
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -647,8 +647,6 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec,
vc4_attach_fences(exec);
- drm_exec_fini(exec_ctx);
-
list_add_tail(&exec->head, &vc4->bin_job_list);
/* If no bin job was executing and if the render job (if any) has the
@@ -665,6 +663,8 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec,
spin_unlock_irqrestore(&vc4->job_lock, irqflags);
+ drm_exec_fini(exec_ctx);
+
if (out_sync) {
drm_syncobj_replace_fence(out_sync, &fence->base);
dma_fence_put(&fence->base);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 070/507] lib/crypto: mips: Disable Octeon SHA code on little-endian kernels
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (68 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 069/507] drm/vc4: Drop the BO reservations " Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 071/507] wifi: mac80211: reinstate IEEE80211_TX_CTL_AMPDU flag in ieee80211_tx_prep_agg() Greg Kroah-Hartman
` (436 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ard Biesheuvel, Eric Biggers,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
[ Upstream commit dd2a4edb26e1c78823c50ba10c42f2d3de2e5ec4 ]
Kernels built for the MIPS64-based Cavium Octeon SoCs are normally
big-endian, but little-endian builds are also supported. Currently, the
SHA-1, SHA-256, and SHA-512 code using the Octeon crypto co-processor is
enabled in both builds.
This code is untestable without the hardware. However, based on the
code itself, it is implausible that it computes hash values correctly in
little-endian builds. Such builds write many incorrect values to COP2:
- SHA-1 and SHA-256: The 64-bit integer that contains the last two
32-bit message words of each block is written to COP2 entirely
byte-reflected, due to missing endianness conversion in
octeon_sha1_start() and octeon_sha256_start() to compensate for
using native 64-bit loads from the message bytes. This differs from
all the earlier message words which are written correctly.
Furthermore, the state is written to COP2 with each 32-bit word
byte-reflected within each 64-bit integer, due to incorrect use of
64-bit endianness conversion in write_octeon_64bit_hash_dword() when
the state is kept in memory in native-endian 32-bit words.
- SHA-512: All the 64-bit message words are written to COP2
byte-reflected, due to missing endianness conversion in
write_octeon_64bit_block_sha512() and octeon_sha512_start(). The
SHA-512 state words seem to be written correctly.
Big-endian kernels aren't affected by these bugs. These bugs also
aren't new; this code has been broken on little-endian ever since it and
Octeon little-endian support were first added in v4.1.
Commit d2a948d2db68 ("MIPS: Octeon: Make octeon-md5 driver
endian-agnostic") made the MD5 code work on little-endian kernels by
adding 64-bit endianness conversions to the COP2 macros used by MD5
(some of which are shared by SHA-1 and SHA-256, despite those algorithms
keeping the state words in native-endian instead of MD5's little-endian,
causing some of the strange behavior described above). However, SHA-1,
SHA-256, and SHA-512 were never fixed to work on little-endian kernels.
Therefore, disable the Octeon SHA-1, SHA-256, and SHA-512 code in
little-endian kernels. This causes the generic code that actually
computes hash values correctly to be used instead.
Fixes: 82be2dcfa6a1 ("crypto: octeon - add SHA1 module")
Fixes: c3d0def62001 ("crypto: octeon - add SHA256 module")
Fixes: fbaa4dfd51a0 ("crypto: octeon - add SHA512 module")
Cc: stable@vger.kernel.org
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://patch.msgid.link/20261022054450.20746-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
lib/crypto/Kconfig | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig
index 56f308dd02731..83b4a211c15d6 100644
--- a/lib/crypto/Kconfig
+++ b/lib/crypto/Kconfig
@@ -237,7 +237,7 @@ config CRYPTO_LIB_SHA1_ARCH
depends on CRYPTO_LIB_SHA1 && !UML
default y if ARM
default y if ARM64
- default y if MIPS && CPU_CAVIUM_OCTEON
+ default y if MIPS && CPU_CAVIUM_OCTEON && CPU_BIG_ENDIAN
default y if PPC
default y if S390
default y if SPARC64
@@ -255,7 +255,7 @@ config CRYPTO_LIB_SHA256_ARCH
depends on CRYPTO_LIB_SHA256 && !UML
default y if ARM && !CPU_V7M
default y if ARM64
- default y if MIPS && CPU_CAVIUM_OCTEON
+ default y if MIPS && CPU_CAVIUM_OCTEON && CPU_BIG_ENDIAN
default y if PPC && SPE
default y if RISCV && 64BIT && TOOLCHAIN_HAS_VECTOR_CRYPTO && \
RISCV_EFFICIENT_VECTOR_UNALIGNED_ACCESS
@@ -275,7 +275,7 @@ config CRYPTO_LIB_SHA512_ARCH
depends on CRYPTO_LIB_SHA512 && !UML
default y if ARM && !CPU_V7M
default y if ARM64
- default y if MIPS && CPU_CAVIUM_OCTEON
+ default y if MIPS && CPU_CAVIUM_OCTEON && CPU_BIG_ENDIAN
default y if RISCV && 64BIT && TOOLCHAIN_HAS_VECTOR_CRYPTO && \
RISCV_EFFICIENT_VECTOR_UNALIGNED_ACCESS
default y if S390
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 071/507] wifi: mac80211: reinstate IEEE80211_TX_CTL_AMPDU flag in ieee80211_tx_prep_agg()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (69 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 070/507] lib/crypto: mips: Disable Octeon SHA code on little-endian kernels Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 072/507] xfrm4: use a full socket for local errors Greg Kroah-Hartman
` (435 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Evan Severson,
Toke Høiland-Jørgensen, Johannes Berg, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Toke Høiland-Jørgensen <toke@toke.dk>
[ Upstream commit 25e73f1d6868c759c8eb56cad4e411692c5341b4 ]
The commit 592234e941f1 ("wifi: mac80211: Fix iTXQ AMPDU fragmentation
handling") changed the way handling of the IEEE80211_TX_CTL_AMPDU flag
is done in mac80211, so the only place it is set is in
ieee80211_tx_dequeue().
This means that any frames that are sent to the driver via drv_tx() will
no longer have the flag set. In particular, this affects packets going
through ieee80211_tx_pending(). Evan reported that this can result in
the ath9k driver failing to account such packets in its block ack
window, eventually overrunning the window and stalling TX.
Fix this by reinstating the flag in ieee80211_tx_prep_agg() when inside
a valid block ack window. This should be harmless for the TXQ path, and
will reinstate the previous behaviour for drivers that use the flag as a
signal to track the packet in the window.
Fixes: 592234e941f1 ("wifi: mac80211: Fix iTXQ AMPDU fragmentation handling")
Cc: stable@vger.kernel.org
Reported-by: Evan Severson <eseverson@gmail.com>
Link: https://lore.kernel.org/all/20261014025734.2288693-1-eseverson@gmail.com/
Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
Tested-by: Evan Severson <eseverson@gmail.com>
Link: https://patch.msgid.link/20261023110052.650519-1-toke@toke.dk
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/tx.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 5714634c81033..27bae2a4fa86e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1130,6 +1130,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
struct sk_buff *purge_skb = NULL;
if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
+ info->flags |= IEEE80211_TX_CTL_AMPDU;
reset_agg_timer = true;
} else if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
/*
@@ -1161,6 +1162,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
if (!tid_tx) {
/* do nothing, let packet pass through */
} else if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
+ info->flags |= IEEE80211_TX_CTL_AMPDU;
reset_agg_timer = true;
} else {
queued = true;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 072/507] xfrm4: use a full socket for local errors
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (70 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 071/507] wifi: mac80211: reinstate IEEE80211_TX_CTL_AMPDU flag in ieee80211_tx_prep_agg() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 073/507] scsi: aic7xxx: Use default settings on the SGI O2 onboard controllers Greg Kroah-Hartman
` (434 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, TencentOS Corvus AI, Eric Dumazet,
Fourie Zhang, Steffen Klassert, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fourie Zhang <fouriezhang@tencent.com>
[ Upstream commit 5def91015ba7b59de62a81384572da7281b8a033 ]
xfrm4_local_error() passes skb->sk to inet_sk() and ip_local_error()
without ensuring it points to a full socket. TCP SYN-ACK skbs can be owned
by TCP_NEW_SYN_RECV request sockets.
xfrm4_tunnel_check_size() already checks sk_fullsock() since commit
1620c88887b1 ("xfrm: Fix the usage of skb->sk"), so iptfs_is_too_big() is
the only remaining IPv4 caller passing a request socket here: the sk it
tests is the listener, while skb->sk is the request socket.
When IP-TFS rejects such an skb because it exceeds its payload MTU, the
local error path treats the request socket as a struct inet_sock. KASAN
reports a slab-out-of-bounds read in ip_local_error() beyond the
request_sock_TCP allocation.
Resolve the skb owner with skb_to_full_sk() before accessing inet_sock
state or reporting the error. This maps a request socket to its listener
and rejects sockets that cannot be used as full sockets, matching what
commit 6973a21ee73c ("ipv6: xfrm: use full sockets in local error paths")
did for xfrm6_local_error().
Fixes: 0e4fbf013fa5 ("xfrm: iptfs: add user packet (tunnel ingress) handling")
Cc: stable@vger.kernel.org
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Link: https://lore.kernel.org/netdev/20260908224856.1591189-1-kuba@kernel.org/
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Assisted-by: tencentos-corvus-ai:hy4-preview
Signed-off-by: Fourie Zhang <fouriezhang@tencent.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/xfrm4_output.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 0ae67d537499a..fffa3c4f456ee 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -38,9 +38,12 @@ int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb)
void xfrm4_local_error(struct sk_buff *skb, u32 mtu)
{
+ struct sock *sk = skb_to_full_sk(skb);
struct iphdr *hdr;
+ if (!sk)
+ return;
+
hdr = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb);
- ip_local_error(skb->sk, EMSGSIZE, hdr->daddr,
- inet_sk(skb->sk)->inet_dport, mtu);
+ ip_local_error(sk, EMSGSIZE, hdr->daddr, inet_sk(sk)->inet_dport, mtu);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 073/507] scsi: aic7xxx: Use default settings on the SGI O2 onboard controllers
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (71 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 072/507] xfrm4: use a full socket for local errors Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 074/507] scsi: aic79xx: Fix NULL pointer dereference in device reset Greg Kroah-Hartman
` (433 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Imre Kaloz,
Martin K. Petersen (Oracle), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Kaloz <kaloz@kernel.org>
[ Upstream commit 696bdfc58975fbc70d2e2347a74e0b562e7e2494 ]
The SGI O2 firmware runs its onboard aic7880s without the Adaptec BIOS, so
scratch RAM holds no settings. The left over BIOS path reads uninitialised
bytes, and bad parity panics the boot.
Use the defaults there with host ID 0. ahc_init() keeps the default host ID
ahc_pci_config() chose, 7 on other PCI controllers, so only the O2 changes.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Imre Kaloz <kaloz@kernel.org>
Link: https://patch.msgid.link/20261026131432.26065-1-kaloz@kernel.org
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/aic7xxx/aic7xxx_core.c | 8 ++++++--
drivers/scsi/aic7xxx/aic7xxx_pci.c | 20 +++++++++++++++++++-
2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c
index b9761f9f0bbc8..8ad82171e925d 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_core.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_core.c
@@ -5266,9 +5266,13 @@ ahc_init(struct ahc_softc *ahc)
/*
* Assume we have a board at this stage and it has been reset.
+ * PCI controllers keep the host ID ahc_pci_config() chose.
*/
- if ((ahc->flags & AHC_USEDEFAULTS) != 0)
- ahc->our_id = ahc->our_id_b = 7;
+ if ((ahc->flags & AHC_USEDEFAULTS) != 0) {
+ if ((ahc->chip & AHC_PCI) == 0)
+ ahc->our_id = 7;
+ ahc->our_id_b = 7;
+ }
/*
* Default to allowing initiator operations.
diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c
index 2d4c85426dc3e..5a04c7d55e4b5 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c
@@ -701,6 +701,21 @@ ahc_find_pci_device(ahc_dev_softc_t pci)
return (NULL);
}
+/*
+ * The SGI O2 firmware runs its onboard controllers, in slots 1 and 2 of the
+ * root bus, without the Adaptec BIOS and at host ID 0. It leaves no settings
+ * in scratch RAM, which may still hold power-on contents with bad parity.
+ */
+static bool
+ahc_pci_sgi_o2_onboard(struct ahc_softc *ahc)
+{
+ int slot = ahc_get_pci_slot(ahc->dev_softc);
+
+ return IS_ENABLED(CONFIG_SGI_IP32) &&
+ ahc_get_pci_bus(ahc->dev_softc) == 0 &&
+ (slot == 1 || slot == 2);
+}
+
int
ahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry)
{
@@ -782,6 +797,9 @@ ahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry)
ahc->bus_intr = ahc_pci_intr;
ahc->bus_chip_init = ahc_pci_chip_init;
+ if (ahc_pci_sgi_o2_onboard(ahc))
+ ahc->flags |= AHC_NO_BIOS_INIT;
+
/* Remember how the card was setup in case there is no SEEPROM */
if ((ahc_inb(ahc, HCNTRL) & POWRDN) == 0) {
ahc_pause(ahc);
@@ -898,7 +916,7 @@ ahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry)
* Assume only one connector and always turn
* on termination.
*/
- our_id = 0x07;
+ our_id = ahc_pci_sgi_o2_onboard(ahc) ? 0 : 0x07;
sxfrctl1 = STPWEN;
}
ahc_outb(ahc, SCSICONF, our_id|ENSPCHK|RESET_SCSI);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 074/507] scsi: aic79xx: Fix NULL pointer dereference in device reset
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (72 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 073/507] scsi: aic7xxx: Use default settings on the SGI O2 onboard controllers Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 075/507] scsi: target: Fix demo-mode dynamic ACL dev-entry UAF vs LUN teardown Greg Kroah-Hartman
` (432 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hannes Reinecke, Andrew Luebke,
Martin K. Petersen (Oracle), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Luebke <andrew.luebke@gmail.com>
[ Upstream commit f057a8bfeb6ff89c65e95540b8700a53c66d4a31 ]
Since commit c67e63800446 ("scsi: aic79xx: Do not reference SCSI command
when resetting device") the device reset SCB has no SCSI command, but
ahd_linux_dev_reset() still sets its residual, and ahd_abort_scbs(), which
completes it, sets its status. Seen on an AIC-7902 when a failing disk
triggered a device reset, which killed the SCSI error handler:
BUG: kernel NULL pointer dereference, address: 0000009c
EIP: ahd_linux_dev_reset.cold+0xee/0x26e
Add NULL command checks to the accessors in aic79xx_osm.h. Also skip
autosense for an SCB without a command and complete it with ahd_done()
right away: the REQUEST SENSE path can clear SCB_DEVICE_RESET, after which
ahd_done() would dereference the missing command.
Fixes: c67e63800446 ("scsi: aic79xx: Do not reference SCSI command when resetting device")
Cc: stable@vger.kernel.org
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Signed-off-by: Andrew Luebke <andrew.luebke@gmail.com>
Assisted-by: LLM
Link: https://patch.msgid.link/20261026172032.749756-1-andrew.luebke@gmail.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/aic7xxx/aic79xx_core.c | 4 +++-
drivers/scsi/aic7xxx/aic79xx_osm.h | 26 +++++++++++++++++++++-----
2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index 3602a1fc40e4e..4abc7948187f8 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -8942,8 +8942,10 @@ ahd_handle_scsi_status(struct ahd_softc *ahd, struct scb *scb)
}
#endif
- if (ahd_perform_autosense(scb) == 0)
+ if (ahd_perform_autosense(scb) == 0) {
+ ahd_done(ahd, scb);
break;
+ }
ahd_compile_devinfo(&devinfo, SCB_GET_OUR_ID(scb),
SCB_GET_TARGET(ahd, scb),
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 793fe19993a90..3bcfcfe18f08b 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -499,6 +499,8 @@ int ahd_linux_show_info(struct seq_file *,struct Scsi_Host *);
static inline
void ahd_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
{
+ if (!cmd)
+ return;
cmd->result &= ~(CAM_STATUS_MASK << 16);
cmd->result |= status << 16;
}
@@ -512,6 +514,8 @@ void ahd_set_transaction_status(struct scb *scb, uint32_t status)
static inline
void ahd_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status)
{
+ if (!cmd)
+ return;
cmd->result &= ~0xFFFF;
cmd->result |= status;
}
@@ -525,6 +529,8 @@ void ahd_set_scsi_status(struct scb *scb, uint32_t status)
static inline
uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd)
{
+ if (!cmd)
+ return CAM_REQ_INPROG;
return ((cmd->result >> 16) & CAM_STATUS_MASK);
}
@@ -537,6 +543,8 @@ uint32_t ahd_get_transaction_status(struct scb *scb)
static inline
uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd)
{
+ if (!cmd)
+ return SAM_STAT_GOOD;
return (cmd->result & 0xFFFF);
}
@@ -564,13 +572,16 @@ u_long ahd_get_transfer_length(struct scb *scb)
static inline
int ahd_get_transfer_dir(struct scb *scb)
{
+ if (!scb->io_ctx)
+ return DMA_NONE;
return (scb->io_ctx->sc_data_direction);
}
static inline
void ahd_set_residual(struct scb *scb, u_long resid)
{
- scsi_set_resid(scb->io_ctx, resid);
+ if (scb->io_ctx)
+ scsi_set_resid(scb->io_ctx, resid);
}
static inline
@@ -582,6 +593,8 @@ void ahd_set_sense_residual(struct scb *scb, u_long resid)
static inline
u_long ahd_get_residual(struct scb *scb)
{
+ if (!scb->io_ctx)
+ return 0;
return scsi_get_resid(scb->io_ctx);
}
@@ -595,11 +608,12 @@ static inline
int ahd_perform_autosense(struct scb *scb)
{
/*
- * We always perform autosense in Linux.
- * On other platforms this is set on a
- * per-transaction basis.
+ * We always perform autosense in Linux, except for the device
+ * reset SCB, which has no command to return sense data to.
*/
- return (1);
+ if (!scb->io_ctx)
+ return 0;
+ return 1;
}
static inline uint32_t
@@ -629,6 +643,8 @@ void ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb);
static inline void
ahd_freeze_scb(struct scb *scb)
{
+ if (!scb->io_ctx)
+ return;
if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
scb->io_ctx->result |= CAM_DEV_QFRZN << 16;
scb->platform_data->dev->qfrozen++;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 075/507] scsi: target: Fix demo-mode dynamic ACL dev-entry UAF vs LUN teardown
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (73 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 074/507] scsi: aic79xx: Fix NULL pointer dereference in device reset Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 076/507] 9p/xen: validate the response size from the backend Greg Kroah-Hartman
` (431 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yu Zhang,
Martin K. Petersen (Oracle), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Zhang <yuz08559@gmail.com>
[ Upstream commit 6a6e7d7230cd4e0a6c003bae5b85bf37a1e77b94 ]
A demo-mode (generate_node_acls=1) login that allocates a dynamic NodeACL
populates that ACL's per-LUN dev entries in core_tpg_add_node_to_devs()
*before* the ACL is linked onto tpg->acl_node_list by
target_add_node_acl():
core_tpg_check_initiator_node_acl():
...
core_tpg_add_node_to_devs(acl, tpg, NULL); /* builds deves */
target_add_node_acl(acl); /* only now listed */
The LUN teardown sweep, core_clear_lun_from_tpg(), enumerates only
tpg->acl_node_list, so a dev entry whose ACL is still in the window above
is invisible to the sweep and is never disabled. It is left on the
se_lun->lun_deve_list after core_tpg_remove_lun() frees the se_lun; when
the same unpacked_lun is later re-added and the se_lun is reallocated at
the same address, the stale dev entry is rediscovered by
target_nacl_find_deve() and core_enable_device_list_for_node() corrupts
lun_deve_list:
BUG: KASAN: slab-use-after-free ...
core_enable_device_list_for_node+0x5ce/0x880
core_tpg_add_node_to_devs+0x169/0x190
core_dev_add_lun+0x146/0x190
target_fabric_port_link+0xe9/0x1b0
configfs_symlink+0x381/0xae0
__x64_sys_symlink+0x55/0x80
The demo-mode login path that drives the ACL/dev-entry creation is
reachable by an unauthenticated initiator; the colliding LUN add/remove is
a local configfs operation.
Commit 49cb77e297dc ("target: Avoid mappedlun symlink creation during lun
shutdown") introduced se_lun->lun_shutdown and guarded the *explicit* ACL
MappedLUN path (target_fabric_mappedlun_link()), but the demo-mode
automatic path, core_tpg_add_node_to_devs() ->
core_enable_device_list_for_node(), was never given the equivalent guard,
and the publish-after-populate ordering in
core_tpg_check_initiator_node_acl() was left unchanged.
Fix it in three cooperating parts:
1) Publish the dynamic NodeACL onto acl_node_list *before* creating its
dev entries, so the teardown sweep can observe them.
2) Refuse to attach a dev entry to an se_lun that is shutting down,
checked under nacl->lun_entry_mutex -- the same lock the sweep takes --
so once the sweep has passed an ACL any later enable for that LUN
observes lun_shutdown and skips it.
3) In core_enable_device_list_for_node(), insert the new dev entry onto
lun->lun_deve_list while still holding nacl->lun_entry_mutex, in both
the replace and the new-entry branch. Previously the entry was added
to nacl->lun_entry_hlist under the mutex but to lun->lun_deve_list only
after dropping it; with the ACL now published early, the sweep could
take the mutex in that gap, find the entry on the hlist,
core_disable_device_list_for_node() it (list_del() on the not-yet-
linked lun_link succeeds and the entry is freed), and then the enable
would list_add_tail() the freed entry back onto lun_deve_list. Linking
both lists under the mutex makes enable and the sweep mutually
exclusive, closing that window.
core_tpg_add_node_to_devs() already ignores the return value of
core_enable_device_list_for_node(), so a shutting-down LUN is simply
skipped.
Cc: stable@vger.kernel.org
Fixes: 49cb77e297dc ("target: Avoid mappedlun symlink creation during lun shutdown")
Signed-off-by: Yu Zhang <yuz08559@gmail.com>
Tested-by: Yu Zhang <yuz08559@gmail.com>
Link: https://patch.msgid.link/20261014013746.46705-1-yuz08559@gmail.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/target/target_core_device.c | 18 +++++++++++++++---
drivers/target/target_core_tpg.c | 10 +++++++++-
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 9db2201aa553f..c5d5d6a91fee7 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -349,6 +349,19 @@ int core_enable_device_list_for_node(
new->attach_count++;
mutex_lock(&nacl->lun_entry_mutex);
+ /*
+ * Do not attach a new dev entry to an se_lun that is being torn down.
+ * lun_shutdown is set by core_tpg_remove_lun() before its
+ * core_clear_lun_from_tpg() sweep; checking it here under the same
+ * nacl->lun_entry_mutex the sweep takes guarantees that once the sweep
+ * has passed this ACL no dev entry can be left dangling on the
+ * se_lun->lun_deve_list that is about to be freed.
+ */
+ if (lun->lun_shutdown) {
+ mutex_unlock(&nacl->lun_entry_mutex);
+ ret = -ENODEV;
+ goto free_stats;
+ }
orig = target_nacl_find_deve(nacl, mapped_lun);
if (orig && orig->se_lun) {
struct se_lun *orig_lun = orig->se_lun;
@@ -375,12 +388,12 @@ int core_enable_device_list_for_node(
new->se_lun_acl = lun_acl;
hlist_del_rcu(&orig->link);
hlist_add_head_rcu(&new->link, &nacl->lun_entry_hlist);
- mutex_unlock(&nacl->lun_entry_mutex);
spin_lock(&lun->lun_deve_lock);
list_del(&orig->lun_link);
list_add_tail(&new->lun_link, &lun->lun_deve_list);
spin_unlock(&lun->lun_deve_lock);
+ mutex_unlock(&nacl->lun_entry_mutex);
kref_put(&orig->pr_kref, target_pr_kref_release);
wait_for_completion(&orig->pr_comp);
@@ -393,11 +406,10 @@ int core_enable_device_list_for_node(
new->se_lun = lun;
new->se_lun_acl = lun_acl;
hlist_add_head_rcu(&new->link, &nacl->lun_entry_hlist);
- mutex_unlock(&nacl->lun_entry_mutex);
-
spin_lock(&lun->lun_deve_lock);
list_add_tail(&new->lun_link, &lun->lun_deve_list);
spin_unlock(&lun->lun_deve_lock);
+ mutex_unlock(&nacl->lun_entry_mutex);
target_luns_data_has_changed(nacl, new, true);
return 0;
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c
index ccff9f6e48266..e615e5e304273 100644
--- a/drivers/target/target_core_tpg.c
+++ b/drivers/target/target_core_tpg.c
@@ -266,6 +266,15 @@ struct se_node_acl *core_tpg_check_initiator_node_acl(
kref_get(&acl->acl_kref);
acl->dynamic_node_acl = 1;
+ /*
+ * Publish the dynamic NodeACL on tpg->acl_node_list before creating
+ * its demo-mode MappedLUN dev entries below, so that a concurrent LUN
+ * teardown sweep (core_clear_lun_from_tpg(), which walks acl_node_list)
+ * can observe and disable those dev entries. Otherwise a dev entry can
+ * be left on an se_lun->lun_deve_list that is about to be freed.
+ */
+ target_add_node_acl(acl);
+
/*
* Here we only create demo-mode MappedLUNs from the active
* TPG LUNs if the fabric is not explicitly asking for
@@ -275,7 +284,6 @@ struct se_node_acl *core_tpg_check_initiator_node_acl(
(tpg->se_tpg_tfo->tpg_check_demo_mode_login_only(tpg) != 1))
core_tpg_add_node_to_devs(acl, tpg, NULL);
- target_add_node_acl(acl);
return acl;
}
EXPORT_SYMBOL(core_tpg_check_initiator_node_acl);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 076/507] 9p/xen: validate the response size from the backend
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (74 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 075/507] scsi: target: Fix demo-mode dynamic ACL dev-entry UAF vs LUN teardown Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 077/507] 9p: dont decrement a server-owned zero nlink Greg Kroah-Hartman
` (430 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yehyeong Lee, Juergen Gross,
Dominique Martinet, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
[ Upstream commit 9b4cf60c6b739461c5b4ec9c52587da6b2608786 ]
p9_xen_response() takes the length of an incoming response from the ring
-- the first field of the 9p header, which the Xen transport reuses as
its framing header -- and uses it to advance the consumer index, but
never checks that it is at least the header size or no larger than the
number of bytes the backend has actually produced.
A malicious or buggy backend can post a response whose size is smaller
than the header (for example 0). The consumer index then never advances,
so the response work re-reads the same ring contents instead of making
progress. In testing this raced with the teardown that the malformed
reply triggers and dereferenced a freed p9_client:
9pfs 9pfs-0: Wrong req tag=ffff
BUG: kernel NULL pointer dereference, address: 0000000000000060
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 0 P4D 0
Oops: Oops: 0000 [#1] SMP NOPTI
CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 7.2.0-rc5 #6 PREEMPT(lazy)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
Workqueue: events p9_xen_response
RIP: 0010:idr_find+0x4/0x10
RSP: 0018:ffffbf5d80063de8 EFLAGS: 00010202
RAX: 0000000000000001 RBX: ffffa229c21195a0 RCX: ffffa229c2400000
RDX: ffffa229c11c2200 RSI: 000000000000ffff RDI: 0000000000000050
RBP: 000000000000ffff R08: 3fffffffffffdfff R09: ffffffffffffffff
R10: 3fffffffffffdfff R11: ffffffff87a60e80 R12: 0000000000000050
R13: 0000000000000000 R14: 000000000000ffff R15: 0000000000100000
FS: 0000000000000000(0000) GS:ffffa22a7661c000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000060 CR3: 000000003ac34002 CR4: 0000000000770ef0
PKRU: 55555554
Call Trace:
<TASK>
p9_tag_lookup+0x2b/0x90
p9_xen_response+0x17c/0x2e0
process_one_work+0x16a/0x3a0
worker_thread+0x172/0x2e0
kthread+0xdd/0x110
ret_from_fork+0x18b/0x240
ret_from_fork_asm+0x1a/0x30
</TASK>
Modules linked in:
CR2: 0000000000000060
---[ end trace 0000000000000000 ]---
Reject a response whose size is outside [sizeof(header), queued] before
using it, matching the validation the backend already applies to
incoming requests.
Fixes: f66c72bea129 ("xen/9pfs: receive responses")
Cc: stable@vger.kernel.org
Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
Reviewed-by: Juergen Gross <jgross@suse.com>
Message-ID: <20261005125640.274054-1-yhlee@isslab.korea.ac.kr>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/9p/trans_xen.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
index 8eea0da8797f4..71a4d276321e2 100644
--- a/net/9p/trans_xen.c
+++ b/net/9p/trans_xen.c
@@ -200,6 +200,14 @@ static void p9_xen_response(struct work_struct *work)
masked_prod, &masked_cons,
XEN_9PFS_RING_SIZE(ring));
+ if (h.size < sizeof(h) ||
+ h.size > xen_9pfs_queued(prod, cons,
+ XEN_9PFS_RING_SIZE(ring))) {
+ dev_warn_ratelimited(&priv->dev->dev,
+ "bad response size %u from backend\n", h.size);
+ break;
+ }
+
req = p9_tag_lookup(priv->client, h.tag);
if (!req || req->status != REQ_STATUS_SENT) {
dev_warn(&priv->dev->dev, "Wrong req tag=%x\n", h.tag);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 077/507] 9p: dont decrement a server-owned zero nlink
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (75 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 076/507] 9p/xen: validate the response size from the backend Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 078/507] batman-adv: Close OGM aggregation before transmission Greg Kroah-Hartman
` (429 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuanfu Xie, Dominique Martinet,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuanfu Xie <yuanfuxie@stu.pku.edu.cn>
[ Upstream commit 4e915aa8566173b44146bc46177c85afbe6bdf96 ]
A 9P2000.L server can report nlink=0 for a regular file that still
exists. On a cache=loose or cache=fscache mount, lookup stores that
value with set_nlink(). A later successful unlink calls
v9fs_dec_count(), which still calls drop_nlink() for a non-directory.
drop_nlink() warns, and the unsigned link count wraps to 4294967295.
fstat() on a descriptor opened before the unlink shows 0 before and
4294967295 after.
The warning on the unpatched kernel, trimmed:
WARNING: fs/inode.c:408 at drop_nlink+0xac/0xd0, CPU#1: trigger/188
CPU: 1 UID: 0 PID: 188 Comm: trigger Tainted: G N 7.3.0-rc4-00537-ga3ff15db6820 #1 PREEMPT(lazy)
RIP: 0010:drop_nlink+0xac/0xd0
Call Trace:
<TASK>
v9fs_remove+0x529/0x750
vfs_unlink+0x2f0/0xbd0
filename_unlinkat+0x340/0x6c0
__x64_sys_unlink+0x46/0x70
do_syscall_64+0xe8/0x4f0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
---[ end trace 0000000000000000 ]---
Directories whose cached nlink is at most 2 already skip this
decrement, because the exported filesystem may not maintain nlink
(commit ac89b2ef9b559). cache=none skips it as well (commit
574aa0b479947). cache=mmap does not take this path: it sets neither
CACHE_META nor CACHE_LOOSE. A regular file on cache=loose or
cache=fscache still does. Its count came from GETATTR and may
already be zero, so skip the decrement when i_nlink is already 0.
Verified on 7.3-rc4-00537-ga3ff15db6820 with only this change. A
server that advertises nlink=0 and accepts the unlink no longer
warns, and the open descriptor stays at nlink 0. An honest server
on the same mount still goes from 1 to 0. A rejected unlink leaves
the count unchanged. cache=none is unchanged. With panic_on_warn
the unpatched kernel panics on the warning; the patched kernel does
not.
Fixes: ac89b2ef9b559 ("9p: don't maintain dir i_nlink if the exported fs doesn't either")
Cc: stable@vger.kernel.org
Signed-off-by: Yuanfu Xie <yuanfuxie@stu.pku.edu.cn>
Message-ID: <8B490036-EBB0-4A36-AE39-F294F7C79649@stu.pku.edu.cn>
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/9p/vfs_inode.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 3829554ca3692..2d7e0c1a5353a 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -495,6 +495,12 @@ static int v9fs_at_to_dotl_flags(int flags)
* nothing and races with concurrent metadata fetches that may already
* have observed the post-unlink value (nlink == 0).
*
+ * The same applies to a regular file whose cached nlink has already been
+ * driven to zero by the server: in the cached modes the attributes come
+ * from GETATTR and are applied verbatim, so decrementing a link count the
+ * server does not maintain only trips the drop_nlink() WARN_ON and
+ * underflows i_nlink.
+ *
* @inode: inode whose nlink is being dropped
*/
static void v9fs_dec_count(struct inode *inode)
@@ -503,6 +509,8 @@ static void v9fs_dec_count(struct inode *inode)
if (!(v9ses->cache & (CACHE_META | CACHE_LOOSE)))
return;
+ if (inode->i_nlink == 0)
+ return;
if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2)
drop_nlink(inode);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 078/507] batman-adv: Close OGM aggregation before transmission
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (76 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 077/507] 9p: dont decrement a server-owned zero nlink Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 079/507] lib/crypto: mldsa: Check pk_len before doing pointer arithmetic Greg Kroah-Hartman
` (428 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Sven Eckelmann,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
[ Upstream commit f91f64a91682c07e6c5f059804e709656364e8a6 ]
The OGM send worker leaves its forwarding packet on forw_bat_list until
after batadv_iv_ogm_emit() returns. Aggregation holds forw_bat_list_lock,
but emission reads and clones the packet without that lock.
CPU 0 can therefore start emitting a queued packet while CPU 1 takes the
list lock, finds the same packet and appends another OGM. The sender can
observe the new packet length before the corresponding direct-link flag
is set, or clone the skb while its length and payload are being updated.
This can transmit an OGM with incorrect flags or inconsistent data.
KCSAN reported:
BUG: KCSAN: data-race in batadv_iv_ogm_queue_add / batadv_iv_send_outstanding_bat_ogm_packet
write to 0xffff888100fedcf8 of 2 bytes by interrupt on cpu 1:
read to 0xffff888100fedcf8 of 2 bytes by task 70 on cpu 2:
value changed: 0x00c0 -> 0x00d8
Mark the aggregate as full under forw_bat_list_lock before emission. This
waits for any ongoing append and prevents further aggregation. Emission
uses packet_len to walk the OGMs, so all queued packets are still sent.
Keep the packet on the list so interface purging can find the worker,
wait for it to finish and free the packet.
Fixes: 9b4aec647a92 ("batman-adv: fix rare race conditions on interface removal")
Cc: stable@vger.kernel.org # 4.10.x: 434becf57bdc ("batman-adv: Limit number of aggregated packets directly")
Cc: stable@vger.kernel.org # 4.10.x
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
[ sven: drop assisted tag, document new meaning of num_packets ]
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/batman-adv/bat_iv_ogm.c | 5 +++++
net/batman-adv/types.h | 8 +++++++-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 53fbdbbe8f4f7..1c2ab79adabc2 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -1909,6 +1909,11 @@ static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
goto out;
}
+ /* Mark aggregate as full before forcing emit. */
+ spin_lock_bh(&bat_priv->forw_bat_list_lock);
+ forw_packet->num_packets = BATADV_MAX_AGGREGATION_PACKETS;
+ spin_unlock_bh(&bat_priv->forw_bat_list_lock);
+
batadv_iv_ogm_emit(forw_packet);
/* we have to have at least one packet in the queue to determine the
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 9bdc5a3e799e2..db0d4f680e65f 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -2019,7 +2019,13 @@ struct batadv_forw_packet {
/** @direct_link_flags: direct link flags for aggregated OGM packets */
DECLARE_BITMAP(direct_link_flags, BATADV_MAX_AGGREGATION_PACKETS);
- /** @num_packets: counter for aggregated OGMv1 packets */
+ /**
+ * @num_packets: counter for aggregated OGMv1 packets. Set to
+ * BATADV_MAX_AGGREGATION_PACKETS (independent of the real number of
+ * aggregated packets) by the send worker to prevent further
+ * aggregation while the packet is emitted. It must therefore not be
+ * used to iterate over the aggregated packets
+ */
u8 num_packets;
/** @delayed_work: work queue callback item for packet sending */
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 079/507] lib/crypto: mldsa: Check pk_len before doing pointer arithmetic
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (77 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 078/507] batman-adv: Close OGM aggregation before transmission Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 080/507] lib/crypto: mldsa: Explicitly check that alg is a valid value Greg Kroah-Hartman
` (427 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ard Biesheuvel, Eric Biggers,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
[ Upstream commit 5c140c870044af2f4b79e87b42d078cf7c318582 ]
Though common in the kernel and benign in practice (not even triggering
UBSAN warnings), taking an address past the end of an array is undefined
behavior according to the C specification.
Therefore, compute &pk[RHO_LEN] only after pk_len has been validated,
since pk_len could be less than RHO_LEN if an incorrectly sized public
key is provided.
(Also fix a typo that isn't worth its own commit.)
Fixes: 64edccea594c ("lib/crypto: Add ML-DSA verification support")
Cc: stable@vger.kernel.org
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://patch.msgid.link/20261029054534.68481-2-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
lib/crypto/mldsa.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/lib/crypto/mldsa.c b/lib/crypto/mldsa.c
index c96fddc4e7dcf..68a1b432315b1 100644
--- a/lib/crypto/mldsa.c
+++ b/lib/crypto/mldsa.c
@@ -306,7 +306,7 @@ static const u8 *decode_t1_elem(struct mldsa_ring_elem *out,
* Reference: FIPS 204 Algorithm 27, sigDecode.
*
* This also validates that the coefficients of z are in range, corresponding
- * the infinity norm check at the end of Algorithm 8, ML-DSA.Verify_internal.
+ * to the infinity norm check at the end of Algorithm 8, ML-DSA.Verify_internal.
*
* Finally, this also converts z to NTT form.
*/
@@ -533,7 +533,7 @@ int mldsa_verify(enum mldsa_alg alg, const u8 *sig, size_t sig_len,
/* For now this just does pure ML-DSA with an empty context string. */
static const u8 msg_prefix[2] = { /* dom_sep= */ 0, /* ctx_len= */ 0 };
const u8 *ctilde; /* The signer's commitment hash */
- const u8 *t1_encoded = &pk[RHO_LEN]; /* Next encoded element of t_1 */
+ const u8 *t1_encoded; /* Next encoded element of t_1 */
u8 *h; /* The signer's hint vector, length k * N */
size_t w1_enc_len;
@@ -587,6 +587,7 @@ int mldsa_verify(enum mldsa_alg alg, const u8 *sig, size_t sig_len,
* The computation is the same for each of the k rows. Just do each row
* before moving on to the next, resulting in only one loop over k.
*/
+ t1_encoded = &pk[RHO_LEN];
for (int i = 0; i < k; i++) {
/*
* tmp = NTT(A) * NTT(z) * 2^-32
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 080/507] lib/crypto: mldsa: Explicitly check that alg is a valid value
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (78 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 079/507] lib/crypto: mldsa: Check pk_len before doing pointer arithmetic Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 081/507] lib/crypto: mldsa: Add __must_check to mldsa_verify() Greg Kroah-Hartman
` (426 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ard Biesheuvel, Eric Biggers,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
[ Upstream commit efb621a57d7e4ce28e12082ba5692231858c4a3a ]
C doesn't guarantee at the language level that an enum actually has one
of the declared values.
For robustness, make mldsa_verify() handle invalid values of 'alg'.
No effect on current callers, who always pass a valid value for 'alg'.
(Except for the KUnit test case that this commit adds.)
Fixes: 64edccea594c ("lib/crypto: Add ML-DSA verification support")
Cc: stable@vger.kernel.org
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://patch.msgid.link/20261029054534.68481-3-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/crypto/mldsa.h | 1 +
lib/crypto/mldsa.c | 10 ++++++++--
lib/crypto/tests/mldsa_kunit.c | 9 +++++++++
3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/include/crypto/mldsa.h b/include/crypto/mldsa.h
index 3ef2676787c9e..e0754879e7452 100644
--- a/include/crypto/mldsa.h
+++ b/include/crypto/mldsa.h
@@ -48,6 +48,7 @@ enum mldsa_alg {
* Return:
* * 0 if the signature is valid
* * -EBADMSG if the signature and/or public key is malformed
+ * * -EINVAL if @alg is not a valid value
* * -EKEYREJECTED if the signature is invalid but otherwise well-formed
* * -ENOMEM if out of memory so the validity of the signature is unknown
*/
diff --git a/lib/crypto/mldsa.c b/lib/crypto/mldsa.c
index 68a1b432315b1..80e0e63b418a7 100644
--- a/lib/crypto/mldsa.c
+++ b/lib/crypto/mldsa.c
@@ -528,8 +528,8 @@ static size_t encode_w1(u8 out[MAX_W1_ENCODED_LEN],
int mldsa_verify(enum mldsa_alg alg, const u8 *sig, size_t sig_len,
const u8 *msg, size_t msg_len, const u8 *pk, size_t pk_len)
{
- const struct mldsa_parameter_set *params = &mldsa_parameter_sets[alg];
- const int k = params->k, l = params->l;
+ const struct mldsa_parameter_set *params;
+ int k, l;
/* For now this just does pure ML-DSA with an empty context string. */
static const u8 msg_prefix[2] = { /* dom_sep= */ 0, /* ctx_len= */ 0 };
const u8 *ctilde; /* The signer's commitment hash */
@@ -537,6 +537,12 @@ int mldsa_verify(enum mldsa_alg alg, const u8 *sig, size_t sig_len,
u8 *h; /* The signer's hint vector, length k * N */
size_t w1_enc_len;
+ if (alg != MLDSA44 && alg != MLDSA65 && alg != MLDSA87)
+ return -EINVAL;
+ params = &mldsa_parameter_sets[alg];
+ k = params->k;
+ l = params->l;
+
/* Validate the public key and signature lengths. */
if (pk_len != params->pk_len || sig_len != params->sig_len)
return -EBADMSG;
diff --git a/lib/crypto/tests/mldsa_kunit.c b/lib/crypto/tests/mldsa_kunit.c
index ec64e10c97f25..d0ee704a36944 100644
--- a/lib/crypto/tests/mldsa_kunit.c
+++ b/lib/crypto/tests/mldsa_kunit.c
@@ -372,6 +372,14 @@ static void test_mldsa_use_hint(struct kunit *test)
}
}
+static void test_mldsa_invalid_alg(struct kunit *test)
+{
+ KUNIT_ASSERT_EQ(test, -EINVAL,
+ mldsa_verify(MLDSA44 - 1, NULL, 0, NULL, 0, NULL, 0));
+ KUNIT_ASSERT_EQ(test, -EINVAL,
+ mldsa_verify(MLDSA87 + 1, NULL, 0, NULL, 0, NULL, 0));
+}
+
static void benchmark_mldsa(struct kunit *test,
const struct mldsa_testvector *tv)
{
@@ -414,6 +422,7 @@ static struct kunit_case mldsa_kunit_cases[] = {
KUNIT_CASE(test_mldsa65),
KUNIT_CASE(test_mldsa87),
KUNIT_CASE(test_mldsa_use_hint),
+ KUNIT_CASE(test_mldsa_invalid_alg),
KUNIT_CASE(benchmark_mldsa44),
KUNIT_CASE(benchmark_mldsa65),
KUNIT_CASE(benchmark_mldsa87),
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 081/507] lib/crypto: mldsa: Add __must_check to mldsa_verify()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (79 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 080/507] lib/crypto: mldsa: Explicitly check that alg is a valid value Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 082/507] batman-adv: mcast: validate tracker padding before forwarding Greg Kroah-Hartman
` (425 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ard Biesheuvel, Eric Biggers,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
[ Upstream commit 01ad209f122b7c173477bd60c7997564f9c65961 ]
Signature verification status always must be checked. Add __must_check,
for consistency with e.g. the AES-GCM and ChaCha20Poly1305 functions.
No effect on current callers, who always check the return value.
Fixes: 64edccea594c ("lib/crypto: Add ML-DSA verification support")
Cc: stable@vger.kernel.org
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Link: https://patch.msgid.link/20261029054534.68481-4-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/crypto/mldsa.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/crypto/mldsa.h b/include/crypto/mldsa.h
index e0754879e7452..b156f166a1413 100644
--- a/include/crypto/mldsa.h
+++ b/include/crypto/mldsa.h
@@ -52,8 +52,9 @@ enum mldsa_alg {
* * -EKEYREJECTED if the signature is invalid but otherwise well-formed
* * -ENOMEM if out of memory so the validity of the signature is unknown
*/
-int mldsa_verify(enum mldsa_alg alg, const u8 *sig, size_t sig_len,
- const u8 *msg, size_t msg_len, const u8 *pk, size_t pk_len);
+int __must_check mldsa_verify(enum mldsa_alg alg, const u8 *sig, size_t sig_len,
+ const u8 *msg, size_t msg_len, const u8 *pk,
+ size_t pk_len);
#if IS_ENABLED(CONFIG_CRYPTO_LIB_MLDSA_KUNIT_TEST)
/* Internal function, exposed only for unit testing */
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 082/507] batman-adv: mcast: validate tracker padding before forwarding
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (80 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 081/507] lib/crypto: mldsa: Add __must_check to mldsa_verify() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 083/507] batman-adv: tpmeter: fix u32 truncation of reported bytes Greg Kroah-Hartman
` (424 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kyle Zeng, Sven Eckelmann,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kyle Zeng <kylebot@openai.com>
[ Upstream commit ea01fff30f631e67ee5f0a2b97855d772b3a35fc ]
A multicast tracker with an even number of destinations needs two
padding bytes after its destination list. batadv_mcast_forw_packet()
currently only checks that the count field and the addresses fit in
the tracker TVLV.
If an unpadded even tracker is compacted to an odd number of
destinations, batadv_mcast_forw_shrink_update_headers() includes those
missing padding bytes in the amount to remove. The subsequent memmove
can then write two bytes past the old packet tail. With no tailroom,
this corrupts skb_shared_info.
Include the required padding in the existing tracker length check.
This rejects the malformed tracker before either received or locally
generated packets can reach the compactor.
Fixes: 2dfe644a1ce0 ("batman-adv: mcast: shrink tracker packet after scrubbing")
Cc: stable@vger.kernel.org
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/batman-adv/multicast_forw.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/batman-adv/multicast_forw.c b/net/batman-adv/multicast_forw.c
index ac97cd8b81dc9..9ffed1f237b6b 100644
--- a/net/batman-adv/multicast_forw.c
+++ b/net/batman-adv/multicast_forw.c
@@ -950,8 +950,11 @@ static int batadv_mcast_forw_packet(struct batadv_priv *bat_priv,
dest = (u8 *)mcast_tracker + sizeof(*mcast_tracker);
- /* check if full tracker tvlv is within skb length */
+ /* check if full tracker tvlv, including padding, is within skb length */
tvlv_len = sizeof(*mcast_tracker) + ETH_ALEN * num_dests;
+ if (!(num_dests % 2))
+ tvlv_len += 2;
+
if (tvlv_len > skb_network_header_len(skb))
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 083/507] batman-adv: tpmeter: fix u32 truncation of reported bytes
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (81 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 082/507] batman-adv: mcast: validate tracker padding before forwarding Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 084/507] batman-adv: dat: initialize orig_node of unfilled candidate slots Greg Kroah-Hartman
` (423 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Sven Eckelmann, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <sven@narfation.org>
[ Upstream commit 1025b76d13288a311e8259a0eefde0854fa63c41 ]
When more than 4 GB are transferred by the throughput meter,
batadv_tp_batctl_notify() will cut of the upper 32 bit of the u64 counter
and thus under-report the actual transferred bytes.
The data type of the temporary storage variable must therefore still
continue to use u64.
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/bug/linux-08bb3be4-6c6a-452d-b4e4-606940c6cfa5
Fixes: 33a3bb4a3345 ("batman-adv: throughput meter implementation")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/batman-adv/tp_meter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
index 022eb13e8ec47..56feb02d2b7ef 100644
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -221,7 +221,7 @@ static void batadv_tp_batctl_notify(enum batadv_tp_meter_reason reason,
unsigned long start_time, u64 total_sent,
u32 cookie)
{
- u32 total_bytes;
+ u64 total_bytes;
u32 test_time;
u8 result;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 084/507] batman-adv: dat: initialize orig_node of unfilled candidate slots
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (82 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 083/507] batman-adv: tpmeter: fix u32 truncation of reported bytes Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 085/507] batman-adv: fix skb leak when hard_iface is being released Greg Kroah-Hartman
` (422 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Linus Lüssing,
Sven Eckelmann, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <sven@narfation.org>
[ Upstream commit 4eb19a389d74f06901b4cd6f24b996b2e84eaefc ]
batadv_dat_select_candidates() allocates the candidate array without
zeroing it. batadv_choose_next_candidate() marks each slot as
BATADV_DAT_CANDIDATE_NOT_FOUND but only sets orig_node when an eligible
originator was found. In the following rounds,
batadv_is_orig_node_eligible() compares res[j].orig_node of all previous
slots against the evaluated originator. For slots without candidates, it
reads uninitialized memory.
The orig_node has to be cleared together with the
BATADV_DAT_CANDIDATE_NOT_FOUND type.
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/bug/linux-b25d9aa4-10bb-427c-a145-ccaadc2a1bb9
Fixes: 785ea1144182 ("batman-adv: Distributed ARP Table - create DHT helper functions")
Acked-by: Linus Lüssing <linus.luessing@c0d3.blue>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/batman-adv/distributed-arp-table.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 011cfdc47fab4..86791ddc148f6 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -653,6 +653,7 @@ static void batadv_choose_next_candidate(struct batadv_priv *bat_priv,
* NOT_FOUND
*/
cands[select].type = BATADV_DAT_CANDIDATE_NOT_FOUND;
+ cands[select].orig_node = NULL;
/* iterate over the originator list and find the node with the closest
* dat_address which has not been selected yet
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 085/507] batman-adv: fix skb leak when hard_iface is being released
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (83 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 084/507] batman-adv: dat: initialize orig_node of unfilled candidate slots Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 086/507] batman-adv: stop originator purge worker before freeing TT Greg Kroah-Hartman
` (421 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sven Eckelmann, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <sven@narfation.org>
[ Upstream commit 522e4aece2e96cacbb8a6ae1eec0d4c0dd6f4fed ]
batadv_batman_skb_recv() owns the skb it is given. When the hard_iface
refcount already dropped to zero, the function jumped to err_out, which
only returned NET_RX_DROP and skipped the kfree_skb() under err_free.
To avoid a leak, free the skb before returning in this case.
Cc: stable@vger.kernel.org
Fixes: 4fe56e60ac1b ("batman-adv: Check hard_iface refcnt when receiving skb")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/batman-adv/main.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index d89d44706269b..eec28e7f82b51 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -483,8 +483,10 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
* shut down otherwise the packet may trigger de-reference errors
* further down in the receive path.
*/
- if (!kref_get_unless_zero(&hard_iface->refcount))
- goto err_out;
+ if (!kref_get_unless_zero(&hard_iface->refcount)) {
+ kfree_skb(skb);
+ return NET_RX_DROP;
+ }
skb = skb_share_check(skb, GFP_ATOMIC);
@@ -540,7 +542,6 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev,
kfree_skb(skb);
err_put:
batadv_hardif_put(hard_iface);
-err_out:
return NET_RX_DROP;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 086/507] batman-adv: stop originator purge worker before freeing TT
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (84 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 085/507] batman-adv: fix skb leak when hard_iface is being released Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 087/507] batman-adv: tt: ignore ROAM flag of received ADD changes Greg Kroah-Hartman
` (420 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Sven Eckelmann, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <sven@narfation.org>
[ Upstream commit f89eda5a9ccf82cba06b085b42ebc4886b8dfe9e ]
batadv_mesh_free() releases the translation tables via batadv_tt_free()
before batadv_originator_free() stops orig_work. The purge worker can
therefore still run while the TT is torn down. When an originator times
out, batadv_purge_orig_ref() calls batadv_tt_global_del_orig(), which
loads tt.global_hash and walks all buckets while taking their locks:
CPU0 CPU1
batadv_tt_free() batadv_purge_orig()
batadv_tt_global_del_orig()
hash = ...tt.global_hash;
batadv_tt_global_table_free()
batadv_hash_destroy(hash);
spin_lock_bh(&hash->list_locks[i]);
Disable orig_work at the beginning of batadv_mesh_free(), directly after
the mesh was marked as deactivating. The second
disable_delayed_work_sync() in batadv_originator_free() is harmless because
it is free'd anyway.
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260708091821.314516-1-sw%40simonwunderlich.de?part=3
Fixes: 9d31b3ce8168 ("batman-adv: fix potential TT client + orig-node memory leak")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/batman-adv/main.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index eec28e7f82b51..5d5a0be323e60 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -294,6 +294,11 @@ void batadv_mesh_free(struct net_device *mesh_iface)
WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_DEACTIVATING);
+ /* the originator purge worker accesses (among others) the TT tables
+ * and must therefore be stopped before any of them are freed
+ */
+ disable_delayed_work_sync(&bat_priv->orig_work);
+
batadv_purge_outstanding_packets(bat_priv, NULL);
batadv_tp_stop_all(bat_priv);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 087/507] batman-adv: tt: ignore ROAM flag of received ADD changes
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (85 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 086/507] batman-adv: stop originator purge worker before freeing TT Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 088/507] batman-adv: tt: dont drop local events queued during TVLV update Greg Kroah-Hartman
` (419 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sven Eckelmann, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <sven@narfation.org>
[ Upstream commit c5d68abe6e7f1dbd132a602cb696fe1fff0389eb ]
A received TT change (OGM diff or full table response) with the ROAM flag
but without DEL is handled by batadv_tt_global_add() like a ROAMING_ADV:
* a newly created global entry gets BATADV_TT_CLIENT_ROAM and is
therefore excluded from the global CRC. The sender has it in its local
CRC and the receiver has to request the full table again
* batadv_tt_global_purge_local() removes the local entry of the
receiver. The receiver's own client is considered as roamed to the sender
and frames for it are rerouted
The ROAM flag only has a meaning together with DEL. Drop it on reception to
keep it from populating the global table with a temporary ROAMING entry
which is not part of the CRC - and therefore causing a CRC mismatch.
Cc: stable@vger.kernel.org
Fixes: 068ee6e204e1 ("batman-adv: roaming handling mechanism redesign")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/batman-adv/translation-table.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 68f79853032ed..6802203119dfa 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -3408,21 +3408,30 @@ static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
u16 tt_num_changes, u8 ttvn)
{
int roams;
+ u8 flags;
int i;
for (i = 0; i < tt_num_changes; i++) {
- if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) {
- roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM;
+ flags = (tt_change + i)->flags;
+
+ if (flags & BATADV_TT_CLIENT_DEL) {
+ roams = flags & BATADV_TT_CLIENT_ROAM;
batadv_tt_global_del(bat_priv, orig_node,
(tt_change + i)->addr,
ntohs((tt_change + i)->vid),
"tt removed by changes",
roams);
} else {
+ /* an announced client cannot have roamed away from
+ * orig_node. Only a ROAMING_ADV is allowed to add a
+ * global entry with the ROAM flag
+ */
+ flags &= ~BATADV_TT_CLIENT_ROAM;
+
if (!batadv_tt_global_add(bat_priv, orig_node,
(tt_change + i)->addr,
ntohs((tt_change + i)->vid),
- (tt_change + i)->flags, ttvn))
+ flags, ttvn))
/* In case of problem while storing a
* global_entry, we stop the updating
* procedure without committing the
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 088/507] batman-adv: tt: dont drop local events queued during TVLV update
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (86 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 087/507] batman-adv: tt: ignore ROAM flag of received ADD changes Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 089/507] net: jme: keep RX MAC clock enabled for WoL Greg Kroah-Hartman
` (418 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Sven Eckelmann, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <sven@narfation.org>
[ Upstream commit ed7a0dfdd370acb48be7a281df732c1bebcc7f1d ]
batadv_tt_tvlv_container_update() read the number of local changes without
holding changes_list_lock. batadv_tt_local_event() is not serialized by
the commit_lock and can queue new events before the changes_list is
flushed:
CPU0 CPU1
batadv_tt_tvlv_container_update()
num = ...local_changes;
batadv_tt_local_event()
list_add_tail(...);
...local_changes++;
spin_lock_bh(&...changes_list_lock);
/* only num events copied but all freed */
The additional events were freed without ever being sent. Other nodes will
only notice this via a CRC mismatch and must request the full table.
The number of changes and the changes_list must therefore be taken
atomically. Events queued afterwards then stay in the tt.changes_list for
the next TT round.
The changes can no longer be kept for the next round when the TVLV buffer
allocation fails. But they would be sent with a skipped TTVN anyway, so the
other nodes have to request the full table in this case either way. The
last changeset is only dropped in this case when the TTVN was incremented.
Without new changes, it still describes the current TTVN.
Previously, the unconsumed changes caused a retry of the TVLV container
update in the next commit round. Since the changes are now consumed, the
next round would only take the path without changes and wait for
BATADV_TT_OGM_APPEND_MAX rounds before updating the container again. Until
then, the outdated container with the previous TTVN would still be
announced. The ogm_append_cnt is therefore reset on failure to retry the
update in the next OGM interval.
This doesn't make the CRC consistent with the announced changeset. The
local table modifications are still not serialized with the commit and
batadv_tt_local_transition_new() can still make a client part of the CRC
for which the event is only part of the next TT round. Such an
inconsistency is detected by the CRC check of the other nodes and solved
via a full table request.
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/bug/linux-fc286ddd-5bed-4683-b842-ee7a307eeb19
Fixes: a73105b8d4c7 ("batman-adv: improved client announcement mechanism")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/batman-adv/translation-table.c | 61 +++++++++++++++++++++++-------
1 file changed, 48 insertions(+), 13 deletions(-)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 6802203119dfa..b1dae5e1bc23d 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1006,22 +1006,24 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
* batadv_tt_tvlv_container_update() - update the translation table tvlv
* container after local tt changes have been committed
* @bat_priv: the bat priv with all the mesh interface information
+ * @changes_list: list of committed changes which will be consumed
+ * @tt_diff_entries_num: number of entries in @changes_list
*/
-static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
+static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv,
+ struct list_head *changes_list,
+ int tt_diff_entries_num)
{
struct batadv_tvlv_tt_change *tt_change;
struct batadv_tt_change_node *entry;
struct batadv_tvlv_tt_data *tt_data;
struct batadv_tt_change_node *safe;
int tt_diff_entries_count = 0;
- int tt_diff_entries_num = 0;
bool drop_changes = false;
size_t tt_extra_len = 0;
int tt_change_len = 0;
int tt_diff_len;
u16 tvlv_len;
- tt_diff_entries_num = READ_ONCE(bat_priv->tt.local_changes);
tt_diff_len = batadv_tt_len(tt_diff_entries_num);
/* if we have too many changes for one packet don't send any
@@ -1039,19 +1041,39 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv, &tt_data,
&tt_change, &tt_diff_len);
- if (!tvlv_len)
+ if (!tvlv_len) {
+ /* the changes are lost and the other nodes have to request the
+ * full table. Don't answer TT requests for the new TTVN with
+ * the stale changeset of the previous TTVN. Without changes, the
+ * TTVN was not incremented and the last changeset is still valid
+ */
+ if (drop_changes || tt_diff_entries_num > 0) {
+ list_for_each_entry_safe(entry, safe, changes_list,
+ list) {
+ list_del(&entry->list);
+ kmem_cache_free(batadv_tt_change_cache, entry);
+ }
+
+ spin_lock_bh(&bat_priv->tt.last_changeset_lock);
+ kfree(bat_priv->tt.last_changeset);
+ bat_priv->tt.last_changeset = NULL;
+ bat_priv->tt.last_changeset_len = 0;
+ spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
+ }
+
+ /* announce the already committed TTVN in the next OGM interval
+ * instead of waiting for BATADV_TT_OGM_APPEND_MAX idle rounds
+ */
+ atomic_set(&bat_priv->tt.ogm_append_cnt, 0);
return;
+ }
tt_data->flags = BATADV_TT_OGM_DIFF;
if (!drop_changes && tt_diff_len == 0)
goto container_register;
- spin_lock_bh(&bat_priv->tt.changes_list_lock);
- WRITE_ONCE(bat_priv->tt.local_changes, 0);
-
- list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
- list) {
+ list_for_each_entry_safe(entry, safe, changes_list, list) {
if (tt_diff_entries_count < tt_diff_entries_num) {
memcpy(tt_change + tt_diff_entries_count,
&entry->change,
@@ -1061,7 +1083,6 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
list_del(&entry->list);
kmem_cache_free(batadv_tt_change_cache, entry);
}
- spin_unlock_bh(&bat_priv->tt.changes_list_lock);
tt_extra_len = batadv_tt_len(tt_diff_entries_num -
tt_diff_entries_count);
@@ -3892,11 +3913,25 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
*/
static void batadv_tt_local_commit_changes_nolock(struct batadv_priv *bat_priv)
{
+ LIST_HEAD(changes_list);
+ int changes_num;
+
lockdep_assert_held(&bat_priv->tt.commit_lock);
- if (READ_ONCE(bat_priv->tt.local_changes) == 0) {
+ /* atomically get the list of changes. The TTVN decision and the
+ * announced changeset must cover the same events. Events queued
+ * afterwards stay in the tt.changes_list for the next TT round
+ */
+ spin_lock_bh(&bat_priv->tt.changes_list_lock);
+ list_splice_init(&bat_priv->tt.changes_list, &changes_list);
+ changes_num = READ_ONCE(bat_priv->tt.local_changes);
+ WRITE_ONCE(bat_priv->tt.local_changes, 0);
+ spin_unlock_bh(&bat_priv->tt.changes_list_lock);
+
+ if (changes_num == 0) {
if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))
- batadv_tt_tvlv_container_update(bat_priv);
+ batadv_tt_tvlv_container_update(bat_priv, &changes_list,
+ changes_num);
return;
}
@@ -3913,7 +3948,7 @@ static void batadv_tt_local_commit_changes_nolock(struct batadv_priv *bat_priv)
/* reset the sending counter */
atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
- batadv_tt_tvlv_container_update(bat_priv);
+ batadv_tt_tvlv_container_update(bat_priv, &changes_list, changes_num);
}
/**
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 089/507] net: jme: keep RX MAC clock enabled for WoL
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (87 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 088/507] batman-adv: tt: dont drop local events queued during TVLV update Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 090/507] ipv6: raw: fix use-after-free in rawv6_send_hdrinc() Greg Kroah-Hartman
` (417 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Franck Baur, Dave Miller,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Franck Baur <franck.baur.67@gmail.com>
[ Upstream commit ed9179fc7228315fb745dc3b111bae446e6894d2 ]
On the JMicron JMC250 revision 03, the MAC reset performed during
suspend leaves GPREG1_RXCLKOFF set. Although the driver enables Magic
Packet detection, the gated RX MAC clock prevents wake-up from ACPI S3.
Keep the RX MAC clock enabled while WoL is armed. Restore the gated
clock state immediately after disabling WoL during resume, preserving
the RX engine initialization ordering.
Prevent concurrent link-change work from gating the clock again after
WoL has been armed. Quiesce interrupt-driven link-change scheduling,
synchronize pending interrupts, and cancel outstanding link-change
work before programming WoL in suspend and shutdown paths.
Restore the deferred processing state before requesting link
reinitialization on resume.
Tested on an ASUS K42JE with JMC250 [197b:0250] rev 03 using a
Debian 6.12.111 kernel and an externally built module. ACPI S3 wake
with a Magic Packet completed in 19 seconds, while a control without
a Magic Packet resumed through the RTC alarm after 123 seconds.
Ethernet and SSH recovered after resume.
S4 and S5 wake behaviour has not been validated with this revision.
Fixes: 854a2e7c331a ("jme: Safer MAC processor reset sequence")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Franck Baur <franck.baur.67@gmail.com>
Signed-off-by: Dave Miller <davem@davem-thinkpadp1gen8.ibmlond.csb>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/jme.c | 37 ++++++++++++++++++++++++++++++++-----
drivers/net/ethernet/jme.h | 1 +
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 25ec5f757c682..acb4d41f56e10 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -1502,7 +1502,8 @@ jme_intr_msi(struct jme_adapter *jme, u32 intrstat)
* all other events are ignored
*/
jwrite32(jme, JME_IEVE, intrstat);
- schedule_work(&jme->linkch_task);
+ if (!test_bit(JME_FLAG_WOL_QUIESCE, &jme->flags))
+ schedule_work(&jme->linkch_task);
goto out_reenable;
}
@@ -1546,7 +1547,8 @@ jme_intr_msi(struct jme_adapter *jme, u32 intrstat)
/*
* Re-enable interrupt
*/
- jwrite32f(jme, JME_IENS, INTR_ENABLE);
+ if (!test_bit(JME_FLAG_WOL_QUIESCE, &jme->flags))
+ jwrite32f(jme, JME_IENS, INTR_ENABLE);
}
static irqreturn_t
@@ -1892,6 +1894,7 @@ jme_powersave_phy(struct jme_adapter *jme)
jme_set_100m_half(jme);
if (jme->reg_pmcs & (PMCS_LFEN | PMCS_LREN))
jme_wait_link(jme);
+ jme_mac_rxclk_on(jme);
jme_clear_pm_enable_wol(jme);
} else {
jme_phy_off(jme);
@@ -3158,6 +3161,21 @@ jme_shutdown(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct jme_adapter *jme = netdev_priv(netdev);
+ if (netif_running(netdev)) {
+ set_bit(JME_FLAG_WOL_QUIESCE, &jme->flags);
+ netif_device_detach(netdev);
+ netif_stop_queue(netdev);
+ jme_stop_irq(jme);
+ synchronize_irq(pdev->irq);
+ jme_stop_irq(jme);
+ cancel_work_sync(&jme->linkch_task);
+ tasklet_disable(&jme->pcc_task);
+ napi_disable(&jme->napi);
+ tasklet_disable(&jme->txclean_task);
+ tasklet_disable(&jme->rxclean_task);
+ tasklet_disable(&jme->rxempty_task);
+ }
+
jme_powersave_phy(jme);
pci_pme_active(pdev, true);
}
@@ -3172,11 +3190,16 @@ jme_suspend(struct device *dev)
if (!netif_running(netdev))
return 0;
- atomic_dec(&jme->link_changing);
-
+ set_bit(JME_FLAG_WOL_QUIESCE, &jme->flags);
netif_device_detach(netdev);
netif_stop_queue(netdev);
jme_stop_irq(jme);
+ synchronize_irq(jme->pdev->irq);
+ jme_stop_irq(jme);
+ cancel_work_sync(&jme->linkch_task);
+ tasklet_disable(&jme->pcc_task);
+ napi_disable(&jme->napi);
+ atomic_dec(&jme->link_changing);
tasklet_disable(&jme->txclean_task);
tasklet_disable(&jme->rxclean_task);
@@ -3215,6 +3238,7 @@ jme_resume(struct device *dev)
return 0;
jme_clear_pm_disable_wol(jme);
+ jme_mac_rxclk_off(jme);
jme_phy_on(jme);
if (test_bit(JME_FLAG_SSET, &jme->flags))
jme_set_link_ksettings(netdev, &jme->old_cmd);
@@ -3226,8 +3250,11 @@ jme_resume(struct device *dev)
atomic_inc(&jme->link_changing);
- jme_reset_link(jme);
+ napi_enable(&jme->napi);
+ tasklet_enable(&jme->pcc_task);
+ clear_bit(JME_FLAG_WOL_QUIESCE, &jme->flags);
+ jme_reset_link(jme);
jme_start_irq(jme);
return 0;
diff --git a/drivers/net/ethernet/jme.h b/drivers/net/ethernet/jme.h
index 860494ff37144..ec5dfddf73227 100644
--- a/drivers/net/ethernet/jme.h
+++ b/drivers/net/ethernet/jme.h
@@ -450,6 +450,7 @@ enum jme_flags_bits {
JME_FLAG_SSET = 2,
JME_FLAG_POLL = 5,
JME_FLAG_SHUTDOWN = 6,
+ JME_FLAG_WOL_QUIESCE = 7,
};
#define TX_TIMEOUT (5 * HZ)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 090/507] ipv6: raw: fix use-after-free in rawv6_send_hdrinc()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (88 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 089/507] net: jme: keep RX MAC clock enabled for WoL Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 091/507] drm/vc4: hdmi: power down the BCM2712 PHY when the output is disabled Greg Kroah-Hartman
` (416 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhou Qiuyue, Hangbin Liu,
Dave Miller, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhou Qiuyue <n0ps1edzz@gmail.com>
[ Upstream commit 66dfb2cacda7faae614d688943d85e75abf7f586 ]
rawv6_send_hdrinc() caches the route before handing the skb to
l3mdev_ip6_out(). The VRF output path may replace skb->dst and release
the original route, leaving the cached pointer stale.
The function later dereferences that pointer for statistics accounting
and as the output device passed to NF_HOOK(). Its RCU read-side critical
section starts after l3mdev_ip6_out(), so it cannot prevent the old route
from being reclaimed in between.
Reload the route from the current skb destination after
l3mdev_ip6_out() returns.
KASAN reports a slab-use-after-free in rawv6_sendmsg(), with the route
allocated by ip6_dst_alloc(), freed by dst_destroy() from rcu_core(), and
the related RCU callback queued from vrf_l3_out().
Fixes: 4c1feac58e06 ("net: vrf: Flip IPv6 output path from FIB lookup hook to out hook")
Cc: stable@vger.kernel.org
Signed-off-by: Zhou Qiuyue <n0ps1edzz@gmail.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Signed-off-by: Dave Miller <davem@davem-thinkpadp1gen8.ibmlond.csb>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/raw.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index b965258cf9e5f..bdea825434ea7 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -654,6 +654,9 @@ static int rawv6_send_hdrinc(struct sock *sk, struct msghdr *msg, int length,
if (unlikely(!skb))
return 0;
+ /* l3mdev_ip6_out() may have replaced the skb dst. */
+ rt = dst_rt6_info(skb_dst(skb));
+
/* Acquire rcu_read_lock() in case we need to use rt->rt6i_idev
* in the error path. Since skb has been freed, the dst could
* have been queued for deletion.
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 091/507] drm/vc4: hdmi: power down the BCM2712 PHY when the output is disabled
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (89 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 090/507] ipv6: raw: fix use-after-free in rawv6_send_hdrinc() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 092/507] drm/vc4: hdmi: always cancel the scrambling work synchronously Greg Kroah-Hartman
` (415 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dom Cobley, Lucas Tanure,
Dave Stevenson, Maíra Canal, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dom Cobley <popcornmix@gmail.com>
[ Upstream commit a59a60e6e9e3a1d5177b28577d935d5ee37ace66 ]
vc6_hdmi_phy_disable() is empty, so on BCM2712 the PHY keeps its PLL
and TMDS drivers running after the HDMI output is disabled, until the
next vc6_hdmi_phy_init(). The TMDS clock is therefore not stopped
between two mode sets, which the SCDC clock ratio change requires, and
the idle PHY wastes power.
Reset and power down the PHY on disable, as the BCM2711 variant does.
Cc: stable@vger.kernel.org
Fixes: 0b1dbe82e051 ("drm/vc4: hdmi: Add support for BCM2712 HDMI controllers")
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
[lucas.tanure: Rewrote commit message to clarify the issue and fix]
Signed-off-by: Lucas Tanure <lucas.tanure@neat.no>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Link: https://patch.msgid.link/20261026164028.78792-2-lucas.tanure@neat.no
Reviewed-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/vc4/vc4_hdmi_phy.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
index 56e6a35da3576..5040f014bf7e6 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi_phy.c
@@ -1197,4 +1197,9 @@ void vc6_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
void vc6_hdmi_phy_disable(struct vc4_hdmi *vc4_hdmi)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&vc4_hdmi->hw_lock, flags);
+ vc6_hdmi_reset_phy(vc4_hdmi);
+ spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 092/507] drm/vc4: hdmi: always cancel the scrambling work synchronously
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (90 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 091/507] drm/vc4: hdmi: power down the BCM2712 PHY when the output is disabled Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 093/507] drm/vc4: hdmi: enable scrambling before the TMDS clock starts Greg Kroah-Hartman
` (414 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lucas Tanure, Maíra Canal,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lucas Tanure <lucas.tanure@neat.no>
[ Upstream commit 2e47848f0d076dec66df3bc403214073cd2214ac ]
The scrambling work re-arms itself every second while a scrambled mode
is active. When the output is disabled, the work may be executing at
that moment rather than pending, and delayed_work_pending() is then
false, so the cancel is skipped. The running instance finishes after
the disable, sees the sink report scrambling off, writes the SCDC
scrambling and clock ratio bits back on, and queues itself again. The
sink is left configured for a scrambled 1/40 link that no longer exists
and the work keeps running until the next enable.
cancel_delayed_work_sync() handles both states: it waits for a running
instance and blocks it from queueing itself again.
Cc: stable@vger.kernel.org
Fixes: 257d36d493e9 ("drm/vc4: hdmi: Add a workqueue to set scrambling")
Assisted-by: LLM
Signed-off-by: Lucas Tanure <lucas.tanure@neat.no>
Reviewed-by: Maíra Canal <mcanal@igalia.com>
Link: https://patch.msgid.link/20261026164028.78792-3-lucas.tanure@neat.no
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/vc4/vc4_hdmi.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index d4672aa81d85e..f58f645ec3c50 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -842,8 +842,7 @@ static void vc4_hdmi_disable_scrambling(struct drm_encoder *encoder)
vc4_hdmi->scdc_enabled = false;
- if (delayed_work_pending(&vc4_hdmi->scrambling_work))
- cancel_delayed_work_sync(&vc4_hdmi->scrambling_work);
+ cancel_delayed_work_sync(&vc4_hdmi->scrambling_work);
if (!drm_dev_enter(drm, &idx))
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 093/507] drm/vc4: hdmi: enable scrambling before the TMDS clock starts
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (91 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 092/507] drm/vc4: hdmi: always cancel the scrambling work synchronously Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 094/507] sctp: account for chunk padding in sctp_init_cause() Greg Kroah-Hartman
` (413 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lucas Tanure, Maíra Canal,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lucas Tanure <lucas.tanure@neat.no>
[ Upstream commit 81383bd290a18f06ccf9b0bfb29e1a3ef73d9357 ]
HDMI 2.0 requires a source to suspend the TMDS clock, write the
TMDS_Bit_Clock_Ratio bit in the sink's SCDC registers, wait at least
1 ms and only then resume the clock. vc4 does the opposite: the PHY
starts at the new rate first, and the SCDC bits are written tens of
milliseconds later, at the very end of the enable sequence, together
with the source side scrambler. On disable the bits are cleared while
the clock is still running.
Some sinks sample the bit only when the clock appears. One HDMI 2.0
sink we tested then sets up its receiver for a 1/10 clock and never
recovers: a Raspberry Pi 5 at 3840x2160@60 shows no picture, while
1080p60 and 4K30 work and other sources work at 4K60 on the same sink.
Writing the bit by hand before enabling the output makes the same mode
lock every time.
Enable scrambling, on the sink and in the controller, before the PHY is
started, and disable it only after the PHY has been stopped. The SCDC
helper already waits the required time after writing the ratio bit.
Cc: stable@vger.kernel.org
Fixes: c85695a2016e ("drm/vc4: hdmi: Enable the scrambler")
Link: https://github.com/raspberrypi/linux/issues/7693
Assisted-by: LLM
Signed-off-by: Lucas Tanure <lucas.tanure@neat.no>
Reviewed-by: Maíra Canal <mcanal@igalia.com>
Link: https://patch.msgid.link/20261026164028.78792-4-lucas.tanure@neat.no
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/vc4/vc4_hdmi.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c
index f58f645ec3c50..f2043f907dc52 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -917,8 +917,6 @@ static void vc4_hdmi_encoder_post_crtc_disable(struct drm_encoder *encoder,
spin_unlock_irqrestore(&vc4_hdmi->hw_lock, flags);
}
- vc4_hdmi_disable_scrambling(encoder);
-
drm_dev_exit(idx);
out:
@@ -946,6 +944,8 @@ static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder,
if (vc4_hdmi->variant->phy_disable)
vc4_hdmi->variant->phy_disable(vc4_hdmi);
+ vc4_hdmi_disable_scrambling(encoder);
+
clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock);
clk_disable_unprepare(vc4_hdmi->pixel_clock);
@@ -1553,6 +1553,8 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder,
goto err_disable_pixel_clock;
}
+ vc4_hdmi_enable_scrambling(encoder);
+
if (vc4_hdmi->variant->phy_init)
vc4_hdmi->variant->phy_init(vc4_hdmi, conn_state);
@@ -1687,7 +1689,6 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder,
}
vc4_hdmi_recenter_fifo(vc4_hdmi);
- vc4_hdmi_enable_scrambling(encoder);
drm_dev_exit(idx);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 094/507] sctp: account for chunk padding in sctp_init_cause()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (92 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 093/507] drm/vc4: hdmi: enable scrambling before the TMDS clock starts Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 095/507] btrfs: fix chattr failing on nodatasum files that have the compress flag Greg Kroah-Hartman
` (412 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Masafumi Suzuki, Xin Long,
Jakub Kicinski, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masafumi Suzuki <shengshilingmu97@gmail.com>
[ Upstream commit ed6c53b27be492643da2017c6f8e2732be5edf1a ]
sctp_init_cause() accepts a chunk when skb_tailroom() can hold the
cause header and the payload. sctp_addto_chunk() then writes 0-3
bytes of padding before that header so the chunk stays 4-byte
aligned. The check does not include the padding, and the following
skb_put() calls skb_over_panic() from softirq.
Count the padding sctp_addto_chunk() is about to write. The cause
length on the wire stays the header plus the payload.
Found by LLM inspection, triggered and tested the fix.
Fixes: 8914f4bace3f ("sctp: add sctp_make_op_error_limited and reuse inner functions")
Cc: stable@vger.kernel.org
Signed-off-by: Masafumi Suzuki <shengshilingmu97@gmail.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20261027082405.1297-1-shengshilingmu97@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sctp/sm_make_chunk.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 84a4c97d0f755..8933caadcdb66 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -136,6 +136,7 @@ int sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code,
size_t paylen)
{
struct sctp_errhdr err;
+ int chunklen, padlen;
__u16 len;
/* Cause code constants are now defined in network order. */
@@ -143,7 +144,13 @@ int sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code,
len = sizeof(err) + paylen;
err.length = htons(len);
- if (skb_tailroom(chunk->skb) < len)
+ /* sctp_addto_chunk() pads the chunk up to a 4-byte boundary before
+ * appending the cause, so account for that padding here as well.
+ */
+ chunklen = ntohs(chunk->chunk_hdr->length);
+ padlen = SCTP_PAD4(chunklen) - chunklen;
+
+ if (skb_tailroom(chunk->skb) < padlen + len)
return -ENOSPC;
chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(err), &err);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 095/507] btrfs: fix chattr failing on nodatasum files that have the compress flag
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (93 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 094/507] sctp: account for chunk padding in sctp_init_cause() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 096/507] btrfs: sysfs: restore NOFS context on early return in btrfs_sysfs_add_block_group_type() Greg Kroah-Hartman
` (411 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Hengyu Liang,
Filipe Manana, David Sterba, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengyu Liang <hengyul@cs.unc.edu>
[ Upstream commit 16b8f07d1ed50d4a8da468b56484873784dd8f4a ]
Commit cf1afec09e9f ("btrfs: validate properties before setting them")
made btrfs_set_prop() validate a property before setting it. For the
compression property, the validation fails with -EINVAL when the inode
has NODATASUM.
However, chattr writes back all the flags it read from the file, and
btrfs_fileattr_set() sets the compression property whenever the new
flags include FS_COMPR_FL, even when the compression flags do not
change. A file created on a filesystem mounted with nodatasum has
NODATASUM and still inherits the compress flag from its directory. As
of now, chattr fails on such a file when it changes any other flag.
The issue can be reproduced with:
mkfs.btrfs -f /dev/sdb
mount -o nodatasum /dev/sdb /mnt
mkdir /mnt/dir
chattr +c /mnt/dir
touch /mnt/dir/file
chattr +A /mnt/dir/file
Before commit cf1afec09e9f ("btrfs: validate properties before setting
them"), the last command succeeds.
After that commit, it fails with EINVAL.
This patch will make btrfs_fileattr_set() leave the compression flags
and the compression property alone when the call changes neither
FS_COMPR_FL nor FS_NOCOMP_FL.
Fixes: cf1afec09e9f ("btrfs: validate properties before setting them")
CC: stable@vger.kernel.org # 7.2+
Suggested-by: Qu Wenruo <wqu@suse.com>
Assisted-by: LLM
Signed-off-by: Hengyu Liang <hengyul@cs.unc.edu>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/ioctl.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 576cd76ca0bf3..905b04ad0ae45 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -375,6 +375,19 @@ int btrfs_fileattr_set(struct mnt_idmap *idmap,
}
}
+ /*
+ * Callers write back the whole flag set, so only touch the compression
+ * flags and the compression property if FS_COMPR_FL or FS_NOCOMP_FL
+ * changes.
+ */
+ if (!((fsflags ^ old_fsflags) & (FS_COMPR_FL | FS_NOCOMP_FL))) {
+ /* 1 item for the inode */
+ trans = btrfs_start_transaction(root, 1);
+ if (IS_ERR(trans))
+ return PTR_ERR(trans);
+ goto update_flags;
+ }
+
/*
* The COMPRESS flag can only be changed by users, while the NOCOMPRESS
* flag may be changed automatically if compression code won't make
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 096/507] btrfs: sysfs: restore NOFS context on early return in btrfs_sysfs_add_block_group_type()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (94 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 095/507] btrfs: fix chattr failing on nodatasum files that have the compress flag Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 097/507] btrfs: prevent deleting the wrong subvolume by ID Greg Kroah-Hartman
` (410 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, guolingxing, Qu Wenruo, David Sterba,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: guolingxing <guolingxing@tju.edu.cn>
[ Upstream commit 4172be965c2ce887ebfb1117c634a68555be8c11 ]
btrfs_sysfs_add_block_group_type() sets up a NOFS context with
memalloc_nofs_save() because kobject_add() performs GFP_KERNEL
allocations deep in its call chain, and the function may be called
while holding a transaction handle or a lock required for a
transaction commit, where reclaim could deadlock.
Every other return path of this function calls memalloc_nofs_restore()
except the early return taken when another thread has already created
the kobject for the same raid index (this can happen when restriping).
Taking that path leaves PF_MEMALLOC_NOFS set on the calling task, so
all subsequent memory allocations performed by that task remain
restricted to the NOFS scope, which may lead to unexpected allocation
failures or deadlocks later on.
Restore the NOFS context before returning from that path.
Fixes: 49ea112da0e6 ("btrfs: do not create raid sysfs entries under any locks")
CC: stable@vger.kernel.org
Signed-off-by: guolingxing <guolingxing@tju.edu.cn>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/sysfs.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index 39cb01ee441ab..71b1ec6c06433 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -1857,6 +1857,7 @@ void btrfs_sysfs_add_block_group_type(struct btrfs_block_group *cache)
if (space_info->block_group_kobjs[index]) {
spin_unlock(&space_info->lock);
kobject_put(&rkobj->kobj);
+ memalloc_nofs_restore(nofs_flag);
return;
} else {
space_info->block_group_kobjs[index] = &rkobj->kobj;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 097/507] btrfs: prevent deleting the wrong subvolume by ID
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (95 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 096/507] btrfs: sysfs: restore NOFS context on early return in btrfs_sysfs_add_block_group_type() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 098/507] ptp: fix use-after-free in extts_fifo_show() reading tsevqs unlocked Greg Kroah-Hartman
` (409 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, guolingxing, David Sterba,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: guolingxing <guolingxing@tju.edu.cn>
[ Upstream commit 1960146913b31b288ed2cd607d103ee3b41681d4 ]
When deleting a subvolume by ID, btrfs_ioctl_snap_destroy() first
resolves the requested ID to a name, then looks up that name again
under the parent directory lock.
A concurrent rename can change which subvolume is associated with
the name between these operations. Since the deletion path does not
verify the ID of the resolved subvolume, it can delete a different
subvolume while leaving the requested one intact.
This was reproduced by repeatedly exchanging the names of two
subvolumes using renameat2(RENAME_EXCHANGE) while deleting one of
them by ID. The wrong subvolume was deleted in 9 out of 14 independent
tests.
Fix this by checking that the resolved subvolume ID matches the
requested ID while holding the parent directory lock. Return -EAGAIN
on a mismatch so that userspace can retry the operation instead of
being told that the requested subvolume does not exist.
Fixes: 949964c92843 ("btrfs: add new BTRFS_IOC_SNAP_DESTROY_V2 ioctl")
CC: stable@vger.kernel.org
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: guolingxing <guolingxing@tju.edu.cn>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/ioctl.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 905b04ad0ae45..beae9dcb5a3e6 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2393,6 +2393,17 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
inode = d_inode(dentry);
dest = BTRFS_I(inode)->root;
+
+ /*
+ * A concurrent rename may have changed which subvolume the name
+ * refers to. Verify that the resolved ID still matches the requested ID.
+ */
+ if (destroy_v2 && (vol_args2->flags & BTRFS_SUBVOL_SPEC_BY_ID) &&
+ btrfs_root_id(dest) != vol_args2->subvolid) {
+ ret = -EAGAIN;
+ goto out_end_removing;
+ }
+
if (!capable(CAP_SYS_ADMIN)) {
/*
* Regular user. Only allow this with a special mount
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 098/507] ptp: fix use-after-free in extts_fifo_show() reading tsevqs unlocked
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (96 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 097/507] btrfs: prevent deleting the wrong subvolume by ID Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 099/507] scsi: bsg: Report synchronous data copyback failures Greg Kroah-Hartman
` (408 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yu Zhang, Jakub Kicinski,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Zhang <yuz08559@gmail.com>
[ Upstream commit 603a0c40d414ea12509fc45f2b930449a8d4aad2 ]
extts_fifo_show() walks ptp->tsevqs with list_count_nodes() and then
list_first_entry() without holding ptp->tsevqs_lock, the spinlock that
"protects tsevqs from concurrent access". Every other accessor of the
list honours it: ptp_open() (list_add_tail), ptp_release() (list_del
followed by kfree of the per-fd queue), ptp_clock_release() and
ptp_clock_event() all take tsevqs_lock. extts_fifo_show() is the only
one that does not.
A per-fd timestamp queue is appended to tsevqs on open("/dev/ptpN") and
removed and freed on close(), both under tsevqs_lock:
scoped_guard(spinlock_irq, &ptp->tsevqs_lock)
list_del(&queue->qlist);
bitmap_free(queue->mask);
kfree(queue);
So a read of /sys/class/ptp/ptpN/fifo running concurrently with a
close() of a /dev/ptpN fd can have list_count_nodes() walk into the
queue that close() is removing and freeing, dereferencing freed memory
(use-after-free) or a poisoned list pointer.
Take tsevqs_lock around the list walk. The fifo only ever draws from the
first queue, which is the registration-time queue created in
ptp_clock_register() and freed only in ptp_clock_release(); that cannot
run while the sysfs attribute is being read, so the dequeue from
queue->buf under queue->lock may stay outside tsevqs_lock and the lock
order is unchanged.
Fixes: d26ab5a35ad9 ("ptp: Replace timestamp event queue with linked list")
Cc: stable@vger.kernel.org
Signed-off-by: Yu Zhang <yuz08559@gmail.com>
Link: https://patch.msgid.link/20261026100535.68114-1-yuz08559@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ptp/ptp_sysfs.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c
index dc398c6b75284..7d09256aca724 100644
--- a/drivers/ptp/ptp_sysfs.c
+++ b/drivers/ptp/ptp_sysfs.c
@@ -80,13 +80,17 @@ static ssize_t extts_fifo_show(struct device *dev,
size_t qcnt;
int cnt = 0;
+ spin_lock_irqsave(&ptp->tsevqs_lock, flags);
cnt = list_count_nodes(&ptp->tsevqs);
- if (cnt <= 0)
+ if (cnt <= 0) {
+ spin_unlock_irqrestore(&ptp->tsevqs_lock, flags);
goto out;
+ }
/* The sysfs fifo will always draw from the fist queue */
queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue,
qlist);
+ spin_unlock_irqrestore(&ptp->tsevqs_lock, flags);
memset(&event, 0, sizeof(event));
spin_lock_irqsave(&queue->lock, flags);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 099/507] scsi: bsg: Report synchronous data copyback failures
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (97 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 098/507] ptp: fix use-after-free in extts_fifo_show() reading tsevqs unlocked Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 100/507] scsi: bsg: Report io_uring " Greg Kroah-Hartman
` (407 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yingjie Wang, Yang Xiuwei,
Bart Van Assche, Martin K. Petersen (Oracle), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yingjie Wang <x-professor@outlook.com>
[ Upstream commit a52f2ad45726d788755b525adcf51f65a6b836ff ]
scsi_bsg_sg_io_fn() ignores the result of blk_rq_unmap_user(). For a
data-in command that uses a bounce buffer, unmapping copies the completed
data to userspace. If that copy fails, SG_IO can report success despite the
copyback failure.
Capture the unmap status. Preserve an earlier sense-buffer copy error and
otherwise return the data copyback error. This matches the error precedence
used by scsi_complete_sghdr_rq().
On x86_64, a virtio-scsi INQUIRY with an unaligned PROT_NONE destination
made ioctl() return 0 in 20/20 runs before this change and return -1 with
errno EFAULT in 20/20 runs afterward. Writable controls succeeded in 20/20
runs on both kernels.
Fixes: 10e8855b9451 ("bsg: add SG_IO to SG v4")
Cc: stable@vger.kernel.org
Signed-off-by: Yingjie Wang <x-professor@outlook.com>
Reviewed-by: Yang Xiuwei <yangxiuwei@kylinos.cn>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/2561d633cc8cef513d75eb1df260046a4971e783.1792772194.git.x-professor@outlook.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/scsi_bsg.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c
index 5eec248a77a6b..37393a8dedd84 100644
--- a/drivers/scsi/scsi_bsg.c
+++ b/drivers/scsi/scsi_bsg.c
@@ -199,7 +199,7 @@ static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
struct scsi_cmnd *scmd;
struct request *rq;
struct bio *bio;
- int ret;
+ int ret, unmap_ret;
if (hdr->protocol != BSG_PROTOCOL_SCSI ||
hdr->subprotocol != BSG_SUB_PROTOCOL_SCSI_CMD)
@@ -273,7 +273,9 @@ static int scsi_bsg_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr,
else
hdr->dout_resid = scmd->resid_len;
- blk_rq_unmap_user(bio);
+ unmap_ret = blk_rq_unmap_user(bio);
+ if (!ret)
+ ret = unmap_ret;
out_put_request:
blk_mq_free_request(rq);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 100/507] scsi: bsg: Report io_uring data copyback failures
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (98 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 099/507] scsi: bsg: Report synchronous data copyback failures Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 101/507] scsi: target: Verify the iSCSI ISID is null-terminated Greg Kroah-Hartman
` (406 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yingjie Wang, Yang Xiuwei,
Bart Van Assche, Martin K. Petersen (Oracle), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yingjie Wang <x-professor@outlook.com>
[ Upstream commit ffb7b533a47906b96166eec4b7eaa4199b7a7462 ]
scsi_bsg_uring_task_cb() discards the result of blk_rq_unmap_user(). For a
data-in command that uses a bounce buffer, the task work can therefore post
a CQE with res == 0 despite a copyback failure.
Use the unmap result as the CQE status. A later sense-buffer copy failure
continues to take precedence.
On x86_64, a raw BSG INQUIRY into an unaligned anonymous PROT_NONE mapping
posted a CQE with res == 0 in 20/20 runs before this change and res ==
-EFAULT in 20/20 runs afterward. Writable controls succeeded in 20/20 runs
on both kernels.
Fixes: 7b6d3255e7f8 ("scsi: bsg: add io_uring passthrough handler")
Cc: stable@vger.kernel.org
Signed-off-by: Yingjie Wang <x-professor@outlook.com>
Reviewed-by: Yang Xiuwei <yangxiuwei@kylinos.cn>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/0b35d2d46bf8ff9f2dbba83ae093d17351e950e9.1792772194.git.x-professor@outlook.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/scsi_bsg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/scsi/scsi_bsg.c b/drivers/scsi/scsi_bsg.c
index 37393a8dedd84..e4a65d7a23742 100644
--- a/drivers/scsi/scsi_bsg.c
+++ b/drivers/scsi/scsi_bsg.c
@@ -41,7 +41,7 @@ static void scsi_bsg_uring_task_cb(struct io_tw_req tw_req, io_tw_token_t tw)
u8 sense_len_wr = 0;
if (pdu->bio)
- blk_rq_unmap_user(pdu->bio);
+ ret = blk_rq_unmap_user(pdu->bio);
if (scsi_status_is_check_condition(scmd->result)) {
driver_status = DRIVER_SENSE;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 101/507] scsi: target: Verify the iSCSI ISID is null-terminated
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (99 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 100/507] scsi: bsg: Report io_uring " Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 102/507] scsi: target: tcmu: Fix divide-by-zero in data_pages_per_blk store Greg Kroah-Hartman
` (405 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, kitta, sashiko AI review,
Bryam Vargas, John Garry, Yuanhe Shu, Martin K. Petersen (Oracle),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuanhe Shu <xiangzao@linux.alibaba.com>
[ Upstream commit cdf4b87a18cb6a0ee26865cb1b7b5660a491d302 ]
iscsi_parse_pr_out_transport_id() returns the ISID of a FORMAT CODE 01b
TransportID as a pointer into the PERSISTENT RESERVE OUT parameter list,
lowercased in place and never null-terminated. spc4r37 Table 508 requires
the field to be null-terminated, but a non-conforming initiator can omit
the NULL; when the ISID ends at the end of the received buffer, the pointer
is not a C string.
The registration code still consumes it as one: strcmp() in
__core_scsi3_locate_pr_reg() and in the REGISTER AND MOVE path, and
snprintf("%s") in __core_scsi3_do_alloc_registration(), which also reads
its first 8 bytes unconditionally with get_unaligned_be64() - a NUL check
does not bound that read.
When the parameter list spans more than one page, transport_kmap_data_sg()
maps it with vmap(), and the over-read walks off the end of the mapping
into the vmalloc() guard page and oopses. Reproduced with a PR OUT
REGISTER + SPEC_I_PT parameter list of exactly 8192 bytes whose final
TransportID carries a 12-byte ISID without a terminating NUL:
BUG: unable to handle page fault for address: ffffc9000138c000
RIP: 0010:strcmp+0xc/0x30
Call Trace:
__core_scsi3_locate_pr_reg+0xd3/0x120 [target_core_mod]
core_scsi3_decode_spec_i_port+0x8fc/0x13a0 [target_core_mod]
core_scsi3_emulate_pro_register+0x73c/0x900 [target_core_mod]
...
iscsi_target_rx_thread+0xef/0x1d0 [iscsi_target_mod]
With a single-page parameter list the buffer is a kmap() direct mapping, so
the over-read continues into the physically adjacent page instead of
faulting. snprintf("%s") then copies whatever follows the ISID in memory
into pr_reg_isid, and PR IN READ FULL STATUS reports the registration back
to any initiator, turning the over-read into an info leak of kernel heap
contents. Reproduced with a 4096-byte parameter list whose last
TransportID ends at the end of the buffer with a 4-byte ISID and no NUL,
interleaved with I/O to populate adjacent pages: the READ FULL STATUS
response returned the ISID as "0xleak" followed by raw bytes that were not
part of the parameter list. The snprintf() into
pr_reg_isid[PR_REG_ISID_LEN] caps the echoed ISID at 15 characters, so at
most 11 bytes past the buffer are leaked per command, but the PR OUT
command is not rate limited.
Any initiator that can send PR OUT to an iSCSI-exported LUN can trigger
either variant, including a guest via vhost-scsi.
Require 8 bytes to remain after the ",i,0x" separator, and a NUL inside the
rest of the descriptor, before the ISID pointer is returned. REGISTER AND
MOVE fails with TCM_INVALID_PARAMETER_LIST; on SPEC_I_PT no target port
claims the malformed TransportID, and the command fails the same way.
Fixes: d04a179085c2 ("scsi: target: Bound PR-OUT TransportID parsing to the received buffer")
Reported-by: kitta <kitta@linux.alibaba.com>
Reported-by: sashiko AI review <sashiko-bot@kernel.org>
Link: https://lore.kernel.org/r/sashiko-outbox-184760@kernel.org/
Cc: stable@vger.kernel.org
Cc: Bryam Vargas <hexlabsecurity@proton.me>
Cc: John Garry <john.garry@linux.dev>
Assisted-by: LLM
Signed-off-by: Yuanhe Shu <xiangzao@linux.alibaba.com>
Fixes: c66ac9db8d4a ("[SCSI] target: Add LIO target core v4.0.0-rc6")
Link: https://patch.msgid.link/20261026124138.2708365-1-xiangzao@linux.alibaba.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/target/target_core_fabric_lib.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/target/target_core_fabric_lib.c b/drivers/target/target_core_fabric_lib.c
index 2853b95b2c597..ad024009df56b 100644
--- a/drivers/target/target_core_fabric_lib.c
+++ b/drivers/target/target_core_fabric_lib.c
@@ -371,6 +371,16 @@ static bool iscsi_parse_pr_out_transport_id(
pr_err("Missing ISID in iSCSI Initiator port TransportID\n");
return false;
}
+ /*
+ * The registration code reads the ISID as a C string,
+ * and its first 8 bytes with get_unaligned_be64(), so
+ * require 8 bytes after the separator and a NUL inside
+ * the rest of the descriptor.
+ */
+ if (buf + tid_len - p < 8 || !memchr(p, '\0', buf + tid_len - p)) {
+ pr_err("Incomplete or unterminated ISID in iSCSI Initiator port TransportID\n");
+ return false;
+ }
*port_nexus_ptr = p;
/*
* Go ahead and do the lower case conversion of the received
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 102/507] scsi: target: tcmu: Fix divide-by-zero in data_pages_per_blk store
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (100 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 101/507] scsi: target: Verify the iSCSI ISID is null-terminated Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 103/507] drm/loongson: Fix framebuffer selection in async cursor updates Greg Kroah-Hartman
` (404 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shao Mingyin, Bodo Stroesser,
Martin K. Petersen (Oracle), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shao Mingyin <shao.mingyin@zte.com.cn>
[ Upstream commit b8d0bb6a8ba0d3878940a914a19336844101867b ]
tcmu_set_data_pages_per_blk() only validates the upper bound of the value
parsed from data_pages_per_blk=. Zero passes that check and is then used as
the divisor when computing udev->max_blocks:
divide error: 0000 [#1] SMP
...
tcmu_set_data_pages_per_blk
tcmu_configure_device
Reject non-positive values, as the neighbouring max_data_area_mb and
cmd_ring_size setters already do.
Fixes: 08976cb548d6 ("scsi: target: tcmu: Make data_pages_per_blk changeable via configfs")
Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
Cc: stable@vger.kernel.org
Reviewed-by: Bodo Stroesser <bostroesser@gmail.com>
Link: https://patch.msgid.link/20261026195245337ktSXy9G17VCcXyw760g9s@zte.com.cn
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/target/target_core_user.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index edc2afd5f4ee2..839d5b2e72506 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -2524,6 +2524,11 @@ static int tcmu_set_data_pages_per_blk(struct tcmu_dev *udev, substring_t *arg)
return ret;
}
+ if (val <= 0) {
+ pr_err("Invalid data_pages_per_blk %d.\n", val);
+ return -EINVAL;
+ }
+
if (val > TCMU_MBS_TO_PAGES(udev->data_area_mb)) {
pr_err("Invalid data_pages_per_blk %d: greater than max_data_area_mb %d -> %zd pages).\n",
val, udev->data_area_mb,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 103/507] drm/loongson: Fix framebuffer selection in async cursor updates
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (101 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 102/507] scsi: target: tcmu: Fix divide-by-zero in data_pages_per_blk store Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 104/507] drm/loongson: Fix double free on BO initialization failure Greg Kroah-Hartman
` (403 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, kernel test robot, Evanshenf,
Icenowy Zheng, Qianhai Wu, Huacai Chen, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Evanshenf <archwse@gmail.com>
[ Upstream commit fa66daafbb6d5c984de2502809ff533ab66f6573 ]
An asynchronous cursor update swaps the new framebuffer into the live
plane state. However, the driver reads both old_fb and new_fb from the
live state before this swap. When an enabled cursor changes buffers, the
address-update condition is therefore false and the hardware continues
scanning the previous buffer.
Read new_fb from the new plane state before swapping the framebuffer
references. This updates the hardware address when the framebuffer
changes while retaining the existing behavior for cursor movement.
Verified on a Loongson 3A5000 with LS7A2000 using 32x32 and 64x64 legacy
cursor updates. Callback counters and read-only register observations
confirmed the asynchronous path, the stale address before the change,
and the new address afterward. Same-framebuffer movement and cursor
disable/re-enable also passed, with the primary framebuffer and mode
unchanged.
AI assistance was used to investigate the existing report, prepare the
fix and test tools, run the build and hardware comparison, and draft
this message.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/r/202311152357.4KFS0M8f-lkp@intel.com/
Fixes: f39db26c5428 ("drm: Add kms driver for loongson display controller")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Evanshenf <archwse@gmail.com>
Reviewed-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
Reviewed-by: Qianhai Wu <wuqianhai@loongson.cn>
Reviewed-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
Link: https://patch.msgid.link/20261003090006.4e29fdce9913-1-archwse@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/loongson/lsdc_plane.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/loongson/lsdc_plane.c b/drivers/gpu/drm/loongson/lsdc_plane.c
index bcc0ffa17bdf2..7b9c65c30a9d1 100644
--- a/drivers/gpu/drm/loongson/lsdc_plane.c
+++ b/drivers/gpu/drm/loongson/lsdc_plane.c
@@ -230,7 +230,7 @@ static void lsdc_cursor_plane_atomic_async_update(struct drm_plane *plane,
new_state = drm_atomic_get_new_plane_state(state, plane);
- new_fb = plane->state->fb;
+ new_fb = new_state->fb;
plane->state->crtc_x = new_state->crtc_x;
plane->state->crtc_y = new_state->crtc_y;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 104/507] drm/loongson: Fix double free on BO initialization failure
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (102 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 103/507] drm/loongson: Fix framebuffer selection in async cursor updates Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 105/507] drm/loongson: Handle buffer mapping failures when clearing a BO Greg Kroah-Hartman
` (402 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Evanshenf, Icenowy Zheng, Qianhai Wu,
Huacai Chen, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Evanshenf <archwse@gmail.com>
[ Upstream commit f086dbdeb6e56510e158a853d752c6d8ed9e0674 ]
If ttm_bo_init_validate() fails, it drops the buffer object's reference
and cleans it up through the supplied destroy callback. lsdc_bo_destroy()
releases the GEM object and frees the enclosing lsdc_bo, so freeing it
again in lsdc_bo_create() causes a double free on a synchronous failure
path.
Let TTM own the cleanup after initialization has started and return the
error directly. Keep the explicit free on drm_gem_object_init() failure,
which occurs before ownership is passed to TTM.
Tested on LS7A2000 by making drm_vma_offset_add() return -ENOSPC for one
selected dumb-buffer creation. The error reached userspace, the destroy
callback ran once, and no handle was published or tracked BO retained.
Normal buffer creation, zeroing, mapping, readback and release passed.
AI assistance was used for the ownership analysis, fix, fault-injection
tools, build and test execution.
Fixes: f39db26c5428 ("drm: Add kms driver for loongson display controller")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Evanshenf <archwse@gmail.com>
Reviewed-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
Reviewed-by: Qianhai Wu <wuqianhai@loongson.cn>
Reviewed-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
Link: https://patch.msgid.link/20261003093415.e64386de1e64-1-archwse@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/loongson/lsdc_ttm.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/loongson/lsdc_ttm.c b/drivers/gpu/drm/loongson/lsdc_ttm.c
index d7441d96a0dca..88536e230c2fb 100644
--- a/drivers/gpu/drm/loongson/lsdc_ttm.c
+++ b/drivers/gpu/drm/loongson/lsdc_ttm.c
@@ -475,10 +475,8 @@ struct lsdc_bo *lsdc_bo_create(struct drm_device *ddev,
ret = ttm_bo_init_validate(bdev, tbo, bo_type, &lbo->placement, 0,
false, sg, resv, lsdc_bo_destroy);
- if (ret) {
- kfree(lbo);
+ if (ret)
return ERR_PTR(ret);
- }
return lbo;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 105/507] drm/loongson: Handle buffer mapping failures when clearing a BO
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (103 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 104/507] drm/loongson: Fix double free on BO initialization failure Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 106/507] ALSA: us122l: Add missing NULL check in usb_stream_hwdep_mmap() Greg Kroah-Hartman
` (401 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Evanshenf, Icenowy Zheng,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Evanshenf <archwse@gmail.com>
[ Upstream commit f00d7a241f846b053e89c0bb2285ef5988d4cafc ]
lsdc_bo_clear() ignores the return value from lsdc_bo_kmap() and writes
to lbo->kptr unconditionally. When the first mapping of a newly allocated
buffer fails, kptr is still NULL and the subsequent memset accesses it.
Return the mapping error without touching the buffer and propagate it
from lsdc_gem_object_create(). Install the GEM object functions before
clearing so that drm_gem_object_put() can release the buffer correctly
on failure. Do not add the failed object to the tracking list or return
an uncleared buffer to the caller.
Imported buffers still skip clearing, and successfully mapped buffers
are cleared and unmapped as before.
Tested on LS7A2000 with a one-shot range error in ttm_bo_kmap(). Its
-EINVAL return reached userspace, the object was destroyed once, and
no GEM handle was published. Normal create/map/zero/write/read/close
cycles passed, with the tracked BO count and VRAM usage unchanged.
AI assistance was used for the lifetime analysis, fix, fault-injection
tools, build and test execution.
Fixes: f39db26c5428 ("drm: Add kms driver for loongson display controller")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Evanshenf <archwse@gmail.com>
Reviewed-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
Signed-off-by: Icenowy Zheng <zhengxingda@iscas.ac.cn>
Link: https://patch.msgid.link/20261003093415.902f89244043-2-archwse@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/loongson/lsdc_gem.c | 12 ++++++++----
drivers/gpu/drm/loongson/lsdc_ttm.c | 10 ++++++++--
drivers/gpu/drm/loongson/lsdc_ttm.h | 2 +-
3 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/loongson/lsdc_gem.c b/drivers/gpu/drm/loongson/lsdc_gem.c
index 2fb03487c983e..9eba4e1a5ba6a 100644
--- a/drivers/gpu/drm/loongson/lsdc_gem.c
+++ b/drivers/gpu/drm/loongson/lsdc_gem.c
@@ -157,14 +157,18 @@ struct drm_gem_object *lsdc_gem_object_create(struct drm_device *ddev,
return ERR_PTR(ret);
}
+ gobj = &lbo->tbo.base;
+ gobj->funcs = &lsdc_gem_object_funcs;
+
if (!sg) {
/* VRAM is filled with random data */
- lsdc_bo_clear(lbo);
+ ret = lsdc_bo_clear(lbo);
+ if (ret) {
+ drm_gem_object_put(gobj);
+ return ERR_PTR(ret);
+ }
}
- gobj = &lbo->tbo.base;
- gobj->funcs = &lsdc_gem_object_funcs;
-
/* tracking the BOs we created */
mutex_lock(&ldev->gem.mutex);
list_add_tail(&lbo->list, &ldev->gem.objects);
diff --git a/drivers/gpu/drm/loongson/lsdc_ttm.c b/drivers/gpu/drm/loongson/lsdc_ttm.c
index 88536e230c2fb..7b30dea039ee2 100644
--- a/drivers/gpu/drm/loongson/lsdc_ttm.c
+++ b/drivers/gpu/drm/loongson/lsdc_ttm.c
@@ -388,9 +388,13 @@ void lsdc_bo_kunmap(struct lsdc_bo *lbo)
ttm_bo_kunmap(&lbo->kmap);
}
-void lsdc_bo_clear(struct lsdc_bo *lbo)
+int lsdc_bo_clear(struct lsdc_bo *lbo)
{
- lsdc_bo_kmap(lbo);
+ int ret;
+
+ ret = lsdc_bo_kmap(lbo);
+ if (ret)
+ return ret;
if (lbo->is_iomem)
memset_io((void __iomem *)lbo->kptr, 0, lbo->size);
@@ -398,6 +402,8 @@ void lsdc_bo_clear(struct lsdc_bo *lbo)
memset(lbo->kptr, 0, lbo->size);
lsdc_bo_kunmap(lbo);
+
+ return 0;
}
int lsdc_bo_evict_vram(struct drm_device *ddev)
diff --git a/drivers/gpu/drm/loongson/lsdc_ttm.h b/drivers/gpu/drm/loongson/lsdc_ttm.h
index 843e1475064e2..df47d9bb0d035 100644
--- a/drivers/gpu/drm/loongson/lsdc_ttm.h
+++ b/drivers/gpu/drm/loongson/lsdc_ttm.h
@@ -89,7 +89,7 @@ size_t lsdc_bo_size(struct lsdc_bo *lbo);
int lsdc_bo_kmap(struct lsdc_bo *lbo);
void lsdc_bo_kunmap(struct lsdc_bo *lbo);
-void lsdc_bo_clear(struct lsdc_bo *lbo);
+int lsdc_bo_clear(struct lsdc_bo *lbo);
int lsdc_bo_evict_vram(struct drm_device *ddev);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 106/507] ALSA: us122l: Add missing NULL check in usb_stream_hwdep_mmap()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (104 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 105/507] drm/loongson: Handle buffer mapping failures when clearing a BO Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 107/507] ALSA: us122l: Fix NULL dereference at hwdep open and release Greg Kroah-Hartman
` (400 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bin Yu, Cheng Wen, YuanZhe Liu,
Takashi Iwai, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: YuanZhe Liu <25031212351@stu.xidian.edu.cn>
[ Upstream commit f5d3eb483fed59fc0f3b059b8b6a32cedc922360 ]
usb_stream_hwdep_mmap() reads us122l->sk.s and dereferences it without
checking for NULL. The stream object is released by usb_stream_free(),
which is reached through us122l_stop() both when the device is
disconnected and when us122l_start() fails, and it leaves us122l->sk.s
set to NULL. The hwdep file stays usable after that, so a later mmap()
KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
RIP: 0010:usb_stream_hwdep_mmap+0x107/0x890 sound/usb/usx2y/us122l.c:182
crashes while reading s->read_size, which sits at offset 0x10.
That NULL is an expected state for this field: usb_stream_hwdep_vm_fault(),
usb_stream_hwdep_poll(), usb_stream_hwdep_ioctl(), usb_stream_stop() and
usb_stream_free() all test it before use. Only the mmap callback misses
the check, so let it return -ENODEV, matching what the other hwdep mapping
in usx2yhwdeppcm.c does when its shared buffer has not been allocated.
Fixes: 030a07e441296c372f946cd4065b5d831d8dc40c ("ALSA: Add USB US122L driver")
Cc: stable@vger.kernel.org
Co-developed-by: Bin Yu <byu@xidian.edu.cn>
Signed-off-by: Bin Yu <byu@xidian.edu.cn>
Co-developed-by: Cheng Wen <wencheng@xidian.edu.cn>
Signed-off-by: Cheng Wen <wencheng@xidian.edu.cn>
Signed-off-by: YuanZhe Liu <25031212351@stu.xidian.edu.cn>
Link: https://patch.msgid.link/20261028042525.8737-1-25031212351@stu.xidian.edu.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/usx2y/us122l.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index a5db0d044ef96..27b6b0bd57681 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -179,6 +179,8 @@ static int usb_stream_hwdep_mmap(struct snd_hwdep *hw,
offset = area->vm_pgoff << PAGE_SHIFT;
guard(mutex)(&us122l->mutex);
s = us122l->sk.s;
+ if (!s)
+ return -ENODEV;
read = offset < s->read_size;
if (read) {
if (area->vm_flags & VM_WRITE)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 107/507] ALSA: us122l: Fix NULL dereference at hwdep open and release
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (105 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 106/507] ALSA: us122l: Add missing NULL check in usb_stream_hwdep_mmap() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 108/507] ALSA: usx2y: Initialize idle URBs before submitting streams Greg Kroah-Hartman
` (399 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bin Yu, Cheng Wen, YuanZhe Liu,
Takashi Iwai, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: YuanZhe Liu <25031212351@stu.xidian.edu.cn>
[ Upstream commit 820e0050866942b5498488496462d12c6ce1c7a9 ]
usb_stream_hwdep_open() and usb_stream_hwdep_release() pass the result of
usb_ifnum_to_if() straight to usb_autopm_get_interface() and
usb_autopm_put_interface(), without checking it for NULL.
usb_ifnum_to_if() returns NULL once the device is gone, since
usb_disable_device() clears udev->actconfig on disconnect. The hwdep file
can outlive the disconnect: the card is released with
snd_card_free_when_closed(), so a process that keeps the character device
open reaches the driver's release callback after the USB configuration has
been dropped, and interface_to_usbdev() then dereferences the NULL
interface at offsetof(struct device, parent). The open callback has the
same problem when it races with the disconnect.
Check both lookups and fail the open with -ENODEV; in release, skip the
runtime PM put when the interface is already gone and still run the rest
of the per-file cleanup. Move the us122l->first bookkeeping after the
checks so that a failed open no longer leaves a stale file pointer behind.
Fixes: 030a07e44129 ("ALSA: Add USB US122L driver")
Cc: stable@vger.kernel.org
Co-developed-by: Bin Yu <byu@xidian.edu.cn>
Signed-off-by: Bin Yu <byu@xidian.edu.cn>
Co-developed-by: Cheng Wen <wencheng@xidian.edu.cn>
Signed-off-by: Cheng Wen <wencheng@xidian.edu.cn>
Signed-off-by: YuanZhe Liu <25031212351@stu.xidian.edu.cn>
Link: https://patch.msgid.link/20261028074143.14440-1-25031212351@stu.xidian.edu.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/usx2y/us122l.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 27b6b0bd57681..9b4ec9bdc1383 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -129,19 +129,26 @@ static const struct vm_operations_struct usb_stream_hwdep_vm_ops = {
static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
{
struct us122l *us122l = hw->private_data;
- struct usb_interface *iface;
+ struct usb_interface *iface, *iface0 = NULL;
if (hw->used >= 2)
return -EBUSY;
- if (!us122l->first)
- us122l->first = file;
-
if (us122l->is_us144) {
- iface = usb_ifnum_to_if(us122l->dev, 0);
- usb_autopm_get_interface(iface);
+ iface0 = usb_ifnum_to_if(us122l->dev, 0);
+ if (!iface0)
+ return -ENODEV;
}
+
iface = usb_ifnum_to_if(us122l->dev, 1);
+ if (!iface)
+ return -ENODEV;
+
+ if (!us122l->first)
+ us122l->first = file;
+
+ if (iface0)
+ usb_autopm_get_interface(iface0);
usb_autopm_get_interface(iface);
return 0;
}
@@ -153,10 +160,12 @@ static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
if (us122l->is_us144) {
iface = usb_ifnum_to_if(us122l->dev, 0);
- usb_autopm_put_interface(iface);
+ if (iface)
+ usb_autopm_put_interface(iface);
}
iface = usb_ifnum_to_if(us122l->dev, 1);
- usb_autopm_put_interface(iface);
+ if (iface)
+ usb_autopm_put_interface(iface);
if (us122l->first == file)
us122l->first = NULL;
guard(mutex)(&us122l->mutex);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 108/507] ALSA: usx2y: Initialize idle URBs before submitting streams
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (106 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 107/507] ALSA: us122l: Fix NULL dereference at hwdep open and release Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 109/507] ALSA: hwdep: Serialize DSP load requests Greg Kroah-Hartman
` (398 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bin Yu, Cheng Wen, YuanZhe Liu,
Takashi Iwai, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: YuanZhe Liu <25031212351@stu.xidian.edu.cn>
[ Upstream commit ceb0d8c22473933099b46cec70639d0f1f7c68ad ]
usb_stream_start() submits the first two capture and playback URBs and
only afterwards assigns sk->idle_inurb, sk->idle_outurb,
sk->completed_inurb and sk->completed_outurb to the remaining two URBs
of each direction.
A transfer can complete as soon as usb_submit_urb() has been called, so
the completion handler i_capture_start() or i_playback_start() may run
before those pointers are set. While the stream is still being
synchronized (state below usb_stream_sync1), stream_start() then calls
playback_prep_freqn(sk, sk->idle_outurb) with sk->idle_outurb still
NULL, and the packet descriptors are written through that NULL pointer:
Oops: general protection fault, probably for non-canonical address
0xdffffc0000000018: 0000 [#1] SMP KASAN
KASAN: null-ptr-deref in range [0x00000000000000c0-0x00000000000000c7]
RIP: 0010:playback_prep_freqn+0x11c/0x4a0 sound/usb/usx2y/usb_stream.c:33
Call Trace:
<IRQ>
stream_start+0x5dc/0x8d0 sound/usb/usx2y/usb_stream.c:596
i_capture_start+0x3da/0x710 sound/usb/usx2y/usb_stream.c:654
__usb_hcd_giveback_urb+0x238/0x550 drivers/usb/core/hcd.c:1657
usb_giveback_urb_bh+0x20b/0x530 drivers/usb/core/hcd.c:1691
tasklet_hi_action+0xa/0x20 kernel/softirq.c:994
handle_softirqs+0x16f/0x440 kernel/softirq.c:645
</IRQ>
The four URBs referenced by these pointers are allocated long before and
do not depend on any transfer state, so assign them before the submit
loop. Keeping the assignment inside the retry path also restores a
well-defined URB rotation when the start frame mismatch handling kills
and resubmits the streams.
Fixes: 030a07e441296c372f946cd4065b5d831d8dc40c ("ALSA: Add USB US122L driver")
Cc: stable@vger.kernel.org
Co-developed-by: Bin Yu <byu@xidian.edu.cn>
Signed-off-by: Bin Yu <byu@xidian.edu.cn>
Co-developed-by: Cheng Wen <wencheng@xidian.edu.cn>
Signed-off-by: Cheng Wen <wencheng@xidian.edu.cn>
Signed-off-by: YuanZhe Liu <25031212351@stu.xidian.edu.cn>
Link: https://patch.msgid.link/20261028103158.22996-1-25031212351@stu.xidian.edu.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/usx2y/usb_stream.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
index 3122cf653273d..7d621280fba33 100644
--- a/sound/usb/usx2y/usb_stream.c
+++ b/sound/usb/usx2y/usb_stream.c
@@ -682,6 +682,10 @@ int usb_stream_start(struct usb_stream_kernel *sk)
s->sync_packet = -1;
s->inpacket_head = -1;
sk->iso_frame_balance = 0;
+ sk->idle_inurb = sk->inurb[USB_STREAM_NURBS - 2];
+ sk->idle_outurb = sk->outurb[USB_STREAM_NURBS - 2];
+ sk->completed_inurb = sk->inurb[USB_STREAM_NURBS - 1];
+ sk->completed_outurb = sk->outurb[USB_STREAM_NURBS - 1];
++try;
for (u = 0; u < 2; u++) {
struct urb *inurb = sk->inurb[u];
@@ -739,11 +743,6 @@ int usb_stream_start(struct usb_stream_kernel *sk)
return -EFAULT;
}
- sk->idle_inurb = sk->inurb[USB_STREAM_NURBS - 2];
- sk->idle_outurb = sk->outurb[USB_STREAM_NURBS - 2];
- sk->completed_inurb = sk->inurb[USB_STREAM_NURBS - 1];
- sk->completed_outurb = sk->outurb[USB_STREAM_NURBS - 1];
-
/* wait, check */
{
int wait_ms = 3000;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 109/507] ALSA: hwdep: Serialize DSP load requests
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (107 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 108/507] ALSA: usx2y: Initialize idle URBs before submitting streams Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 110/507] bpf: Fix skb_pull() BUG in __bpf_redirect_neigh() Greg Kroah-Hartman
` (397 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bin Yu, Cheng Wen, YuanZhe Liu,
Takashi Iwai, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: YuanZhe Liu <25031212351@stu.xidian.edu.cn>
[ Upstream commit aee83c204f80d56b4d55f53acdb8594308ddcd4a ]
The check of the loaded DSP indices and the call of the driver's
dsp_load callback in snd_hwdep_dsp_load() are not serialized. A hwdep
file descriptor can be shared among threads, or inherited across fork,
so two SNDRV_HWDEP_IOCTL_DSP_LOAD requests for the same index can both
observe the index as unloaded and enter the driver's callback
concurrently, even though the device itself is opened exclusively.
This breaks the assumption behind hw->dsp_loaded that a firmware index
is loaded only once. For example, snd-usb-usx2y hits
WARN_ON(usx2y->as04.buffer) in usx2y_async_seq04_init() and may
allocate the US-428 sequence URBs twice.
Serialize the check, the callback invocation and the bookkeeping with a
per-hwdep mutex, so that the second request returns -EBUSY.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Co-developed-by: Bin Yu <byu@xidian.edu.cn>
Signed-off-by: Bin Yu <byu@xidian.edu.cn>
Co-developed-by: Cheng Wen <wencheng@xidian.edu.cn>
Signed-off-by: Cheng Wen <wencheng@xidian.edu.cn>
Signed-off-by: YuanZhe Liu <25031212351@stu.xidian.edu.cn>
Link: https://patch.msgid.link/20261029084810.21910-2-25031212351@stu.xidian.edu.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/sound/hwdep.h | 1 +
sound/core/hwdep.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/include/sound/hwdep.h b/include/sound/hwdep.h
index b0da633184cde..7357727f06603 100644
--- a/include/sound/hwdep.h
+++ b/include/sound/hwdep.h
@@ -57,6 +57,7 @@ struct snd_hwdep {
struct mutex open_mutex;
int used; /* reference counter */
+ struct mutex dsp_mutex; /* serializes DSP load requests */
unsigned int dsp_loaded; /* bit fields of loaded dsp indices */
unsigned int exclusive:1; /* exclusive access mode */
};
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index c6de5345e946f..fb9034897c561 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -212,6 +212,7 @@ static int snd_hwdep_dsp_load(struct snd_hwdep *hw,
return -ENXIO;
if (info->index >= 32)
return -EINVAL;
+ guard(mutex)(&hw->dsp_mutex);
/* check whether the dsp was already loaded */
if (hw->dsp_loaded & (1u << info->index))
return -EBUSY;
@@ -380,6 +381,7 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device,
init_waitqueue_head(&hwdep->open_wait);
mutex_init(&hwdep->open_mutex);
+ mutex_init(&hwdep->dsp_mutex);
hwdep->card = card;
hwdep->device = device;
if (id)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 110/507] bpf: Fix skb_pull() BUG in __bpf_redirect_neigh()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (108 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 109/507] ALSA: hwdep: Serialize DSP load requests Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 111/507] ksmbd: require DELETE access for delete-on-close opens Greg Kroah-Hartman
` (396 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jamal Hadi Salim, Alexei Starovoitov,
Victor Nogueira, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit 23503acb214cbefaf3945d05ab9667ff11ae3de9 ]
The issue:
This is a follow-up to the short link-layer header fixes from Eric.
After vlan pop_eth, a privileged SCHED_ACT BPF program can call
bpf_skb_change_head(skb, 1, 0) and then bpf_redirect_neigh().
__bpf_redirect_neigh() calls skb_pull(skb, sizeof(*ethh)) after checking
only that mac_header < network_header. Nothing verifies that the MAC
header is long enough, that it is linear, or that the IP header the
redirect goes on to read is linear either.
A SCHED_ACT BPF program can do:
bpf_skb_change_head(skb, 1, 0);
bpf_redirect_neigh(lo, NULL, 0, 0);
after vlan pop_eth. The skb then has mac_len == 1 and only one byte of
linear data; skb_pull(ETH_HLEN) trips the skb->len < skb->data_len BUG in
__skb_pull():
kernel BUG at ./include/linux/skbuff.h:2839!
RIP: skb_pull+0x40/0x50
Call Trace: skb_do_redirect -> packet_xmit -> packet_sendmsg
Kernel panic - not syncing: Fatal exception in interrupt
The v4 and v6 paths read ip_hdr() and ipv6_hdr() as soon as the MAC
header is gone. On the AF_PACKET frame below that leaves headlen == 0
after the pull, so the network header sits at skb->tail and the route
lookup reads ip4h->protocol, ip4h->saddr and ip4h->daddr past the linear
area.
The Fix:
Use skb_network_offset(), which is the MAC header span, instead of
skb->mac_len. mac_len is zero for locally generated tc egress and netkit
packets, while the span still rejects the one-byte header produced by
pop_eth + bpf_skb_change_head(skb, 1, 0). The single check also covers
the mac_header >= network_header test it replaces.
Use pskb_may_pull() to make the Ethernet header linear before it is read
or pulled, and to make the IP header linear in both the v4 and the v6
path before ip_hdr()/ipv6_hdr() is read. The header pointers are taken
after the pull, since pskb_may_pull() may reallocate skb->head.
Conditions to recreate the bug:
On x86-64 with 4 KiB pages, enable CONFIG_PACKET, CONFIG_BPF_SYSCALL,
CONFIG_NET_SCH_INGRESS, CONFIG_NET_CLS_MATCHALL, CONFIG_NET_ACT_VLAN and
CONFIG_NET_ACT_BPF. Run as root with BPF loading, network administration
and raw-packet privileges. Bring lo up and attach a SCHED_ACT program
that calls bpf_skb_change_head(skb, 1, 0), then returns
bpf_redirect_neigh(skb->ifindex, NULL, 0, 0):
ip link set lo up
tc qdisc add dev lo clsact
tc filter add dev lo egress matchall action vlan pop_eth pipe \
action bpf object-file neigh_chghead.o section action
Send an untagged ETH_P_IP frame of ETH_HLEN + 8192 bytes through an
AF_PACKET/SOCK_RAW socket bound to lo, without PACKET_VNET_HDR or
PACKET_QDISC_BYPASS. Use a unicast destination MAC. The sender's skb
has a 14-byte linear Ethernet prefix and a fragmented payload; pop_eth
removes that prefix and change_head restores only one linear byte.
The unfixed neighbor redirect then tries to pull 14 bytes and BUGs.
Sending the same frame without pop_eth and change_head leaves the IP
header in the frags, which is the route lookup reading past skb->tail.
Fixes: b4ab31414970 ("bpf: Add redirect_neigh helper as redirect drop-in")
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/netdev/20261027082604.1485903-1-edumazet@kernel.org/
Link: https://lore.kernel.org/all/2a0f5ff1d8db81b07fc4b344b8e68e3505fcbf36f72a471d1678b2f1cecd881b@mail.kernel.org/
Link: https://lore.kernel.org/netdev/DMII4JGTEUEG.2WRJPT6ODT6J0@gmail.com/
Link: https://patch.msgid.link/bpf_redirect_neigh_short_linear.v3.r0.20261031153053-1@mojatatu.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/filter.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c
index 70dc621672f2e..fa20285b841dd 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2271,9 +2271,13 @@ static int bpf_out_neigh_v6(struct net *net, struct sk_buff *skb,
static int __bpf_redirect_neigh_v6(struct sk_buff *skb, struct net_device *dev,
struct bpf_nh_params *nh)
{
- const struct ipv6hdr *ip6h = ipv6_hdr(skb);
struct net *net = dev_net(dev);
int err, ret = NET_XMIT_DROP;
+ const struct ipv6hdr *ip6h;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*ip6h))))
+ goto out_drop;
+ ip6h = ipv6_hdr(skb);
if (!nh) {
struct dst_entry *dst;
@@ -2380,9 +2384,13 @@ static int bpf_out_neigh_v4(struct net *net, struct sk_buff *skb,
static int __bpf_redirect_neigh_v4(struct sk_buff *skb, struct net_device *dev,
struct bpf_nh_params *nh)
{
- const struct iphdr *ip4h = ip_hdr(skb);
struct net *net = dev_net(dev);
int err, ret = NET_XMIT_DROP;
+ const struct iphdr *ip4h;
+
+ if (unlikely(!pskb_may_pull(skb, sizeof(*ip4h))))
+ goto out_drop;
+ ip4h = ip_hdr(skb);
if (!nh) {
struct flowi4 fl4 = {
@@ -2432,15 +2440,14 @@ static int __bpf_redirect_neigh_v4(struct sk_buff *skb, struct net_device *dev,
static int __bpf_redirect_neigh(struct sk_buff *skb, struct net_device *dev,
struct bpf_nh_params *nh)
{
- struct ethhdr *ethh = eth_hdr(skb);
-
- if (unlikely(skb->mac_header >= skb->network_header))
+ if (unlikely(skb_network_offset(skb) < ETH_HLEN ||
+ !pskb_may_pull(skb, ETH_HLEN)))
goto out;
bpf_push_mac_rcsum(skb);
- if (is_multicast_ether_addr(ethh->h_dest))
+ if (is_multicast_ether_addr(eth_hdr(skb)->h_dest))
goto out;
- skb_pull(skb, sizeof(*ethh));
+ skb_pull(skb, ETH_HLEN);
skb_unset_mac_header(skb);
skb_reset_network_header(skb);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 111/507] ksmbd: require DELETE access for delete-on-close opens
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (109 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 110/507] bpf: Fix skb_pull() BUG in __bpf_redirect_neigh() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 112/507] ksmbd: enforce the read-only share flag when creating a stream Greg Kroah-Hartman
` (395 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ian Bridges, Namjae Jeon,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Bridges <icb@fastmail.org>
[ Upstream commit 1dd91081ba3c692565f9c1f884149178d5a06d1e ]
smb2_open() accepts FILE_DELETE_ON_CLOSE on an existing file without
DELETE in DesiredAccess. When the request asks only for
FILE_READ_ATTRIBUTES or READ_CONTROL, it also skips inode_permission()
and the parent directory MAY_WRITE | MAY_EXEC check that delete-on-close
is meant to get. The file is then marked for deletion by a caller who
could not delete it.
The unlink happens later, in __ksmbd_inode_close(), when the last handle
on the inode is closed, and it runs with the credentials of that handle.
If the caller closes last, the unlink fails. If another user who can
write the parent directory, such as the file's owner, still has the file
open, the file is deleted when that user closes it. Until then new opens
of the file fail with STATUS_DELETE_PENDING. So a user with only search
permission on a directory can delete a file in it, or block opens of it,
while the owner has it open.
A MAXIMUM_ALLOWED open that also requests DELETE has the same problem.
The requested access is replaced with the maximal access, which does not
include DELETE when the caller cannot write the parent directory, and the
later permission checks are skipped as already done.
MS-FSA 2.1.5.1 requires an open with FILE_DELETE_ON_CLOSE and without
DELETE in DesiredAccess to fail with STATUS_INVALID_PARAMETER, and Samba
does the same. Add that check to the CreateOptions validation, using
the generic-mapped DesiredAccess so that GENERIC_ALL still qualifies.
This also refuses MAXIMUM_ALLOWED with FILE_DELETE_ON_CLOSE but no
explicit DELETE, as MS-FSA and Samba do. When MAXIMUM_ALLOWED is
requested with DELETE but the maximal access does not include DELETE,
fail with STATUS_ACCESS_DENIED. With DELETE requested, delete-on-close
opens go through the existing parent directory check.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
Cc: stable@vger.kernel.org
Signed-off-by: Ian Bridges <icb@fastmail.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smb2pdu.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 30549a02ccfb2..b740be1030f57 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -4508,6 +4508,14 @@ int smb2_open(struct ksmbd_work *work)
goto err_out2;
}
}
+
+ /* MS-FSA 2.1.5.1: delete-on-close requires DELETE access */
+ if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE &&
+ !(smb_map_generic_desired_access(req->DesiredAccess) &
+ FILE_DELETE_LE)) {
+ rc = -EINVAL;
+ goto err_out2;
+ }
}
if (le32_to_cpu(req->CreateDisposition) >
@@ -4777,6 +4785,13 @@ int smb2_open(struct ksmbd_work *work)
maximal_access = daccess;
}
+ /* MAXIMUM_ALLOWED may not have granted the requested DELETE */
+ if (req->CreateOptions & FILE_DELETE_ON_CLOSE_LE &&
+ !(daccess & FILE_DELETE_LE)) {
+ rc = -EACCES;
+ goto err_out;
+ }
+
open_flags = smb2_create_open_flags(file_present, daccess,
req->CreateDisposition,
&may_flags,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 112/507] ksmbd: enforce the read-only share flag when creating a stream
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (110 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 111/507] ksmbd: require DELETE access for delete-on-close opens Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 113/507] ksmbd: revert fsids on durable reconnect and replay failure Greg Kroah-Hartman
` (394 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ian Bridges, Namjae Jeon,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Bridges <icb@fastmail.org>
[ Upstream commit 09139429fab3a5114c18d7c15fb161511d4d66c9 ]
When a share is read-only, smb2_open() rejects opens that would create
or truncate a file. Creating a named stream on an existing file with
streams_xattr sets neither O_CREAT nor O_TRUNC, so it passes this check,
and smb2_set_stream_name_xattr() then creates the stream. On a Time
Machine share, opening a missing AFP_AfpInfo stream also writes one. A
user who can write a file at the filesystem level can therefore add
streams to it through a read-only share.
Do not create a stream or synthesize AFP_AfpInfo when the share is not
writable. Existing streams still open normally, and a missing stream
opened with FILE_OPEN still returns STATUS_OBJECT_NAME_NOT_FOUND.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
Fixes: eaff8e924f60 ("ksmbd: synthesize empty AFP_AfpInfo xattr on first probe")
Cc: stable@vger.kernel.org
Signed-off-by: Ian Bridges <icb@fastmail.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smb2pdu.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index b740be1030f57..abdbe54a2c04a 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -3453,7 +3453,8 @@ static noinline int smb2_set_stream_name_xattr(const struct path *path,
if (fp->cdoption == FILE_OPEN_LE) {
if (!strcmp(stream_name, "AFP_AfpInfo") &&
test_share_config_flag(fp->tcon->share_conf,
- KSMBD_SHARE_FLAG_TIME_MACHINE)) {
+ KSMBD_SHARE_FLAG_TIME_MACHINE) &&
+ test_tree_conn_flag(fp->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE)) {
/*
* Synthesize an empty AFP_AfpInfo xattr on first access.
* type=0/creator=0 tells macOS to use the file extension
@@ -3479,6 +3480,9 @@ static noinline int smb2_set_stream_name_xattr(const struct path *path,
return -EBADF;
}
+ if (!test_tree_conn_flag(fp->tcon, KSMBD_TREE_CONN_FLAG_WRITABLE))
+ return -EACCES;
+
rc = ksmbd_vfs_setxattr(idmap, path, xattr_stream_name, NULL, 0, 0, false);
if (rc < 0)
pr_err("Failed to store XATTR stream name :%d\n", rc);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 113/507] ksmbd: revert fsids on durable reconnect and replay failure
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (111 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 112/507] ksmbd: enforce the read-only share flag when creating a stream Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 114/507] ksmbd: fix NULL pointer dereference in session_user_name() and session_account_type() Greg Kroah-Hartman
` (393 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ian Bridges, Namjae Jeon,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Bridges <icb@fastmail.org>
[ Upstream commit 539223f18026448f67d33d09719c355b91db7fd0 ]
On a durable handle reconnect or a request replay, smb2_open() switches
to the SMB user's fsids before calling ksmbd_vfs_getattr(). If that call
fails, the code jumps to err_out2 and skips ksmbd_revert_fsids() at
err_out1. The user's credentials then stay installed on the shared ksmbd
worker. Later work on that worker, including other users' requests, runs
with the first user's fsuid, fsgid and supplementary groups.
ksmbd_free_work_struct() also warns, because work->saved_cred is still
set.
Jump to err_out1 instead. No path is held at this point, so skipping the
path_put() at err_out is correct.
Fixes: c8efcc786146 ("ksmbd: add support for durable handles v1/v2")
Fixes: bb8bf7eb13b5 ("ksmbd: add SMB3 request replay support")
Cc: stable@vger.kernel.org
Signed-off-by: Ian Bridges <icb@fastmail.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smb2pdu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index abdbe54a2c04a..1c8037c85de95 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -4432,7 +4432,7 @@ int smb2_open(struct ksmbd_work *work)
file_info = FILE_OPENED;
rc = ksmbd_vfs_getattr(&fp->filp->f_path, &stat);
if (rc)
- goto err_out2;
+ goto err_out1;
goto reconnected_fp;
}
@@ -4462,7 +4462,7 @@ int smb2_open(struct ksmbd_work *work)
rc = ksmbd_vfs_getattr(&fp->filp->f_path, &stat);
if (rc)
- goto err_out2;
+ goto err_out1;
goto reconnected_fp;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 114/507] ksmbd: fix NULL pointer dereference in session_user_name() and session_account_type()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (112 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 113/507] ksmbd: revert fsids on durable reconnect and replay failure Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 115/507] rust: cpufreq: fix `undocumented_unsafe_blocks` in `PolicyCpu::from_cpu()` Greg Kroah-Hartman
` (392 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jack Blessed Kimani, Namjae Jeon,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jack Blessed Kimani <jackblessed191@gmail.com>
[ Upstream commit d13da43938d15b0b719827d8f2b32df8eaec5def ]
session_user_name() and session_account_type() dereference
session->user without checking for NULL. A session can be published
and exposed via the procfs session interface before authentication
completes, during which session->user is NULL:
show_proc_session() -> session_user_name(sess)
-> user_guest(session->user) -> NULL->flags -> oops
Guard both functions by treating a NULL session->user as an explicit
not-yet-authenticated state rather than dereferencing it.
Fixes: 1f7dd03a88a8 ("ksmbd: fix malformed procfs status output")
Cc: stable@vger.kernel.org
Signed-off-by: Jack Blessed Kimani <jackblessed191@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/mgmt/user_session.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c
index 1b30e432ebfd8..d131809dd08ad 100644
--- a/fs/smb/server/mgmt/user_session.c
+++ b/fs/smb/server/mgmt/user_session.c
@@ -89,6 +89,8 @@ static const char *session_state_string(struct ksmbd_session *session)
static const char *session_user_name(struct ksmbd_session *session)
{
+ if (!session->user)
+ return "(Unauthenticated)";
if (user_guest(session->user))
return "(Guest)";
else if (ksmbd_anonymous_user(session->user))
@@ -98,6 +100,8 @@ static const char *session_user_name(struct ksmbd_session *session)
static const char *session_account_type(struct ksmbd_session *session)
{
+ if (!session->user)
+ return "unauthenticated";
if (user_guest(session->user))
return "guest";
if (ksmbd_anonymous_user(session->user))
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 115/507] rust: cpufreq: fix `undocumented_unsafe_blocks` in `PolicyCpu::from_cpu()`
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (113 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 114/507] ksmbd: fix NULL pointer dereference in session_user_name() and session_account_type() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 116/507] ASoC: SOF: Intel: hda-sdw-bpt: Stop active DMA before closing BPT streams Greg Kroah-Hartman
` (391 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhongqiu Han, Viresh Kumar,
Miguel Ojeda, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <ojeda@kernel.org>
[ Upstream commit 62a40c72905be262e9e10790008d505ed0be6c0f ]
For Rust <= 1.86, Clippy triggers after commit 02c5d7bfa872 ("rust:
cpufreq: reject NULL from cpufreq_cpu_get()"):
warning: unsafe block missing a safety comment
--> rust/kernel/cpufreq.rs:700:26
|
700 | NonNull::new(unsafe { bindings::cpufreq_cpu_get(u32::from(cpu)) }).ok_or(ENODEV)?;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider adding a safety comment on the preceding line
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks
= note: requested on the command line with `-W clippy::undocumented-unsafe-blocks`
Thus clean it up.
Cc: stable@vger.kernel.org
Fixes: 02c5d7bfa872 ("rust: cpufreq: reject NULL from cpufreq_cpu_get()")
Assisted-by: LLM
Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Link: https://patch.msgid.link/20261018163719.81691-1-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
rust/kernel/cpufreq.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/rust/kernel/cpufreq.rs b/rust/kernel/cpufreq.rs
index b75d692846a25..f31671129c984 100644
--- a/rust/kernel/cpufreq.rs
+++ b/rust/kernel/cpufreq.rs
@@ -696,8 +696,8 @@ fn clear_data<T: ForeignOwnable>(&mut self) -> Option<T> {
impl<'a> PolicyCpu<'a> {
fn from_cpu(cpu: CpuId) -> Result<Self> {
// SAFETY: It is safe to call `cpufreq_cpu_get` for any valid CPU.
- let ptr =
- NonNull::new(unsafe { bindings::cpufreq_cpu_get(u32::from(cpu)) }).ok_or(ENODEV)?;
+ let ptr = unsafe { bindings::cpufreq_cpu_get(u32::from(cpu)) };
+ let ptr = NonNull::new(ptr).ok_or(ENODEV)?;
Ok(Self(
// SAFETY: `ptr` is non-NULL and `cpufreq_cpu_get()` took a reference on it, so it is
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 116/507] ASoC: SOF: Intel: hda-sdw-bpt: Stop active DMA before closing BPT streams
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (114 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 7.3 115/507] rust: cpufreq: fix `undocumented_unsafe_blocks` in `PolicyCpu::from_cpu()` Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 117/507] x86/bugs: Select the BHI mitigation based on the attack vector properly Greg Kroah-Hartman
` (390 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lee Jones, Peter Ujfalusi,
Mark Brown, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lee Jones <lee@kernel.org>
[ Upstream commit 348bc756d912dd8f47fd36c167075717951a515e ]
When sdw_enable_stream() fails in intel_ace2x_bpt_send_async() after
hda_sdw_bpt_send_async() has already started the TX and RX DMA streams,
intel_ace2x_bpt_close_stream() invokes hda_sdw_bpt_close() directly
without calling hda_sdw_bpt_wait(). As a result,
hda_sdw_bpt_dma_deprepare() tears down the DMA buffers and BDL while
the DMA hardware is still running.
Disable any running TX or RX BPT DMA stream at the start of
hda_sdw_bpt_close() before unmapping channels and depreparing DMA
resources.
Fixes: 4c1ce9f37d8a ("soundwire: intel_ace2x: add BPT send_async/wait callbacks")
Closes: https://sashiko.dev/#/bug/linux-ff0012de-abdd-4796-875e-b1fbbf47235f
Cc: stable@vger.kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
Acked-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://patch.msgid.link/20261030104840.3361217-6-lee@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/sof/intel/hda-sdw-bpt.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/sound/soc/sof/intel/hda-sdw-bpt.c b/sound/soc/sof/intel/hda-sdw-bpt.c
index ba9fbd662b859..9d97d86762514 100644
--- a/sound/soc/sof/intel/hda-sdw-bpt.c
+++ b/sound/soc/sof/intel/hda-sdw-bpt.c
@@ -456,6 +456,12 @@ int hda_sdw_bpt_close(struct device *dev, int link_id, struct hdac_ext_stream *b
int ret;
int ret1;
+ if (bpt_rx_stream && hdac_stream(bpt_rx_stream)->running)
+ hda_sdw_bpt_dma_disable(dev, bpt_rx_stream);
+
+ if (bpt_tx_stream && hdac_stream(bpt_tx_stream)->running)
+ hda_sdw_bpt_dma_disable(dev, bpt_tx_stream);
+
/*
* In the case of SoundWire we need to reset the PCMSyCM registers.
* Need to continue depreparing the DMA buffers even if this fails.
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 117/507] x86/bugs: Select the BHI mitigation based on the attack vector properly
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (115 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 116/507] ASoC: SOF: Intel: hda-sdw-bpt: Stop active DMA before closing BPT streams Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 118/507] x86/csum: Relax the len and proto constraints in 32-bit csum_ipv6_magic() Greg Kroah-Hartman
` (389 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Breno Leitao, Borislav Petkov (AMD),
David Kaplan, stable, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <leitao@debian.org>
[ Upstream commit 3457b3bcd344005af894876cab4e634cabdcbb62 ]
The BHI mitigation selection is inconsistent with the documentation
(attack_vector_controls.rst), which lists BHI under both the
user->kernel and guest->host attack vectors. bhi_select_mitigation()
only enables it when CPU_MITIGATE_GUEST_HOST is set; otherwise it
selects BHI_MITIGATION_OFF, even if CPU_MITIGATE_USER_KERNEL is set.
As a result, a kernel compiled with KVM disabled gets BHI automatically
disabled, since CPU_MITIGATE_GUEST_HOST defaults to off without KVM.
This is a bug, given that CPU_MITIGATE_USER_KERNEL still needs it: on
affected Intel CPUs these kernels lose BHI_DIS_S or the BHB clearing
loop by default. Booting with mitigations=auto,no_guest_host has the
same effect.
Select BHI_MITIGATION_ON whenever user->kernel is mitigated, and keep
BHI_MITIGATION_VMEXIT_ONLY for the guest->host-only case.
[ bp: Clarify commit title. ]
Fixes: ddcd4d3cb37c ("x86/bugs: Add attack vector controls for BHI")
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Acked-by: David Kaplan <david.kaplan@amd.com>
Cc: <stable@kernel.org>
Link: https://patch.msgid.link/20261029-bhi-attack-vector-v1-1-29cfa697efb6@debian.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kernel/cpu/bugs.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
index 000ebee2d247b..4ced10c6ba0db 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -2088,14 +2088,12 @@ static void __init bhi_select_mitigation(void)
if (bhi_mitigation != BHI_MITIGATION_AUTO)
return;
- if (cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_HOST)) {
- if (cpu_attack_vector_mitigated(CPU_MITIGATE_USER_KERNEL))
- bhi_mitigation = BHI_MITIGATION_ON;
- else
- bhi_mitigation = BHI_MITIGATION_VMEXIT_ONLY;
- } else {
+ if (cpu_attack_vector_mitigated(CPU_MITIGATE_USER_KERNEL))
+ bhi_mitigation = BHI_MITIGATION_ON;
+ else if (cpu_attack_vector_mitigated(CPU_MITIGATE_GUEST_HOST))
+ bhi_mitigation = BHI_MITIGATION_VMEXIT_ONLY;
+ else
bhi_mitigation = BHI_MITIGATION_OFF;
- }
}
static void __init bhi_update_mitigation(void)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 118/507] x86/csum: Relax the len and proto constraints in 32-bit csum_ipv6_magic()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (116 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 117/507] x86/bugs: Select the BHI mitigation based on the attack vector properly Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 119/507] drm/i915/psr: Clear selective fetch area when duplicating plane state Greg Kroah-Hartman
` (388 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, kernelci.org bot, Jeff Johnson,
Rosen Penev, Sasha Levin, Borislav Petkov (AMD), Nick Desaulniers
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <rosenp@gmail.com>
[ Upstream commit f01a394fe2a00d3cb4cf2cda279c58604a2540ad ]
Building an i386 allmodconfig kernel with clang fails since allmodconfig
started building netfilter with GCOV profiling:
In file included from net/netfilter/nf_synproxy_core.c:7:
In file included from ./include/linux/skbuff.h:26:
In file included from ./include/net/checksum.h:21:
In file included from ./arch/x86/include/asm/checksum.h:9:
./arch/x86/include/asm/checksum_32.h:149:6: error: inline assembly requires more registers than available
The csum_ipv6_magic() asm needs five registers at once: the early-clobber sum
plus register-only inputs for saddr, daddr, htonl(len) and htonl(proto). With
frame pointers enabled, six general purpose registers are left to choose from.
In synproxy_send_tcp_ipv6(), the GCOV instrumentation lets clang's machine
scheduler move the copies of two incoming register arguments, EDX and ECX,
below the asm.
Both registers then stay live across the asm, which leaves four registers for
its five operands. This is LLVM issue #206307. The error goes away without
either GCOV or frame pointers, and it reproduces with clang 19-22.
Neither len nor proto has to be in a register: ADCL also takes a 32-bit memory
or immediate source operand. Use "g" for both, so the asm needs at most three
registers whatever the caller looks like.
ASM_INPUT_G, which normally replaces "g" to avoid clang's poor handling of it,
is not enough here. It expands to "ir" for clang, so callers that pass
a variable protocol, like nf_ip6_checksum(), would still need five registers.
With "g", clang passes a non-constant len or proto through the stack and still
turns constants into immediates.
[ bp: Make Rosen Penev the author because of a previous identical submission
https://lore.kernel.org/all/20260904000833.2058186-1-rosenp@gmail.com/ and
Sasha graciously agreeing and giving his much more detailed commit message
explaining the background of why this exists. ]
Fixes: 403cec8ab6d0 ("netfilter: add option for GCOV profiling")
Closes: https://dashboard.kernelci.org/build/maestro:6ad55fe255fda507603d2651
Closes: https://lore.kernel.org/a28df759-d0e9-41c0-97c7-5f89a18d54e2@oss.qualcomm.com
Reported-by: kernelci.org bot <bot@kernelci.org>
Reported-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Assisted-by: LLM
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Acked-by: Nick Desaulniers <ndesaulniers@google.com>
Cc: stable@vger.kernel.org
Link: https://github.com/llvm/llvm-project/issues/206307
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/include/asm/checksum_32.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/checksum_32.h b/arch/x86/include/asm/checksum_32.h
index 17da953879976..f74873a5e3510 100644
--- a/arch/x86/include/asm/checksum_32.h
+++ b/arch/x86/include/asm/checksum_32.h
@@ -159,7 +159,7 @@ static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
"adcl $0, %0 ;\n"
: "=&r" (sum)
: "r" (saddr), "r" (daddr),
- "r" (htonl(len)), "r" (htonl(proto)), "0" (sum)
+ "g" (htonl(len)), "g" (htonl(proto)), "0" (sum)
: "memory");
return csum_fold(sum);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 119/507] drm/i915/psr: Clear selective fetch area when duplicating plane state
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (117 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 118/507] x86/csum: Relax the len and proto constraints in 32-bit csum_ipv6_magic() Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 120/507] drm/i915/display: Add enabled pipe planes into state for selective fetch Greg Kroah-Hartman
` (387 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jouni Högander, Mika Kahola,
Joonas Lahtinen, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jouni Högander <jouni.hogander@intel.com>
[ Upstream commit cbe565475988d3b22dc36f13c14d9f0eec1685cd ]
We are currently not clearing selective fetch area when duplicating plane
state. This is causing problem when plane is re-used for another
purpose. Fix this by clearing selective fetch area when duplicating plane
state.
Now as the state is cleared we need to ensure we have consistent selective
fetch area in plane state on full update. Earlier this was relying on
selective fetch area being copied from old state on state duplicate. Now
this isn't true anymore as we are clearing it. Tackle this by setting full
plane area as selective fetch area for each plane on full update. Rename
the label as skip_su_area_calc as the loop setting the plane selective
fetch area is not skipped anymore.
Move also psr2_sel_fetch_pipe_state_supported check after psr2_su_area
initialization. The loop is run on full update as well now and it needs
initialized psr2_su_area. Clip_area_update is only touching rect height and
x1/x2 are left untouched.
Don't set the area at all for planes not intersecting with the selective
update area. It is already zero sized after plane state duplicate.
Fixes: efab47658a6c ("drm/i915/display/psr: Calculate selective fetch plane registers")
Cc: <stable@vger.kernel.org> # v5.12+
Assisted-by: GitHub-Copilot:claude-opus-5
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
Link: https://patch.msgid.link/20260929094434.77129-2-jouni.hogander@intel.com
(cherry picked from commit bd58f0e221386808cd614bb205112e807dc6b159)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/intel_plane.c | 1 +
drivers/gpu/drm/i915/display/intel_psr.c | 24 ++++++++++------------
2 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c
index d0f99a87c42e8..d0e7309483234 100644
--- a/drivers/gpu/drm/i915/display/intel_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_plane.c
@@ -140,6 +140,7 @@ intel_plane_duplicate_state(struct drm_plane *plane)
intel_state->dpt_vma = NULL;
intel_state->fence_id = -1;
intel_state->damage = DRM_RECT_INIT(0, 0, 0, 0);
+ intel_state->psr2_sel_fetch_area = DRM_RECT_INIT(0, 0, 0, 0);
/* add reference to fb */
if (intel_state->hw.fb)
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index c28bcb1a01841..15421b0a3bb0d 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2913,16 +2913,16 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
if (!crtc_state->enable_psr2_sel_fetch)
return 0;
- if (!psr2_sel_fetch_pipe_state_supported(crtc_state)) {
- full_update = true;
- goto skip_sel_fetch_set_loop;
- }
-
crtc_state->psr2_su_area.x1 = 0;
crtc_state->psr2_su_area.y1 = -1;
crtc_state->psr2_su_area.x2 = drm_rect_width(&display_area);
crtc_state->psr2_su_area.y2 = -1;
+ if (!psr2_sel_fetch_pipe_state_supported(crtc_state)) {
+ full_update = true;
+ goto skip_su_area_calc;
+ }
+
/*
* Calculate minimal selective fetch area of each plane and calculate
* the pipe damaged area.
@@ -3006,7 +3006,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
}
if (full_update)
- goto skip_sel_fetch_set_loop;
+ goto skip_su_area_calc;
intel_psr_apply_su_area_workarounds(crtc_state);
@@ -3042,6 +3042,11 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
break;
} while (su_area_changed);
+skip_su_area_calc:
+ if (full_update)
+ clip_area_update(&crtc_state->psr2_su_area, &display_area,
+ &display_area);
+
/*
* Now that we have the pipe damaged area check if it intersect with
* every plane, if it does set the plane selective fetch area.
@@ -3058,8 +3063,6 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
inter = crtc_state->psr2_su_area;
sel_fetch_area = &new_plane_state->psr2_sel_fetch_area;
if (!drm_rect_intersect(&inter, &new_plane_state->uapi.dst)) {
- sel_fetch_area->y1 = -1;
- sel_fetch_area->y2 = -1;
/*
* if plane sel fetch was previously enabled ->
* disable it
@@ -3099,11 +3102,6 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
}
}
-skip_sel_fetch_set_loop:
- if (full_update)
- clip_area_update(&crtc_state->psr2_su_area, &display_area,
- &display_area);
-
psr2_man_trk_ctl_calc(crtc_state, full_update);
crtc_state->pipe_srcsz_early_tpt =
psr2_pipe_srcsz_early_tpt_calc(crtc_state, full_update);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 120/507] drm/i915/display: Add enabled pipe planes into state for selective fetch
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (118 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 119/507] drm/i915/psr: Clear selective fetch area when duplicating plane state Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 121/507] drm/i915/psr: Disable linked plane sel fetch as well Greg Kroah-Hartman
` (386 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jouni Högander, Mika Kahola,
Joonas Lahtinen, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jouni Högander <jouni.hogander@intel.com>
[ Upstream commit 94cb1f08b197d9ae932ff98c741bd0dbc96e17e8 ]
Selective fetch support for biplanar formats relies on linking of UV and
the Y planes. Planes that are not part of the atomic state are pulled in by
the drm_atomic_add_affected_planes. If the UV plane is added into the state
by drm_atomic_add_affected_planes in the selective fetch calculation, the
linking isn't done anymore and the Y plane is left disabled.
Fix this by adding affected planes already in intel_add_affected_planes if
selective fetch is enabled.
Remove redundant drm_atomic_add_affected_planes from
intel_psr2_sel_fetch_update and redundant check for plane selective fetch
support that is not needed as all planes are already in atomic state on
first loop iterating them. Also switch to intel_atomic_get_new_plane_state
for linked plane new plane state.
Fixes: 3809991ff5f4 ("drm/i915/display: Add initial selective fetch support for biplanar formats")
Cc: <stable@vger.kernel.org> # v5.17+
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
Link: https://patch.msgid.link/20260929094434.77129-3-jouni.hogander@intel.com
(cherry picked from commit 0d173898b11157d37de3e5f01ef28a48582167d8)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/intel_plane.c | 10 +++++++++
drivers/gpu/drm/i915/display/intel_psr.c | 25 +++++++---------------
2 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c
index d0e7309483234..c1c5a6128614f 100644
--- a/drivers/gpu/drm/i915/display/intel_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_plane.c
@@ -1931,6 +1931,16 @@ static int intel_add_affected_planes(struct intel_atomic_state *state)
ret = intel_joiner_add_affected_planes(state, intel_crtc_joined_pipe_mask(crtc_state));
if (ret)
return ret;
+
+ /*
+ * Add affected plane here to ensure UV and Y plane linking is
+ * in place if UV plane is added as a part of selective update.
+ */
+ if (crtc_state->enable_psr2_sel_fetch) {
+ ret = intel_plane_add_affected(state, crtc);
+ if (ret)
+ return ret;
+ }
}
return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 15421b0a3bb0d..5522d1e0cbcc5 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2895,7 +2895,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
.y2 = crtc_state->hw.adjusted_mode.crtc_vdisplay,
};
bool full_update = false, su_area_changed;
- int i, ret;
+ int i;
/*
* Selective fetch is not always usable, for instance it is dropped
@@ -3010,19 +3010,15 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
intel_psr_apply_su_area_workarounds(crtc_state);
- ret = drm_atomic_add_affected_planes(&state->base, &crtc->base);
- if (ret)
- return ret;
-
do {
bool cursor_in_su_area = false;
/*
* Adjust su area to cover cursor fully as necessary
- * (early transport). This needs to be done after
- * drm_atomic_add_affected_planes to ensure visible
- * cursor is added into affected planes even when
- * cursor is not updated by itself.
+ * (early transport). A visible cursor is in the state
+ * even when it is not updated by itself as all planes
+ * of the pipe are added into the state before the plane
+ * checks when selective fetch is enabled.
*/
intel_psr2_sel_fetch_et_alignment(state, crtc, &display_area,
&cursor_in_su_area);
@@ -3073,11 +3069,6 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
continue;
}
- if (!psr2_sel_fetch_plane_state_supported(new_plane_state)) {
- full_update = true;
- break;
- }
-
sel_fetch_area = &new_plane_state->psr2_sel_fetch_area;
sel_fetch_area->y1 = inter.y1 - new_plane_state->uapi.dst.y1;
sel_fetch_area->y2 = inter.y2 - new_plane_state->uapi.dst.y1;
@@ -3091,9 +3082,9 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
struct intel_plane_state *linked_new_plane_state;
struct drm_rect *linked_sel_fetch_area;
- linked_new_plane_state = intel_atomic_get_plane_state(state, linked);
- if (IS_ERR(linked_new_plane_state))
- return PTR_ERR(linked_new_plane_state);
+ linked_new_plane_state = intel_atomic_get_new_plane_state(state, linked);
+ if (!linked_new_plane_state)
+ return -EINVAL;
linked_sel_fetch_area = &linked_new_plane_state->psr2_sel_fetch_area;
linked_sel_fetch_area->y1 = sel_fetch_area->y1;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 121/507] drm/i915/psr: Disable linked plane sel fetch as well
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (119 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 120/507] drm/i915/display: Add enabled pipe planes into state for selective fetch Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 122/507] drm/i915/psr: Fix SFF and CFF CTL register bit definitions Greg Kroah-Hartman
` (385 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jouni Högander, Mika Kahola,
Joonas Lahtinen, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jouni Högander <jouni.hogander@intel.com>
[ Upstream commit b56721c32eb3ad0f086fdc0f33479be395e43bb9 ]
Currently we are not setting linked plane selective area when selective
fetch is about to be disabled for the UV plane. Fix this by simplifying the
loop by just handling plane selective fetch disable and area setting same
way.
Also set the update_planes bit based on comparing old and new plane
selective fetch area. This way both the plane and its linked Y plane are
updated only when their selective fetch area changed.
Fixes: a4f477e6ac17 ("drm/i915/psr: Add proper handling for disabling sel fetch for planes")
Cc: <stable@vger.kernel.org> # v6.8+
Assisted-by: GitHub-Copilot:claude-opus-5
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
Link: https://patch.msgid.link/20260929094434.77129-4-jouni.hogander@intel.com
(cherry picked from commit b10c83af60cbc00ce4112742fd297581233e43cd)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/intel_psr.c | 27 ++++++++++++------------
1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 5522d1e0cbcc5..1a9706d43b625 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -3058,21 +3058,14 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
inter = crtc_state->psr2_su_area;
sel_fetch_area = &new_plane_state->psr2_sel_fetch_area;
- if (!drm_rect_intersect(&inter, &new_plane_state->uapi.dst)) {
- /*
- * if plane sel fetch was previously enabled ->
- * disable it
- */
- if (drm_rect_height(&old_plane_state->psr2_sel_fetch_area) > 0)
- crtc_state->update_planes |= BIT(plane->id);
-
- continue;
+ if (drm_rect_intersect(&inter, &new_plane_state->uapi.dst)) {
+ sel_fetch_area->y1 = inter.y1 - new_plane_state->uapi.dst.y1;
+ sel_fetch_area->y2 = inter.y2 - new_plane_state->uapi.dst.y1;
}
- sel_fetch_area = &new_plane_state->psr2_sel_fetch_area;
- sel_fetch_area->y1 = inter.y1 - new_plane_state->uapi.dst.y1;
- sel_fetch_area->y2 = inter.y2 - new_plane_state->uapi.dst.y1;
- crtc_state->update_planes |= BIT(plane->id);
+ if (!drm_rect_equals(&old_plane_state->psr2_sel_fetch_area,
+ sel_fetch_area))
+ crtc_state->update_planes |= BIT(plane->id);
/*
* Sel_fetch_area is calculated for UV plane. Use
@@ -3080,16 +3073,22 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
*/
if (linked) {
struct intel_plane_state *linked_new_plane_state;
+ struct intel_plane_state *linked_old_plane_state;
struct drm_rect *linked_sel_fetch_area;
linked_new_plane_state = intel_atomic_get_new_plane_state(state, linked);
if (!linked_new_plane_state)
return -EINVAL;
+ linked_old_plane_state = intel_atomic_get_old_plane_state(state, linked);
+
linked_sel_fetch_area = &linked_new_plane_state->psr2_sel_fetch_area;
linked_sel_fetch_area->y1 = sel_fetch_area->y1;
linked_sel_fetch_area->y2 = sel_fetch_area->y2;
- crtc_state->update_planes |= BIT(linked->id);
+
+ if (!drm_rect_equals(&linked_old_plane_state->psr2_sel_fetch_area,
+ linked_sel_fetch_area))
+ crtc_state->update_planes |= BIT(linked->id);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 122/507] drm/i915/psr: Fix SFF and CFF CTL register bit definitions
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (120 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 121/507] drm/i915/psr: Disable linked plane sel fetch as well Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 123/507] drm/i915/psr: Dont clip plane state destination rectangle Greg Kroah-Hartman
` (384 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jouni Högander, Mika Kahola,
Joonas Lahtinen, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jouni Högander <jouni.hogander@intel.com>
[ Upstream commit 15b3187740291c4705b995bbf984da462e9f1e35 ]
Single full frame bit in SFF_CTL and continuous full frame bit in CFF_CTL
are bit 0. Fix the definitions accordingly.
Fixes: 3b5bf853e309 ("drm/i915/psr: Add register definitions for SFF_CTL and CFF_CTL registers")
Cc: <stable@vger.kernel.org> # v6.15+
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
Link: https://patch.msgid.link/20260929094434.77129-5-jouni.hogander@intel.com
(cherry picked from commit 95ca8fab5232dfb7459989d54f09501704a8d7ad)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/intel_psr_regs.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_psr_regs.h b/drivers/gpu/drm/i915/display/intel_psr_regs.h
index 16a9e3af198d0..428f3da045003 100644
--- a/drivers/gpu/drm/i915/display/intel_psr_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_psr_regs.h
@@ -254,12 +254,12 @@
#define _LNL_SFF_CTL_A 0x60918
#define _LNL_SFF_CTL_B 0x61918
#define LNL_SFF_CTL(tran) _MMIO_TRANS(tran, _LNL_SFF_CTL_A, _LNL_SFF_CTL_B)
-#define LNL_SFF_CTL_SF_SINGLE_FULL_FRAME REG_BIT(1)
+#define LNL_SFF_CTL_SF_SINGLE_FULL_FRAME REG_BIT(0)
#define _LNL_CFF_CTL_A 0x6091c
#define _LNL_CFF_CTL_B 0x6191c
#define LNL_CFF_CTL(tran) _MMIO_TRANS(tran, _LNL_CFF_CTL_A, _LNL_CFF_CTL_B)
-#define LNL_CFF_CTL_SF_CONTINUOUS_FULL_FRAME REG_BIT(1)
+#define LNL_CFF_CTL_SF_CONTINUOUS_FULL_FRAME REG_BIT(0)
/* PSR2 Early transport */
#define _PIPE_SRCSZ_ERLY_TPT_A 0x70074
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 123/507] drm/i915/psr: Dont clip plane state destination rectangle
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (121 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 122/507] drm/i915/psr: Fix SFF and CFF CTL register bit definitions Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 124/507] drm/i915/display: Add quirk to force backlight type on some TUXEDO devices Greg Kroah-Hartman
` (383 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jouni Högander, Mika Kahola,
Joonas Lahtinen, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jouni Högander <jouni.hogander@intel.com>
[ Upstream commit e30830d21860fbf030ad162c3db4d1219477dfb5 ]
clip_area_update() uses drm_rect_intersect which modifies passed r1
rectangle. Early transport alignment passes the cursor uapi.dst rectangle
to clip_area_update, so the cursor uapi.dst is unintentionally modified by
drm_rect_intersect.
Fix this by using local copy in clip_area_update(). Also make the damage
and the display area const.
Fixes: 1bff93b8bc27 ("drm/i915/psr: Extend SU area to cover cursor fully if needed")
Cc: <stable@vger.kernel.org> # v6.9+
Assisted-by: GitHub-Copilot:claude-opus-5
Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
Link: https://patch.msgid.link/20260929094434.77129-9-jouni.hogander@intel.com
(cherry picked from commit 8621f3bcea6b0a790a954ddf2e6514c20a24ac1a)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/intel_psr.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 1a9706d43b625..7aaf5b4d35035 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2702,23 +2702,25 @@ static u32 psr2_pipe_srcsz_early_tpt_calc(struct intel_crtc_state *crtc_state,
}
static void clip_area_update(struct drm_rect *overlap_damage_area,
- struct drm_rect *damage_area,
- struct drm_rect *display_area)
+ const struct drm_rect *damage_area,
+ const struct drm_rect *display_area)
{
- if (!drm_rect_intersect(damage_area, display_area))
+ struct drm_rect inter = *damage_area;
+
+ if (!drm_rect_intersect(&inter, display_area))
return;
if (overlap_damage_area->y1 == -1) {
- overlap_damage_area->y1 = damage_area->y1;
- overlap_damage_area->y2 = damage_area->y2;
+ overlap_damage_area->y1 = inter.y1;
+ overlap_damage_area->y2 = inter.y2;
return;
}
- if (damage_area->y1 < overlap_damage_area->y1)
- overlap_damage_area->y1 = damage_area->y1;
+ if (inter.y1 < overlap_damage_area->y1)
+ overlap_damage_area->y1 = inter.y1;
- if (damage_area->y2 > overlap_damage_area->y2)
- overlap_damage_area->y2 = damage_area->y2;
+ if (inter.y2 > overlap_damage_area->y2)
+ overlap_damage_area->y2 = inter.y2;
}
static bool intel_psr2_sel_fetch_pipe_alignment(struct intel_crtc_state *crtc_state)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 124/507] drm/i915/display: Add quirk to force backlight type on some TUXEDO devices
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (122 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 123/507] drm/i915/psr: Dont clip plane state destination rectangle Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 125/507] drm/i915/gem: Reset err for each fence entry Greg Kroah-Hartman
` (382 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Werner Sembach, Suraj Kandpal,
Joonas Lahtinen, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Werner Sembach <wse@tuxedocomputers.com>
[ Upstream commit 88d804cd1be9a8ffcaf67f1a414ee92b5166a0a8 ]
The display backlight on TUXEDO DX1708 and InsanityBook 15 v1 have a broken
VBT in the AUO 12701 and AUO 12701 panels, but not others. They are
advertising INTEL_BACKLIGHT_DISPLAY_DDI, but are actually failing to use
the Intel interface. Adding a fallback to the VESA interface gives
these devices a working backlight for both the broken and non broken
panel VBTs.
Forcing the fallback can already be achieved via a module parameter,
but this patch adds a quirk to apply this by default on the mentioned
devices.
This commit does not actually test for the exact panels as the ID that is
used in the intel_dpcd_quirks list is sadly zeroed on the devices, but
afaik all these devices use try_intel_interface first anyway so all the
quirk does is to add the fallback to try_vesa_interface, so the behaviour
on the devices not needing the quirk and fallback should functionally stay
the same.
Fixes: 2914709c9141 ("Revert "drm/i915/backlight: Remove try_vesa_interface"")
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/work_items/15679
Cc: stable@vger.kernel.org
Signed-off-by: Werner Sembach <wse@tuxedocomputers.com>
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com>
Link: https://patch.msgid.link/20260807200709.464343-2-wse@tuxedocomputers.com
(cherry picked from commit 9499c3fca1c70ccfaddc9815b4c5afdfddedbd04)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../drm/i915/display/intel_dp_aux_backlight.c | 22 ++++++++++++++++-
drivers/gpu/drm/i915/display/intel_quirks.c | 24 +++++++++++++++++++
drivers/gpu/drm/i915/display/intel_quirks.h | 1 +
3 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
index 266e042e00237..d84def79c4bfb 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_aux_backlight.c
@@ -41,6 +41,7 @@
#include "intel_display_types.h"
#include "intel_dp.h"
#include "intel_dp_aux_backlight.h"
+#include "intel_quirks.h"
/*
* DP AUX registers for Intel's proprietary HDR backlight interface. We define
@@ -687,11 +688,30 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *connector)
struct drm_device *dev = connector->base.dev;
struct intel_panel *panel = &connector->panel;
bool try_intel_interface = false, try_vesa_interface = false;
+ int enable_dpcd_backlight;
+
+ /*
+ * Some devices have a broken VBT in some Panels, but not others,
+ * advertising INTEL_BACKLIGHT_DISPLAY_DDI, but actually failing to use
+ * the Intel interface. Adding a fallback to the Vesa interface gives
+ * these devices a working backlight for both the broken and non broken
+ * panel VBTs.
+ *
+ * This fallback can not be made the general default as this has broken
+ * other devices in the past whose VBT correctly reports
+ * INTEL_BACKLIGHT_DISPLAY_DDI and whose PWM path is the actual
+ * backlight control, but whose DPCD optimistically advertises
+ * DP_EDP_BACKLIGHT_AUX_ENABLE_CAP / _BRIGHTNESS_AUX_SET_CAP.
+ */
+ enable_dpcd_backlight = display->params.enable_dpcd_backlight;
+ if (enable_dpcd_backlight == INTEL_DP_AUX_BACKLIGHT_AUTO &&
+ intel_has_dpcd_quirk(intel_dp, QUIRK_ENABLE_DPCD_BACKLIGHT))
+ enable_dpcd_backlight = INTEL_DP_AUX_BACKLIGHT_ON;
/* Check the VBT and user's module parameters to figure out which
* interfaces to probe
*/
- switch (display->params.enable_dpcd_backlight) {
+ switch (enable_dpcd_backlight) {
case INTEL_DP_AUX_BACKLIGHT_OFF:
return -ENODEV;
case INTEL_DP_AUX_BACKLIGHT_AUTO:
diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c
index 7d7db774d8c7b..96eb9a40df9b9 100644
--- a/drivers/gpu/drm/i915/display/intel_quirks.c
+++ b/drivers/gpu/drm/i915/display/intel_quirks.c
@@ -100,6 +100,14 @@ static void quirk_disable_psr2(struct intel_display *display)
drm_info(display->drm, "PSR2 support not currently available for this setup, applying disable PSR2 quirk\n");
}
+static void quirk_enable_dpcd_backlight(struct intel_dp *intel_dp)
+{
+ struct intel_display *display = to_intel_display(intel_dp);
+
+ intel_set_dpcd_quirk(intel_dp, QUIRK_ENABLE_DPCD_BACKLIGHT);
+ drm_info(display->drm, "Applying Enable DPCD Backlight quirk\n");
+}
+
struct intel_quirk {
int device;
int subsystem_vendor;
@@ -289,6 +297,22 @@ static const struct intel_dpcd_quirk intel_dpcd_quirks[] = {
.sink_oui = SINK_OUI(0x00, 0x22, 0xb9),
.hook = quirk_disable_edp_panel_replay,
},
+ /* TUXEDO InsanityBook 15 v1 */
+ {
+ .device = 0x591b,
+ .subsystem_vendor = 0x1558,
+ .subsystem_device = 0x9501,
+ .sink_oui = SINK_OUI(0x38, 0xec, 0x11),
+ .hook = quirk_enable_dpcd_backlight,
+ },
+ /* TUXEDO DX1708 */
+ {
+ .device = 0x3e9b,
+ .subsystem_vendor = 0x1558,
+ .subsystem_device = 0x8500,
+ .sink_oui = SINK_OUI(0x38, 0xec, 0x11),
+ .hook = quirk_enable_dpcd_backlight,
+ },
};
void intel_init_quirks(struct intel_display *display)
diff --git a/drivers/gpu/drm/i915/display/intel_quirks.h b/drivers/gpu/drm/i915/display/intel_quirks.h
index 970a4fe52fafc..4996419ae76bd 100644
--- a/drivers/gpu/drm/i915/display/intel_quirks.h
+++ b/drivers/gpu/drm/i915/display/intel_quirks.h
@@ -23,6 +23,7 @@ enum intel_quirk_id {
QUIRK_EDP_LIMIT_RATE_HBR2,
QUIRK_DISABLE_EDP_PANEL_REPLAY,
QUIRK_DISABLE_PSR2,
+ QUIRK_ENABLE_DPCD_BACKLIGHT,
};
void intel_init_quirks(struct intel_display *display);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 125/507] drm/i915/gem: Reset err for each fence entry
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (123 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 124/507] drm/i915/display: Add quirk to force backlight type on some TUXEDO devices Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 126/507] drm/i915/display: Single scaler per pipe on WCL Greg Kroah-Hartman
` (381 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lu Yao, Andi Shyti, Joonas Lahtinen,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lu Yao <yaolu@kylinos.cn>
[ Upstream commit 31643dc89818d9b65bf42ecb1c67c99b64146fba ]
If dma_fence_chain_find_seqno() failed once, 'err' will store val in
the following loop. May causing returns '-EINVAL' even though that
entry never called dma_fence_chain_find_seqno() at all.
Fixes: 13149e8bafc4 ("drm/i915: add syncobj timeline support")
Signed-off-by: Lu Yao <yaolu@kylinos.cn>
Cc: <stable@vger.kernel.org> # v5.10+
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
Link: https://patch.msgid.link/20261027072832.726435-1-yaolu@kylinos.cn
(cherry picked from commit 4e9db08db75f55c920986ac929cfd82a4ee99f41)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
index d5aadced7da0c..7fdd41a190b42 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -2790,7 +2790,6 @@ add_timeline_fence_array(struct i915_execbuffer *eb,
u64 __user *user_values;
struct eb_fence *f;
u64 nfences;
- int err = 0;
nfences = timeline_fences->fence_count;
if (!nfences)
@@ -2828,6 +2827,7 @@ add_timeline_fence_array(struct i915_execbuffer *eb,
struct drm_syncobj *syncobj;
struct dma_fence *fence = NULL;
u64 point;
+ int err = 0;
if (__copy_from_user(&user_fence,
user_fences++,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 126/507] drm/i915/display: Single scaler per pipe on WCL
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (124 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 125/507] drm/i915/gem: Reset err for each fence entry Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 127/507] drm/i915/display: Disable pipe joiner " Greg Kroah-Hartman
` (380 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Charlton Lin, Uma Shankar,
Vidya Srinivas, Joonas Lahtinen, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vidya Srinivas <vidya.srinivas@intel.com>
[ Upstream commit 25ea7671bdbc85820026776cbe22df41c560d518 ]
WCL has only one scaler per pipe. Set num_scalers to 1 for
WCL.
v2: Rebase onto latest upstream
v3: Fix up the commit message
v4: Split the scaler and joiner changes into separate patches (Jani)
Bspec: 74286
Fixes: f8e1c3e07db1 ("drm/i915/xe3lpd: Add support for display version 30.02")
Cc: stable@vger.kernel.org
Suggested-by: Charlton Lin <charlton.lin@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Vidya Srinivas <vidya.srinivas@intel.com>
Signed-off-by: Uma Shankar <uma.shankar@intel.com>
Link: https://patch.msgid.link/20261028070404.1913843-2-vidya.srinivas@intel.com
(cherry picked from commit 8ff2ba499b20edf6c4aad89527a1e9a70c2b2074)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/intel_display_device.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c
index f17fc2c684724..c74256359c253 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.c
+++ b/drivers/gpu/drm/i915/display/intel_display_device.c
@@ -1813,7 +1813,10 @@ static void __intel_display_device_info_runtime_init(struct intel_display *displ
if (intel_display_wa(display, INTEL_DISPLAY_WA_14011765242))
for_each_pipe(display, pipe)
display_runtime->num_scalers[pipe] = 0;
- else if (DISPLAY_VER(display) >= 11) {
+ else if (DISPLAY_VERx100(display) == 3002) {
+ for_each_pipe(display, pipe)
+ display_runtime->num_scalers[pipe] = 1;
+ } else if (DISPLAY_VER(display) >= 11) {
for_each_pipe(display, pipe)
display_runtime->num_scalers[pipe] = 2;
} else if (DISPLAY_VER(display) >= 9) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 127/507] drm/i915/display: Disable pipe joiner on WCL
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (125 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 126/507] drm/i915/display: Single scaler per pipe on WCL Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 128/507] drm/i915/display: Allow port sync on PTL Greg Kroah-Hartman
` (379 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Charlton Lin, Uma Shankar,
Vidya Srinivas, Joonas Lahtinen, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vidya Srinivas <vidya.srinivas@intel.com>
[ Upstream commit b42b656db1384255044754cd2163d370d766b776 ]
Pipe joining is not supported in the WCL display configuration.
Report no joiner support on WCL so that modes which would require
joining are rejected, matching the 4k 60Hz maximum resolution
documented for the platform.
v2: Rebase onto latest upstream
v3: Fix up the commit message
v4: Split the scaler and joiner changes into separate patches (Jani)
Bspec: 74286
Fixes: f8e1c3e07db1 ("drm/i915/xe3lpd: Add support for display version 30.02")
Cc: stable@vger.kernel.org
Suggested-by: Charlton Lin <charlton.lin@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Vidya Srinivas <vidya.srinivas@intel.com>
Signed-off-by: Uma Shankar <uma.shankar@intel.com>
Link: https://patch.msgid.link/20261028070404.1913843-3-vidya.srinivas@intel.com
(cherry picked from commit 917676a55a690319a01b45d3956eaf94ba564df8)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/intel_dp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 3152122e6aefe..d79b6367cd57f 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -475,9 +475,9 @@ bool intel_dp_has_joiner(struct intel_dp *intel_dp)
!connector->panel.vbt.edp.pipe_joiner_enable)
return false;
- return DISPLAY_VER(display) >= 12 ||
+ return ((DISPLAY_VER(display) >= 12 && DISPLAY_VERx100(display) != 3002) ||
(DISPLAY_VER(display) == 11 &&
- encoder->port != PORT_A);
+ encoder->port != PORT_A));
}
static int dg2_max_source_rate(struct intel_dp *intel_dp)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 128/507] drm/i915/display: Allow port sync on PTL
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (126 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 127/507] drm/i915/display: Disable pipe joiner " Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 129/507] net: atl1c: drop oversized RX frames instead of panicking Greg Kroah-Hartman
` (378 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mitul Golani, Suraj Kandpal,
Jani Nikula, Joonas Lahtinen, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
[ Upstream commit 285300ef89aacbe902ba29c91625975f51345217 ]
Some dual-SST tiled displays exhibit visual corruption on PTL, with
one tile's image vertically shifted or wrapped by a random amount
that changes on every hotplug.
PTL supports port sync, so allow it to be used to avoid these
display issues.
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/8991
Fixes: 05cffc074938 ("drm/i915/display: Implement Wa_16024710867")
Cc: stable@vger.kernel.org
Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
Link: https://patch.msgid.link/20261012040402.3332398-1-mitulkumar.ajitkumar.golani@intel.com
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
(cherry picked from commit 7b308d9d496dd3bbe2fdd09d4e9d32499f2a1a0b)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/intel_ddi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 02a53c9848e13..8de6e13cf2dde 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -4594,7 +4594,7 @@ intel_ddi_port_sync_transcoders(const struct intel_crtc_state *ref_crtc_state,
* From, xe3lpd onwards we have defeatured this with reference to
* Wa_16024710867
*/
- if (!IS_DISPLAY_VER(display, 9, 20))
+ if (!IS_DISPLAY_VER(display, 9, 30))
return 0;
if (!intel_crtc_has_type(ref_crtc_state, INTEL_OUTPUT_DP))
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 129/507] net: atl1c: drop oversized RX frames instead of panicking
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (127 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 128/507] drm/i915/display: Allow port sync on PTL Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 130/507] ksmbd: do not read past the DACL in the access denied debug message Greg Kroah-Hartman
` (377 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Federico Musto, Dave Miller,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Federico Musto <federico@rimpianto.com>
[ Upstream commit c4ba1716853de5178a9df785844ebb5e397a80e6 ]
atl1c sizes its receive buffers from the netdev MTU plus a fixed set of L2
overheads, which comes to 1522 bytes at the default MTU. A link partner
that sends a longer frame - in practice a MikroTik CCR2004-1G-2XS-PCIe,
whose RouterOS side defaults to l2mtu 1600 while the host stays at MTU 1500
- makes the length reported by the RX return descriptor exceed what the
hardware wrote, and skb_put() then either includes bytes that were never
received or trips skb_over_panic and takes the host down.
Compare the descriptor length against buffer_info->length, the length the
hardware was given, rather than against skb_tailroom(): the skb carries 64
bytes of slack for the DMA erratum, so tailroom is larger than the DMA
buffer and a frame in between would pass the check and still be delivered
with a tail the device never wrote. The same test rejects frames shorter
than ETH_HLEN + ETH_FCS_LEN; before this change a reported length below
ETH_FCS_LEN underflowed in skb_put().
The frame is dropped with kfree_skb_reason(SKB_DROP_REASON_PKT_TOO_BIG) so
drop_monitor and the kfree_skb tracepoint see it, and counted through
dev_core_stats_rx_dropped_inc(), which survives atl1c_get_stats()
overwriting the hardware counters on every read. It also counts as work:
atl1c_clean_rfd() has already recycled the RFD, and the refill at the end
of the poll only runs when work_done is non-zero, so sustained oversized
traffic would otherwise drain the ring and stop RX.
Tested on a MikroTik CCR2004-1G-2XS-PCIe (4x AR8151) in a Proxmox VE host,
with atl1c built from a DKMS tree carrying this change: the l2mtu-1600
traffic that panics the stock driver is dropped and counted with the patch
applied, and received normally once the host MTU is raised to match.
This complements commit 36c2009d90f2 ("net: atl1c: fix soft lockup on
out-of-range tpd_cons read"), which fixed the TX side of the same
"host dies while the card resets" problem.
Fixes: 43250ddd75a3 ("atl1c: Atheros L1C Gigabit Ethernet driver")
Cc: stable@vger.kernel.org
Signed-off-by: Federico Musto <federico@rimpianto.com>
Signed-off-by: Dave Miller <davem@davem-thinkpadp1gen8.ibmlond.csb>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/atheros/atl1c/atl1c_main.c | 33 +++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index e58f1d2c26bdf..eddd8406867f7 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -1934,6 +1934,39 @@ static int atl1c_clean_rx(struct napi_struct *napi, int budget)
break;
}
atl1c_clean_rfd(rfd_ring, rrs, rfd_num);
+
+ /* A link partner whose l2mtu is larger than ours can hand us a
+ * frame that does not fit the buffer the hardware was given:
+ * the descriptor reports the untruncated length while at most
+ * buffer_info->length bytes were written. skb_put() of such a
+ * length would pull in whatever the tail of the buffer holds
+ * and, past the end of the skb, trips skb_over_panic and takes
+ * the host down. Bound it by what the device actually wrote
+ * rather than by skb_tailroom(): the skb carries 64 bytes of
+ * slack for the DMA erratum, so the two are not the same.
+ *
+ * Frames shorter than an Ethernet header plus its FCS are
+ * rejected by the same test; before this, a length below
+ * ETH_FCS_LEN underflowed in skb_put().
+ */
+ if (unlikely(length < ETH_HLEN + ETH_FCS_LEN ||
+ length > buffer_info->length)) {
+ dev_core_stats_rx_dropped_inc(netdev);
+ if (netif_msg_rx_err(adapter))
+ dev_warn_ratelimited(&pdev->dev,
+ "dropped rx frame: %u bytes, buffer %u\n",
+ length, buffer_info->length);
+ kfree_skb_reason(skb, SKB_DROP_REASON_PKT_TOO_BIG);
+ /* atl1c_clean_rfd() has already recycled the RFD, so
+ * count the drop as work: the refill at the end of the
+ * poll only runs when work_done is non-zero, and
+ * sustained oversized traffic would otherwise drain the
+ * ring and stop RX for good.
+ */
+ work_done++;
+ continue;
+ }
+
skb_put(skb, length - ETH_FCS_LEN);
skb->protocol = eth_type_trans(skb, netdev);
atl1c_rx_checksum(adapter, skb, rrs);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 130/507] ksmbd: do not read past the DACL in the access denied debug message
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (128 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 129/507] net: atl1c: drop oversized RX frames instead of panicking Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 131/507] ksmbd: grant a POSIX ACL group entry only to the groups members Greg Kroah-Hartman
` (376 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ian Bridges, Namjae Jeon,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Bridges <icb@fastmail.org>
[ Upstream commit 8296a64df5448548f410fb246c1d88a93609602b ]
When smb_check_perm_dacl() falls back to the POSIX ACL and then denies
the request, its debug message prints the access mask of the ACE that
the second DACL walk stopped at. On that path the walk ran to the end
of the DACL, so the pointer is one past the last ACE. If the DACL is
the last part of the stored security descriptor, the message reads 4
bytes past the buffer, and KASAN reports a slab-out-of-bounds read in
smb_check_perm_dacl().
Print the requested and allowed masks instead. They are what the check
compares.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
Cc: stable@vger.kernel.org
Signed-off-by: Ian Bridges <icb@fastmail.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smbacl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
index f8bd8e2ed33e5..b95f8c2d6f3e6 100644
--- a/fs/smb/server/smbacl.c
+++ b/fs/smb/server/smbacl.c
@@ -1665,8 +1665,8 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
}
if (granted & ~access_bits) {
- ksmbd_debug(SMB, "Access denied with winACL, granted : %x, access_req : %x\n",
- granted, le32_to_cpu(ace->access_req));
+ ksmbd_debug(SMB, "Access denied with winACL, requested : %x, allowed : %x\n",
+ granted, access_bits);
rc = -EACCES;
goto err_out;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 131/507] ksmbd: grant a POSIX ACL group entry only to the groups members
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (129 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 130/507] ksmbd: do not read past the DACL in the access denied debug message Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 132/507] ksmbd: let the owner read and change the DACL when no ACE names it Greg Kroah-Hartman
` (375 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Ian Bridges,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Bridges <icb@fastmail.org>
[ Upstream commit c00ec7ad449b68c291a4986e481941302ed399c5 ]
When no ACE of the DACL matches the caller, Everyone or Authenticated
Users, smb_check_perm_dacl() falls back to the file's POSIX ACL. It
takes the first ACL_USER or ACL_GROUP entry whose id equals the
caller's uid. For ACL_GROUP, this compares a gid with the caller's uid.
A numerical match grants the group's permissions even when the caller
is not a member.
Match a group entry only when the caller is also in the group.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
Reported-by: Namjae Jeon <linkinjeon@kernel.org>
Closes: https://lore.kernel.org/linux-cifs/CAKYAXd93czbFD=znZUq_pJLXzDR5N3zc_auvAGWT7pzKR1f9Ag@mail.gmail.com/
Cc: stable@vger.kernel.org
Signed-off-by: Ian Bridges <icb@fastmail.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smbacl.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
index b95f8c2d6f3e6..c9e4429a19638 100644
--- a/fs/smb/server/smbacl.c
+++ b/fs/smb/server/smbacl.c
@@ -1618,7 +1618,10 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
else
continue;
- if (id == uid) {
+ /* A group entry grants only to the group's members */
+ if (id == uid &&
+ (pa_entry->e_tag == ACL_USER ||
+ in_group_p(make_kgid(&init_user_ns, id)))) {
mode_to_access_flags(pa_entry->e_perm,
0777,
&access_bits);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 132/507] ksmbd: let the owner read and change the DACL when no ACE names it
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (130 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 131/507] ksmbd: grant a POSIX ACL group entry only to the groups members Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 133/507] mm/mempolicy: charge shared policy nodes Greg Kroah-Hartman
` (374 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ian Bridges, Namjae Jeon,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Bridges <icb@fastmail.org>
[ Upstream commit ffc855fe16afe02b22305111aa68cd8d07360941 ]
smb_check_perm_dacl() refuses the owner when neither its DACL lookup nor
the POSIX ACL fallback matches. The owner then cannot read or replace
the DACL over SMB. MS-DTYP 2.5.3.2 grants the owner READ_CONTROL and
WRITE_DAC unless an OWNER RIGHTS ACE applies.
An empty DACL allows the owner's explicit requests for these rights but
refuses MAXIMUM_ALLOWED. smb2_open() uses that check for the maximal
access reply (MS-SMB2 3.3.5.9.5), so even a READ_CONTROL open fails when
it asks for that reply.
Grant the owner's implicit rights on both paths, for explicit requests
and MAXIMUM_ALLOWED, unless an OWNER RIGHTS ACE applies.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
Cc: stable@vger.kernel.org
Signed-off-by: Ian Bridges <icb@fastmail.org>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smbacl.c | 34 ++++++++++++++++++++++++++++++----
1 file changed, 30 insertions(+), 4 deletions(-)
diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
index c9e4429a19638..cc3a450e4cb29 100644
--- a/fs/smb/server/smbacl.c
+++ b/fs/smb/server/smbacl.c
@@ -1470,6 +1470,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
int i, found = 0;
unsigned int access_bits = 0, denied = 0;
struct smb_ace *others_ace = NULL;
+ bool or_ace = false;
struct posix_acl_entry *pa_entry;
unsigned int sid_type = SIDOWNER;
unsigned short ace_size;
@@ -1502,6 +1503,8 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
is_owner = uid == from_kuid(&init_user_ns, vfsuid_into_kuid(vfsuid));
if (!pdacl->num_aces) {
+ unsigned int allowed = 0;
+
/*
* An empty (present, zero-ACE) DACL grants no access to
* anyone except the object owner's implicit READ_CONTROL
@@ -1510,9 +1513,14 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
* not let trailing bytes after a zero-ACE DACL become an
* implicit grant.
*/
- if (!is_owner ||
- (*pdaccess & ~(FILE_READ_CONTROL_LE | FILE_WRITE_DAC_LE)))
+ if (is_owner)
+ allowed = READ_CONTROL | WRITE_DAC;
+ if (*pdaccess & FILE_MAXIMAL_ACCESS_LE)
+ requested |= allowed;
+ if (!allowed || requested & ~allowed)
rc = -EACCES;
+ else
+ *pdaccess = cpu_to_le32(requested);
goto err_out;
}
@@ -1597,6 +1605,9 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
found = 1;
break;
}
+ if (!compare_sids(&sid_owner_rights, &ace->sid) &&
+ !(ace->flags & INHERIT_ONLY_ACE))
+ or_ace = true;
if (!compare_sids(&sid_everyone, &ace->sid) ||
!compare_sids(&sid_authusers, &ace->sid))
others_ace = ace;
@@ -1641,8 +1652,23 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
if (others_ace) {
ace = others_ace;
} else {
- ksmbd_debug(SMB, "Can't find corresponding sid\n");
- rc = -EACCES;
+ unsigned int allowed = 0;
+
+ /*
+ * No ACE names the owner, who may still read and
+ * change the DACL unless OWNER RIGHTS applies
+ * (MS-DTYP 2.5.3.2).
+ */
+ if (is_owner && !or_ace)
+ allowed = READ_CONTROL | WRITE_DAC;
+ if (*pdaccess & FILE_MAXIMAL_ACCESS_LE)
+ requested |= allowed;
+ if (!allowed || requested & ~allowed) {
+ ksmbd_debug(SMB, "Can't find corresponding sid\n");
+ rc = -EACCES;
+ goto err_out;
+ }
+ *pdaccess = cpu_to_le32(requested);
goto err_out;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 133/507] mm/mempolicy: charge shared policy nodes
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (131 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 132/507] ksmbd: let the owner read and change the DACL when no ACE names it Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 134/507] tmpfs: keep the quota soft limits of an unused id Greg Kroah-Hartman
` (373 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Pedro Falcato,
Kiryl Shutsemau (Meta), Zi Yan, Baolin Wang, Gregory Price (Meta),
Balbir Singh, David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit 68b2aa37afa390f08de13bc0bac61a9ded3318bc ]
Any local user can bypass memory.max with mbind() on a tmpfs file, and
allocate unbounded kernel memory.
mbind() sets a NUMA memory policy for a range of a mapping. If the
mapping is of a shmem and friends, the kernel also stores the policy on
the inode, in a tree with one entry per range of the file.
Each mbind() on a single page of a mapping can add one shared policy node
(struct sp_node) and one struct mempolicy to that tree. They outlive the
mapping and stay around until the inode is destroyed. The tree is not
bounded by the file size, so the file can be empty.
Memory that user space can allocate must be charged to a memory cgroup. A
slab cache does that for all of its objects if it is created with
SLAB_ACCOUNT. numa_policy_init() creates the slab caches for both
structs without SLAB_ACCOUNT, so they are not charged to any cgroup.
Reproduced with mbind() on single pages of an empty tmpfs file, from a
cgroup with memory.max=8M: the global OOM killer killed tasks owned by
root, and the machine panicked.
Fix this by creating both caches with SLAB_ACCOUNT. This change implies
that mbind() can now fail when running into memcg limits. Further,
the policy_cache also serves task and VMA policies, so they are
similarly accounted now.
Note that per-file limits are not really helpful, as the user could
simply use many files; having limits per user is tricky as well.
Fix generated by an LLM and submitted by Chris Mason in private.
Fixes: 5d097056c9a0 ("kmemcg: account certain kmem allocations to memcg")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
Acked-by: Pedro Falcato <pfalcato@suse.de>
Acked-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Acked-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
[ david: smaller description tweaks ]
Reviewed-by: Balbir Singh <balbirs@nvidia.com>
Link: https://patch.msgid.link/20261029-fixes_shmem-v4-1-392fc715d8f6@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/mempolicy.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 839c3fe985a0c..d9de3b5d5ebe8 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -3346,11 +3346,11 @@ void __init numa_policy_init(void)
policy_cache = kmem_cache_create("numa_policy",
sizeof(struct mempolicy),
- 0, SLAB_PANIC, NULL);
+ 0, SLAB_PANIC | SLAB_ACCOUNT, NULL);
sn_cache = kmem_cache_create("shared_policy_node",
sizeof(struct sp_node),
- 0, SLAB_PANIC, NULL);
+ 0, SLAB_PANIC | SLAB_ACCOUNT, NULL);
for_each_node(nid) {
preferred_node_policy[nid] = (struct mempolicy) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 134/507] tmpfs: keep the quota soft limits of an unused id
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (132 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 133/507] mm/mempolicy: charge shared policy nodes Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 135/507] tmpfs: preserve explicitly disabled quota limits Greg Kroah-Hartman
` (372 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jan Kara,
Gregory Price (Meta), David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit 968d73463059156e1b89bfa6b189acd7d27197b2 ]
When the last reference to a dquot goes away, shmem_release_dquot()
stores its limits in the rb tree of the mount, unless
shmem_is_empty_dquot() says that there is nothing worth storing. That
function looks at the usage and at the two hard limits only.
So if the administrator sets nothing but soft limits for an id that owns
no file yet, the entry is thrown away as soon as the dquot that
Q_SETQUOTA used is released, and the id never gets to see a limit.
To fix it, compare the soft limits as well: an entry can be empty only if
both soft limits are zero as well, which is exactly what
shmem_acquire_dquot() sets for a new entry.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: de4c0e7ca8b5 ("shmem: Add default quota limit mount options")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
[ david: slightly adjusted description ]
Link: https://patch.msgid.link/20261029-fixes_shmem-v4-2-392fc715d8f6@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/shmem_quota.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/mm/shmem_quota.c b/mm/shmem_quota.c
index d0b92d6da50f5..a83392f75e56b 100644
--- a/mm/shmem_quota.c
+++ b/mm/shmem_quota.c
@@ -251,6 +251,8 @@ static bool shmem_is_empty_dquot(struct dquot *dquot)
if (test_bit(DQ_FAKE_B, &dquot->dq_flags) ||
(dquot->dq_dqb.dqb_curspace == 0 &&
dquot->dq_dqb.dqb_curinodes == 0 &&
+ dquot->dq_dqb.dqb_bsoftlimit == 0 &&
+ dquot->dq_dqb.dqb_isoftlimit == 0 &&
dquot->dq_dqb.dqb_bhardlimit == bhardlimit &&
dquot->dq_dqb.dqb_ihardlimit == ihardlimit))
return true;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 135/507] tmpfs: preserve explicitly disabled quota limits
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (133 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 134/507] tmpfs: keep the quota soft limits of an unused id Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 136/507] mm/shmem: stop retrying folios that cannot be split Greg Kroah-Hartman
` (371 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jan Kara,
Gregory Price (Meta), David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit d5d861ee303da01e59fdf8e8b2f7096c76e7efd5 ]
An administrator’s decision to disable a user’s or group’s quota
limits can be silently lost when tmpfs restores the mount defaults
after releasing and reacquiring the quota record. This can cause
later file creation or writes to fail with EDQUOT, even though the
administrator has explicitly disabled quota limits for the user or
group.
do_set_dqblk() sets DQ_FAKE_B when all block and inode limits are zero.
This means quota enforcement is disabled for that user or group.
shmem_is_empty_dquot() treats the flag as a reason to discard the entry
from the mount's quota tree. The next shmem_acquire_dquot() finds no
saved entry and recreates it with the mount's default hard limits.
If the cached dquot is reused, DQ_FAKE_B remains set: Q_GETQUOTA reports
the restored defaults, but enforcement is still disabled. Once that
dquot has been reclaimed, a new dquot enforces the restored defaults.
Remove the DQ_FAKE_B test. Only discard entries with zero usage, zero
soft limits and hard limits equal to the mount defaults. Explicitly
disabled limits are then preserved whenever the mount defaults are
nonzero.
Explicitly disabled limits now retain a quota-tree entry, just like other
limits that differ from the mount defaults.
Rename shmem_is_empty_dquot() to shmem_is_default_dquot() to describe
the check for default values.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: de4c0e7ca8b5 ("shmem: Add default quota limit mount options")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
[ david: code cleanups; rewrite description ]
Link: https://patch.msgid.link/20261029-fixes_shmem-v4-3-392fc715d8f6@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/shmem_quota.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/mm/shmem_quota.c b/mm/shmem_quota.c
index a83392f75e56b..eeca9efd448a2 100644
--- a/mm/shmem_quota.c
+++ b/mm/shmem_quota.c
@@ -234,7 +234,7 @@ static int shmem_acquire_dquot(struct dquot *dquot)
return ret;
}
-static bool shmem_is_empty_dquot(struct dquot *dquot)
+static bool shmem_is_default_dquot(struct dquot *dquot)
{
struct shmem_sb_info *sbinfo = dquot->dq_sb->s_fs_info;
qsize_t bhardlimit;
@@ -248,21 +248,21 @@ static bool shmem_is_empty_dquot(struct dquot *dquot)
ihardlimit = sbinfo->qlimits.grpquota_ihardlimit;
}
- if (test_bit(DQ_FAKE_B, &dquot->dq_flags) ||
- (dquot->dq_dqb.dqb_curspace == 0 &&
- dquot->dq_dqb.dqb_curinodes == 0 &&
- dquot->dq_dqb.dqb_bsoftlimit == 0 &&
- dquot->dq_dqb.dqb_isoftlimit == 0 &&
- dquot->dq_dqb.dqb_bhardlimit == bhardlimit &&
- dquot->dq_dqb.dqb_ihardlimit == ihardlimit))
- return true;
-
- return false;
+ /*
+ * Defaults are zero usage and soft limits, and the mount's hard limits.
+ * DQ_FAKE_B only means that *all* limits are zero, which need not match
+ * the mount defaults.
+ */
+ return dquot->dq_dqb.dqb_curspace == 0 &&
+ dquot->dq_dqb.dqb_curinodes == 0 &&
+ dquot->dq_dqb.dqb_bsoftlimit == 0 &&
+ dquot->dq_dqb.dqb_isoftlimit == 0 &&
+ dquot->dq_dqb.dqb_bhardlimit == bhardlimit &&
+ dquot->dq_dqb.dqb_ihardlimit == ihardlimit;
}
/*
- * Store limits from dquot in the tree unless it's fake. If it is fake
- * remove the id from the tree since there is no useful information in
- * there.
+ * Remove the ID from the tree if it has no usage and its limits match
+ * the mount defaults. Otherwise, save its limits for the next acquire.
*/
static int shmem_release_dquot(struct dquot *dquot)
{
@@ -297,7 +297,7 @@ static int shmem_release_dquot(struct dquot *dquot)
return -ENOENT;
found:
- if (shmem_is_empty_dquot(dquot)) {
+ if (shmem_is_default_dquot(dquot)) {
/* Remove entry from the tree */
rb_erase(&entry->node, info->dqi_priv);
kfree(entry);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 136/507] mm/shmem: stop retrying folios that cannot be split
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (134 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 135/507] tmpfs: preserve explicitly disabled quota limits Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 137/507] mm/shmem: preserve data in clean folios when splitting fails Greg Kroah-Hartman
` (370 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Gregory Price (Meta),
Zi Yan, Balbir Singh, David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit a842a1f947da8a7020e72f885ffbf2ce6a93685f ]
A fault or collapse can insert a large folio crossing EOF after
shmem_undo_range() has handled the boundary folios. If splitting that
folio fails, truncate_inode_partial_folio() retains it when it is dirty.
The final scan then repeatedly finds it because it restarts from an
unchanged start.
Truncation keeps the inode lock and ignores fatal signals while looping.
A concurrent unlink() can then block other directory operations while
holding the directory lock and waiting for the file's lock.
Advance start past the retained folio, whose truncated part has already
been zeroed. Do not move start backwards if the failed split has shrunk
the folio.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: 55ac8bbe358b ("mm/shmem: fix race in shmem_undo_range w/THP")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
[ david: split fixes, simplify descriptions, adjust comments ]
Reviewed-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Balbir Singh <balbirs@nvidia.com>
Link: https://patch.msgid.link/20261029-fixes_shmem-v4-7-392fc715d8f6@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/shmem.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/mm/shmem.c b/mm/shmem.c
index de2362209cc38..249914d48f2ca 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1275,6 +1275,15 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, uoff_t lend,
index = start;
break;
}
+ } else if (folio->mapping) {
+ /*
+ * Splitting failed, but the part in the
+ * range is already zeroed. The folio
+ * was not dropped, so skip it when
+ * restarting the scan to avoid retrying
+ * it forever.
+ */
+ start = max(start, folio_next_index(folio));
}
}
folio_unlock(folio);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 137/507] mm/shmem: preserve data in clean folios when splitting fails
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (135 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 136/507] mm/shmem: stop retrying folios that cannot be split Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 138/507] mm/shmem: discard whole new large folios on fallocate rollback Greg Kroah-Hartman
` (369 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Kiryl Shutsemau (Meta),
Baolin Wang, Zi Yan, Gregory Price (Meta),
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit 0c800435394a172f33bf4df4a5a04e187546cc9b ]
A shared writable mapping can have dirty PTEs while its shmem folio is
still clean. A read fault can install a writable PTE, and a later store
sets the PTE's dirty bit without marking the folio dirty.
After shmem_undo_range() has handled the boundary folios, a concurrent
read fault into a hole below the new EOF can allocate a large folio.
For example, on a tmpfs mount with huge=always, the fault's offset must
be within the file, but the allocated folio can extend beyond i_size.
The final scan then finds this folio and calls
truncate_inode_partial_folio() without marking it dirty.
Splitting normally collects the PTE dirty bits when unmapping the
folio. An extra reference, for example from vmsplice(), can make it
fail before that step. The fallback unmapping on split failure excludes
shmem, so the helper still sees a clean folio and drops it, losing data
outside the range.
CPU0: ftruncate(fd, 3M) CPU1: MAP_SHARED, tmpfs huge=always
───────────────────────────────────── ──────────────────────────────────
i_size = 3M
shmem_undo_range(3M, -1)
first pass: hole, nothing to do
boundary folio at 3M: hole, none
read fault at 2M+x (below EOF)
PMD folio [2M,4M), crosses EOF
writable PTE, folio clean
store to 2M+x
PTE dirty, folio still clean
vmsplice(2M+x)
extra folio reference
whole_folios: finds [2M,4M) folio
truncate_inode_partial_folio()
zero [3M,4M)
folio_split()
unmap_folio(): extra ref
→ -EAGAIN, PTE dirty bit
never reaches the folio
folio clean
→ truncate_inode_folio(whole)
[2M,3M) dropped
read 2M+x → refault → zeroes
Mark large folios dirty before partial truncation in the final scan,
as the boundary handling already does. Exclude failed-fallocate
rollback, which must discard the folios it added.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: b9a8a4195c7d ("truncate,shmem: Handle truncates that split large folios")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
Acked-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
[ david: simplify descriptions, adjust comments ]
Link: https://patch.msgid.link/20261029-fixes_shmem-v4-8-392fc715d8f6@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/shmem.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/mm/shmem.c b/mm/shmem.c
index 249914d48f2ca..de4d9424f0596 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1259,6 +1259,15 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, uoff_t lend,
VM_BUG_ON_FOLIO(folio_test_writeback(folio),
folio);
+ /*
+ * A shared mapping can have dirty PTEs while
+ * the folio is still clean. Mark the folio
+ * dirty so a failed split cannot discard data
+ * outside the range.
+ */
+ if (!unfalloc && folio_test_large(folio))
+ folio_mark_dirty(folio);
+
if (!folio_test_large(folio)) {
truncate_inode_folio(mapping, folio);
} else if (truncate_inode_partial_folio(folio, lstart, lend)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 138/507] mm/shmem: discard whole new large folios on fallocate rollback
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (136 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 137/507] mm/shmem: preserve data in clean folios when splitting fails Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 139/507] mm/shmem: rescan after nonuniform folio splitting Greg Kroah-Hartman
` (368 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zi Yan, Kiryl Shutsemau (Meta),
Baolin Wang, Gregory Price (Meta), David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 23f2a880c0b9518fcb7e7e2ad54a29c0a2c4fba0 ]
When undoing a failed fallocate(), shmem_undo_range() must discard each
newly allocated folio. Its second scan instead passes large
folios to truncate_inode_partial_folio(), which does not necessarily
discard the entire large folio, but instead tries splitting it to
discard only the requested range.
For example, with huge=always, a failed allocation starting at offset
4 KiB can leave page 0 allocated in an otherwise empty file.
Discard the whole folio when unfalloc is set. Note that we enter this
path only for folios that are not uptodate, and can consequently be
dropped without losing any data.
Fixes: 55ac8bbe358b ("mm/shmem: fix race in shmem_undo_range w/THP")
Cc: stable@vger.kernel.org
Reviewed-by: Zi Yan <ziy@nvidia.com>
Acked-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Link: https://patch.msgid.link/20261029-fixes_shmem-v4-9-392fc715d8f6@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/shmem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/shmem.c b/mm/shmem.c
index de4d9424f0596..7d9083c482a4e 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1268,7 +1268,7 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, uoff_t lend,
if (!unfalloc && folio_test_large(folio))
folio_mark_dirty(folio);
- if (!folio_test_large(folio)) {
+ if (unfalloc || !folio_test_large(folio)) {
truncate_inode_folio(mapping, folio);
} else if (truncate_inode_partial_folio(folio, lstart, lend)) {
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 139/507] mm/shmem: rescan after nonuniform folio splitting
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (137 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 138/507] mm/shmem: discard whole new large folios on fallocate rollback Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 140/507] mm/shmem: fix truncate hang in large swap entry Greg Kroah-Hartman
` (367 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baolin Wang, Kiryl Shutsemau (Meta),
Gregory Price (Meta), Zi Yan, David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit f0d67b3d0a464847337d5063766d55e16041323e ]
The final scan in shmem_undo_range() restarts after a successful split
only if the original folio is no longer large. A nonuniform split can
leave that folio large, so the scan skips the newly created folios.
Hole punching then leaves pages within the hole allocated even though
they could be discarded.
For example, a fault below the hole can allocate a 2 MiB folio after
boundary handling. Punching a 1 MiB hole at offset 64 KiB splits the
folio successfully but leaves the original folio at order 4. The scan
continues past all 512 pages, leaving 2 MiB allocated instead of 1 MiB.
The hole reads as zero, but the pages and their block charges remain.
Fixes: 7460b470a131 ("mm/truncate: use folio_split() in truncate operation")
Cc: stable@vger.kernel.org
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Acked-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Link: https://patch.msgid.link/20261029-fixes_shmem-v4-10-392fc715d8f6@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/shmem.c | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/mm/shmem.c b/mm/shmem.c
index 7d9083c482a4e..90fd180c924cc 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1272,18 +1272,12 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, uoff_t lend,
truncate_inode_folio(mapping, folio);
} else if (truncate_inode_partial_folio(folio, lstart, lend)) {
/*
- * If we split a page, reset the loop so
- * that we pick up the new sub pages.
- * Otherwise the THP was entirely
- * dropped or the target range was
- * zeroed, so just continue the loop as
- * is.
+ * The folio was split. Retry the scan
+ * to find the split folios.
*/
- if (!folio_test_large(folio)) {
- folio_unlock(folio);
- index = start;
- break;
- }
+ folio_unlock(folio);
+ index = start;
+ break;
} else if (folio->mapping) {
/*
* Splitting failed, but the part in the
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 140/507] mm/shmem: fix truncate hang in large swap entry
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (138 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 139/507] mm/shmem: rescan after nonuniform folio splitting Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 141/507] mm/shmem: preserve allocation errors when swapping in large entries Greg Kroah-Hartman
` (366 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Kiryl Shutsemau (Meta),
Baolin Wang, Gregory Price (Meta), David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit fa213b08f37f9dff78ce240a87579dc264fc7a5d ]
Truncating a tmpfs file or memfd to a page-aligned size inside a large
swap entry can loop indefinitely in shmem_undo_range(). The task holds
the inode lock and cannot be killed.
A large swap entry represents a whole swapped-out folio. For example,
truncate a file whose pages 0-7 share one swap entry to four pages:
[ 0 1 2 3 | 4 5 6 7 ]
keep | discard
^
new EOF, start = 4
i_size has already been updated when boundary handling asks
shmem_get_partial_folio() for page 4. Since it is swapped out, the helper
calls shmem_get_folio() with SGP_READ. That rejects page 4 with -EINVAL
because its starting offset equals i_size. Nothing is read back.
The final scan cannot free the entry without losing pages 0-3. It skips
it, restarts from start = 4, and finds it again indefinitely. An unaligned
truncate avoids this particular failure because the requested page starts
below i_size. Folios already in the page-cache cannot trigger it as the
direct lookup will return them beyond EOF.
Fix it by letting shmem_get_partial_folio() call shmem_swapin_folio()
directly for swap entries. This bypasses the read path's i_size check,
allowing the existing boundary handling to zero and split the folio. If
swap-in returns a smaller folio, it also splits the swap entry so the
final scan can free the entries beyond EOF. Retry the lookup if the entry
changes during swap-in.
Handling swap-in allocation failures remains broken and is unchanged by
this commit. Even when shmem_swapin_folio() correctly returns -ENOMEM
instead of -EEXIST, shmem_get_partial_folio() returns NULL and
shmem_undo_range() skips boundary handling. If the large swap entry
remains intact, truncation can still loop in the final scan, while hole
punching can return without zeroing the boundary.
This may read an entire large folio back from swap while holding
i_rwsem, only to discard part of it. Avoiding that I/O would require
splitting both the swap entry and any large folio still in the swap
cache. That, however, is much bigger work.
Fixes: 8a1968bd997f ("mm/shmem, swap: fix race of truncate and swap entry split")
Cc: stable@vger.kernel.org
Reported-by: Chris Mason <mason@kernel.org>
Acked-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Link: https://patch.msgid.link/20261029-fixes_shmem-v4-11-392fc715d8f6@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/shmem.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/mm/shmem.c b/mm/shmem.c
index 90fd180c924cc..fab3f1d24550a 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1089,12 +1089,10 @@ void shmem_unlock_mapping(struct address_space *mapping)
static struct folio *shmem_get_partial_folio(struct inode *inode, pgoff_t index)
{
+ const gfp_t gfp = mapping_gfp_mask(inode->i_mapping);
struct folio *folio;
- /*
- * At first avoid shmem_get_folio(,,,SGP_READ): that fails
- * beyond i_size, and reports fallocated folios as holes.
- */
+retry:
folio = filemap_get_entry(inode->i_mapping, index);
if (!folio)
return folio;
@@ -1105,13 +1103,14 @@ static struct folio *shmem_get_partial_folio(struct inode *inode, pgoff_t index)
/* The folio has been swapped out */
folio_unlock(folio);
folio_put(folio);
+ goto retry;
}
/*
- * But read a folio back from swap if any of it is within i_size
- * (although in some cases this is just a waste of time).
+ * Truncation can look up a large swap entry at or beyond i_size.
+ * Swap it in directly to bypass the size check in shmem_get_folio().
*/
- folio = NULL;
- shmem_get_folio(inode, index, 0, &folio, SGP_READ);
+ if (shmem_swapin_folio(inode, index, &folio, SGP_READ, gfp, NULL, NULL) == -EEXIST)
+ goto retry;
return folio;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 141/507] mm/shmem: preserve allocation errors when swapping in large entries
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (139 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 140/507] mm/shmem: fix truncate hang in large swap entry Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 142/507] mm/shmem: fix truncate loop after boundary swapin failure Greg Kroah-Hartman
` (365 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Kiryl Shutsemau (Meta),
Baolin Wang, Gregory Price (Meta), David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit f4ce23b1feef16d435aa1188b6c2a637a5373ed5 ]
shmem_swapin_folio() adjusts swap to the requested slot within a large
swap entry before allocating a folio. If allocation or charging fails,
the error path compares this adjusted value with the original entry
still stored in the XArray in shmem_confirm_swap().
Unless the index is at the start of the entry, this turns -ENOMEM into
-EEXIST even though nothing changed.
The caller retries -EEXIST, so persistent allocation failures can leave
the task spinning instead of returning the error.
Restore swap to index_entry on allocation failure so the existing error
path checks the original entry. This preserves the allocation error if
the entry is unchanged and still retries if it changed concurrently.
Fixes: 91ab656ece13 ("mm/shmem, swap: tidy up swap entry splitting")
Cc: stable@vger.kernel.org
Reported-by: Josef Bacik <josef@toxicpanda.com>
Acked-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Link: https://patch.msgid.link/20261029-fixes_shmem-v4-12-392fc715d8f6@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/shmem.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/mm/shmem.c b/mm/shmem.c
index fab3f1d24550a..2b2f347bb8a71 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2327,6 +2327,8 @@ static int shmem_swapin_folio(struct inode *inode, pgoff_t index,
else
error = -ENOMEM;
folio = NULL;
+ /* Make sure to validate the original value. */
+ swap = index_entry;
goto failed;
}
if (fault_type) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 142/507] mm/shmem: fix truncate loop after boundary swapin failure
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (140 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 141/507] mm/shmem: preserve allocation errors when swapping in large entries Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 143/507] mm/shmem: fix accounting of swapin-error markers Greg Kroah-Hartman
` (364 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kiryl Shutsemau (Meta),
Gregory Price (Meta), Baolin Wang, Nhat Pham,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 5f1ec2cf92a7d655a8eb39711987822f9b1f9d67 ]
If swapping in a large entry at the new EOF fails, shmem_undo_range()
leaves the entry in place. Its final scan skips the entry, then restarts
from the same start index and finds it again. Truncation can loop forever
while holding i_rwsem.
Advance start past the skipped entry so that a restarted scan can finish,
as we already do for folios that cannot be split.
Note that this does not fix the missing zeroing when boundary swapin fails,
it merely prevents the endless loop.
Fixes: 8a1968bd997f ("mm/shmem, swap: fix race of truncate and swap entry split")
Cc: stable@vger.kernel.org
Acked-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Reviewed-by: Nhat Pham <nphamcs@gmail.com>
Link: https://patch.msgid.link/20261029-fixes_shmem-v4-13-392fc715d8f6@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/shmem.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/mm/shmem.c b/mm/shmem.c
index 2b2f347bb8a71..508ada89151d8 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1229,14 +1229,16 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, uoff_t lend,
order = shmem_confirm_swap(mapping, indices[i],
radix_to_swp_entry(folio));
/*
- * If found a large swap entry cross the end or start
- * border, skip it as the truncate_inode_partial_folio
- * above should have at least zerod its content once.
+ * Skip boundary entries when restarting
+ * the scan to avoid endless loops after
+ * swapin failure.
*/
if (order > 0) {
base = round_down(base, 1 << order);
- if (base < start || base + (1 << order) > end)
+ if (base < start || base + (1 << order) > end) {
+ start = max(start, base + (1 << order));
continue;
+ }
}
/* Swap was replaced by page or extended, retry */
index = base;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 143/507] mm/shmem: fix accounting of swapin-error markers
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (141 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 142/507] mm/shmem: fix truncate loop after boundary swapin failure Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 144/507] mm/shmem: fix truncation of files containing only " Greg Kroah-Hartman
` (363 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gregory Price (Meta), Baolin Wang,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 66ce68a249f4ac56cd6968aa6d8ded20fb4b7d09 ]
A failed swap read replaces the swap entry with a swapin-error marker in
the page-cache and subtracts its pages from "alloced" and "swapped";
however, it leaves their block charge in place.
Removing the marker during truncate then subtracts from "swapped" again.
This can underflow the counters or make swapped reach zero while other
pages remain swapped out, causing swapoff to loop without finding them.
When installing the marker, subtract only from "swapped" and let
shmem_recalc_inode() reduce "alloced" and release the block charge.
Make shmem_free_swap() report successful removal separately from the
number of swap pages freed, so removing a swapin-error marker does not
subtract from "swapped" again.
It's a bit confusing, but replacing a swapped out page by a swapin-error
marker in shmem_set_folio_swapin_error() behaves as follows:
Initially:
alloced=1, swapped=1, nrpages=0
Calling shmem_recalc_inode(inode, 0, -1)
-> swapped = 0
-> freed = 1 - 0 - 0 = 1
-> alloced -= freed
-> alloced=0, swapped=0, block charge released
Fixes: 6cec2b95dadf ("mm/shmem: fix infinite loop when swap in shmem error at swapoff time")
Cc: stable@vger.kernel.org
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Link: https://patch.msgid.link/20261029-fixes_shmem-v4-14-392fc715d8f6@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/shmem.c | 31 ++++++++++++++-----------------
1 file changed, 14 insertions(+), 17 deletions(-)
diff --git a/mm/shmem.c b/mm/shmem.c
index 508ada89151d8..31103314b6b62 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -968,12 +968,11 @@ static void shmem_delete_from_page_cache(struct folio *folio, void *radswap)
}
/*
- * Remove swap entry from page cache, free the swap and its page cache. Returns
- * the number of pages being freed. 0 means entry not found in XArray (0 pages
- * being freed).
+ * Remove a swap entry or swapin-error marker wholly within [index, end].
+ * Return whether it was removed, counting freed swap pages in nr_swaps_freed.
*/
-static long shmem_free_swap(struct address_space *mapping,
- pgoff_t index, pgoff_t end, void *radswap)
+static bool shmem_free_swap(struct address_space *mapping,
+ pgoff_t index, pgoff_t end, void *radswap, long *nr_swaps_freed)
{
XA_STATE(xas, &mapping->i_pages, index);
const softleaf_t swp = radix_to_swp_entry(radswap);
@@ -994,8 +993,10 @@ static long shmem_free_swap(struct address_space *mapping,
xas_unlock_irq(&xas);
/* A swapin-error marker holds no swap slot, so just drop it. */
- if (nr_pages && softleaf_is_swap(swp))
+ if (nr_pages && softleaf_is_swap(swp)) {
swap_put_entries_direct(swp, nr_pages);
+ *nr_swaps_freed += nr_pages;
+ }
return nr_pages;
}
@@ -1149,8 +1150,8 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, uoff_t lend,
if (xa_is_value(folio)) {
if (unfalloc)
continue;
- nr_swaps_freed += shmem_free_swap(mapping, indices[i],
- end - 1, folio);
+ shmem_free_swap(mapping, indices[i], end - 1,
+ folio, &nr_swaps_freed);
continue;
}
@@ -1217,13 +1218,11 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, uoff_t lend,
if (xa_is_value(folio)) {
int order;
- long swaps_freed;
if (unfalloc)
continue;
- swaps_freed = shmem_free_swap(mapping, indices[i],
- end - 1, folio);
- if (!swaps_freed) {
+ if (!shmem_free_swap(mapping, indices[i], end - 1,
+ folio, &nr_swaps_freed)) {
pgoff_t base = indices[i];
order = shmem_confirm_swap(mapping, indices[i],
@@ -1244,7 +1243,6 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, uoff_t lend,
index = base;
break;
}
- nr_swaps_freed += swaps_freed;
continue;
}
@@ -2184,11 +2182,10 @@ static void shmem_set_folio_swapin_error(struct inode *inode, pgoff_t index,
folio_put_swap(folio, NULL);
swap_cache_del_folio(folio);
/*
- * Don't treat swapin error folio as alloced. Otherwise inode->i_blocks
- * won't be 0 when inode is released and thus trigger WARN_ON(i_blocks)
- * in shmem_evict_inode().
+ * Let shmem_recalc_inode() reduce alloced and release the block charge
+ * for the freed swap pages.
*/
- shmem_recalc_inode(inode, -nr_pages, -nr_pages);
+ shmem_recalc_inode(inode, 0, -nr_pages);
}
static int shmem_split_large_entry(struct inode *inode, pgoff_t index,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 144/507] mm/shmem: fix truncation of files containing only swapin-error markers
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (142 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 143/507] mm/shmem: fix accounting of swapin-error markers Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 145/507] mm/mglru: dont use stack pointers when walking PUD and PMD tables Greg Kroah-Hartman
` (362 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gregory Price (Meta), Baolin Wang,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 59511d630a6942356ac4b6984797998a8f3a9017 ]
It might not be very common, but we can end up with shmem files that are
composed only of swapin-error/poison markers.
Such markers are not counted in info->alloced. Consequently,
shmem_setattr() can skip shmem_truncate_range(), leaving the markers
behind.
Truncating the file to zero and growing it again will result in reads
failing with -EIO instead of returning zeroes.
Check whether the mapping contains entries, in addition to
info->alloced, before skipping the truncation. Keep the info->alloced
check so that shmem_recalc_inode(), called at the end of
shmem_undo_range(), can fix up accounting after reclaim has emptied the
mapping.
Fixes: 6cec2b95dadf ("mm/shmem: fix infinite loop when swap in shmem error at swapoff time")
Cc: stable@vger.kernel.org
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Link: https://patch.msgid.link/20261029-fixes_shmem-v4-15-392fc715d8f6@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/shmem.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mm/shmem.c b/mm/shmem.c
index 31103314b6b62..199e8a9c2a2b4 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1384,7 +1384,8 @@ static int shmem_setattr(struct mnt_idmap *idmap,
if (oldsize > holebegin)
unmap_mapping_range(inode->i_mapping,
holebegin, 0, 1);
- if (info->alloced)
+ /* Swapin-error markers are not counted in alloced. */
+ if (info->alloced || !mapping_empty(inode->i_mapping))
shmem_truncate_range(inode,
newsize, (loff_t)-1);
/* unmap again to remove racily COWed private pages */
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 145/507] mm/mglru: dont use stack pointers when walking PUD and PMD tables
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (143 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 144/507] mm/shmem: fix truncation of files containing only " Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 146/507] fork: take mmap_lock before copying mm_struct Greg Kroah-Hartman
` (361 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Rik van Riel, Qi Zheng,
Dev Jain, Lorenzo Stoakes (ARM), Kairui Song,
Muhammad Usama Anjum, Harry Yoo (Meta), Barry Song, Baolin Wang,
Pedro Falcato, Kiryl Shutsemau (Meta), SJ Park, Baoquan He,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit 65a9bf08a3e4d6e58df211ed900c16bafb79b267 ]
MGLRU passes stack copies of page-table entries in walk_pud_range() and
walk_pmd_range() when walking to the next level. These copies can become
stale when khugepaged or MADV_DONTNEED (CONFIG_PT_RECLAIM) removes a PTE
table concurrently.
This pattern dates back to commit bd74fdaea146 ("mm: multi-gen LRU:
support page table walks"). Likely, earlier locking masked the latent
bug. Later changes exposed it: commit 1d65b771bc08 ("mm/khugepaged:
retract_page_tables() without mmap or vma lock") allowed concurrent
retraction, and commit cf4a65539c13 ("memcg-v1: no need for memcg locking
for MGLRU") dropped the walker's outer RCU protection.
The fix is simple, so just fix the original commit so we don't have to
speculate. To fix it, pass the actual PMD/PUD pointers. This restores the
RCU-protected lookup and validation against the live PMD. Note that the PUD
handling is required as well to handle folded page tables correctly in all
cases.
Fix generated by an LLM and sent by Josef Bacik in private.
[ david: handle walk_pud_range() as well, clarify+simplify description,
adjust Fixes: ]
Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Rik van Riel <riel@surriel.com>
Reviewed-by: Qi Zheng <qi.zheng@linux.dev>
Reviewed-by: Dev Jain <dev.jain@arm.com>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Kairui Song <kasong@tencent.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Reviewed-by: Harry Yoo (Meta) <harry@kernel.org>
Reviewed-by: Barry Song <baohua@kernel.org>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: SJ Park <sj@kernel.org>
Link: https://patch.msgid.link/20261031-fixes_core-v3-1-d6437171ecc3@kernel.org
Reviewed-by: Baoquan He <baoquan.he@linux.dev>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/vmscan.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 6a53762d55447..963cdd67039d1 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3771,7 +3771,7 @@ static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end,
walk->mm_stats[MM_NONLEAF_FOUND]++;
- if (!walk_pte_range(&val, addr, next, args))
+ if (!walk_pte_range(pmd + i, addr, next, args))
continue;
walk->mm_stats[MM_NONLEAF_ADDED]++;
@@ -3807,7 +3807,7 @@ static int walk_pud_range(p4d_t *p4d, unsigned long start, unsigned long end,
if (!pud_present(val) || WARN_ON_ONCE(pud_leaf(val)))
continue;
- walk_pmd_range(&val, addr, next, args);
+ walk_pmd_range(pud + i, addr, next, args);
if (need_resched() || walk->batched >= MAX_LRU_BATCH) {
end = (addr | ~PUD_MASK) + 1;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 146/507] fork: take mmap_lock before copying mm_struct
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (144 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 145/507] mm/mglru: dont use stack pointers when walking PUD and PMD tables Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 147/507] mm/shmem: make shmem_file() check the files inode Greg Kroah-Hartman
` (360 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Lorenzo Stoakes (ARM),
Rik van Riel, Vlastimil Babka (SUSE), Barry Song, Pedro Falcato,
Harry Yoo (Meta), Kiryl Shutsemau (Meta), SJ Park,
Muhammad Usama Anjum, David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit ef694e2d210111cc08c52fd25da9ab130170bfa3 ]
dup_mm() copies the parent's mm_struct before dup_mmap() takes the
mmap_lock. A concurrent brk() can leave the child with a stale mm->brk
and newer heap mappings, causing later brk() requests to fail.
Other operations (e.g., PR_SET_MM) on the parent's mm_struct can similarly
cause inconsistencies.
As a simple and robust fix, grab the parent's mmap_lock earlier. This
way we don't need to update individual mm fields in dup_mmap() and
keep missing ones. Stop updating the 4 existing members (total_vm, data_vm,
exec_vm, stack_vm), as that is now no longer required.
Keep releasing the parent's mmap_lock in dup_mmap(), before
userfaultfd completion, to avoid moving the userfaultfd handling into the
caller. This should get cleaned up later.
Move uprobe_start_dup_mmap() to preserve the lock ordering.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Rik van Riel <riel@surriel.com>
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Reviewed-by: Barry Song <baohua@kernel.org>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Reviewed-by: Harry Yoo (Meta) <harry@kernel.org>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: SJ Park <sj@kernel.org>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-2-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/fork.c | 20 ++++++++++++++------
mm/mmap.c | 8 +-------
mm/nommu.c | 2 +-
3 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/kernel/fork.c b/kernel/fork.c
index 8ad34646962d2..48d7ca0644042 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1535,12 +1535,19 @@ static struct mm_struct *dup_mm(struct task_struct *tsk,
if (!mm)
goto fail_nomem;
+ uprobe_start_dup_mmap();
+ if (mmap_write_lock_killable(oldmm)) {
+ free_mm(mm);
+ goto fail_uprobe;
+ }
+
memcpy(mm, oldmm, sizeof(*mm));
- if (!mm_init(mm, tsk))
- goto fail_nomem;
+ if (!mm_init(mm, tsk)) {
+ mmap_write_unlock(oldmm);
+ goto fail_uprobe;
+ }
- uprobe_start_dup_mmap();
err = dup_mmap(mm, oldmm);
if (err)
goto free_pt;
@@ -1559,9 +1566,10 @@ static struct mm_struct *dup_mm(struct task_struct *tsk,
mm->binfmt = NULL;
mm_init_owner(mm, NULL);
mmput(mm);
- if (err)
- uprobe_end_dup_mmap();
-
+ if (!err)
+ return NULL;
+fail_uprobe:
+ uprobe_end_dup_mmap();
fail_nomem:
return NULL;
}
diff --git a/mm/mmap.c b/mm/mmap.c
index 4bf26b0f1e6e3..6f22cd76be4f3 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -1713,8 +1713,7 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
LIST_HEAD(uf);
VMA_ITERATOR(vmi, mm, 0);
- if (mmap_write_lock_killable(oldmm))
- return -EINTR;
+ mmap_assert_write_locked(oldmm);
flush_cache_dup_mm(oldmm);
uprobe_dup_mmap(oldmm, mm);
/*
@@ -1725,11 +1724,6 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
/* No ordering required: file already has been exposed. */
dup_mm_exe_file(mm, oldmm);
- mm->total_vm = oldmm->total_vm;
- mm->data_vm = oldmm->data_vm;
- mm->exec_vm = oldmm->exec_vm;
- mm->stack_vm = oldmm->stack_vm;
-
/* Use __mt_dup() to efficiently build an identical maple tree. */
retval = __mt_dup(&oldmm->mm_mt, &mm->mm_mt, GFP_KERNEL);
if (unlikely(retval))
diff --git a/mm/nommu.c b/mm/nommu.c
index ed44510e37707..6e0f9c7da2364 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1926,7 +1926,7 @@ subsys_initcall(init_admin_reserve);
int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
{
- mmap_write_lock(oldmm);
+ mmap_assert_write_locked(oldmm);
dup_mm_exe_file(mm, oldmm);
mmap_write_unlock(oldmm);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 147/507] mm/shmem: make shmem_file() check the files inode
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (145 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 146/507] fork: take mmap_lock before copying mm_struct Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 148/507] mm/memfd: make f_pos accesses atomic Greg Kroah-Hartman
` (359 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Pratyush Yadav,
Baolin Wang, David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit d3710111839d11339e414b1bb3fea3d05ab83f6e ]
shmem_file() only checks if file->f_mapping is a shmem mapping. This
mapping can belong to another file, however, as with a Coda file backed
by a tmpfs container after mmap().
So it does not guarantee that the file inode is an actual shmem inode.
Seal handling and memfd preservation use this check before accessing
shmem inode state, so they can access an inode of the wrong type.
Let's make shmem_file() check the inode's file operations instead, to
identify shmem inodes reliably. This will identify regular shmem inodes,
including memfds and ordinary tmpfs files, independently of wrapper file
operations.
Use shmem_mapping() in collapse_file() instead to not change the behavior
of collapse_file(): it operates on the page cache and uses mapping->host
for shmem inode operations. Focusing on the file does not seem relevant.
Fixes: c49fcfcda8b5 ("mm/shmem: update file sealing comments and file checking")
Fixes: b3749f174d68 ("mm: memfd_luo: allow preserving memfd")
Cc: stable@vger.kernel.org
Reported-by: Chris Mason <mason@kernel.org>
Suggested-by: Pratyush Yadav <pratyush@kernel.org>
Reviewed-by: Pratyush Yadav (Google) <pratyush@kernel.org>
Link: https://patch.msgid.link/20261031-fixes_core-v3-3-d6437171ecc3@kernel.org
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/shmem_fs.h | 15 ++++++---------
mm/khugepaged.c | 2 +-
mm/shmem.c | 5 +++++
3 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index 5663dff53186e..842cc0f961470 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -111,8 +111,14 @@ extern unsigned long shmem_get_unmapped_area(struct file *, unsigned long addr,
unsigned long len, unsigned long pgoff, unsigned long flags);
extern int shmem_lock(struct file *file, int lock, struct ucounts *ucounts);
#ifdef CONFIG_SHMEM
+bool shmem_file(struct file *file);
bool shmem_mapping(const struct address_space *mapping);
#else
+static inline bool shmem_file(struct file *file)
+{
+ return false;
+}
+
static inline bool shmem_mapping(const struct address_space *mapping)
{
return false;
@@ -187,15 +193,6 @@ static inline struct page *shmem_read_mapping_page(
mapping_gfp_mask(mapping));
}
-static inline bool shmem_file(struct file *file)
-{
- if (!IS_ENABLED(CONFIG_SHMEM))
- return false;
- if (!file || !file->f_mapping)
- return false;
- return shmem_mapping(file->f_mapping);
-}
-
/* Must be called with inode lock taken exclusive. */
static inline void shmem_freeze(struct inode *inode, bool freeze)
{
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 792166950bba8..b717de08e3c8b 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -2251,6 +2251,7 @@ static enum scan_result collapse_file(struct mm_struct *mm, unsigned long addr,
struct file *file, pgoff_t start, struct collapse_control *cc)
{
struct address_space *mapping = file->f_mapping;
+ const bool is_shmem = shmem_mapping(mapping);
struct page *dst;
struct folio *folio, *tmp, *new_folio;
unsigned long new_pfn = -1;
@@ -2259,7 +2260,6 @@ static enum scan_result collapse_file(struct mm_struct *mm, unsigned long addr,
XA_STATE_ORDER(xas, &mapping->i_pages, start, HPAGE_PMD_ORDER);
enum scan_result result = SCAN_SUCCEED;
int nr_none = 0;
- bool is_shmem = shmem_file(file);
/*
* MADV_COLLAPSE ignores shmem huge config, so do not check shmem
diff --git a/mm/shmem.c b/mm/shmem.c
index 199e8a9c2a2b4..edda9f90b3d89 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -275,6 +275,11 @@ static const struct vm_operations_struct shmem_vm_ops;
static const struct vm_operations_struct shmem_anon_vm_ops;
static struct file_system_type shmem_fs_type;
+bool shmem_file(struct file *file)
+{
+ return file && file_inode(file)->i_fop == &shmem_file_operations;
+}
+
bool shmem_mapping(const struct address_space *mapping)
{
return mapping->a_ops == &shmem_aops;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 148/507] mm/memfd: make f_pos accesses atomic
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (146 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 147/507] mm/shmem: make shmem_file() check the files inode Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 149/507] mm/truncate: look again if a folio left the mapping Greg Kroah-Hartman
` (358 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Rik van Riel,
Gregory Price (Meta), Mike Rapoport (Microsoft),
Lorenzo Stoakes (ARM), Pedro Falcato, Kiryl Shutsemau (Meta),
Pasha Tatashin, Muhammad Usama Anjum, David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit 5426cd43a4d28f1041c9ca45955121b921f29548 ]
Commit 9c225f2655e3 ("vfs: atomic f_pos accesses as per POSIX") made
read(), write() and lseek() on a shared open file description of a regular
file serialize on ->f_pos_lock. The flag that asks for it,
FMODE_ATOMIC_POS, is set in do_dentry_open(). A memfd is a regular file
too, but its struct file comes from alloc_file_pseudo() and never passes
through do_dentry_open(), so it does not get the flag:
CPU0 CPU1
write(memfd, "a", 1) write(memfd, "b", 1)
pos = file->f_pos (= 0)
pos = file->f_pos (= 0)
vfs_write(..., &pos)
vfs_write(..., &pos)
file->f_pos = pos (= 1)
file->f_pos = pos (= 1)
One of the two bytes is overwritten. Two threads writing 100000 bytes
each, one at a time, to a memfd end up with a file that is far shorter than
200000 bytes, while the same program on a tmpfs file never loses a byte.
Set the flag when the memfd is created. As for any other regular file the
lock is only taken if the file is reachable in more than one way, and
nothing a memfd does in read or write waits for another operation on the
same file. This cannot be done for all alloc_file_pseudo() files: anon
inode files such as eventfd are S_IFREG as well, and a blocked read holding
->f_pos_lock would lock out the write that is supposed to wake it.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: 9183df25fe7b ("shm: add memfd_create() syscall")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
[ david: minor description tweaks ]
Reviewed-by: Rik van Riel <riel@surriel.com>
Reviewed-by: Gregory Price (Meta) <gourry@gourry.net>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Signed-off-by: Gregory Price (Meta) <gourry@gourry.net>
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-4-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/memfd.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/mm/memfd.c b/mm/memfd.c
index 0f6fff004f5e4..0e3ff3eebfa82 100644
--- a/mm/memfd.c
+++ b/mm/memfd.c
@@ -482,6 +482,8 @@ struct file *memfd_alloc_file(const char *name, unsigned int flags)
}
file->f_mode |= FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE;
+ /* a regular file like any other: POSIX.1-2008/SUSv4 Section XSI 2.9.7 */
+ file->f_mode |= FMODE_ATOMIC_POS;
file->f_flags |= O_LARGEFILE;
if (flags & MFD_NOEXEC_SEAL) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 149/507] mm/truncate: look again if a folio left the mapping
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (147 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 148/507] mm/memfd: make f_pos accesses atomic Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 150/507] mm/filemap: read mapping->a_ops->free_folio under i_lock Greg Kroah-Hartman
` (357 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Rik van Riel,
Muhammad Usama Anjum, Kiryl Shutsemau (Meta), Zi Yan,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 9cf632e139737314afa889ca18122bc3fddb9120 ]
invalidate_inode_pages2_range() skips a folio which no longer belongs to
the mapping by the time it has got the folio lock, on the assumption
that somebody else has removed it from the page cache. But the folio may
have been replaced, and then there is a new folio with the same data at
that index.
For most cases, like folio migration, that is impossible. However,
collapse_file() only checks the refcount of the old folios, under the
i_pages lock, and relies on their folio locks from there on. That works for
users which repeat the lookup when they find folio->mapping changed.
The following scenario is, however, possible:
CPU0 pwrite(O_DIRECT) CPU1 collapse_file()
kiocb_invalidate_pages()
read the folio (old data), lock it
refcount check
the write completes copy to new_folio
kiocb_invalidate_post_direct_write()
find_get_entries() -> old folio
xas_store(new_folio)
folio->mapping = NULL
folio_unlock(folio)
folio_lock()
folio->mapping != mapping
-> continue
In that scenario, the collapsed folio with the data from before the write
stays in the page cache after the write has returned.
This used to be impossible, as khugepaged only collapsed files that nobody
had open for writing.
Restart the lookup at that index, like shmem_undo_range() does. The same
problem seems to exist in truncate_inode_pages_range() as well when
truncate_inode_folio() fails, so handle it there as well, but slightly
differently: simply check once more through find_get_entries().
Fixes: 1b6444331beb ("mm/khugepaged: enable clean pagecache folio collapse for writable files")
Cc: stable@vger.kernel.org
Reported-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Rik van Riel <riel@surriel.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-5-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/truncate.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/mm/truncate.c b/mm/truncate.c
index 29782aced8bad..b7c5d3384748c 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -436,8 +436,11 @@ void truncate_inode_pages_range(struct address_space *mapping,
}
}
+ if (start >= end)
+ return;
+
index = start;
- while (index < end) {
+ while (true) {
cond_resched();
if (!find_get_entries(mapping, &index, end - 1, &fbatch,
indices)) {
@@ -460,6 +463,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
folio_lock(folio);
VM_BUG_ON_FOLIO(!folio_contains(folio, indices[i]), folio);
folio_wait_writeback(folio);
+ /* Do not handle errors, we'll do another lookup */
truncate_inode_folio(mapping, folio);
folio_unlock(folio);
}
@@ -721,7 +725,12 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
folio_lock(folio);
if (unlikely(folio->mapping != mapping)) {
folio_unlock(folio);
- continue;
+ /*
+ * Folio might have been replaced: look up
+ * again.
+ */
+ index = indices[i];
+ break;
}
VM_BUG_ON_FOLIO(!folio_contains(folio, indices[i]), folio);
folio_wait_writeback(folio);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 150/507] mm/filemap: read mapping->a_ops->free_folio under i_lock
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (148 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 149/507] mm/truncate: look again if a folio left the mapping Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 151/507] mm/filemap: dont lose a folio lock wakeup to a signal Greg Kroah-Hartman
` (356 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Rik van Riel,
Muhammad Usama Anjum, Zi Yan, David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit dc24e273244e9d712257d5a6c20a32c7f5ca84e6 ]
memory_failure() -> ... -> filemap_remove_folio() can read mapping->a_ops
after the inode has been freed. Once the folio is deleted from the
pagecache it no longer pins the mapping, so after i_lock is dropped
e.g., a concurrent final iput() can evict and free the inode before
filemap_free_folio() looks up mapping->a_ops->free_folio.
Most callers hold a reference on the inode, but not all.
Documentation/filesystems/vfs.rst explicitly states that ->free_folio()
must not assume the original address_space mapping still exists.
Fix it by loading ->free_folio while i_lock is still held, similar to
what folio_unmap_invalidate() does.
Inline filemap_free_folio() into its remaining caller such that
delete_from_page_cache_batch() also just loads the callback before
dropping the i_lock.
The bug was found by code inspection and has not been reproduced.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: 59c66c5f8c4f ("mm: factor out page cache page freeing into a separate function")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
[ david: get rid of filemap_free_folio() entirely; improve patch description ]
Reviewed-by: Rik van Riel <riel@surriel.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-6-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/filemap.c | 29 ++++++++++++++---------------
1 file changed, 14 insertions(+), 15 deletions(-)
diff --git a/mm/filemap.c b/mm/filemap.c
index 00fd89cf6f550..0494c246fb18e 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -227,18 +227,6 @@ void __filemap_remove_folio(struct folio *folio, void *shadow)
page_cache_delete(mapping, folio, shadow);
}
-static void filemap_free_folio(const struct address_space *mapping,
- struct folio *folio)
-{
- void (*free_folio)(struct folio *);
-
- free_folio = mapping->a_ops->free_folio;
- if (free_folio)
- free_folio(folio);
-
- folio_put_refs(folio, folio_nr_pages(folio));
-}
-
/**
* filemap_remove_folio - Remove folio from page cache.
* @folio: The folio.
@@ -250,6 +238,7 @@ static void filemap_free_folio(const struct address_space *mapping,
void filemap_remove_folio(struct folio *folio)
{
struct address_space *mapping = folio->mapping;
+ void (*free_folio)(struct folio *folio);
BUG_ON(!folio_test_locked(folio));
spin_lock(&mapping->host->i_lock);
@@ -258,9 +247,12 @@ void filemap_remove_folio(struct folio *folio)
xa_unlock_irq(&mapping->i_pages);
if (mapping_shrinkable(mapping))
inode_lru_list_add(mapping->host);
+ free_folio = mapping->a_ops->free_folio;
spin_unlock(&mapping->host->i_lock);
- filemap_free_folio(mapping, folio);
+ if (free_folio)
+ free_folio(folio);
+ folio_put_refs(folio, folio_nr_pages(folio));
}
/*
@@ -320,6 +312,7 @@ static void page_cache_delete_batch(struct address_space *mapping,
void delete_from_page_cache_batch(struct address_space *mapping,
struct folio_batch *fbatch)
{
+ void (*free_folio)(struct folio *folio);
int i;
if (!folio_batch_count(fbatch))
@@ -337,10 +330,16 @@ void delete_from_page_cache_batch(struct address_space *mapping,
xa_unlock_irq(&mapping->i_pages);
if (mapping_shrinkable(mapping))
inode_lru_list_add(mapping->host);
+ free_folio = mapping->a_ops->free_folio;
spin_unlock(&mapping->host->i_lock);
- for (i = 0; i < folio_batch_count(fbatch); i++)
- filemap_free_folio(mapping, fbatch->folios[i]);
+ for (i = 0; i < folio_batch_count(fbatch); i++) {
+ struct folio *folio = fbatch->folios[i];
+
+ if (free_folio)
+ free_folio(folio);
+ folio_put_refs(folio, folio_nr_pages(folio));
+ }
}
int filemap_check_errors(struct address_space *mapping)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 151/507] mm/filemap: dont lose a folio lock wakeup to a signal
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (149 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 150/507] mm/filemap: read mapping->a_ops->free_folio under i_lock Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 152/507] mm/filemap: finish fault cleanup before dropping the fault lock Greg Kroah-Hartman
` (355 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Rik van Riel,
Pedro Falcato, Muhammad Usama Anjum, David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit 8ccb6ded6a47b59b4907ed4f8c293cf8122de889 ]
An exclusive waiter in folio_wait_bit_common() can leave the wait loop
because of a fatal signal, then be woken by folio_unlock() before
finish_wait(). If the waker did not hand over the lock, the waiter returns
-EINTR without trying to acquire it.
folio_wake_bit() stops after waking the first exclusive waiter, so this
loses the wakeup and can leave other waiters asleep indefinitely on an
unlocked folio.
After finish_wait(), let a waiter woken without a lock handoff try once
more to acquire the lock. If successful, return success so the caller's
eventual unlock wakes the next waiter. Otherwise, the current lock owner
will do so.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: 5ef64cc8987a ("mm: allow a controlled amount of unfairness in the page lock")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
[ david: clarify and simplify comment + description ]
Reviewed-by: Rik van Riel <riel@surriel.com>
Acked-by: Pedro Falcato <pfalcato@suse.de>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-7-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/filemap.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/mm/filemap.c b/mm/filemap.c
index 0494c246fb18e..c6a573caef70e 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1374,10 +1374,22 @@ static inline int folio_wait_bit_common(struct folio *folio, int bit_nr,
* return value based on that state without races.
*
* Also note that WQ_FLAG_WOKEN is sufficient for a non-exclusive
- * waiter, but an exclusive one requires WQ_FLAG_DONE.
+ * waiter, but an exclusive one must also acquire the bit.
*/
- if (behavior == EXCLUSIVE)
- return wait->flags & WQ_FLAG_DONE ? 0 : -EINTR;
+ if (behavior == EXCLUSIVE) {
+ if (wait->flags & WQ_FLAG_DONE)
+ return 0;
+ /*
+ * We might have just been woken up and the waker will not
+ * wake up anybody else. If we ignore that now, the remaining
+ * waiters may not get woken up: take the bit now if it is
+ * still free.
+ */
+ if ((wait->flags & WQ_FLAG_WOKEN) &&
+ !test_and_set_bit(bit_nr, folio_flags(folio, 0)))
+ return 0;
+ return -EINTR;
+ }
return wait->flags & WQ_FLAG_WOKEN ? 0 : -EINTR;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 152/507] mm/filemap: finish fault cleanup before dropping the fault lock
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (150 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 151/507] mm/filemap: dont lose a folio lock wakeup to a signal Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 153/507] mm/rmap: handle device-exclusive entries in folio_referenced_one() Greg Kroah-Hartman
` (354 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason,
Thadeu Lima de Souza Cascardo, Muhammad Usama Anjum,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 97156a6c355c21f7122421915f05461bd11699a4 ]
On a retried fault, a fatal signal interrupting the folio lock wait
makes lock_folio_maybe_drop_mmap() drop the fault lock without pinning
the file. However, filemap_fault() may still need to release
mapping->invalidate_lock. A concurrent munmap() can release the last
file reference and free the mapping before that unlock.
Defer dropping the fault lock to filemap_fault()'s retry cleanup, after
releasing invalidate_lock. If the fault lock was already dropped for
I/O, release the existing file reference instead. Keep the fault lock
held for FAULT_FLAG_RETRY_NOWAIT as before.
Fixes: 730633f0b7f9 ("mm: Protect operations adding pages to page cache with invalidate_lock")
Cc: stable@vger.kernel.org
Reported-by: Chris Mason <mason@kernel.org>
Reviewed-by: Thadeu Lima de Souza Cascardo <cascardo@igalia.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-8-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/filemap.c | 37 +++++++++++++------------------------
1 file changed, 13 insertions(+), 24 deletions(-)
diff --git a/mm/filemap.c b/mm/filemap.c
index c6a573caef70e..73a26cd5b6d52 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -3290,11 +3290,11 @@ loff_t mapping_seek_hole_data(struct address_space *mapping, loff_t start,
* @folio - the folio to lock.
* @fpin - the pointer to the file we may pin (or is already pinned).
*
- * This works similar to lock_folio_or_retry in that it can drop the
- * mmap_lock. It differs in that it actually returns the folio locked
- * if it returns 1 and 0 if it couldn't lock the folio. If we did have
- * to drop the mmap_lock then fpin will point to the pinned file and
- * needs to be fput()'ed at a later point.
+ * Returns 1 with the folio locked, or 0 if locking failed.
+ *
+ * On both entry and return, a non-NULL *fpin means the fault lock has
+ * already been dropped and the caller must eventually fput() the file.
+ * Otherwise the fault lock is still held, including on failure.
*/
static int lock_folio_maybe_drop_mmap(struct vm_fault *vmf, struct folio *folio,
struct file **fpin)
@@ -3311,21 +3311,9 @@ static int lock_folio_maybe_drop_mmap(struct vm_fault *vmf, struct folio *folio,
return 0;
*fpin = maybe_unlock_mmap_for_io(vmf, *fpin);
- if (vmf->flags & FAULT_FLAG_KILLABLE) {
- if (__folio_lock_killable(folio)) {
- /*
- * We didn't have the right flags to drop the
- * fault lock, but all fault_handlers only check
- * for fatal signals if we return VM_FAULT_RETRY,
- * so we need to drop the fault lock here and
- * return 0 if we don't have a fpin.
- */
- if (*fpin == NULL)
- release_fault_lock(vmf);
- return 0;
- }
- } else
- __folio_lock(folio);
+ if (vmf->flags & FAULT_FLAG_KILLABLE)
+ return !__folio_lock_killable(folio);
+ __folio_lock(folio);
return 1;
}
@@ -3554,7 +3542,7 @@ static vm_fault_t filemap_fault_recheck_pte_none(struct vm_fault *vmf)
* vma->vm_mm->mmap_lock must be held on entry.
*
* If our return value has VM_FAULT_RETRY set, it's because the mmap_lock
- * may be dropped before doing I/O or by lock_folio_maybe_drop_mmap().
+ * may be dropped before doing I/O or when aborting an interrupted wait.
*
* If our return value does not have VM_FAULT_RETRY set, the mmap_lock
* has not been released.
@@ -3710,9 +3698,8 @@ vm_fault_t filemap_fault(struct vm_fault *vmf)
out_retry:
/*
- * We dropped the mmap_lock, we need to return to the fault handler to
- * re-find the vma and come back and find our hopefully still populated
- * page.
+ * With fpin set, the fault lock was already dropped. Otherwise it is
+ * still held. Release invalidate_lock before dropping either protection.
*/
if (!IS_ERR(folio))
folio_put(folio);
@@ -3720,6 +3707,8 @@ vm_fault_t filemap_fault(struct vm_fault *vmf)
filemap_invalidate_unlock_shared(mapping);
if (fpin)
fput(fpin);
+ else if (!(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
+ release_fault_lock(vmf);
return ret | VM_FAULT_RETRY;
}
EXPORT_SYMBOL(filemap_fault);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 153/507] mm/rmap: handle device-exclusive entries in folio_referenced_one()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (151 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 152/507] mm/filemap: finish fault cleanup before dropping the fault lock Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 154/507] mm/huge_memory: fix list corruption when deferred_split_scan() races with deferred_split_folio() Greg Kroah-Hartman
` (353 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM), Josef Bacik,
Harry Yoo (Meta), Barry Song, Dev Jain, Muhammad Usama Anjum,
Baolin Wang, David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit f3c493d2f42b5f44a5c134d8d7ea7f960caf5e2c ]
page_vma_mapped_walk() can return non-present device-exclusive entries,
but folio_referenced_one() passes them to PTE young-bit accessors that
require present PTEs.
We must neither call clear_flush_young_ptes_notify() nor
folio_pte_batch() with non-present entries. For example, clearing the
young bit on non-present PTEs can corrupt the entry: on arm64
PTE_AF overlaps the swap type, so clearing it turns a device-exclusive
entry into an ordinary swap entry.
folio_pte_batch() will VM_WARN_ON_FOLIO.
Apply the same approach as the previous fixes to e.g., damon_ptep_mkold():
treat these entries as old from the CPU's perspective and obtain their
young state through the MMU notifier.
Skip PTE batching and MGLRU look-around for non-present entries, and
don't modify non-present PTEs.
Fixes: b756a3b5e7ea ("mm: device exclusive memory access")
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Cc: stable@vger.kernel.org
Reported-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Harry Yoo (Meta) <harry@kernel.org>
Reviewed-by: Barry Song <baohua@kernel.org>
Reviewed-by: Dev Jain <dev.jain@arm.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-9-d6437171ecc3@kernel.org
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/rmap.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/mm/rmap.c b/mm/rmap.c
index 6b3480330b924..9ffd3e833e082 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -926,6 +926,7 @@ static bool folio_referenced_one(struct folio *folio,
DEFINE_FOLIO_VMA_WALK(pvmw, folio, vma, address, 0);
int ptes = 0, referenced = 0;
unsigned int nr;
+ pte_t pteval;
while (page_vma_mapped_walk(&pvmw)) {
address = pvmw.address;
@@ -970,10 +971,12 @@ static bool folio_referenced_one(struct folio *folio,
return false;
}
- if (pvmw.pte && folio_test_large(folio)) {
+ if (pvmw.pte)
+ pteval = ptep_get(pvmw.pte);
+
+ if (pvmw.pte && pte_present(pteval) && folio_test_large(folio)) {
const unsigned long end_addr = pmd_addr_end(address, vma->vm_end);
const unsigned int max_nr = (end_addr - address) >> PAGE_SHIFT;
- pte_t pteval = ptep_get(pvmw.pte);
nr = folio_pte_batch(folio, pvmw.pte, pteval, max_nr);
}
@@ -983,11 +986,23 @@ static bool folio_referenced_one(struct folio *folio,
* are. —they could be on active/inactive lists or on MGLRU. So the
* simplest approach is to disable this look-around optimization.
*/
- if (lru_gen_enabled() && !lru_gen_switching() && pvmw.pte) {
+ if (lru_gen_enabled() && !lru_gen_switching() && pvmw.pte &&
+ pte_present(pteval)) {
if (lru_gen_look_around(&pvmw, nr))
referenced++;
} else if (pvmw.pte) {
- if (clear_flush_young_ptes_notify(vma, address, pvmw.pte, nr))
+ bool young = false;
+
+ /*
+ * PFN swap PTEs, such as device-exclusive ones, that
+ * actually map pages are "old" from a CPU perspective.
+ * The MMU notifier takes care of any device aspects.
+ */
+ if (pte_present(pteval))
+ young = clear_flush_young_ptes(vma, address, pvmw.pte, nr);
+ young |= mmu_notifier_clear_flush_young(vma->vm_mm, address,
+ address + nr * PAGE_SIZE);
+ if (young)
referenced++;
} else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
if (pmdp_clear_flush_young_notify(vma, address,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 154/507] mm/huge_memory: fix list corruption when deferred_split_scan() races with deferred_split_folio()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (152 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 153/507] mm/rmap: handle device-exclusive entries in folio_referenced_one() Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 155/507] mm/huge_memory: properly handle refcounted PUD mappings on fork Greg Kroah-Hartman
` (352 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Johannes Weiner,
Mani Tofigh, Lance Yang, Muhammad Usama Anjum, Baolin Wang,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit f09171b67ea06a7fe425db33e8b74a92de1426b9 ]
Since the deferred split queue became a list_lru, the isolate callback
moves the folios it took a reference on to an on-stack list, linked
through folio->_deferred_list, and deferred_split_scan() takes them off
that list with list_del_init() without holding the list_lru lock.
deferred_split_folio() does not know about the on-stack list. It only
holds the list_lru lock when it looks at the same list_head, and it can
run for such a folio: a THP is queued when it is mapped, as a candidate
for the underused check, and is queued "again" when a part of it gets
unmapped:
CPU0 deferred_split_scan() CPU1 deferred_split_folio()
list_del_init(&folio->_deferred_list)
next->prev = prev
prev->next = next
entry->next = entry
list_lru_lock_irqsave()
folio_set_partially_mapped()
__list_lru_add()
list_empty(item) -> true
list_add_tail(item, &l->list)
item->next = &l->list
item->prev = tail
entry->prev = entry
The folio now sits on the list_lru with ->prev pointing to itself. The
next removal leaves the neighbours pointing to it, and they still do so
after the folio has been freed. With CONFIG_DEBUG_LIST:
list_del corruption. prev->next should be ffd4000000270090, but was
ffd4000000278090. (prev=ffd4000000270090)
Fix it by grabbing the lock around list_del_init() so
deferred_split_folio() cannot race with it.
Fixes: fafaeceb89a5 ("mm: switch deferred split shrinker to list_lru")
Cc: stable@vger.kernel.org
Reported-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Mani Tofigh <mt4022@columbia.edu>
Tested-by: Mani Tofigh <mt4022@columbia.edu>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-10-d6437171ecc3@kernel.org
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/huge_memory.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 779c02e0bf6cc..fd32f629400a6 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -4511,8 +4511,7 @@ int split_folio_to_list(struct folio *folio, struct list_head *list)
*
* It is unsafe to call folio_unqueue_deferred_split() until folio refcount is
* zero: because even when the list_lru lock is held, a non-empty
- * _deferred_list might be in use on deferred_split_scan()'s unlocked
- * on-stack list.
+ * _deferred_list might be in use on deferred_split_scan()'s on-stack list.
*
* The list_lru sublist is determined by folio's memcg: it is therefore
* important to unqueue deferred split before changing folio memcg.
@@ -4658,10 +4657,22 @@ static unsigned long deferred_split_scan(struct shrinker *shrink,
deferred_split_isolate, &dispose);
list_for_each_entry_safe(folio, next, &dispose, _deferred_list) {
+ struct mem_cgroup *memcg;
+ struct list_lru_one *lru;
bool did_split = false;
bool underused = false;
+ /*
+ * Sync with deferred_split_folio(), which can requeue the
+ * folio once list_empty() is true, and sets PG_partially_mapped.
+ */
+ rcu_read_lock();
+ memcg = folio_memcg(folio);
+ lru = list_lru_lock_irq(&deferred_split_lru, folio_nid(folio),
+ &memcg);
list_del_init(&folio->_deferred_list);
+ list_lru_unlock_irq(lru);
+ rcu_read_unlock();
if (!folio_test_partially_mapped(folio)) {
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 155/507] mm/huge_memory: properly handle refcounted PUD mappings on fork
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (153 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 154/507] mm/huge_memory: fix list corruption when deferred_split_scan() races with deferred_split_folio() Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 156/507] ext2: preserve completed DIO bytes when buffered fallback fails Greg Kroah-Hartman
` (351 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zi Yan, Pedro Falcato, Lance Yang,
Muhammad Usama Anjum, David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit d90bdc02e36ec08d8248ebc6cdc52e12043eb28c ]
copy_huge_pud() copies device-DAX entries without taking a folio reference
or updating mapcounts and the child's RSS.
For example, MADV_GUARD_INSTALL sets VM_MAYBE_GUARD on a device-DAX VMA,
forcing copy_page_range() to traverse the whole VMA on fork. Any remaining
huge PUDs are then copied without accounting for the new mappings.
Unmapping them in the child decrements accounting that was never added.
Use vm_normal_page_pud() to identify refcounted mappings. Take a folio
reference and add the child's PUD rmap and RSS accounting before installing
the copied entry. Pass src and dst VMAs consistently instead of src and
dst MM. Move the TODO.
Fixes: aed877c2b4257 ("device/dax: properly refcount device dax pages when mapping")
Cc: stable@vger.kernel.org
Reviewed-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-11-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/huge_mm.h | 5 ++---
mm/huge_memory.c | 27 +++++++++++++++++++--------
mm/memory.c | 4 +---
3 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index c745f7ad22987..fac05120ab774 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -12,9 +12,8 @@ int copy_huge_pmd(struct mm_struct *dst_mm, struct mm_struct *src_mm,
pmd_t *dst_pmd, pmd_t *src_pmd, unsigned long addr,
struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma);
bool huge_pmd_set_accessed(struct vm_fault *vmf);
-int copy_huge_pud(struct mm_struct *dst_mm, struct mm_struct *src_mm,
- pud_t *dst_pud, pud_t *src_pud, unsigned long addr,
- struct vm_area_struct *vma);
+int copy_huge_pud(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
+ pud_t *dst_pud, pud_t *src_pud, unsigned long addr);
#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD
void huge_pud_set_accessed(struct vm_fault *vmf, pud_t orig_pud);
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index fd32f629400a6..f5e871059ba6b 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2073,11 +2073,13 @@ void touch_pud(struct vm_area_struct *vma, unsigned long addr,
update_mmu_cache_pud(vma, addr, pud);
}
-int copy_huge_pud(struct mm_struct *dst_mm, struct mm_struct *src_mm,
- pud_t *dst_pud, pud_t *src_pud, unsigned long addr,
- struct vm_area_struct *vma)
+int copy_huge_pud(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
+ pud_t *dst_pud, pud_t *src_pud, unsigned long addr)
{
+ struct mm_struct *dst_mm = dst_vma->vm_mm;
+ struct mm_struct *src_mm = src_vma->vm_mm;
spinlock_t *dst_ptl, *src_ptl;
+ struct page *page;
pud_t pud;
int ret;
@@ -2090,11 +2092,20 @@ int copy_huge_pud(struct mm_struct *dst_mm, struct mm_struct *src_mm,
if (unlikely(!pud_trans_huge(pud)))
goto out_unlock;
- /*
- * TODO: once we support anonymous pages, use
- * folio_try_dup_anon_rmap_*() and split if duplicating fails.
- */
- if (vma_is_cow_mapping(vma) && pud_write(pud)) {
+ page = vm_normal_page_pud(src_vma, addr, pud);
+ if (page) {
+ struct folio *folio = page_folio(page);
+
+ folio_get(folio);
+ /*
+ * TODO: once we support anonymous pages, use
+ * folio_try_dup_anon_rmap_*() and split if duplicating fails.
+ */
+ folio_add_file_rmap_pud(folio, page, dst_vma);
+ add_mm_counter(dst_mm, mm_counter_file(folio), HPAGE_PUD_NR);
+ }
+
+ if (vma_is_cow_mapping(src_vma) && pud_write(pud)) {
pudp_set_wrprotect(src_mm, addr, src_pud);
pud = pud_wrprotect(pud);
}
diff --git a/mm/memory.c b/mm/memory.c
index 9e395ad33ffdf..9eb7975e4a45e 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1500,7 +1500,6 @@ copy_pud_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
unsigned long end)
{
struct mm_struct *dst_mm = dst_vma->vm_mm;
- struct mm_struct *src_mm = src_vma->vm_mm;
pud_t *src_pud, *dst_pud;
unsigned long next;
@@ -1514,8 +1513,7 @@ copy_pud_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma,
int err;
VM_BUG_ON_VMA(next-addr != HPAGE_PUD_SIZE, src_vma);
- err = copy_huge_pud(dst_mm, src_mm,
- dst_pud, src_pud, addr, src_vma);
+ err = copy_huge_pud(dst_vma, src_vma, dst_pud, src_pud, addr);
if (err == -ENOMEM)
return -ENOMEM;
if (!err)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 156/507] ext2: preserve completed DIO bytes when buffered fallback fails
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (154 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 155/507] mm/huge_memory: properly handle refcounted PUD mappings on fork Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 157/507] xfs: set healthmon mount cookie before publishing it Greg Kroah-Hartman
` (350 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hungyu Lin, Jan Kara, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hungyu Lin <dennylin0707@gmail.com>
[ Upstream commit cbf04dde8b3c5a7e043e91cefad68b8980ea0d18 ]
ext2_dio_write_iter() can complete part of a direct write before
falling back to buffered I/O for a hole inside i_size. If
generic_perform_write() then fails, its error overwrites the completed
direct-I/O byte count.
For example, on a full filesystem, an 8 KiB write to a file with an
allocated 4 KiB prefix and a 4 KiB hole overwrites the prefix but returns
ENOSPC and leaves the file position unchanged. GNU dd with oflag=direct
consequently reports zero bytes written.
Preserve a positive direct-I/O result and return the buffered error
when no bytes were direct-written. This restores the fallback policy of
generic_file_write_iter(), which ext2 used before its iomap conversion.
Fixes: fb5de4358e1a ("ext2: Move direct-io to use iomap")
Cc: stable@vger.kernel.org
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
Link: https://patch.msgid.link/20261102061555.55183-1-dennylin0707@gmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext2/file.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index b9020df7d89e0..d4a0a528c3429 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -138,7 +138,8 @@ static ssize_t ext2_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)
pos = iocb->ki_pos;
status = generic_perform_write(iocb, from);
if (unlikely(status < 0)) {
- ret = status;
+ if (!ret)
+ ret = status;
goto out_unlock;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 157/507] xfs: set healthmon mount cookie before publishing it
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (155 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 156/507] ext2: preserve completed DIO bytes when buffered fallback fails Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 158/507] xfs: dont skip free extents in later batches of a whole-AG FITRIM Greg Kroah-Hartman
` (349 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Binbin Deng, Christoph Hellwig,
Darrick J. Wong, Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Binbin Deng <18983559317@163.com>
[ Upstream commit 0344a9492efac4c79202a07cf284a382f7054170 ]
xfs_ioc_health_monitor() allocates the healthmon object with kzalloc(), so
mount_cookie starts as zero. zero is also DETACHED_MOUNT_COOKIE, but
xfs_healthmon_attach() publishes hm through mp->m_healthmon before storing
the mount cookie. A concurrent reporter can therefore acquire hm from
xfs_healthmon_get(), see the detached cookie in xfs_healthmon_push(), and
drop the event even though the monitor is being attached.
This is reachable by racing XFS_IOC_HEALTH_MONITOR with an operation
that reports a health event, such as a filesystem shutdown. Initialize
the mount cookie before making hm visible through the RCU pointer so
reporters always observe an attached monitor.
Found during a static-analysis-assisted audit: candidate sites were
surfaced by a Coccinelle rule, and the reader/writer paths were
confirmed by LLM-assisted (GLM-5.3) code inspection. The issue was
not observed at runtime; it is identified by code inspection only.
Fixes: a48373e7d35a ("xfs: start creating infrastructure for health monitoring")
Cc: stable@vger.kernel.org
Signed-off-by: Binbin Deng <18983559317@163.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_healthmon.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/xfs/xfs_healthmon.c b/fs/xfs/xfs_healthmon.c
index 2bdd747f1ead2..05d6f0494139d 100644
--- a/fs/xfs/xfs_healthmon.c
+++ b/fs/xfs/xfs_healthmon.c
@@ -114,8 +114,8 @@ xfs_healthmon_attach(
}
refcount_inc(&hm->ref);
- rcu_assign_pointer(mp->m_healthmon, hm);
hm->mount_cookie = (uintptr_t)mp->m_super;
+ rcu_assign_pointer(mp->m_healthmon, hm);
spin_unlock(&xfs_healthmon_lock);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 158/507] xfs: dont skip free extents in later batches of a whole-AG FITRIM
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (156 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 157/507] xfs: set healthmon mount cookie before publishing it Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 159/507] xfs: dont skip free extents of the longest length in " Greg Kroah-Hartman
` (348 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daejun Park, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daejun Park <daejun7.park@samsung.com>
[ Upstream commit 595e67d7261673d03c96950ffbb2e545c00376ed ]
A whole-device FITRIM walks every AG but the last by length, in
batches. xfs_trim_gather_extents() saves the record to restart from in
tcur->start. But tcur->start is also the start of the range to trim.
Later batches therefore never discard the free extents below that
block.
Save the restart record in a new restart_bno field.
Cc: stable@vger.kernel.org # v6.10
Fixes: b0ffe661fab4 ("xfs: fix performance problems when fstrimming a subset of a fragmented AG")
Signed-off-by: Daejun Park <daejun7.park@samsung.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_discard.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c
index 906221ffe9ba8..8120f136af931 100644
--- a/fs/xfs/xfs_discard.c
+++ b/fs/xfs/xfs_discard.c
@@ -155,6 +155,8 @@ struct xfs_trim_cur {
xfs_agblock_t end;
xfs_extlen_t minlen;
bool by_bno;
+ /* restart point (with count) for the by-length walk */
+ xfs_agblock_t restart_bno;
};
static int
@@ -198,14 +200,15 @@ xfs_trim_gather_extents(
error = xfs_alloc_lookup_le(cur, tcur->start, 0, &i);
if (!error && !i)
error = xfs_alloc_lookup_ge(cur, tcur->start, 0, &i);
- } else if (tcur->start == 0) {
+ } else if (tcur->restart_bno == NULLAGBLOCK) {
/* first time through a by-len starts with max length */
cur = xfs_cntbt_init_cursor(mp, tp, agbp, pag);
error = xfs_alloc_lookup_ge(cur, 0, tcur->count, &i);
} else {
/* nth time through a by-len starts where we left off */
cur = xfs_cntbt_init_cursor(mp, tp, agbp, pag);
- error = xfs_alloc_lookup_le(cur, tcur->start, tcur->count, &i);
+ error = xfs_alloc_lookup_le(cur, tcur->restart_bno,
+ tcur->count, &i);
}
if (error)
goto out_del_cursor;
@@ -235,9 +238,15 @@ xfs_trim_gather_extents(
if (--batch <= 0) {
/*
* Update the cursor to point at this extent so we
- * restart the next batch from this extent.
+ * restart the next batch from this extent. The
+ * by-length walk does not visit extents in block
+ * order, so it must keep the start of the range and
+ * restart from restart_bno instead.
*/
- tcur->start = fbno;
+ if (tcur->by_bno)
+ tcur->start = fbno;
+ else
+ tcur->restart_bno = fbno;
tcur->count = flen;
break;
}
@@ -340,6 +349,7 @@ xfs_trim_perag_extents(
.start = start,
.end = end,
.minlen = minlen,
+ .restart_bno = NULLAGBLOCK,
};
int error = 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 159/507] xfs: dont skip free extents of the longest length in a whole-AG FITRIM
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (157 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 158/507] xfs: dont skip free extents in later batches of a whole-AG FITRIM Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 160/507] drm/v3d: Initialize timedout_batches when running a CSD job Greg Kroah-Hartman
` (347 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dave Chinner, Daejun Park,
Christoph Hellwig, Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daejun Park <daejun7.park@samsung.com>
[ Upstream commit 5745f4f10a1a16aa5bb020acc38afa33f2d5ff99 ]
Since commit a66d636385d6 ("xfs: fix fstrim offset calculations"), the
by-length walk of an AG in FITRIM starts with
xfs_alloc_lookup_ge(cur, 0, pagf_longest) and walks down. The lookup
lands on the longest free extent with the lowest block number. The
other free extents of that length sort after it and are never
discarded.
Start every by-length batch with xfs_alloc_lookup_le() at restart_bno.
Suggested-by: Dave Chinner <dgc@kernel.org>
Link: https://lore.kernel.org/r/ZgiJWxVcVwag0fIP@dread.disaster.area
Cc: stable@vger.kernel.org
Fixes: a66d636385d6 ("xfs: fix fstrim offset calculations")
Signed-off-by: Daejun Park <daejun7.park@samsung.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_discard.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c
index 8120f136af931..cdf660344c281 100644
--- a/fs/xfs/xfs_discard.c
+++ b/fs/xfs/xfs_discard.c
@@ -200,12 +200,12 @@ xfs_trim_gather_extents(
error = xfs_alloc_lookup_le(cur, tcur->start, 0, &i);
if (!error && !i)
error = xfs_alloc_lookup_ge(cur, tcur->start, 0, &i);
- } else if (tcur->restart_bno == NULLAGBLOCK) {
- /* first time through a by-len starts with max length */
- cur = xfs_cntbt_init_cursor(mp, tp, agbp, pag);
- error = xfs_alloc_lookup_ge(cur, 0, tcur->count, &i);
} else {
- /* nth time through a by-len starts where we left off */
+ /*
+ * A by-len walk starts at the last record of the longest
+ * length (restart_bno is NULLAGBLOCK until the first batch
+ * ends) and then where the previous batch stopped.
+ */
cur = xfs_cntbt_init_cursor(mp, tp, agbp, pag);
error = xfs_alloc_lookup_le(cur, tcur->restart_bno,
tcur->count, &i);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 160/507] drm/v3d: Initialize timedout_batches when running a CSD job
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (158 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 159/507] xfs: dont skip free extents of the longest length in " Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 161/507] drm/v3d: Widen cache_clean_lock over the whole L2TCACTL sequence Greg Kroah-Hartman
` (346 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jose Maria Casanova Crespo,
Iago Toral Quiroga, Maíra Canal, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
[ Upstream commit 0afdbdd5b1af729108de8f893d179c3b99eac29d ]
v3d_csd_job_timedout() decides whether a compute job made progress by
comparing CSD_CURRENT_CFG4, the number of batches the dispatcher still
has to start, against the value saved at the previous timeout. That
saved value is never initialized, so it is zero on the first timeout.
On V3D 7.1.6 and later, CFG4 counts down to zero once the dispatcher has
started the last batch, but the dispatch keeps running until the batches
in flight complete. If the first timeout fires in that window, the
handler sees no change and resets the GPU while the job is about to
complete. For example, this happens with long dispatches that only keep a
single supergroup in flight.
Initialize timedout_batches to the value programmed in CFG4 when the job
is started. The register does not return to it once a batch has started:
it counts down to zero on V3D 7.1.6 and later (CFG4 holds the number of
batches), and to 0xffffffff on V3D 4.2 (CFG4 holds the number of batches
minus one).
Cc: stable@vger.kernel.org
Fixes: d223f98f0209 ("drm/v3d: Add support for compute shader dispatch.")
Signed-off-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Link: https://patch.msgid.link/20261101125619.2465064-1-mcanal@igalia.com
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/v3d/v3d_sched.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c
index e6283a75bcdf0..002116efc874b 100644
--- a/drivers/gpu/drm/v3d/v3d_sched.c
+++ b/drivers/gpu/drm/v3d/v3d_sched.c
@@ -360,6 +360,8 @@ v3d_csd_job_run(struct drm_sched_job *sched_job)
dma_fence_put(job->base.irq_fence);
job->base.irq_fence = dma_fence_get(fence);
+ job->timedout_batches = job->args.cfg[4];
+
trace_v3d_submit_csd(dev, to_v3d_fence(fence)->seqno);
v3d_job_start_stats(&job->base);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 161/507] drm/v3d: Widen cache_clean_lock over the whole L2TCACTL sequence
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (159 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 160/507] drm/v3d: Initialize timedout_batches when running a CSD job Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 162/507] cipso: fix optlen corruption in cipso_v4_delopt() Greg Kroah-Hartman
` (345 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Iago Toral Quiroga,
Jose Maria Casanova Crespo, Maíra Canal, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maíra Canal <mcanal@igalia.com>
[ Upstream commit 994ba6e5c87d6a3d471ea987fe8622168f092334 ]
v3d_clean_caches() and v3d_flush_l2t() both write the single L2TCACTL
register and poll its status bits. The mutex cache_clean_lock exists to
serialize them, but v3d_clean_caches() only took the lock around its final
FLM_CLEAN write.
These functions run concurrently: v3d_flush_l2t() is issued from the
BIN/RENDER/CSD invalidate path while v3d_clean_caches() runs from the
CACHE_CLEAN queue, and each queue's scheduler uses its own ordered
workqueue, so their run_job callbacks execute in parallel.
Because clean locked only its final write, a concurrent flush can write
L2TCACTL during clean's unlocked phase. Both use non read-modify-write
writes to the one register, so whichever lands last wins: clean's TMUWCF
write can land on the flush's in-flight L2TFLS invalidate, triggering the
GFXH-1897 hazard of writing L2TCACTL while a flush is pending.
Hold cache_clean_lock across the entire L2TCACTL access sequence so it
is fully mutually exclusive with v3d_flush_l2t(), which already takes the
lock around its own write.
Cc: stable@vger.kernel.org
Fixes: abf888b03a98 ("drm/v3d: Wait for pending L2T flush before cleaning caches")
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Jose Maria Casanova Crespo <jmcasanova@igalia.com>
Link: https://patch.msgid.link/20260707200738.659002-2-mcanal@igalia.com
Signed-off-by: Maíra Canal <mcanal@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/v3d/v3d_gem.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/v3d/v3d_gem.c b/drivers/gpu/drm/v3d/v3d_gem.c
index bc88ebdcdbead..cf3df526e7739 100644
--- a/drivers/gpu/drm/v3d/v3d_gem.c
+++ b/drivers/gpu/drm/v3d/v3d_gem.c
@@ -217,6 +217,8 @@ v3d_clean_caches(struct v3d_dev *v3d)
struct drm_device *dev = &v3d->drm;
int core = 0;
+ guard(mutex)(&v3d->cache_clean_lock);
+
trace_v3d_cache_clean_begin(dev);
/* GFXH-1897: Ensure pending flushes complete before writing L2TCACTL */
@@ -233,7 +235,6 @@ v3d_clean_caches(struct v3d_dev *v3d)
drm_err(dev, "Timeout waiting for TMU write combiner flush\n");
}
- mutex_lock(&v3d->cache_clean_lock);
V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL,
V3D_L2TCACTL_L2TFLS |
V3D_SET_FIELD(V3D_L2TCACTL_FLM_CLEAN, V3D_L2TCACTL_FLM));
@@ -243,8 +244,6 @@ v3d_clean_caches(struct v3d_dev *v3d)
drm_err(dev, "Timeout waiting for L2T clean\n");
}
- mutex_unlock(&v3d->cache_clean_lock);
-
trace_v3d_cache_clean_end(dev);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 162/507] cipso: fix optlen corruption in cipso_v4_delopt()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (160 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 161/507] drm/v3d: Widen cache_clean_lock over the whole L2TCACTL sequence Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 163/507] ntfs: dont allow compression on volumes with clusters larger than 4K Greg Kroah-Hartman
` (344 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qihang, Paul Moore, Dave Miller,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qihang <q.h.hack.winter@gmail.com>
[ Upstream commit 1f1f8e8c5176234fa31858cd25f2e9b88aac0a45 ]
cipso_v4_delopt() recomputes the option length by walking the option
buffer after the CIPSO option has been moved out. The walk then reads
the stale bytes at the tail of the buffer as option data, and a crafted
setsockopt(IP_OPTIONS) buffer can make it treat one of them as an option
length, increasing opt->opt.optlen beyond the valid option data.
The corrupted length stays on the socket and is later used as the copy
length by getsockopt(IP_OPTIONS) and by the udp/raw/ping sendmsg paths,
where it exceeds the size of the buffers they copy into.
Compute the new length from the intact options before the move and
subtract the CIPSO length, and fill the padding with IPOPT_END.
Assisted-by: LLM
Fixes: 014ab19a69c32 ("selinux: Set socket NetLabel based on connection endpoint")
Cc: stable@vger.kernel.org
Signed-off-by: Qihang <q.h.hack.winter@gmail.com>
Acked-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Dave Miller <davem@davem-thinkpadp1gen8.ibmlond.csb>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/cipso_ipv4.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 1aacbbeffbc64..e65a3f29d2caf 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -2013,6 +2013,10 @@ static int cipso_v4_delopt(struct ip_options_rcu __rcu **opt_ptr)
cipso_ptr = &opt->opt.__data[cipso_off];
cipso_len = cipso_ptr[1];
+ optlen_new = cipso_v4_get_actual_opt_len(opt->opt.__data,
+ opt->opt.optlen);
+ optlen_new -= cipso_len;
+
if (opt->opt.srr > opt->opt.cipso)
opt->opt.srr -= cipso_len;
if (opt->opt.rr > opt->opt.cipso)
@@ -2026,11 +2030,12 @@ static int cipso_v4_delopt(struct ip_options_rcu __rcu **opt_ptr)
memmove(cipso_ptr, cipso_ptr + cipso_len,
opt->opt.optlen - cipso_off - cipso_len);
- optlen_new = cipso_v4_get_actual_opt_len(opt->opt.__data,
- opt->opt.optlen);
hdr_delta = opt->opt.optlen;
opt->opt.optlen = (optlen_new + 3) & ~3;
hdr_delta -= opt->opt.optlen;
+
+ memset(&opt->opt.__data[optlen_new], IPOPT_END,
+ opt->opt.optlen - optlen_new);
} else {
/* only the cipso option was present on the socket so we can
* remove the entire option struct */
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 163/507] ntfs: dont allow compression on volumes with clusters larger than 4K
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (161 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 162/507] cipso: fix optlen corruption in cipso_v4_delopt() Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 164/507] vhost-vdpa: fix pinned page leak in vhost_vdpa_pa_map() error path Greg Kroah-Hartman
` (343 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhan Xusheng, Baolin Liu,
Namjae Jeon, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhan Xusheng <zhanxusheng@xiaomi.com>
[ Upstream commit c77ab4eeeb3ed471bcc99a94673f0e0142c4b84a ]
On a volume made with "mkntfs -c 8192", a user can set
FILE_ATTR_COMPRESSED on an empty file through system.ntfs_attrib.
Writing to the file and reading it back after dropping the page cache
then crashes:
BUG: KASAN: slab-out-of-bounds in ntfs_read_compressed_block+0xa2c/0x2040
Read of size 8192 at addr ffff88804355a000 by task dd/106
The read path only handles clusters up to 4K. It copies each cluster
out of a single page, and a compression block of 16 8K clusters does
not fit in the 64K ntfs_compression_buffer. Loading an inode already
rejects compressed data on such volumes.
Reject the flag change the same way.
Fixes: fc053f05ca28 ("ntfs: add reparse and ea operations")
Cc: stable@vger.kernel.org
Signed-off-by: Zhan Xusheng <zhanxusheng@xiaomi.com>
Reviewed-by: Baolin Liu <liubaolin@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs/ea.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/fs/ntfs/ea.c b/fs/ntfs/ea.c
index 6ac551fe8ea64..9e00588ff9b5c 100644
--- a/fs/ntfs/ea.c
+++ b/fs/ntfs/ea.c
@@ -699,6 +699,11 @@ static int ntfs_new_attr_flags(struct ntfs_inode *ni, __le32 fattr)
goto err_out;
}
+ if ((new_aflags & ATTR_IS_COMPRESSED) && ni->vol->cluster_size > 4096) {
+ err = -EOPNOTSUPP;
+ goto err_out;
+ }
+
if (!a->non_resident) {
if (!(new_aflags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED))) {
err = 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 164/507] vhost-vdpa: fix pinned page leak in vhost_vdpa_pa_map() error path
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (162 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 163/507] ntfs: dont allow compression on volumes with clusters larger than 4K Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 165/507] vringh: bound top-level re-entry into indirect tables Greg Kroah-Hartman
` (342 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tal Zussman, Linfeng Sun,
Michael S. Tsirkin, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tal Zussman <tz2294@columbia.edu>
[ Upstream commit fd1462c96bafe2cb14e88c837b270f8990b717b5 ]
When pin_user_pages() or vhost_vdpa_map() fails, vhost_vdpa_pa_map()
is supposed to unpin the pages pinned after the last successfully
mapped chunk, i.e. the range [map_pfn, last_pfn]. The unpin is guarded
by nchunks, but nchunks is reset to 0 every time a chunk is mapped from
inside the current page list, so a failure after any such boundary
leaves that pending range pinned forever. With physically scattered
memory nearly every page list contains a boundary, so the leak happens
on practically every failed IOTLB update.
The pending range is non-empty exactly when a page has been pinned,
which last_pfn already tells us, so drop nchunks and test last_pfn.
Fixes: ad89653f79f1 ("vhost-vdpa: fix page pinning leakage in error path (rework)")
Cc: stable@vger.kernel.org
Signed-off-by: Tal Zussman <tz2294@columbia.edu>
Reported-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261031-vhost-vdpa-unpin-v1-1-94ffc9683256@columbia.edu>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vhost/vdpa.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index a31786796d4ce..c7a9702c2447b 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -1151,7 +1151,7 @@ static int vhost_vdpa_pa_map(struct vhost_vdpa *v,
unsigned long list_size = PAGE_SIZE / sizeof(struct page *);
unsigned int gup_flags = FOLL_LONGTERM;
unsigned long npages, cur_base, map_pfn, last_pfn = 0;
- unsigned long lock_limit, sz2pin, nchunks, i;
+ unsigned long lock_limit, sz2pin, i;
unsigned long page_offset;
u64 start = iova;
long pinned;
@@ -1187,7 +1187,6 @@ static int vhost_vdpa_pa_map(struct vhost_vdpa *v,
cur_base = uaddr & PAGE_MASK;
iova &= PAGE_MASK;
- nchunks = 0;
while (npages) {
sz2pin = min_t(unsigned long, npages, list_size);
@@ -1202,7 +1201,6 @@ static int vhost_vdpa_pa_map(struct vhost_vdpa *v,
}
goto out;
}
- nchunks++;
if (!last_pfn)
map_pfn = page_to_pfn(page_list[0]);
@@ -1233,7 +1231,6 @@ static int vhost_vdpa_pa_map(struct vhost_vdpa *v,
map_pfn = this_pfn;
iova += csize;
- nchunks = 0;
}
last_pfn = this_pfn;
@@ -1248,7 +1245,7 @@ static int vhost_vdpa_pa_map(struct vhost_vdpa *v,
PFN_PHYS(map_pfn), perm, NULL);
out:
if (ret) {
- if (nchunks) {
+ if (last_pfn) {
unsigned long pfn;
/*
@@ -1260,7 +1257,6 @@ static int vhost_vdpa_pa_map(struct vhost_vdpa *v,
* the corresponding unpinning will be handled by
* vdpa_unmap().
*/
- WARN_ON(!last_pfn);
for (pfn = map_pfn; pfn <= last_pfn; pfn++)
unpin_user_page(pfn_to_page(pfn));
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 165/507] vringh: bound top-level re-entry into indirect tables
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (163 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 164/507] vhost-vdpa: fix pinned page leak in vhost_vdpa_pa_map() error path Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 166/507] vringh: reject empty / undersized indirect descriptor tables Greg Kroah-Hartman
` (341 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xie Yongji, Fang Xieyan,
Michael S. Tsirkin, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fang Xieyan <fangxy@xiaopeng.com>
[ Upstream commit f898439ace7f89922e853b43bcbfcd26ea2e0a98 ]
In __vringh_iov(), the F_INDIRECT branch descends into the indirect
table and continues before the descriptor accounting runs. A top-level
indirect descriptor is therefore never charged to count. If such a
descriptor sets NEXT to point back at itself, returning from the
indirect table resumes at the same top-level descriptor, which is again
not counted, so the walk never makes forward progress.
Because count stays flat and indirect_count is reset to 0 on every
return to the top-level table, neither bound in the loop check trips.
A guest can spin the vringh worker at 100% CPU inside __vringh_iov(),
an uninterruptible host DoS.
Move the descriptor accounting above the indirect switch so that a
top-level indirect descriptor is charged one top-level traversal step
before the walk descends into its table, bringing this re-entry under
the existing vrh->vring.num bound. Each top-level descriptor is still
charged at most one step and indirect_count still bounds a single
table, so legitimate chains (including the multiple-indirect case in
tools/virtio/vringh_test.c) stay within vring.num, while a cyclic
indirect descriptor is now rejected with -ELOOP.
Fixes: dbd29e075228 ("vringh: Fix loop descriptors check in the indirect cases")
Cc: Xie Yongji <xieyongji@bytedance.com>
Cc: stable@vger.kernel.org
Assisted-by: Hawkeye:GLM-5.3-flash
Assisted-by: Qoder:Qwen3.8-Max
Signed-off-by: Fang Xieyan <fangxy@xiaopeng.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260922122955.69433-2-fangxy@xiaopeng.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vhost/vringh.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
index 9066f9f12ba13..f672e1115d13c 100644
--- a/drivers/vhost/vringh.c
+++ b/drivers/vhost/vringh.c
@@ -333,6 +333,17 @@ __vringh_iov(struct vringh *vrh, u16 i,
if (unlikely(err))
goto fail;
+ if (up_next == -1)
+ count++;
+ else
+ indirect_count++;
+
+ if (count > vrh->vring.num || indirect_count > desc_max) {
+ vringh_bad("Descriptor loop in %p", descs);
+ err = -ELOOP;
+ goto fail;
+ }
+
if (unlikely(desc.flags &
cpu_to_vringh16(vrh, VRING_DESC_F_INDIRECT))) {
u64 a = vringh64_to_cpu(vrh, desc.addr);
@@ -358,17 +369,6 @@ __vringh_iov(struct vringh *vrh, u16 i,
continue;
}
- if (up_next == -1)
- count++;
- else
- indirect_count++;
-
- if (count > vrh->vring.num || indirect_count > desc_max) {
- vringh_bad("Descriptor loop in %p", descs);
- err = -ELOOP;
- goto fail;
- }
-
if (desc.flags & cpu_to_vringh16(vrh, VRING_DESC_F_WRITE))
iov = wiov;
else {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 166/507] vringh: reject empty / undersized indirect descriptor tables
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (164 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 165/507] vringh: bound top-level re-entry into indirect tables Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 167/507] veth: keep carrier off when resizing channels with a down peer Greg Kroah-Hartman
` (340 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Fang Xieyan, Michael S. Tsirkin,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fang Xieyan <fangxy@xiaopeng.com>
[ Upstream commit 60a792b97933a686316737838cd007d27963011e ]
move_to_indirect() validates an indirect descriptor table only with
"len % sizeof(struct vring_desc)". A descriptor flagged
VRING_DESC_F_INDIRECT with len == 0 passes that test, so *desc_max is
set to 0 while *descs points at the empty table. __vringh_iov() then
copies one struct vring_desc from descs[0] -- 16 bytes past the end of
the table -- before the "indirect_count > desc_max" loop detection
aborts the walk. The over-read value is discarded when the walk aborts
and is never used to map anything, but the access itself is out of
bounds.
Reject any len smaller than one descriptor, alongside the existing
stride check, so an empty table is refused with -EINVAL and no
descriptor is ever fetched from it.
Fixes: f87d0fbb5798 ("vringh: host-side implementation of virtio rings.")
Cc: stable@vger.kernel.org
Assisted-by: Hawkeye:GLM-5.3-flash
Assisted-by: Qoder:Qwen3.8-Max
Signed-off-by: Fang Xieyan <fangxy@xiaopeng.com>
Message-ID: <20260926160755.21485-1-fangxy@xiaopeng.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vhost/vringh.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c
index f672e1115d13c..f027f669460f4 100644
--- a/drivers/vhost/vringh.c
+++ b/drivers/vhost/vringh.c
@@ -197,8 +197,9 @@ static int move_to_indirect(const struct vringh *vrh,
}
len = vringh32_to_cpu(vrh, desc->len);
- if (unlikely(len % sizeof(struct vring_desc))) {
- vringh_bad("Strange indirect len %u", desc->len);
+ if (unlikely(len < sizeof(struct vring_desc) ||
+ len % sizeof(struct vring_desc))) {
+ vringh_bad("Invalid indirect len %u", desc->len);
return -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 167/507] veth: keep carrier off when resizing channels with a down peer
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (165 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 166/507] vringh: reject empty / undersized indirect descriptor tables Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 168/507] hwmon: (sht15) Stop deferred work before releasing its resources Greg Kroah-Hartman
` (339 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hangbin Liu, Xia Yan, Jiayuan Chen,
Paolo Abeni, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xia Yan <yana06070@163.com>
[ Upstream commit 2d02191779345b13de91048db441191b20264d16 ]
veth_set_channels() temporarily turns carrier off while reconfiguring a
running interface. It then turns carrier on for both ends without
checking whether the peer is administratively up. If only one end is up,
changing its channel counts therefore reports LOWER_UP even though the
peer remains down.
For example, after creating a pair with two RX and TX queues per end:
ip link set vca up
ethtool -L vca rx 1 tx 1
vca incorrectly reports LOWER_UP while vcb is still down.
Only restore carrier when the peer has IFF_UP, matching veth_open().
The local interface is already known to be running at this point.
Found during LLM-assisted source review and reproduced with a veth pair
in network namespaces, without kernel instrumentation or error injection.
The companion veth.sh test reproduces the two mixed up/down failures
before the fix and passes after it.
Fixes: 4752eeb3d891 ("veth: implement support for set_channel ethtool op")
Cc: stable@vger.kernel.org
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Signed-off-by: Xia Yan <yana06070@163.com>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://patch.msgid.link/20261029024259.3700-1-yana06070@163.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/veth.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 7db389ae866dd..c1859ffcdaf1a 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -1372,9 +1372,10 @@ static int veth_set_channels(struct net_device *dev,
* to identify the range we have to disable
*/
veth_disable_range_safe(dev, new_rx_count, old_rx_count);
- netif_carrier_on(dev);
- if (peer)
+ if (peer && (peer->flags & IFF_UP)) {
+ netif_carrier_on(dev);
netif_carrier_on(peer);
+ }
}
/* update XDP supported features */
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 168/507] hwmon: (sht15) Stop deferred work before releasing its resources
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (166 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 167/507] veth: keep carrier off when resizing channels with a down peer Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 169/507] hwmon: (corsair-cpro) Cache fan target only after a successful command Greg Kroah-Hartman
` (338 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak,
Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
[ Upstream commit 5eab1e7f7ed12893f3864fe46ffcd5a41a752d6a ]
The IRQ handler and regulator notifier can leave work pending after a
measurement or notification completes. Neither work item is drained before
its resources are released on removal or probe failure.
Disable read_work before freeing the IRQ, since the worker can re-enable
it. Use request_irq()/free_irq() for explicit teardown. Unregister the
regulator notifier before cancelling update_supply_work and disabling the
regulator. Apply the same ordering to probe failures.
Fixes: 251eb40f5ccd ("hwmon: sht15 humidity sensor driver")
Cc: stable@vger.kernel.org
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Link: https://patch.msgid.link/20261024014044.27853-1-mhun512@gmail.com
[groeck: Dropped obsolete 'Assisted-by: tag]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/sht15.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
index 7bb2105d1ae22..48d93c61345c1 100644
--- a/drivers/hwmon/sht15.c
+++ b/drivers/hwmon/sht15.c
@@ -31,6 +31,7 @@
#include <linux/bitrev.h>
#include <linux/gpio/consumer.h>
#include <linux/of.h>
+#include <linux/workqueue.h>
/* Commands */
#define SHT15_MEASURE_TEMP 0x03
@@ -976,25 +977,22 @@ static int sht15_probe(struct platform_device *pdev)
goto err_release_reg;
}
- ret = devm_request_irq(&pdev->dev, gpiod_to_irq(data->data),
- sht15_interrupt_fired,
- IRQF_TRIGGER_FALLING,
- "sht15 data",
- data);
+ ret = request_irq(gpiod_to_irq(data->data), sht15_interrupt_fired,
+ IRQF_TRIGGER_FALLING, "sht15 data", data);
if (ret)
goto err_release_reg;
disable_irq_nosync(gpiod_to_irq(data->data));
ret = sht15_connection_reset(data);
if (ret)
- goto err_release_reg;
+ goto err_free_irq;
ret = sht15_soft_reset(data);
if (ret)
- goto err_release_reg;
+ goto err_free_irq;
ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group);
if (ret) {
dev_err(&pdev->dev, "sysfs create failed\n");
- goto err_release_reg;
+ goto err_free_irq;
}
data->hwmon_dev = hwmon_device_register(data->dev);
@@ -1007,9 +1005,13 @@ static int sht15_probe(struct platform_device *pdev)
err_release_sysfs_group:
sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group);
+err_free_irq:
+ disable_work_sync(&data->read_work);
+ free_irq(gpiod_to_irq(data->data), data);
err_release_reg:
if (!IS_ERR(data->reg)) {
regulator_unregister_notifier(data->reg, &data->nb);
+ cancel_work_sync(&data->update_supply_work);
regulator_disable(data->reg);
}
return ret;
@@ -1023,12 +1025,16 @@ static void sht15_remove(struct platform_device *pdev)
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group);
+ disable_work_sync(&data->read_work);
+ free_irq(gpiod_to_irq(data->data), data);
+
ret = sht15_soft_reset(data);
if (ret)
dev_err(&pdev->dev, "Failed to reset device (%pe)\n", ERR_PTR(ret));
if (!IS_ERR(data->reg)) {
regulator_unregister_notifier(data->reg, &data->nb);
+ cancel_work_sync(&data->update_supply_work);
regulator_disable(data->reg);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 169/507] hwmon: (corsair-cpro) Cache fan target only after a successful command
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (167 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 168/507] hwmon: (sht15) Stop deferred work before releasing its resources Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 170/507] hwmon: (aquacomputer_d5next) reject short status reports Greg Kroah-Hartman
` (337 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baek Kyu, Kim, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baek Kyu, Kim <pocj8ur4in@gmail.com>
[ Upstream commit e2c26431b4e47892378582a414b4bbaa9edf1798 ]
set_target() updates the cached fan target before sending the command.
If the command fails, subsequent fanN_target reads report the failed
request instead of the previous value. For example, after successfully
setting 1200 RPM, a rejected request for 1800 RPM returns an error but
leaves fanN_target reporting 1800. A failed request also replaces
-ENODATA when no target has been successfully set.
Update the target cache under the existing mutex only after
send_usb_cmd() succeeds, as set_pwm() already does when invalidating
the target. Preserve the previous cached value and return the original
error on failure.
Fixes: 40c3a4454225 ("hwmon: add Corsair Commander Pro driver")
Cc: stable@vger.kernel.org
Signed-off-by: Baek Kyu, Kim <pocj8ur4in@gmail.com>
Link: https://patch.msgid.link/20261020160941.36787-1-pocj8ur4in@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/corsair-cpro.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/corsair-cpro.c b/drivers/hwmon/corsair-cpro.c
index e6d31d3676980..6ce5da37de03b 100644
--- a/drivers/hwmon/corsair-cpro.c
+++ b/drivers/hwmon/corsair-cpro.c
@@ -215,10 +215,11 @@ static int set_target(struct ccp_device *ccp, int channel, long val)
int ret;
val = clamp_val(val, 0, 0xFFFF);
- ccp->target[channel] = val;
mutex_lock(&ccp->mutex);
ret = send_usb_cmd(ccp, CTL_SET_FAN_TARGET, channel, val >> 8, val);
+ if (!ret)
+ ccp->target[channel] = val;
mutex_unlock(&ccp->mutex);
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 170/507] hwmon: (aquacomputer_d5next) reject short status reports
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (168 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 169/507] hwmon: (corsair-cpro) Cache fan target only after a successful command Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 171/507] hwmon: (asus_rog_ryujin) Fix pump control source on the Ryujin III Greg Kroah-Hartman
` (336 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Jiale Yao,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiale Yao <yaojiale02@163.com>
[ Upstream commit cf8f81babd2e96087dedbb74985bc1781c98f73d ]
The HID raw_event callback runs before HID core validates the received
report length. aqc_raw_event() reads device-specific status fields at fixed
offsets, including multi-byte values, without first ensuring that the
received buffer contains every field. A truncated report can therefore
cause out-of-bounds reads and update hwmon state with unrelated data.
The required length differs between supported devices and cannot be
derived from the HID report descriptor. Define the minimum length needed
by each asynchronous status format, select it while configuring the
device, and reject reports that do not contain the last field accessed by
that format. Keep the published length zero until probe configuration is
complete, which also excludes legacy devices whose status is retrieved
through feature reports.
Suggested-by: Guenter Roeck <linux@roeck-us.net>
Fixes: 0e35f63f7f4e ("hwmon: add driver for Aquacomputer D5 Next")
Fixes: 19692f17cd13 ("hwmon: (aquacomputer_d5next) Add support for Aquacomputer Aquastream XT")
Cc: stable@vger.kernel.org
Signed-off-by: Jiale Yao <yaojiale02@163.com>
Link: https://patch.msgid.link/20261021120408.48495-1-yaojiale02@163.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/aquacomputer_d5next.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c
index 1ca70e7262988..341cce4347e24 100644
--- a/drivers/hwmon/aquacomputer_d5next.c
+++ b/drivers/hwmon/aquacomputer_d5next.c
@@ -132,6 +132,7 @@ static u8 aquaero_secondary_ctrl_report[] = {
#define AQUAERO_FAN_CURRENT_OFFSET 0x06
#define AQUAERO_FAN_POWER_OFFSET 0x08
#define AQUAERO_FAN_SPEED_OFFSET 0x00
+#define AQUAERO_MIN_STATUS_REPORT_SIZE (0x18B + AQUAERO_FAN_POWER_OFFSET + sizeof(u16))
static u16 aquaero_sensor_fan_offsets[] = { 0x167, 0x173, 0x17f, 0x18B };
/* Control report offsets for the Aquaero fan controllers */
@@ -155,6 +156,8 @@ static u16 aquaero_ctrl_fan_offsets[] = { 0x20c, 0x220, 0x234, 0x248 };
#define D5NEXT_5V_VOLTAGE 0x39
#define D5NEXT_12V_VOLTAGE 0x37
#define D5NEXT_VIRTUAL_SENSORS_START 0x3f
+#define D5NEXT_MIN_STATUS_REPORT_SIZE (D5NEXT_PUMP_OFFSET + AQC_FAN_SPEED_OFFSET + \
+ sizeof(u16))
static u16 d5next_sensor_fan_offsets[] = { D5NEXT_PUMP_OFFSET, D5NEXT_FAN_OFFSET };
/* Control report offsets for the D5 Next pump */
@@ -179,11 +182,14 @@ static u16 d5next_ctrl_fan_offsets[] = { 0x97, 0x42 }; /* Pump and fan speed (fr
#define AQUASTREAMULT_FAN_CURRENT_OFFSET 0x00
#define AQUASTREAMULT_FAN_POWER_OFFSET 0x04
#define AQUASTREAMULT_FAN_SPEED_OFFSET 0x06
+#define AQUASTREAMULT_MIN_STATUS_REPORT_SIZE (AQUASTREAMULT_PRESSURE_OFFSET + sizeof(u16))
static u16 aquastreamult_sensor_fan_offsets[] = { AQUASTREAMULT_FAN_OFFSET };
/* Spec and sensor report offset for the Farbwerk RGB controller */
#define FARBWERK_NUM_SENSORS 4
#define FARBWERK_SENSOR_START 0x2f
+#define FARBWERK_MIN_STATUS_REPORT_SIZE (FARBWERK_SENSOR_START + \
+ FARBWERK_NUM_SENSORS * AQC_SENSOR_SIZE)
/* Specs of the Farbwerk 360 RGB controller */
#define FARBWERK360_NUM_SENSORS 4
@@ -193,6 +199,8 @@ static u16 aquastreamult_sensor_fan_offsets[] = { AQUASTREAMULT_FAN_OFFSET };
/* Sensor report offsets for the Farbwerk 360 */
#define FARBWERK360_SENSOR_START 0x32
#define FARBWERK360_VIRTUAL_SENSORS_START 0x3a
+#define FARBWERK360_MIN_STATUS_REPORT_SIZE (FARBWERK360_VIRTUAL_SENSORS_START + \
+ FARBWERK360_NUM_VIRTUAL_SENSORS * AQC_SENSOR_SIZE)
/* Control report offsets for the Farbwerk 360 */
#define FARBWERK360_TEMP_CTRL_OFFSET 0x8
@@ -209,6 +217,7 @@ static u16 aquastreamult_sensor_fan_offsets[] = { AQUASTREAMULT_FAN_OFFSET };
#define OCTO_SENSOR_START 0x3D
#define OCTO_VIRTUAL_SENSORS_START 0x45
#define OCTO_FLOW_SENSOR_OFFSET 0x7B
+#define OCTO_MIN_STATUS_REPORT_SIZE (0xD8 + AQC_FAN_SPEED_OFFSET + sizeof(u16))
static u16 octo_sensor_fan_offsets[] = { 0x7D, 0x8A, 0x97, 0xA4, 0xB1, 0xBE, 0xCB, 0xD8 };
/* Control report offsets for the Octo */
@@ -229,6 +238,7 @@ static u16 octo_ctrl_fan_offsets[] = { 0x5B, 0xB0, 0x105, 0x15A, 0x1AF, 0x204, 0
#define QUADRO_SENSOR_START 0x34
#define QUADRO_VIRTUAL_SENSORS_START 0x3c
#define QUADRO_FLOW_SENSOR_OFFSET 0x6e
+#define QUADRO_MIN_STATUS_REPORT_SIZE (0x97 + AQC_FAN_SPEED_OFFSET + sizeof(u16))
static u16 quadro_sensor_fan_offsets[] = { 0x70, 0x7D, 0x8A, 0x97 };
/* Control report offsets for the Quadro */
@@ -248,6 +258,7 @@ static u16 quadro_ctrl_fan_offsets[] = { 0x37, 0x8c, 0xe1, 0x136 }; /* Fan speed
#define HIGHFLOWNEXT_CONDUCTIVITY 95
#define HIGHFLOWNEXT_5V_VOLTAGE 97
#define HIGHFLOWNEXT_5V_VOLTAGE_USB 99
+#define HIGHFLOWNEXT_MIN_STATUS_REPORT_SIZE (HIGHFLOWNEXT_5V_VOLTAGE_USB + sizeof(u16))
/* Specs of the Leakshield */
#define LEAKSHIELD_NUM_SENSORS 2
@@ -263,6 +274,7 @@ static u16 quadro_ctrl_fan_offsets[] = { 0x37, 0x8c, 0xe1, 0x136 }; /* Fan speed
#define LEAKSHIELD_FLOW_IN 111
#define LEAKSHIELD_RESERVOIR_VOLUME 313
#define LEAKSHIELD_RESERVOIR_FILLED 311
+#define LEAKSHIELD_MIN_STATUS_REPORT_SIZE (LEAKSHIELD_RESERVOIR_VOLUME + sizeof(u16))
/* Specs of the Aquastream XT pump */
#define AQUASTREAMXT_SERIAL_START 0x3a
@@ -554,6 +566,7 @@ struct aqc_data {
const char *name;
int status_report_id; /* Used for legacy devices, report is stored in buffer */
+ u16 min_report_size;
int ctrl_report_id;
int secondary_ctrl_report_id;
int secondary_ctrl_report_size;
@@ -1333,6 +1346,8 @@ static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8
return 0;
priv = hid_get_drvdata(hdev);
+ if (!priv->min_report_size || size < priv->min_report_size)
+ return 0;
/* Info provided with every report */
priv->serial_number[0] = get_unaligned_be16(data + priv->serial_number_start_offset);
@@ -1518,6 +1533,7 @@ static void aqc_debugfs_init(struct aqc_data *priv)
static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
struct aqc_data *priv;
+ u16 min_report_size = 0;
int ret;
priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -1585,6 +1601,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->power_label = label_fan_power;
priv->voltage_label = label_fan_voltage;
priv->current_label = label_fan_current;
+ min_report_size = AQUAERO_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_D5NEXT:
priv->kind = d5next;
@@ -1610,6 +1627,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->power_label = label_d5next_power;
priv->voltage_label = label_d5next_voltages;
priv->current_label = label_d5next_current;
+ min_report_size = D5NEXT_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_FARBWERK:
priv->kind = farbwerk;
@@ -1620,6 +1638,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->temp_sensor_start_offset = FARBWERK_SENSOR_START;
priv->temp_label = label_temp_sensors;
+ min_report_size = FARBWERK_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_FARBWERK360:
priv->kind = farbwerk360;
@@ -1636,6 +1655,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->temp_label = label_temp_sensors;
priv->virtual_temp_label = label_virtual_temp_sensors;
+ min_report_size = FARBWERK360_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_OCTO:
priv->kind = octo;
@@ -1665,6 +1685,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->power_label = label_fan_power;
priv->voltage_label = label_fan_voltage;
priv->current_label = label_fan_current;
+ min_report_size = OCTO_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_QUADRO:
priv->kind = quadro;
@@ -1694,6 +1715,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->power_label = label_fan_power;
priv->voltage_label = label_fan_voltage;
priv->current_label = label_fan_current;
+ min_report_size = QUADRO_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_HIGHFLOWNEXT:
priv->kind = highflownext;
@@ -1711,6 +1733,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->speed_label = label_highflownext_fan_speed;
priv->power_label = label_highflownext_power;
priv->voltage_label = label_highflownext_voltage;
+ min_report_size = HIGHFLOWNEXT_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_LEAKSHIELD:
/*
@@ -1730,6 +1753,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->temp_label = label_leakshield_temp_sensors;
priv->speed_label = label_leakshield_fan_speed;
+ min_report_size = LEAKSHIELD_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_AQUASTREAMXT:
priv->kind = aquastreamxt;
@@ -1760,6 +1784,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
priv->power_label = label_aquastreamult_power;
priv->voltage_label = label_aquastreamult_voltages;
priv->current_label = label_aquastreamult_current;
+ min_report_size = AQUASTREAMULT_MIN_STATUS_REPORT_SIZE;
break;
case USB_PRODUCT_ID_POWERADJUST3:
priv->kind = poweradjust3;
@@ -1833,6 +1858,8 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
break;
}
+ priv->min_report_size = min_report_size;
+
if (priv->buffer_size != 0) {
priv->checksum_start = 0x01;
priv->checksum_length = priv->buffer_size - 3;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 171/507] hwmon: (asus_rog_ryujin) Fix pump control source on the Ryujin III
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (169 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 170/507] hwmon: (aquacomputer_d5next) reject short status reports Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 172/507] hwmon: (gpd-fan) Reset both fans to automatic on duo boards Greg Kroah-Hartman
` (335 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Edward Blair, Zac Lanzon,
Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zac Lanzon <lanzonza@gmail.com>
[ Upstream commit 743b4481b6112d8ac11c165628daa8e0f0ecf78c ]
The RYUJIN III pump has a 4-pin cable for a motherboard fan header in
addition to USB. Byte 2 of the set cooler duty command selects the pump
control source: 0 hands the pump to its internal controller, which
follows the PWM of the header its 4-pin cable is plugged into, and 1
makes it follow the pump duty in byte 3. Byte 3 of the cooler duty
report returns the current source.
The driver fills byte 2 with duty_channel, which is 1 for the RYUJIN
III, and a pwm2 write re-sends the reported pump duty with the new fan
duty. So writing only the internal fan duty takes the pump away from
its internal controller.
Measured on a RYUJIN III 360 (firmware AURJ2-S750-0108) with the pump
cable on AIO_PUMP and the header PWM set through nct6775, after loading
the driver with the pump on its internal controller (pump rpm):
header 50% header 80% source
no write yet 2160 3090 0
pwm2 = 40%, before this patch 1740 1740 1
pwm2 = 40%, with this patch 2130 3090 0
Send the reported source with pwm2 writes. The fan duty applies with
either source (40%: 1545 to 1590 rpm, 30%: 870 rpm). A pwm2 write sent
right after a pwm1 write that took the pump over, before the report
could show the change, left the pump on USB and applied its fan duty
(2 of 2 trials, and 7 of 7 with raw commands up to 0.9 s after).
pwm1 writes keep selecting source 1. The cooler reports the pump duty of
the last write, whichever source it selected, and 40% after power-on.
Byte 9 of the status report follows the duty the pump runs at. Measured
from power-on (PSU switched off) once per driver, with the header at
100%:
before this patch with this patch
source duty rpm source duty rpm
no write yet 0 100 3570 0 100 3570
pwm2 = 40% 1 100 3570 0 100 3570
pwm1 = 40%, the reported duty 1 100 3570 1 40 1710
pwm1 = 60% 1 60 2430
pwm1 = 40% 1 40 1725
So a pwm1 write of the reported duty did not reach the pump, while
other duties applied in one write, also when taking the pump from its
internal controller (60%: 2460 rpm). When a pwm1 write requests the
reported duty, write a duty 1% away first (below at 100%), then the
requested one. Sent back to back, the two writes left the pump at the
requested duty in all 19 trials, 9 with raw commands and 10 through
this driver.
Tested on the RYUJIN III 360 only. The EXTREME, EVA and WHITE EDITION
use the same rog_ryujin_iii_info and send the same command, and Edward
Blair's analysis of the WHITE EDITION firmware shows the same pump
control source. The RYUJIN II, whose duty_channel is 0, is unchanged.
Fixes: cd258aca0dc4 ("hwmon: (asus_rog_ryujin) Add ROG Ryujin III support")
Closes: https://github.com/aleksamagicka/asus_rog_ryujin-hwmon/issues/12
Suggested-by: Edward Blair <edward.blair@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Zac Lanzon <lanzonza@gmail.com>
Link: https://patch.msgid.link/7ca8fe6cd6b4125813613bd4187ff6cdda72e4b6.1790512964.git.lanzonza@gmail.com
[groeck: Dropped obsolete 'Assisted-by: tag]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/hwmon/asus_rog_ryujin.rst | 6 +++
drivers/hwmon/asus_rog_ryujin.c | 54 ++++++++++++++++++++++++-
2 files changed, 59 insertions(+), 1 deletion(-)
diff --git a/Documentation/hwmon/asus_rog_ryujin.rst b/Documentation/hwmon/asus_rog_ryujin.rst
index b0d7ce8dd921f..24dccef2d2df1 100644
--- a/Documentation/hwmon/asus_rog_ryujin.rst
+++ b/Documentation/hwmon/asus_rog_ryujin.rst
@@ -33,6 +33,12 @@ Usage notes
As these are USB HIDs, the driver can be loaded automatically by the kernel and
supports hot swapping.
+The pump of the RYUJIN III also has a 4-pin cable for a motherboard fan header.
+The cooler either hands the pump to its internal controller, which follows the
+PWM of the header its 4-pin cable is plugged into, or runs it at the pump duty
+set over USB. Writing pwm1 selects the duty set over USB. Writing pwm2 sets
+only the internal fan duty and leaves the pump control as it is.
+
Sysfs entries
-------------
diff --git a/drivers/hwmon/asus_rog_ryujin.c b/drivers/hwmon/asus_rog_ryujin.c
index e297557ca3463..a400e523d2e9c 100644
--- a/drivers/hwmon/asus_rog_ryujin.c
+++ b/drivers/hwmon/asus_rog_ryujin.c
@@ -49,6 +49,7 @@ static const struct rog_ryujin_device_info rog_ryujin_iii_info = {
#define MAX_REPORT_LENGTH 65
/* Cooler duty report offsets */
+#define RYUJIN_PUMP_SOURCE 3
#define RYUJIN_PUMP_DUTY 4
#define RYUJIN_INTERNAL_FAN_DUTY 5
@@ -69,10 +70,15 @@ static const u8 get_cooler_duty_cmd[] = { RYUJIN_CMD_PREFIX, 0x9A };
static const u8 get_controller_speed_cmd[] = { RYUJIN_CMD_PREFIX, 0xA0 };
static const u8 get_controller_duty_cmd[] = { RYUJIN_CMD_PREFIX, 0xA1 };
+#define RYUJIN_SET_COOLER_CHANNEL_OFFSET 2
#define RYUJIN_SET_COOLER_PUMP_DUTY_OFFSET 3
#define RYUJIN_SET_COOLER_FAN_DUTY_OFFSET 4
static const u8 set_cooler_duty_cmd[] = { RYUJIN_CMD_PREFIX, 0x1A, 0x00, 0x00, 0x00 };
+/* Pump control sources in the set cooler duty command and the cooler duty report */
+#define RYUJIN_SOURCE_HEADER 0
+#define RYUJIN_SOURCE_USB 1
+
#define RYUJIN_SET_CONTROLLER_FAN_DUTY_OFFSET 4
static const u8 set_controller_duty_cmd[] = { RYUJIN_CMD_PREFIX, 0x21, 0x00, 0x00, 0x00 };
@@ -116,6 +122,7 @@ struct rog_ryujin_data {
s32 temp_input[1];
u16 speed_input[6]; /* Pump, internal fan and four controller fan speeds in RPM */
u8 duty_input[3]; /* Pump, internal fan and controller fan duty in PWM */
+ u8 pump_source; /* Pump control source from the cooler duty report */
u8 *buffer;
unsigned long updated; /* jiffies */
@@ -305,6 +312,44 @@ static int rog_ryujin_read_string(struct device *dev, enum hwmon_sensor_types ty
return 0;
}
+/*
+ * On devices with a non-zero duty_channel (the RYUJIN III), the channel byte of
+ * the set cooler duty command selects the pump control source.
+ * RYUJIN_SOURCE_HEADER hands the pump to its internal controller, which follows
+ * the PWM of the header its 4-pin cable is plugged into. RYUJIN_SOURCE_USB
+ * makes the pump follow the pump duty in the command. The cooler duty report
+ * returns the current source.
+ *
+ * A fan duty write sends the reported source back, so that it leaves the pump
+ * control source as it is. A pump duty write selects USB. The cooler does not
+ * pass on a pump duty equal to the one it reports, and after power-on it
+ * reports 40% while a pump handed over at that duty runs at full speed. So
+ * when a pump duty write asks for the reported duty, write a duty 1% away
+ * first.
+ */
+static int rog_ryujin_select_pump_source(struct rog_ryujin_data *priv, u8 *set_cmd,
+ int channel)
+{
+ u8 duty = set_cmd[RYUJIN_SET_COOLER_PUMP_DUTY_OFFSET];
+ int ret;
+
+ if (channel == 1) {
+ set_cmd[RYUJIN_SET_COOLER_CHANNEL_OFFSET] = priv->pump_source;
+ return 0;
+ }
+
+ set_cmd[RYUJIN_SET_COOLER_CHANNEL_OFFSET] = RYUJIN_SOURCE_USB;
+
+ if (duty != rog_ryujin_pwm_to_percent(priv->duty_input[0]))
+ return 0;
+
+ set_cmd[RYUJIN_SET_COOLER_PUMP_DUTY_OFFSET] = duty < 100 ? duty + 1 : duty - 1;
+ ret = rog_ryujin_execute_cmd(priv, set_cmd, SET_CMD_LENGTH, &priv->cooler_duty_set);
+ set_cmd[RYUJIN_SET_COOLER_PUMP_DUTY_OFFSET] = duty;
+
+ return ret;
+}
+
static int rog_ryujin_write_fixed_duty(struct rog_ryujin_data *priv, int channel, int val)
{
u8 set_cmd[SET_CMD_LENGTH];
@@ -322,7 +367,7 @@ static int rog_ryujin_write_fixed_duty(struct rog_ryujin_data *priv, int channel
return ret;
memcpy(set_cmd, set_cooler_duty_cmd, SET_CMD_LENGTH);
- set_cmd[2] = priv->info->duty_channel;
+ set_cmd[RYUJIN_SET_COOLER_CHANNEL_OFFSET] = priv->info->duty_channel;
/* Cooler duties are set as 0-100% */
val = rog_ryujin_pwm_to_percent(val);
@@ -339,6 +384,12 @@ static int rog_ryujin_write_fixed_duty(struct rog_ryujin_data *priv, int channel
set_cmd[RYUJIN_SET_COOLER_FAN_DUTY_OFFSET] = val;
}
+ if (priv->info->duty_channel) {
+ ret = rog_ryujin_select_pump_source(priv, set_cmd, channel);
+ if (ret < 0)
+ return ret;
+ }
+
return rog_ryujin_execute_cmd(priv, set_cmd, SET_CMD_LENGTH, &priv->cooler_duty_set);
} else {
/*
@@ -481,6 +532,7 @@ static int rog_ryujin_raw_event(struct hid_device *hdev, struct hid_report *repo
goto unlock;
}
read_cooler_duty:
+ priv->pump_source = data[RYUJIN_PUMP_SOURCE];
priv->duty_input[0] = rog_ryujin_percent_to_pwm(data[RYUJIN_PUMP_DUTY]);
priv->duty_input[1] = rog_ryujin_percent_to_pwm(data[RYUJIN_INTERNAL_FAN_DUTY]);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 172/507] hwmon: (gpd-fan) Reset both fans to automatic on duo boards
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (170 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 171/507] hwmon: (asus_rog_ryujin) Fix pump control source on the Ryujin III Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 173/507] hwmon: chipcap2: fix command error diagnostics Greg Kroah-Hartman
` (334 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexei Solcanu, Antheas Kapenekakis,
Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexei Solcanu <alexei.solcanu@pm.me>
[ Upstream commit d1f60971fbf85c243ab6c78f6535fbc88fa640ce ]
On boards using gpd_duo_drvdata (GPD Duo, GPD Win 5), writing
pwm1_enable=2 only returns the first fan to EC control. The second fan
keeps its last manual duty cycle, e.g. full speed after pwm1=255, so a
fan control tool that exits leaves it running at that speed.
gpd_duo_write_pwm() writes both fan registers (pwm_write and
pwm_write + 1), but switching to automatic only clears pwm_write.
Also clear pwm_write + 1, so both fans return to EC control.
Tested on a GPD Win 5 (G1618-05). Not tested on the GPD Duo.
Fixes: 0ab88e239439 ("hwmon: add GPD devices sensor driver")
Cc: stable@vger.kernel.org
Signed-off-by: Alexei Solcanu <alexei.solcanu@pm.me>
Reviewed-by: Antheas Kapenekakis <lkml@antheas.dev>
Link: https://patch.msgid.link/20260926-gpd-fan-duo-auto-v2-1-0a2ea41ee3b5@pm.me
[groeck: Dropped obsolete 'Assisted-by: tag]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/gpd-fan.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/hwmon/gpd-fan.c b/drivers/hwmon/gpd-fan.c
index ed212615b2fe9..b3b75f99f5883 100644
--- a/drivers/hwmon/gpd-fan.c
+++ b/drivers/hwmon/gpd-fan.c
@@ -444,6 +444,7 @@ static void gpd_duo_set_pwm_enable(struct gpd_fan_data *data, enum FAN_PWM_ENABL
break;
case AUTOMATIC:
gpd_ecram_write(data->drvdata, data->drvdata->pwm_write, 0);
+ gpd_ecram_write(data->drvdata, data->drvdata->pwm_write + 1, 0);
break;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 173/507] hwmon: chipcap2: fix command error diagnostics
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (171 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 172/507] hwmon: (gpd-fan) Reset both fans to automatic on duo boards Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 174/507] hwmon: chipcap2: fix off-by-one in command mode retry loop Greg Kroah-Hartman
` (333 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
[ Upstream commit d0a03e1a2d9bd53b94fe6dff7a1a8058d25be82d ]
The command response field only contains bits 1:0, while the
error flags are stored in bits 2:5. The existing diagnostic
checks test the extracted response field, so they can never report
an error flag.
Test the full status byte for the error flags, and check the
configuration-load flag instead of RAM parity for the last diagnostic.
Fixes: 3af350929e75 ("hwmon: Add support for Amphenol ChipCap 2")
Cc: stable@vger.kernel.org
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Link: https://patch.msgid.link/20261014-chipcap2_locks-v3-1-27ebfc2c5b9e@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/chipcap2.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/chipcap2.c b/drivers/hwmon/chipcap2.c
index 9bef767b589ee..8550578928523 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -167,13 +167,13 @@ static int cc2_cmd_response_diagnostic(struct device *dev, u8 status)
case CC2_RESPONSE_BUSY:
return -EBUSY;
case CC2_RESPONSE_NACK:
- if (resp & CC2_ERR_CORR_EEPROM)
+ if (status & CC2_ERR_CORR_EEPROM)
dev_dbg(dev, "Command failed: corrected EEPROM\n");
- if (resp & CC2_ERR_UNCORR_EEPROM)
+ if (status & CC2_ERR_UNCORR_EEPROM)
dev_dbg(dev, "Command failed: uncorrected EEPROM\n");
- if (resp & CC2_ERR_RAM_PARITY)
+ if (status & CC2_ERR_RAM_PARITY)
dev_dbg(dev, "Command failed: RAM parity\n");
- if (resp & CC2_ERR_RAM_PARITY)
+ if (status & CC2_ERR_CONFIG_LOAD)
dev_dbg(dev, "Command failed: configuration error\n");
return -ENODATA;
default:
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 174/507] hwmon: chipcap2: fix off-by-one in command mode retry loop
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (172 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 173/507] hwmon: chipcap2: fix command error diagnostics Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 175/507] hwmon: chipcap2: fix be16 handling Greg Kroah-Hartman
` (332 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
[ Upstream commit 4c0e65a4ed665c416ccb1524c58a646a580e491f ]
i == CC2_CM_RETRIES can never be true inside the loop, since it
only runs while i < CC2_CM_RETRIES. Use CC2_CM_RETRIES - 1 so the
last failed retry breaks out immediately instead of doing a useless
disable + 80 ms power-cycle delay before the loop condition ends it
anyway.
Fixes: 3af350929e75 ("hwmon: Add support for Amphenol ChipCap 2")
Cc: stable@vger.kernel.org
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Link: https://patch.msgid.link/20261014-chipcap2_locks-v3-2-27ebfc2c5b9e@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/chipcap2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwmon/chipcap2.c b/drivers/hwmon/chipcap2.c
index 8550578928523..8102b6851d3d1 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -226,7 +226,7 @@ static int cc2_command_mode_start(struct cc2_data *data)
2 * CC2_RESP_START_CM_US);
}
ret = cc2_read_command_status(data->client);
- if (ret != -ETIMEDOUT || i == CC2_CM_RETRIES)
+ if (ret != -ETIMEDOUT || i == CC2_CM_RETRIES - 1)
break;
/* command window missed, prepare for a retry */
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 175/507] hwmon: chipcap2: fix be16 handling
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (173 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 174/507] hwmon: chipcap2: fix off-by-one in command mode retry loop Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 176/507] hwmon: chipcap2: defer probe when IRQs are unavailable Greg Kroah-Hartman
` (331 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
[ Upstream commit 36b07ddfe20b0fe06a8bc32c5e09974876fb5e42 ]
The driver currently only works correctly on little-endian
architectures when writing 16-bit register values.
Use i2c_smbus_write_word_swapped() for writes and get_unaligned_be16()
for reads to correctly handle the ChipCap 2's big-endian data format
on all architectures.
Fixes: 3af350929e75 ("hwmon: Add support for Amphenol ChipCap 2")
Cc: stable@vger.kernel.org
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Link: https://patch.msgid.link/20261014-chipcap2_locks-v3-3-27ebfc2c5b9e@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/chipcap2.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/chipcap2.c b/drivers/hwmon/chipcap2.c
index 8102b6851d3d1..aec4adf986584 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/module.h>
+#include <linux/unaligned.h>
#include <linux/regulator/consumer.h>
#include <linux/mod_devicetable.h>
#include <linux/property.h>
@@ -260,8 +261,7 @@ static int cc2_write_reg(struct cc2_data *data, u8 reg, u16 val)
if (ret < 0)
goto disable;
- cpu_to_be16s(&val);
- ret = i2c_smbus_write_word_data(data->client, reg, val);
+ ret = i2c_smbus_write_word_swapped(data->client, reg, val);
if (ret < 0)
goto disable;
@@ -311,7 +311,7 @@ static int cc2_read_reg(struct cc2_data *data, u8 reg, u16 *val)
if (ret != CC2_EEPROM_DATA_LEN)
return ret < 0 ? ret : -EIO;
- *val = be16_to_cpup((__be16 *)&buf[1]);
+ *val = get_unaligned_be16(&buf[1]);
return cc2_read_command_status(data->client);
}
@@ -351,10 +351,10 @@ static int cc2_data_fetch(struct i2c_client *client,
switch (type) {
case hwmon_humidity:
- *val = cc2_rh_convert(be16_to_cpup((__be16 *)&data[0]));
+ *val = cc2_rh_convert(get_unaligned_be16(&data[0]));
break;
case hwmon_temp:
- *val = cc2_temp_convert(be16_to_cpup((__be16 *)&data[2]));
+ *val = cc2_temp_convert(get_unaligned_be16(&data[2]));
break;
default:
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 176/507] hwmon: chipcap2: defer probe when IRQs are unavailable
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (174 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 7.3 175/507] hwmon: chipcap2: fix be16 handling Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 177/507] hwmon: chipcap2: fix IRQ teardown ordering Greg Kroah-Hartman
` (330 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
[ Upstream commit b5a1412618f93b594f924cf4f3b4bb6b5dc49d41 ]
This device can work with or without interrupts, but if they
are provided and still not available, but if -EPROBE_DEFER is read,
its value must be propagated to enable probe retries.
Fixes: 3af350929e75 ("hwmon: Add support for Amphenol ChipCap 2")
Cc: stable@vger.kernel.org
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Link: https://patch.msgid.link/20261014-chipcap2_locks-v3-4-27ebfc2c5b9e@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/chipcap2.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/hwmon/chipcap2.c b/drivers/hwmon/chipcap2.c
index aec4adf986584..37dbf6a76fbce 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -636,6 +636,8 @@ static int cc2_request_ready_irq(struct cc2_data *data, struct device *dev)
int ret = 0;
data->irq_ready = fwnode_irq_get_byname(dev_fwnode(dev), "ready");
+ if (data->irq_ready == -EPROBE_DEFER)
+ return data->irq_ready;
if (data->irq_ready > 0) {
init_completion(&data->complete);
ret = devm_request_threaded_irq(dev, data->irq_ready, NULL,
@@ -653,6 +655,8 @@ static int cc2_request_alarm_irqs(struct cc2_data *data, struct device *dev)
int ret = 0;
data->irq_low = fwnode_irq_get_byname(dev_fwnode(dev), "low");
+ if (data->irq_low == -EPROBE_DEFER)
+ return data->irq_low;
if (data->irq_low > 0) {
ret = devm_request_threaded_irq(dev, data->irq_low, NULL,
cc2_low_interrupt,
@@ -666,6 +670,8 @@ static int cc2_request_alarm_irqs(struct cc2_data *data, struct device *dev)
}
data->irq_high = fwnode_irq_get_byname(dev_fwnode(dev), "high");
+ if (data->irq_high == -EPROBE_DEFER)
+ return data->irq_high;
if (data->irq_high > 0) {
ret = devm_request_threaded_irq(dev, data->irq_high, NULL,
cc2_high_interrupt,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 177/507] hwmon: chipcap2: fix IRQ teardown ordering
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (175 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 176/507] hwmon: chipcap2: defer probe when IRQs are unavailable Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 178/507] hwmon: chipcap2: disable device after hwmon teardown Greg Kroah-Hartman
` (329 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
[ Upstream commit d2a66c515d7730fd453485ffb306c412f1f46d72 ]
The threaded IRQs are currently requested before the hwmon device
is registered. Since devres releases resources in reverse order,
the hwmon device is unregistered before the IRQs are freed during
driver teardown. An IRQ may therefore still run after the hwmon
device has been released and access the stale data->hwmon pointer.
Separate IRQ discovery from IRQ registration so that the IRQ numbers
and alarm visibility flags are initialized before registering the
hwmon device while the IRQs are released before the hwmon device
during devres cleanup.
Fixes: 3af350929e75 ("hwmon: Add support for Amphenol ChipCap 2")
Cc: stable@vger.kernel.org
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Link: https://patch.msgid.link/20261014-chipcap2_locks-v3-5-27ebfc2c5b9e@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/chipcap2.c | 52 ++++++++++++++++++++++++----------------
1 file changed, 32 insertions(+), 20 deletions(-)
diff --git a/drivers/hwmon/chipcap2.c b/drivers/hwmon/chipcap2.c
index 37dbf6a76fbce..21dc6db27c401 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -631,32 +631,47 @@ static int cc2_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
}
}
-static int cc2_request_ready_irq(struct cc2_data *data, struct device *dev)
+static int cc2_get_irqs(struct cc2_data *data, struct device *dev)
{
- int ret = 0;
-
data->irq_ready = fwnode_irq_get_byname(dev_fwnode(dev), "ready");
if (data->irq_ready == -EPROBE_DEFER)
return data->irq_ready;
- if (data->irq_ready > 0) {
+ if (data->irq_ready > 0)
init_completion(&data->complete);
+
+ data->irq_low = fwnode_irq_get_byname(dev_fwnode(dev), "low");
+ if (data->irq_low == -EPROBE_DEFER)
+ return data->irq_low;
+ if (data->irq_low > 0)
+ data->rh_alarm.low_alarm_visible = true;
+
+ data->irq_high = fwnode_irq_get_byname(dev_fwnode(dev), "high");
+ if (data->irq_high == -EPROBE_DEFER)
+ return data->irq_high;
+ if (data->irq_high > 0)
+ data->rh_alarm.high_alarm_visible = true;
+
+ return 0;
+}
+
+static int cc2_request_data_ready(struct cc2_data *data, struct device *dev)
+{
+ int ret = 0;
+
+ if (data->irq_ready > 0)
ret = devm_request_threaded_irq(dev, data->irq_ready, NULL,
cc2_ready_interrupt,
IRQF_ONESHOT |
IRQF_TRIGGER_RISING,
dev_name(dev), data);
- }
return ret;
}
-static int cc2_request_alarm_irqs(struct cc2_data *data, struct device *dev)
+static int cc2_request_alarms(struct cc2_data *data, struct device *dev)
{
int ret = 0;
- data->irq_low = fwnode_irq_get_byname(dev_fwnode(dev), "low");
- if (data->irq_low == -EPROBE_DEFER)
- return data->irq_low;
if (data->irq_low > 0) {
ret = devm_request_threaded_irq(dev, data->irq_low, NULL,
cc2_low_interrupt,
@@ -665,13 +680,8 @@ static int cc2_request_alarm_irqs(struct cc2_data *data, struct device *dev)
dev_name(dev), data);
if (ret)
return ret;
-
- data->rh_alarm.low_alarm_visible = true;
}
- data->irq_high = fwnode_irq_get_byname(dev_fwnode(dev), "high");
- if (data->irq_high == -EPROBE_DEFER)
- return data->irq_high;
if (data->irq_high > 0) {
ret = devm_request_threaded_irq(dev, data->irq_high, NULL,
cc2_high_interrupt,
@@ -680,8 +690,6 @@ static int cc2_request_alarm_irqs(struct cc2_data *data, struct device *dev)
dev_name(dev), data);
if (ret)
return ret;
-
- data->rh_alarm.high_alarm_visible = true;
}
return ret;
@@ -732,13 +740,13 @@ static int cc2_probe(struct i2c_client *client)
device_property_read_string(dev, "label", &data->label);
- ret = cc2_request_ready_irq(data, dev);
+ ret = cc2_get_irqs(data, dev);
if (ret)
- return dev_err_probe(dev, ret, "Failed to request ready irq\n");
+ return dev_err_probe(dev, ret, "Failed to get IRQs\n");
- ret = cc2_request_alarm_irqs(data, dev);
+ ret = cc2_request_data_ready(data, dev);
if (ret)
- return dev_err_probe(dev, ret, "Failed to request alarm irqs\n");
+ return dev_err_probe(dev, ret, "Failed to request ready irq\n");
data->hwmon = devm_hwmon_device_register_with_info(dev, client->name,
data, &cc2_chip_info,
@@ -747,6 +755,10 @@ static int cc2_probe(struct i2c_client *client)
return dev_err_probe(dev, PTR_ERR(data->hwmon),
"Failed to register hwmon device\n");
+ ret = cc2_request_alarms(data, dev);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to request alarm irqs\n");
+
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 178/507] hwmon: chipcap2: disable device after hwmon teardown
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (176 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 177/507] hwmon: chipcap2: fix IRQ teardown ordering Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 179/507] hwmon: chipcap2: enable IRQ processing when regulator is already enabled Greg Kroah-Hartman
` (328 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
[ Upstream commit 4724ac5556ce63f01a3f5d61fc7fcc20f4ddef3f ]
cc2_remove() disables the device while the device-managed hwmon device is
still registered. A concurrent sysfs callback can then enable the device
after it has been disabled during removal.
Register a device-managed disable action before registering the hwmon
device, so devres unregisters the hwmon device before disabling the
physical device.
Fixes: 3af350929e75 ("hwmon: Add support for Amphenol ChipCap 2")
Cc: stable@vger.kernel.org
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Link: https://patch.msgid.link/20261014-chipcap2_locks-v3-6-27ebfc2c5b9e@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/chipcap2.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/hwmon/chipcap2.c b/drivers/hwmon/chipcap2.c
index 21dc6db27c401..654f6420da7ab 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -152,6 +152,11 @@ static void cc2_disable(struct cc2_data *data)
}
}
+static void cc2_disable_action(void *data)
+{
+ cc2_disable(data);
+}
+
static int cc2_cmd_response_diagnostic(struct device *dev, u8 status)
{
int resp;
@@ -744,6 +749,10 @@ static int cc2_probe(struct i2c_client *client)
if (ret)
return dev_err_probe(dev, ret, "Failed to get IRQs\n");
+ ret = devm_add_action_or_reset(dev, cc2_disable_action, data);
+ if (ret)
+ return ret;
+
ret = cc2_request_data_ready(data, dev);
if (ret)
return dev_err_probe(dev, ret, "Failed to request ready irq\n");
@@ -762,13 +771,6 @@ static int cc2_probe(struct i2c_client *client)
return 0;
}
-static void cc2_remove(struct i2c_client *client)
-{
- struct cc2_data *data = i2c_get_clientdata(client);
-
- cc2_disable(data);
-}
-
static const struct i2c_device_id cc2_id[] = {
{ .name = "cc2d23" },
{ .name = "cc2d23s" },
@@ -801,7 +803,6 @@ static struct i2c_driver cc2_driver = {
.of_match_table = cc2_of_match,
},
.probe = cc2_probe,
- .remove = cc2_remove,
.id_table = cc2_id,
};
module_i2c_driver(cc2_driver);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 179/507] hwmon: chipcap2: enable IRQ processing when regulator is already enabled
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (177 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 178/507] hwmon: chipcap2: disable device after hwmon teardown Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 180/507] hwmon: chipcap2: balance regulator state Greg Kroah-Hartman
` (327 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
[ Upstream commit d1ce827a9cc11ffdfec77b7fec9b73a8020a308d ]
cc2_enable() returns early when the regulator is already enabled.
This can happen if a previous regulator_disable() failed or if the
regulator was configured as always-on.
In this case, process_irqs remains false, causing the ready interrupt
to be ignored. Subsequent operations waiting for the ready completion
then time out.
Set process_irqs before returning when the regulator is already
enabled, so that the driver continues to process ready interrupts.
Fixes: 3af350929e75 ("hwmon: Add support for Amphenol ChipCap 2")
Cc: stable@vger.kernel.org
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Link: https://patch.msgid.link/20261014-chipcap2_locks-v3-7-27ebfc2c5b9e@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/chipcap2.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/chipcap2.c b/drivers/hwmon/chipcap2.c
index 654f6420da7ab..837b1830f2e4e 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -120,8 +120,10 @@ static int cc2_enable(struct cc2_data *data)
int ret;
/* exclusive regulator, check in case a disable failed */
- if (regulator_is_enabled(data->regulator))
+ if (regulator_is_enabled(data->regulator)) {
+ data->process_irqs = true;
return 0;
+ }
/* clear any pending completion */
try_wait_for_completion(&data->complete);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 180/507] hwmon: chipcap2: balance regulator state
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (178 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 179/507] hwmon: chipcap2: enable IRQ processing when regulator is already enabled Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 181/507] hwmon: chipcap2: do not discard pending alarms on disable Greg Kroah-Hartman
` (326 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
[ Upstream commit 378add65fd7d352de9fe440d167fde5bf511b090 ]
The current implementation does not guarantee that the calls to
regulator_enable() and regulator_disable() are balanced.
regulator_is_enabled() might return a negative value, and an always-on
attribute in the DT might break the symmetry anyway.
Add a regulator_enabled flag to keep balance within this regulator
consumer.
Fixes: 3af350929e75 ("hwmon: Add support for Amphenol ChipCap 2")
Cc: stable@vger.kernel.org
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Link: https://patch.msgid.link/20261014-chipcap2_locks-v3-8-27ebfc2c5b9e@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/chipcap2.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/chipcap2.c b/drivers/hwmon/chipcap2.c
index 837b1830f2e4e..952789fdb9db6 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -91,6 +91,7 @@ struct cc2_data {
int irq_low;
int irq_high;
bool process_irqs;
+ bool regulator_enabled;
};
/* %RH as a per cent mille from a register value */
@@ -120,7 +121,7 @@ static int cc2_enable(struct cc2_data *data)
int ret;
/* exclusive regulator, check in case a disable failed */
- if (regulator_is_enabled(data->regulator)) {
+ if (data->regulator_enabled) {
data->process_irqs = true;
return 0;
}
@@ -132,6 +133,8 @@ static int cc2_enable(struct cc2_data *data)
if (ret < 0)
return ret;
+ data->regulator_enabled = true;
+
usleep_range(CC2_STARTUP_TIME_US, CC2_STARTUP_TIME_US + 125);
data->process_irqs = true;
@@ -147,11 +150,16 @@ static void cc2_disable(struct cc2_data *data)
data->process_irqs = false;
/* exclusive regulator, check in case an enable failed */
- if (regulator_is_enabled(data->regulator)) {
- err = regulator_disable(data->regulator);
- if (err)
- dev_dbg(&data->client->dev, "Failed to disable device");
+ if (!data->regulator_enabled)
+ return;
+
+ err = regulator_disable(data->regulator);
+ if (err) {
+ dev_dbg(&data->client->dev, "Failed to disable device");
+ return;
}
+
+ data->regulator_enabled = false;
}
static void cc2_disable_action(void *data)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 181/507] hwmon: chipcap2: do not discard pending alarms on disable
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (179 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 180/507] hwmon: chipcap2: balance regulator state Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 182/507] hwmon: chipcap2: serialize access to the alarm indicators Greg Kroah-Hartman
` (325 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
[ Upstream commit 22aecf164e1c0c849808c342c65322d14f45176f ]
cc2_disable() stops processing interrupts before the device is powered
down to ignore the alarms caused by voltage toggling. The handler of an
alarm raised by the last measurement might not have run at that point,
and the alarm is discarded when it finally does.
The sysfs read that triggered the measurement can then report no alarm
although the device raised one.
Wait for the alarm handlers that have already been raised before the
interrupt processing is stopped. This covers the case where the handler
thread has not been scheduled yet; an alarm that has not reached the
interrupt core at that point is discarded.
Fixes: 3af350929e75 ("hwmon: Add support for Amphenol ChipCap 2")
Cc: stable@vger.kernel.org
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Link: https://patch.msgid.link/20261014-chipcap2_locks-v3-9-27ebfc2c5b9e@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/chipcap2.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/hwmon/chipcap2.c b/drivers/hwmon/chipcap2.c
index 952789fdb9db6..eba6469940ab5 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -146,6 +146,13 @@ static void cc2_disable(struct cc2_data *data)
{
int err;
+ /* let the alarms already raised by the last measurement be processed */
+ if (data->irq_low > 0)
+ synchronize_irq(data->irq_low);
+
+ if (data->irq_high > 0)
+ synchronize_irq(data->irq_high);
+
/* ignore alarms triggered by voltage toggling when powering up */
data->process_irqs = false;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 182/507] hwmon: chipcap2: serialize access to the alarm indicators
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (180 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 181/507] hwmon: chipcap2: do not discard pending alarms on disable Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 183/507] hwmon: chipcap2: synchronize ready IRQ state Greg Kroah-Hartman
` (324 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
[ Upstream commit bed5f0c075eb99442fca6a61c009a32752eceda2 ]
low_alarm and high_alarm are accessed from the threaded interrupt
handlers and from sysfs without any locking, which can lead to lost
alarms.
Add a mutex to serialize the access to the alarm indicators and to
process_irqs, which the handlers use to decide whether an interrupt
belongs to an ongoing operation.
Fixes: 3af350929e75 ("hwmon: Add support for Amphenol ChipCap 2")
Cc: stable@vger.kernel.org
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Link: https://patch.msgid.link/20261014-chipcap2_locks-v3-10-27ebfc2c5b9e@gmail.com
[groeck: Dropped obsolete 'Assisted-by: tag]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/chipcap2.c | 58 +++++++++++++++++++++++++---------------
1 file changed, 37 insertions(+), 21 deletions(-)
diff --git a/drivers/hwmon/chipcap2.c b/drivers/hwmon/chipcap2.c
index eba6469940ab5..b3b725cc7224f 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -20,6 +20,7 @@
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/unaligned.h>
#include <linux/regulator/consumer.h>
@@ -91,6 +92,8 @@ struct cc2_data {
int irq_low;
int irq_high;
bool process_irqs;
+ /* protects process_irqs and the alarm indicators */
+ struct mutex irq_lock;
bool regulator_enabled;
};
@@ -122,7 +125,8 @@ static int cc2_enable(struct cc2_data *data)
/* exclusive regulator, check in case a disable failed */
if (data->regulator_enabled) {
- data->process_irqs = true;
+ scoped_guard(mutex, &data->irq_lock)
+ data->process_irqs = true;
return 0;
}
@@ -137,7 +141,8 @@ static int cc2_enable(struct cc2_data *data)
usleep_range(CC2_STARTUP_TIME_US, CC2_STARTUP_TIME_US + 125);
- data->process_irqs = true;
+ scoped_guard(mutex, &data->irq_lock)
+ data->process_irqs = true;
return 0;
}
@@ -154,7 +159,8 @@ static void cc2_disable(struct cc2_data *data)
synchronize_irq(data->irq_high);
/* ignore alarms triggered by voltage toggling when powering up */
- data->process_irqs = false;
+ scoped_guard(mutex, &data->irq_lock)
+ data->process_irqs = false;
/* exclusive regulator, check in case an enable failed */
if (!data->regulator_enabled)
@@ -514,10 +520,12 @@ static irqreturn_t cc2_low_interrupt(int irq, void *data)
{
struct cc2_data *cc2 = data;
- if (cc2->process_irqs) {
- hwmon_notify_event(cc2->hwmon, hwmon_humidity,
- hwmon_humidity_min_alarm, 0);
- cc2->rh_alarm.low_alarm = true;
+ scoped_guard(mutex, &cc2->irq_lock) {
+ if (cc2->process_irqs) {
+ hwmon_notify_event(cc2->hwmon, hwmon_humidity,
+ hwmon_humidity_min_alarm, 0);
+ cc2->rh_alarm.low_alarm = true;
+ }
}
return IRQ_HANDLED;
@@ -527,10 +535,12 @@ static irqreturn_t cc2_high_interrupt(int irq, void *data)
{
struct cc2_data *cc2 = data;
- if (cc2->process_irqs) {
- hwmon_notify_event(cc2->hwmon, hwmon_humidity,
- hwmon_humidity_max_alarm, 0);
- cc2->rh_alarm.high_alarm = true;
+ scoped_guard(mutex, &cc2->irq_lock) {
+ if (cc2->process_irqs) {
+ hwmon_notify_event(cc2->hwmon, hwmon_humidity,
+ hwmon_humidity_max_alarm, 0);
+ cc2->rh_alarm.high_alarm = true;
+ }
}
return IRQ_HANDLED;
@@ -546,11 +556,13 @@ static int cc2_humidity_min_alarm_status(struct cc2_data *data, long *val)
if (ret < 0)
return ret;
- if (data->rh_alarm.low_alarm) {
- *val = (measurement < min_hyst) ? 1 : 0;
- data->rh_alarm.low_alarm = *val;
- } else {
- *val = 0;
+ scoped_guard(mutex, &data->irq_lock) {
+ if (data->rh_alarm.low_alarm) {
+ *val = (measurement < min_hyst) ? 1 : 0;
+ data->rh_alarm.low_alarm = *val;
+ } else {
+ *val = 0;
+ }
}
return 0;
@@ -566,11 +578,13 @@ static int cc2_humidity_max_alarm_status(struct cc2_data *data, long *val)
if (ret < 0)
return ret;
- if (data->rh_alarm.high_alarm) {
- *val = (measurement > max_hyst) ? 1 : 0;
- data->rh_alarm.high_alarm = *val;
- } else {
- *val = 0;
+ scoped_guard(mutex, &data->irq_lock) {
+ if (data->rh_alarm.high_alarm) {
+ *val = (measurement > max_hyst) ? 1 : 0;
+ data->rh_alarm.high_alarm = *val;
+ } else {
+ *val = 0;
+ }
}
return 0;
@@ -753,6 +767,8 @@ static int cc2_probe(struct i2c_client *client)
i2c_set_clientdata(client, data);
+ mutex_init(&data->irq_lock);
+
data->client = client;
data->regulator = devm_regulator_get_exclusive(dev, "vdd");
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 183/507] hwmon: chipcap2: synchronize ready IRQ state
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (181 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 182/507] hwmon: chipcap2: serialize access to the alarm indicators Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 184/507] hwmon: (aquacomputer_d5next) Check maxcollection when probing AQUAERO devices Greg Kroah-Hartman
` (323 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
[ Upstream commit 8c02722be2caa6604a837b81faeaba78250eda4a ]
The ready IRQ handler can race with reinit_completion() in the enable
path. In particular, a handler from an earlier operation can complete
the completion after it is reset for a new operation.
Use irq_lock to serialize access to the completion and process_irqs.
Disable IRQ processing and synchronize any running handler before resetting
the completion for a new operation.
Fixes: 3af350929e75 ("hwmon: Add support for Amphenol ChipCap 2")
Cc: stable@vger.kernel.org
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Link: https://patch.msgid.link/20261014-chipcap2_locks-v3-11-27ebfc2c5b9e@gmail.com
[groeck: Dropped obsolete 'Assisted-by: tag]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/chipcap2.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/chipcap2.c b/drivers/hwmon/chipcap2.c
index b3b725cc7224f..00f62a33d4637 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -123,6 +123,16 @@ static int cc2_enable(struct cc2_data *data)
{
int ret;
+ if (data->irq_ready > 0) {
+ scoped_guard(mutex, &data->irq_lock)
+ data->process_irqs = false;
+
+ synchronize_irq(data->irq_ready);
+
+ scoped_guard(mutex, &data->irq_lock)
+ reinit_completion(&data->complete);
+ }
+
/* exclusive regulator, check in case a disable failed */
if (data->regulator_enabled) {
scoped_guard(mutex, &data->irq_lock)
@@ -130,9 +140,6 @@ static int cc2_enable(struct cc2_data *data)
return 0;
}
- /* clear any pending completion */
- try_wait_for_completion(&data->complete);
-
ret = regulator_enable(data->regulator);
if (ret < 0)
return ret;
@@ -162,6 +169,9 @@ static void cc2_disable(struct cc2_data *data)
scoped_guard(mutex, &data->irq_lock)
data->process_irqs = false;
+ if (data->irq_ready > 0)
+ synchronize_irq(data->irq_ready);
+
/* exclusive regulator, check in case an enable failed */
if (!data->regulator_enabled)
return;
@@ -510,8 +520,10 @@ static irqreturn_t cc2_ready_interrupt(int irq, void *data)
{
struct cc2_data *cc2 = data;
- if (cc2->process_irqs)
- complete(&cc2->complete);
+ scoped_guard(mutex, &cc2->irq_lock) {
+ if (cc2->process_irqs)
+ complete(&cc2->complete);
+ }
return IRQ_HANDLED;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 184/507] hwmon: (aquacomputer_d5next) Check maxcollection when probing AQUAERO devices
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (182 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 183/507] hwmon: chipcap2: synchronize ready IRQ state Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 185/507] hwmon: (asus_wmi_sensors) Avoid global struct mutation Greg Kroah-Hartman
` (322 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aleksa Savic, Jack Doan,
Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit b7743c6dbe3ab94045164ef298f65cfb9b0b450a ]
When a USB HID device matching USB_PRODUCT_ID_AQUAERO presents a
malformed report descriptor, an out-of-bounds array access occurs in
aqc_probe() due to an unchecked index into the parsed collections array.
During device initialization, the driver distinguishes between the
multiple logical interfaces exposed by the Aquaero device by evaluating
the type of the second element in the collection array. The driver
unconditionally accesses hdev->collection[1] without verifying that
hdev->maxcollection is greater than 1. Because the collection array is
dynamically allocated by the HID core based on the number of collections
found in the report descriptor, a crafted device exposing fewer than two
collections causes an immediate heap out-of-bounds read or NULL pointer
dereference. This leads to a kernel panic during the device probe phase.
Add the missing check to fix the problem.
Fixes: 2c55211104b4 ("hwmon: (aquacomputer_d5next) Support sensors for Aquacomputer Aquaero")
Cc: stable@vger.kernel.org
Cc: Aleksa Savic <savicaleksa83@gmail.com>
Cc: Jack Doan <me@jackdoan.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/aquacomputer_d5next.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c
index 341cce4347e24..6565731b0e71f 100644
--- a/drivers/hwmon/aquacomputer_d5next.c
+++ b/drivers/hwmon/aquacomputer_d5next.c
@@ -1570,7 +1570,7 @@ static int aqc_probe(struct hid_device *hdev, const struct hid_device_id *id)
* they present. The two other devices have the type of the second element in
* their respective collections set to 1, while the real device has it set to 0.
*/
- if (hdev->collection[1].type != 0) {
+ if (hdev->maxcollection < 2 || hdev->collection[1].type != 0) {
ret = -ENODEV;
goto fail_and_close;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 185/507] hwmon: (asus_wmi_sensors) Avoid global struct mutation
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (183 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 184/507] hwmon: (aquacomputer_d5next) Check maxcollection when probing AQUAERO devices Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 186/507] hwmon: (hp-wmi-sensors) " Greg Kroah-Hartman
` (321 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ed Brindley, Denis Pauk,
Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 59d586c9e47d1205563bc9b5a5d443adc3ba5bc5 ]
In the asus_wmi_sensors driver, device-managed memory allocated in
asus_wmi_configure_sensor_setup() is assigned to a global static structure,
leading to a potential use-after-free when the device is unbound.
The driver defines a single global asus_wmi_chip_info structure to register
with the hwmon core. During probe, it dynamically allocates the .info
channel array using devm_kcalloc() and assigns it directly to this global
structure. When a device is unbound, its device-managed memory is
automatically freed, leaving asus_wmi_chip_info.info as a dangling pointer.
Furthermore, if multiple WMI devices are probed sequentially, each probe
overwrites the same global pointer, forcing all registered hwmon instances
to reference the channel information of the most recently probed device.
While it is unlikely if not impossible that multiple WMI devices of the same
kind exist, modifying a global static data structure is undesirable. Remove
the static data structure and allocate it as part of struct asus_wmi_sensors
to avoid the potential problem.
Fixes: 548820e21ce1 ("hwmon: (asus_wmi_sensors) Support X370 Asus WMI.")
Cc: stable@vger.kernel.org
Cc: Ed Brindley <kernel@maidavale.org>
Cc: Denis Pauk <pauk.denis@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/asus_wmi_sensors.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/drivers/hwmon/asus_wmi_sensors.c b/drivers/hwmon/asus_wmi_sensors.c
index c2dd7ff882f24..502996e97cf14 100644
--- a/drivers/hwmon/asus_wmi_sensors.c
+++ b/drivers/hwmon/asus_wmi_sensors.c
@@ -164,6 +164,7 @@ struct asus_wmi_wmi_info {
struct asus_wmi_sensors {
struct asus_wmi_wmi_info wmi;
+ struct hwmon_chip_info chip_info;
/* lock access to internal cache */
struct mutex lock;
};
@@ -496,11 +497,6 @@ static const struct hwmon_ops asus_wmi_hwmon_ops = {
.read_string = asus_wmi_hwmon_read_string,
};
-static struct hwmon_chip_info asus_wmi_chip_info = {
- .ops = &asus_wmi_hwmon_ops,
- .info = NULL,
-};
-
static int asus_wmi_configure_sensor_setup(struct device *dev,
struct asus_wmi_sensors *sensor_data)
{
@@ -508,7 +504,7 @@ static int asus_wmi_configure_sensor_setup(struct device *dev,
struct hwmon_channel_info *asus_wmi_hwmon_chan;
int nr_count[hwmon_max] = {}, nr_types = 0;
struct asus_wmi_sensor_info *temp_sensor;
- const struct hwmon_chip_info *chip_info;
+ struct hwmon_chip_info *chip_info;
enum hwmon_sensor_types type;
struct device *hwdev;
int i, idx;
@@ -549,8 +545,9 @@ static int asus_wmi_configure_sensor_setup(struct device *dev,
if (!ptr_asus_wmi_ci)
return -ENOMEM;
- asus_wmi_chip_info.info = ptr_asus_wmi_ci;
- chip_info = &asus_wmi_chip_info;
+ chip_info = &sensor_data->chip_info;
+ chip_info->ops = &asus_wmi_hwmon_ops;
+ chip_info->info = ptr_asus_wmi_ci;
sensor_data->wmi.info_by_id = devm_kcalloc(dev, sensor_data->wmi.sensor_count,
sizeof(*sensor_data->wmi.info_by_id),
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 186/507] hwmon: (hp-wmi-sensors) Avoid global struct mutation
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (184 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 185/507] hwmon: (asus_wmi_sensors) Avoid global struct mutation Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 187/507] hwmon: (hp-wmi-sensors) Fix unbounded loops in scale_numeric_sensor() Greg Kroah-Hartman
` (320 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, James Seo, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit dc992efeace99e479aec7a8f0c49a9493c729606 ]
In the HP WMI sensors driver, make_chip_info() assigns a device-managed
memory allocation to a static global structure, resulting in a
use-after-free when the device unbinds.
During hp_wmi_sensors_probe(), make_chip_info() dynamically allocates a
hwmon_channel_info array using devm_kcalloc() and assigns it to the
static global hp_wmi_chip_info.info pointer.
If multiple instances probe sequentially or concurrently, the shared
global pointer is overwritten by each new device. When any device unbinds,
its devm-managed memory is automatically freed, leaving the global
hp_wmi_chip_info struct and any other active device instances with a
dangling pointer. Subsequent accesses by the hwmon core (such as thermal
zone reads) will dereference this freed memory, causing a use-after-free.
While this is not supposed to happen in the real world (there should only
be one instance of the driver in any system), modifying global structures
is undesirable and should be avoided whenever possible. Allocate struct
hwmon_chip_info as part of struct hp_wmi_sensors instead and initialize it
in make_chip_info() to avoid mutating the global structure.
Fixes: 23902f98f8d4 ("hwmon: add HP WMI Sensors driver")
Cc: stable@vger.kernel.org
Cc: James Seo <james@equiv.tech>
Acked-by: James Seo <james@equiv.tech
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/hp-wmi-sensors.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/drivers/hwmon/hp-wmi-sensors.c b/drivers/hwmon/hp-wmi-sensors.c
index cfa0d6ad0fb3f..dd1fa48314a54 100644
--- a/drivers/hwmon/hp-wmi-sensors.c
+++ b/drivers/hwmon/hp-wmi-sensors.c
@@ -390,6 +390,7 @@ struct hp_wmi_info {
*/
struct hp_wmi_sensors {
struct wmi_device *wdev;
+ struct hwmon_chip_info chip_info;
struct hp_wmi_info **info_map[hwmon_max];
u8 channel_count[hwmon_max];
bool has_intrusion;
@@ -1531,11 +1532,6 @@ static const struct hwmon_ops hp_wmi_hwmon_ops = {
.write = hp_wmi_hwmon_write,
};
-static struct hwmon_chip_info hp_wmi_chip_info = {
- .ops = &hp_wmi_hwmon_ops,
- .info = NULL,
-};
-
static struct hp_wmi_info *match_fan_event(struct hp_wmi_sensors *state,
const char *event_description)
{
@@ -1962,7 +1958,8 @@ static int make_chip_info(struct hp_wmi_sensors *state, bool has_events)
if (!ptr_channel_info)
return -ENOMEM;
- hp_wmi_chip_info.info = ptr_channel_info;
+ state->chip_info.ops = &hp_wmi_hwmon_ops;
+ state->chip_info.info = ptr_channel_info;
for (type = hwmon_chip; type < hwmon_max; type++) {
count = channel_count[type];
@@ -2053,7 +2050,7 @@ static int hp_wmi_sensors_init(struct hp_wmi_sensors *state)
return err;
hwdev = devm_hwmon_device_register_with_info(dev, "hp_wmi_sensors",
- state, &hp_wmi_chip_info,
+ state, &state->chip_info,
NULL);
return PTR_ERR_OR_ZERO(hwdev);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 187/507] hwmon: (hp-wmi-sensors) Fix unbounded loops in scale_numeric_sensor()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (185 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 186/507] hwmon: (hp-wmi-sensors) " Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 188/507] hwmon: (lm87) Fix drvdata type confusion in vrm_show() and vrm_store() Greg Kroah-Hartman
` (319 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, James Seo, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 185039b1c0389b70ec52a6d3e3c1494e2d0e23da ]
In scale_numeric_sensor() in the hp-wmi-sensors hwmon driver, an unbounded
loop occurs if the ACPI WMI implementation provides a highly anomalous or
malformed UnitModifier value for a numeric sensor.
The UnitModifier property is extracted from a WMI ACPI object without
bounds checking and cast to a signed 32-bit integer. This value directly
controls the iteration count of two scaling loops. If the provided
unit_modifier is extremely negative (e.g., INT_MIN), the first loop
executes billions of times before reaching target_modifier. Conversely,
if unit_modifier is extremely large (e.g., INT_MAX) and the current
sensor reading (val) is exactly 0, the second loop's overflow safeguard
(val > LONG_MAX / 10) never evaluates to true, resulting in billions of
unnecessary iterations. This prolonged execution causes severe CPU stalls
and thread soft lockups during driver initialization or whenever a
user-space process reads the sensor attribute via sysfs, resulting in a
denial of service on the affected CPU core.
Fix the problem in the first loop by exiting it as soon as val is zero.
Fix the problem with the second loop by only entering it if val is not
zero. Also add a check for val < LONG_MIN / 10 and exit the loop if that
is the case.
Fixes: 23902f98f8d4 ("hwmon: add HP WMI Sensors driver")
Cc: stable@vger.kernel.org
Cc: James Seo <james@equiv.tech>
Acked-by: James Seo <james@equiv.tech>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/hp-wmi-sensors.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/hwmon/hp-wmi-sensors.c b/drivers/hwmon/hp-wmi-sensors.c
index dd1fa48314a54..12950666c9810 100644
--- a/drivers/hwmon/hp-wmi-sensors.c
+++ b/drivers/hwmon/hp-wmi-sensors.c
@@ -739,15 +739,21 @@ static long scale_numeric_sensor(const struct hp_wmi_numeric_sensor *nsensor)
val = current_reading;
- for (; unit_modifier < target_modifier; unit_modifier++)
+ for (; val && unit_modifier < target_modifier; unit_modifier++)
val = DIV_ROUND_CLOSEST(val, 10);
- for (; unit_modifier > target_modifier; unit_modifier--) {
- if (val > LONG_MAX / 10) {
- val = LONG_MAX;
- break;
+ if (val) {
+ for (; unit_modifier > target_modifier; unit_modifier--) {
+ if (val > LONG_MAX / 10) {
+ val = LONG_MAX;
+ break;
+ }
+ if (val < LONG_MIN / 10) {
+ val = LONG_MIN;
+ break;
+ }
+ val *= 10;
}
- val *= 10;
}
if (sensor_type == HP_WMI_TYPE_TEMPERATURE) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 188/507] hwmon: (lm87) Fix drvdata type confusion in vrm_show() and vrm_store()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (186 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 187/507] hwmon: (hp-wmi-sensors) Fix unbounded loops in scale_numeric_sensor() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 189/507] hwmon: (nct6683) Fix incorrect struct cast in show_pwm() and store_pwm() Greg Kroah-Hartman
` (318 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 5b51ff0887b9f88d042b92dd07fcdda4132f0ebc ]
When an LM87 or ADM1024 device is probed with VID support enabled, reading
from or writing to the vrm sysfs attribute triggers a driver data type
confusion in vrm_show() and vrm_store() in drivers/hwmon/lm87.c.
In lm87_probe(), the driver stores the struct lm87_data pointer on the I2C
client via i2c_set_clientdata() and passes the struct i2c_client pointer as
the drvdata argument to devm_hwmon_device_register_with_groups(), which
attaches the attribute groups to the registered hwmon device with client as
its driver_data. Unlike the other sysfs callbacks that retrieve client via
dev_get_drvdata() and then obtain data via i2c_get_clientdata(), vrm_show()
and vrm_store() assign dev_get_drvdata(dev) directly to struct lm87_data *.
Dereferencing data->vrm therefore accesses the struct i2c_client instance
at offsetof(struct lm87_data, vrm), causing vrm_show() to leak an unrelated
byte from struct i2c_client to userspace and vrm_store() to corrupt a byte
within struct i2c_client while failing to update the actual VRM value.
Fix the problem by assigning the return value from dev_get_drvdata(dev) to
struct i2c_client *client and using i2c_get_clientdata() to get the actual
client data.
Fixes: 00a0c905ab4b ("hwmon: (lm87) Use hwmon to create the sysfs groups")
Cc: stable@vger.kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/lm87.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c
index c09074f447083..bb4e15b663557 100644
--- a/drivers/hwmon/lm87.c
+++ b/drivers/hwmon/lm87.c
@@ -606,13 +606,16 @@ static DEVICE_ATTR_RO(cpu0_vid);
static ssize_t vrm_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct lm87_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = dev_get_drvdata(dev);
+ struct lm87_data *data = i2c_get_clientdata(client);
+
return sprintf(buf, "%d\n", data->vrm);
}
static ssize_t vrm_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
- struct lm87_data *data = dev_get_drvdata(dev);
+ struct i2c_client *client = dev_get_drvdata(dev);
+ struct lm87_data *data = i2c_get_clientdata(client);
unsigned long val;
int err;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 189/507] hwmon: (nct6683) Fix incorrect struct cast in show_pwm() and store_pwm()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (187 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 188/507] hwmon: (lm87) Fix drvdata type confusion in vrm_show() and vrm_store() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 190/507] hwmon: (peci/dimmtemp) Fix devres leak and UAF on concurrent unbind Greg Kroah-Hartman
` (317 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit c4a01c2a80b203ab5f80885f6994346fe217f19c ]
On big-endian architectures, reading or writing the pwm[1-8] sysfs
attributes in the nct6683 hardware monitoring driver always redirects to
channel 0 due to an incorrect struct downcast in show_pwm() and
store_pwm().
The driver defines the PWM sysfs attributes using SENSOR_TEMPLATE(),
which initializes them as struct sensor_device_attribute (where the index
is a 32-bit int). However, the sysfs callbacks show_pwm() and store_pwm()
incorrectly downcast the attribute to a struct sensor_device_attribute_2
(where the index is an 8-bit u8). Because both structs start with struct
device_attribute, container_of() resolves to the same base address. On
big-endian architectures, reading the 8-bit index field from the memory
layout of a 32-bit int fetches the most significant byte (which is 0),
rather than the intended channel number.
This type mismatch causes all PWM reads to return data for channel 0, and
any writes intended to configure other channels will silently overwrite the
duty cycle of PWM channel 0 instead.
Fix the type casts in show_pwm() and store_pwm() to solve the problem.
Fixes: 41082d66bfd6 ("hwmon: Driver for NCT6683D")
Cc: stable@vger.kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/nct6683.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/nct6683.c b/drivers/hwmon/nct6683.c
index e1c36c95affb2..f34cb62305be8 100644
--- a/drivers/hwmon/nct6683.c
+++ b/drivers/hwmon/nct6683.c
@@ -920,7 +920,7 @@ static ssize_t
show_pwm(struct device *dev, struct device_attribute *attr, char *buf)
{
struct nct6683_data *data = nct6683_update_device(dev);
- struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+ struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
int index = sattr->index;
return sprintf(buf, "%d\n", data->pwm[index]);
@@ -930,7 +930,7 @@ static ssize_t
store_pwm(struct device *dev, struct device_attribute *attr, const char *buf,
size_t count)
{
- struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
+ struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
struct nct6683_data *data = dev_get_drvdata(dev);
int index = sattr->index;
unsigned long val;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 190/507] hwmon: (peci/dimmtemp) Fix devres leak and UAF on concurrent unbind
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (188 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 189/507] hwmon: (nct6683) Fix incorrect struct cast in show_pwm() and store_pwm() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 191/507] hwmon: (pmbus/q54sj108a2) Add missing NULL pointer check Greg Kroah-Hartman
` (316 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Iwona Winiarska, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 61bc4514b8e99e9733c04de028885f6fc906d628 ]
When a peci_dimmtemp device is unbound concurrently with its delayed
initialization work (detect_work), newly allocated devm resources and
the hwmon device are leaked, leading to a use-after-free when reading
the lingering hwmon sysfs attributes.
In peci_dimmtemp_probe(), detect_work is registered for cancellation via
devm_delayed_work_autocancel(). During driver detach, devres_release_all()
first moves all existing entries from dev->devres_head onto a local todo
list before invoking their release callbacks in reverse order. If
create_dimm_temp_info_delayed() is already running when
devm_delayed_work_drop() calls cancel_delayed_work_sync(),
create_dimm_temp_info() can allocate dimmtemp_label strings via
devm_kzalloc()/devm_kasprintf() and register the hwmon device via
devm_hwmon_device_register_with_info(), appending new devres entries to
the now-empty dev->devres_head. Once the work finishes,
devres_release_all() frees priv and priv->name from the local todo list
without re-evaluating dev->devres_head, leaving the late devres
allocations and registered hwmon device behind with a dangling priv
pointer.
Cancel detect_work synchronously in a driver .remove() callback instead
of relying on devm_delayed_work_autocancel() so that the work is fully
drained before devres_release_all() detaches dev->devres_head, allowing
any devm resources registered by the delayed work to be released in
proper reverse order. Also only schedule detect_work when
check_populated_dimms() returns -EAGAIN so that probe failure paths do
not leave delayed work pending.
Fixes: 73bc1b885dae ("hwmon: peci: Add dimmtemp driver")
Cc: stable@vger.kernel.org
Cc: Iwona Winiarska <iwona.winiarska@intel.com>
Reviewed-by: Iwona Winiarska <iwona.winiarska@intel.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/peci/dimmtemp.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/hwmon/peci/dimmtemp.c b/drivers/hwmon/peci/dimmtemp.c
index bd3e8715dfece..617a4cc0f65c7 100644
--- a/drivers/hwmon/peci/dimmtemp.c
+++ b/drivers/hwmon/peci/dimmtemp.c
@@ -4,7 +4,6 @@
#include <linux/auxiliary_bus.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
-#include <linux/devm-helpers.h>
#include <linux/hwmon.h>
#include <linux/jiffies.h>
#include <linux/module.h>
@@ -326,11 +325,13 @@ static int create_dimm_temp_info(struct peci_dimmtemp *priv)
if (ret == -ENODEV) {
dev_dbg(priv->dev, "No DIMMs found\n");
return 0;
- } else if (ret) {
+ }
+ if (ret == -EAGAIN) {
schedule_delayed_work(&priv->detect_work, DIMM_MASK_CHECK_DELAY_JIFFIES);
dev_dbg(priv->dev, "Deferred populating DIMM temp info\n");
- return ret;
}
+ if (ret)
+ return ret;
channels = priv->gen_info->chan_rank_max * priv->gen_info->dimm_idx_max;
@@ -398,10 +399,8 @@ static int peci_dimmtemp_probe(struct auxiliary_device *adev, const struct auxil
"Unexpected PECI revision %#x, some features may be unavailable\n",
peci_dev->info.peci_revision);
- ret = devm_delayed_work_autocancel(priv->dev, &priv->detect_work,
- create_dimm_temp_info_delayed);
- if (ret)
- return ret;
+ auxiliary_set_drvdata(adev, priv);
+ INIT_DELAYED_WORK(&priv->detect_work, create_dimm_temp_info_delayed);
ret = create_dimm_temp_info(priv);
if (ret && ret != -EAGAIN) {
@@ -412,6 +411,13 @@ static int peci_dimmtemp_probe(struct auxiliary_device *adev, const struct auxil
return 0;
}
+static void peci_dimmtemp_remove(struct auxiliary_device *adev)
+{
+ struct peci_dimmtemp *priv = auxiliary_get_drvdata(adev);
+
+ cancel_delayed_work_sync(&priv->detect_work);
+}
+
static int
read_thresholds_hsx(struct peci_dimmtemp *priv, int dimm_order, int chan_rank, u32 *data)
{
@@ -665,6 +671,7 @@ MODULE_DEVICE_TABLE(auxiliary, peci_dimmtemp_ids);
static struct auxiliary_driver peci_dimmtemp_driver = {
.probe = peci_dimmtemp_probe,
+ .remove = peci_dimmtemp_remove,
.id_table = peci_dimmtemp_ids,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 191/507] hwmon: (pmbus/q54sj108a2) Add missing NULL pointer check
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (189 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 190/507] hwmon: (peci/dimmtemp) Fix devres leak and UAF on concurrent unbind Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 192/507] hwmon: (pmbus) Check return value from pmbus_thermal_add_sensor() Greg Kroah-Hartman
` (315 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit a5802c587da97a4ff85c04aad6043fa26640fc9b ]
When CONFIG_DEBUG_FS is enabled and per-client PMBus debugfs directory
creation fails during pmbus_do_probe(), q54sj108a2_probe() passes the NULL
pointer returned by pmbus_get_debugfs_dir() to debugfs_create_dir()
without validation, creating its debugfs directory at the debugfs root
instead of under the client directory.
If pmbus_init_debugfs() fails to create the client directory, data->debugfs
is left as NULL or an ERR_PTR, which pmbus_get_debugfs_dir() converts to
NULL. Passing a NULL parent to debugfs_create_dir() places q54sj108a2_dir
in the root of the debugfs filesystem and populates it with attribute files
whose private data pointers reference psu->debugfs_entries. Because this
root-level directory is outside the client debugfs hierarchy, PMBus core
cleanup does not remove it on device unbind, leaking the debugfs entries
and causing a use-after-free of the devm-allocated struct q54sj108a2_data
if the orphaned files are accessed via q54sj108a2_debugfs_read() or
q54sj108a2_debugfs_write() after device removal.
Fix the problem by adding the missing NULL pointer check.
Fixes: d014538aa385 ("hwmon: (pmbus) Driver for Delta power supplies Q54SJ108A2")
Cc: stable@vger.kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/pmbus/q54sj108a2.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/hwmon/pmbus/q54sj108a2.c b/drivers/hwmon/pmbus/q54sj108a2.c
index ecac405d75362..b018a611d9b64 100644
--- a/drivers/hwmon/pmbus/q54sj108a2.c
+++ b/drivers/hwmon/pmbus/q54sj108a2.c
@@ -351,6 +351,8 @@ static int q54sj108a2_probe(struct i2c_client *client)
psu->client = client;
debugfs = pmbus_get_debugfs_dir(client);
+ if (!debugfs)
+ return 0;
q54sj108a2_dir = debugfs_create_dir(client->name, debugfs);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 192/507] hwmon: (pmbus) Check return value from pmbus_thermal_add_sensor()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (190 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 191/507] hwmon: (pmbus/q54sj108a2) Add missing NULL pointer check Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 193/507] hwmon: (pmbus) Release devres allocated memory after devm_thermal_of_zone_register error Greg Kroah-Hartman
` (314 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 11dfbd835b17b75f7cc7a4a969f33ff702b1b081 ]
During PMBus device probe, if registering a temperature sensor with the
thermal subsystem fails, pmbus_add_sensor() silently ignores the error and
returns success.
When a valid temperature sensor is detected (class PSC_TEMPERATURE and type
"input"), pmbus_add_sensor() invokes pmbus_thermal_add_sensor() to hook it
into the kernel's thermal framework. However, the return value of this call
is completely discarded. If thermal registration fails, such as from an
-ENOMEM allocation failure or an invalid device tree configuration like a
malformed #thermal-sensor-cells property, no error is propagated.
Because the hardware monitor probe falsely succeeds despite the failure to
register the thermal zone, the system is left without thermal mitigation
for the affected PMBus device. This silently blinds the system to actual
PMIC temperatures, preventing the execution of necessary cooling mechanisms
or emergency shutdowns and risking localized overheating.
Pass the return value from pmbus_thermal_add_sensor() to the calling code
to fix the problem. To enable passing the actual error, change the error
return from pmbus_add_sensor() from NULL to ERR_PTR() and extract the error
from in the calling code.
Fixes: 3aa74796cfd0 ("hwmon: (pmbus) Register with thermal for PSC_TEMPERATURE")
Cc: stable@vger.kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/pmbus/pmbus_core.c | 42 ++++++++++++++++++--------------
1 file changed, 24 insertions(+), 18 deletions(-)
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 5f69c1420b4e1..ba1ce0dccfc1a 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -1526,10 +1526,11 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data,
{
struct sensor_device_attribute *a;
struct pmbus_sensor *sensor;
+ int err;
sensor = devm_kzalloc(data->dev, sizeof(*sensor), GFP_KERNEL);
if (!sensor)
- return NULL;
+ return ERR_PTR(-ENOMEM);
a = &sensor->attribute;
if (type)
@@ -1554,14 +1555,17 @@ static struct pmbus_sensor *pmbus_add_sensor(struct pmbus_data *data,
pmbus_set_sensor, -1);
if (pmbus_add_attribute(data, &a->dev_attr.attr))
- return NULL;
+ return ERR_PTR(-ENOMEM);
sensor->next = data->sensors;
data->sensors = sensor;
/* temperature sensors with _input values are registered with thermal */
- if (class == PSC_TEMPERATURE && strcmp(type, "input") == 0)
- pmbus_thermal_add_sensor(data, sensor, seq);
+ if (class == PSC_TEMPERATURE && strcmp(type, "input") == 0) {
+ err = pmbus_thermal_add_sensor(data, sensor, seq);
+ if (err)
+ return ERR_PTR(err);
+ }
return sensor;
}
@@ -1662,8 +1666,8 @@ static int pmbus_add_limit_attrs(struct i2c_client *client,
page, 0xff, l->reg, attr->class,
attr->update || l->update,
l->readonly, l->writeonly, true);
- if (!curr)
- return -ENOMEM;
+ if (IS_ERR(curr))
+ return PTR_ERR(curr);
if (l->sbit && (info->func[page] & attr->sfunc)) {
ret = pmbus_add_boolean(data, name,
l->alarm, index,
@@ -1702,8 +1706,8 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client,
}
base = pmbus_add_sensor(data, name, "input", index, page, phase,
attr->reg, attr->class, true, true, false, true);
- if (!base)
- return -ENOMEM;
+ if (IS_ERR(base))
+ return PTR_ERR(base);
/* No limit and alarm attributes for phase specific sensors */
if (attr->sfunc && phase == 0xff) {
ret = pmbus_add_limit_attrs(client, data, info, name,
@@ -2376,8 +2380,8 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client,
0xff, PMBUS_VIRT_FAN_TARGET_1 + id, PSC_FAN,
false, false, false, true);
- if (!sensor)
- return -ENOMEM;
+ if (IS_ERR(sensor))
+ return PTR_ERR(sensor);
if (!((data->info->func[page] & PMBUS_HAVE_PWM12) ||
(data->info->func[page] & PMBUS_HAVE_PWM34)))
@@ -2387,15 +2391,15 @@ static int pmbus_add_fan_ctrl(struct i2c_client *client,
0xff, PMBUS_VIRT_PWM_1 + id, PSC_PWM,
false, false, false, true);
- if (!sensor)
- return -ENOMEM;
+ if (IS_ERR(sensor))
+ return PTR_ERR(sensor);
sensor = pmbus_add_sensor(data, "pwm", "enable", index, page,
0xff, PMBUS_VIRT_PWM_ENABLE_1 + id, PSC_PWM,
true, false, false, false);
- if (!sensor)
- return -ENOMEM;
+ if (IS_ERR(sensor))
+ return PTR_ERR(sensor);
return 0;
}
@@ -2412,6 +2416,7 @@ static int pmbus_add_fan_attributes(struct i2c_client *client,
int f;
for (f = 0; f < ARRAY_SIZE(pmbus_fan_registers); f++) {
+ struct pmbus_sensor *sensor;
int regval;
if (!(info->func[page] & pmbus_fan_flags[f]))
@@ -2432,10 +2437,11 @@ static int pmbus_add_fan_attributes(struct i2c_client *client,
(!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4)))))
continue;
- if (pmbus_add_sensor(data, "fan", "input", index,
- page, 0xff, pmbus_fan_registers[f],
- PSC_FAN, true, true, false, true) == NULL)
- return -ENOMEM;
+ sensor = pmbus_add_sensor(data, "fan", "input", index,
+ page, 0xff, pmbus_fan_registers[f],
+ PSC_FAN, true, true, false, true);
+ if (IS_ERR(sensor))
+ return PTR_ERR(sensor);
/* Fan control */
if (pmbus_check_word_register(client, page,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 193/507] hwmon: (pmbus) Release devres allocated memory after devm_thermal_of_zone_register error
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (191 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 192/507] hwmon: (pmbus) Check return value from pmbus_thermal_add_sensor() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 194/507] hwmon: (pmbus) Fix return value check from thermal zone registration Greg Kroah-Hartman
` (313 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 9aa6cc563e881c3cad96ea36926cadceee151f32 ]
In pmbus_thermal_add_sensor(), a devres memory leak occurs when a PMBus
temperature sensor is initialized but no thermal zone is configured for
it.
The function allocates a pmbus_thermal_data structure using
devm_kzalloc(). It then attempts to register the sensor with the thermal
subsystem via devm_thermal_of_zone_register(). If this registration
returns -ENODEV (e.g., when no thermal zone is mapped in the Device Tree
or CONFIG_THERMAL_OF is disabled), the function intentionally catches the
error and returns 0 to allow device probing to continue.
Because devm_kfree() is not called on the -ENODEV path, the unused tdata
structure remains allocated on the device's managed resource list. Since
most PMBus temperature sensors are not attached to thermal zones, this
results in an accumulation of unused objects that needlessly consume kernel
memory for the lifetime of the PMBus device.
Add the missing call to devm_kfree() to fix the problem.
Fixes: 3aa74796cfd0 ("hwmon: (pmbus) Register with thermal for PSC_TEMPERATURE")
Cc: stable@vger.kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/pmbus/pmbus_core.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index ba1ce0dccfc1a..5534717ba5f7a 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -1510,8 +1510,10 @@ static int pmbus_thermal_add_sensor(struct pmbus_data *pmbus_data,
* If CONFIG_THERMAL_OF is disabled, this returns -ENODEV,
* so ignore that error but forward any other error.
*/
- if (IS_ERR(tzd) && (PTR_ERR(tzd) != -ENODEV))
+ if (IS_ERR(tzd) && (PTR_ERR(tzd) != -ENODEV)) {
+ devm_kfree(dev, tdata);
return PTR_ERR(tzd);
+ }
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 194/507] hwmon: (pmbus) Fix return value check from thermal zone registration
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (192 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 193/507] hwmon: (pmbus) Release devres allocated memory after devm_thermal_of_zone_register error Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 195/507] hwmon: (lm75) Fix setting polarity mask for chips with 16-bit config register Greg Kroah-Hartman
` (312 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 4fc79634af8cdf734e0a633923ba4817e30d29ad ]
The PMBus core used to call devm_thermal_zone_of_sensor_register()
to register thermal zones. Commit 613ed3f676092 ("hwmon: pm_bus: core:
Switch to new of thermal API") changed this to call
devm_thermal_of_zone_register() instead. The code subsequently checks if
the call failed because the thermal subsystem is not configured.
devm_thermal_zone_of_sensor_register() used to return -ENODEV in this
case. devm_thermal_of_zone_register() returns -ENOTSUPP. The code currently
still checks for -ENOVEV. This results in driver instantiation failures if
the thermal subsystem is disabled.
Check for -ENOTSUPP to fix the problem. Keep checking for -ENODEV because
this indicates that no thermal zone is configured for the sensor, which is
acceptable for the driver and must not cause a registration failure.
Fixes: 613ed3f676092 ("hwmon: pm_bus: core: Switch to new of thermal API")
Cc: stable@vger.kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/pmbus/pmbus_core.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
index 5534717ba5f7a..b033bd3b1527b 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -1507,10 +1507,11 @@ static int pmbus_thermal_add_sensor(struct pmbus_data *pmbus_data,
tzd = devm_thermal_of_zone_register(dev, index, tdata,
&pmbus_thermal_ops);
/*
- * If CONFIG_THERMAL_OF is disabled, this returns -ENODEV,
- * so ignore that error but forward any other error.
+ * If CONFIG_THERMAL_OF is disabled, devm_thermal_of_zone_register()
+ * returns -ENOTSUPP. If no thermal zone is configured for the sensor,
+ * it returns -ENODEV. Ignore those errors but forward any other error.
*/
- if (IS_ERR(tzd) && (PTR_ERR(tzd) != -ENODEV)) {
+ if (IS_ERR(tzd) && PTR_ERR(tzd) != -ENODEV && PTR_ERR(tzd) != -ENOTSUPP) {
devm_kfree(dev, tdata);
return PTR_ERR(tzd);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 195/507] hwmon: (lm75) Fix setting polarity mask for chips with 16-bit config register
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (193 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 194/507] hwmon: (pmbus) Fix return value check from thermal zone registration Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 196/507] hwmon: (tmp108) Fix initial conversion delay and wait until ready Greg Kroah-Hartman
` (311 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 3897309ede38d7f3ff34c4c4583b1dd345666988 ]
When probing a 16-bit compatible temperature sensor configured with the
"ti,alert-polarity-active-high" device property, lm75_generic_probe()
writes to a reserved bit instead of the alert polarity bit due to an
incorrect bit shift in the 16-bit polarity mask.
On 16-bit sensors, the polarity bit is physically located at bit 2 of the
MSByte. When accessed via i2c_smbus_read_word_data() or
i2c_smbus_write_word_data(), the SMBus protocol maps the first received
byte (the physical MSByte) to the lower 8 bits of the integer
representation. Consequently, the polarity bit is consistently mapped to
bit 2, identically to 8-bit sensors. However, the
LM75_ALERT_POLARITY_HIGH_16_BIT macro applies an 8-bit left shift,
erroneously targeting bit 10. This causes the driver to silently corrupt a
reserved bit in the configuration register while leaving the active-high
alert polarity unconfigured, breaking the polarity feature.
Use BIT(2) as polarity mask in the configuration register for all chips
to fix the problem.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Fixes: 1be4001d9b9b ("hwmon: (lm75) Support active-high alert polarity")
Cc: stable@vger.kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/lm75.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index 2d2d752aeac9d..917ac250a648b 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -123,8 +123,7 @@ struct lm75_data {
static const u8 lm75_sample_set_masks[] = { 0 << 5, 1 << 5, 2 << 5, 3 << 5 };
-#define LM75_ALERT_POLARITY_HIGH_8_BIT (BIT(2))
-#define LM75_ALERT_POLARITY_HIGH_16_BIT (BIT(2) << 8)
+#define LM75_ALERT_POLARITY_HIGH_BIT BIT(2)
#define LM75_SAMPLE_CLEAR_MASK (3 << 5)
/* The structure below stores the configuration values of the supported devices.
@@ -770,11 +769,7 @@ static int lm75_generic_probe(struct device *dev, const char *name,
data->orig_conf = status;
/* Enforce polarity active-low (default) or active-high (devicetree) */
- if (!data->params->config_reg_16bits)
- pol_mask = LM75_ALERT_POLARITY_HIGH_8_BIT;
- else
- pol_mask = LM75_ALERT_POLARITY_HIGH_16_BIT;
-
+ pol_mask = LM75_ALERT_POLARITY_HIGH_BIT;
clr_mask = data->params->clr_mask | pol_mask;
set_mask = data->params->set_mask & ~pol_mask;
if (device_property_read_bool(dev, "ti,alert-polarity-active-high"))
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 196/507] hwmon: (tmp108) Fix initial conversion delay and wait until ready
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (194 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 195/507] hwmon: (lm75) Fix setting polarity mask for chips with 16-bit config register Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 197/507] hwmon: (gpio-fan) Update the speed cache before dropping the PM reference Greg Kroah-Hartman
` (310 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 7cd60538073e465310c94b2a2f0ea8d2f03768ef ]
In tmp108_common_probe(), the driver only adds the 30 ms conversion delay
(TMP108_CONVERSION_TIME_MS) to ready_time if the sensor was previously in
TMP108_MODE_SHUTDOWN. However, the TMP108 hardware defaults to continuous
conversion mode (TMP108_MODE_CONTINUOUS) upon power-on reset, including
immediately after enabling the vcc supply regulator during probe, while
the temperature register retains its power-on reset value of 0x0000 (0°C)
until the first conversion completes. Because the initial mode is not
shutdown, the delay is bypassed and early reads via thermal zone
registration or sysfs before the first conversion finishes return an
uninitialized 0°C reading.
In addition, returning -EAGAIN from tmp108_read() while waiting for a
conversion to complete after probe or resume can trigger an unnecessary
tight retry loop in callers or fail initial reads.
Unconditionally set ready_time to TMP108_CONVERSION_TIME_MS ahead in
tmp108_common_probe(), track ready_time as ktime_t, and wait for the
remaining conversion time in tmp108_read() using usleep_range() instead
of returning -EAGAIN.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Fixes: 66e1c9171339 ("hwmon: Add Texas Instruments TMP108 temperature sensor driver.")
Cc: stable@vger.kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/tmp108.c | 26 +++++++++++---------------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/drivers/hwmon/tmp108.c b/drivers/hwmon/tmp108.c
index 91d20a1ce1120..862b944d3e609 100644
--- a/drivers/hwmon/tmp108.c
+++ b/drivers/hwmon/tmp108.c
@@ -13,7 +13,7 @@
#include <linux/i2c.h>
#include <linux/i3c/device.h>
#include <linux/init.h>
-#include <linux/jiffies.h>
+#include <linux/ktime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
@@ -78,7 +78,7 @@
struct tmp108 {
struct regmap *regmap;
u16 orig_config;
- u64 ready_time;
+ ktime_t ready_time;
const struct tmp108_params *params;
};
@@ -121,6 +121,7 @@ static int tmp108_read(struct device *dev, enum hwmon_sensor_types type,
struct tmp108 *tmp108 = dev_get_drvdata(dev);
unsigned int regval;
int err, hyst;
+ s64 delay;
if (type == hwmon_chip) {
if (attr == hwmon_chip_update_interval) {
@@ -137,12 +138,10 @@ static int tmp108_read(struct device *dev, enum hwmon_sensor_types type,
switch (attr) {
case hwmon_temp_input:
- /* Is it too early to return a conversion ? */
- if (time_before64(get_jiffies_64(), tmp108->ready_time)) {
- dev_dbg(dev, "%s: Conversion not ready yet..\n",
- __func__);
- return -EAGAIN;
- }
+ /* Wait if it is too early to return a conversion */
+ delay = ktime_us_delta(tmp108->ready_time, ktime_get());
+ if (delay > 0)
+ usleep_range(delay, delay + 1000);
err = regmap_read(tmp108->regmap, TMP108_REG_TEMP, ®val);
if (err < 0)
return err;
@@ -477,11 +476,8 @@ static int tmp108_common_probe(struct device *dev, struct regmap *regmap, char *
return err;
}
- tmp108->ready_time = get_jiffies_64();
- if ((tmp108->orig_config & TMP108_CONF_MODE_MASK) ==
- TMP108_MODE_SHUTDOWN)
- tmp108->ready_time +=
- msecs_to_jiffies(TMP108_CONVERSION_TIME_MS);
+ tmp108->ready_time = ktime_add_ms(ktime_get(),
+ TMP108_CONVERSION_TIME_MS);
err = devm_add_action_or_reset(dev, tmp108_restore_config, tmp108);
if (err) {
@@ -528,8 +524,8 @@ static int tmp108_resume(struct device *dev)
err = regmap_update_bits(tmp108->regmap, TMP108_REG_CONF,
TMP108_CONF_MODE_MASK, TMP108_MODE_CONTINUOUS);
- tmp108->ready_time = get_jiffies_64() +
- msecs_to_jiffies(TMP108_CONVERSION_TIME_MS);
+ tmp108->ready_time = ktime_add_ms(ktime_get(),
+ TMP108_CONVERSION_TIME_MS);
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 197/507] hwmon: (gpio-fan) Update the speed cache before dropping the PM reference
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (195 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 196/507] hwmon: (tmp108) Fix initial conversion delay and wait until ready Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 198/507] hwmon: (coretemp) Check for NULL platform device in hotplug callbacks Greg Kroah-Hartman
` (309 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baek Kyu, Kim, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baek Kyu, Kim <pocj8ur4in@gmail.com>
[ Upstream commit f324179e6ccd05dfdc8e98fba2e9d50aea8e7ea2 ]
set_fan_speed() writes the GPIO control value before dropping the runtime
PM reference when stopping the fan. pm_runtime_put_sync() decrements the
usage count even when suspending the device fails, but the error return
currently leaves speed_index at the previous running speed.
A request for that same running speed then returns success without
changing the GPIOs or taking a runtime PM reference. Retrying the stop
instead drops a reference the driver no longer owns and can trigger a
runtime PM usage count underflow warning.
Update speed_index after writing the GPIOs and before dropping the PM
reference. The initial same-speed check already excludes a stopped fan,
so a zero target is sufficient to identify the transition that needs a
PM put. Preserve the PM error return and the CONFIG_PM=n exception.
This keeps the cached control state and PM reference ownership consistent
without restoring running GPIOs after a possibly partial supply failure.
It does not clear persistent runtime PM errors or claim that a failing
regulator has successfully powered off.
Fixes: 0d01110e6356 ("hwmon: (gpio-fan) Add regulator support")
Cc: stable@vger.kernel.org
Signed-off-by: Baek Kyu, Kim <pocj8ur4in@gmail.com>
Link: https://patch.msgid.link/20261031095039.11683-1-pocj8ur4in@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/gpio-fan.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c
index 3f78375eeb448..08b58b49be5b9 100644
--- a/drivers/hwmon/gpio-fan.c
+++ b/drivers/hwmon/gpio-fan.c
@@ -150,7 +150,10 @@ static int set_fan_speed(struct gpio_fan_data *fan_data, int speed_index)
__set_fan_ctrl(fan_data, fan_data->speed[speed_index].ctrl_val);
- if (fan_data->speed_index > 0 && speed_index == 0) {
+ /* The GPIOs have changed, and a PM put drops the reference on error. */
+ fan_data->speed_index = speed_index;
+
+ if (speed_index == 0) {
int ret;
ret = pm_runtime_put_sync(fan_data->dev);
@@ -158,8 +161,6 @@ static int set_fan_speed(struct gpio_fan_data *fan_data, int speed_index)
return ret;
}
- fan_data->speed_index = speed_index;
-
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 198/507] hwmon: (coretemp) Check for NULL platform device in hotplug callbacks
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (196 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 197/507] hwmon: (gpio-fan) Update the speed cache before dropping the PM reference Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 199/507] hwmon: (coretemp) Set nr_cores only after core_data allocation succeeds Greg Kroah-Hartman
` (308 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Asaf Nuri Bertizlioğlu,
Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 0f9c7ed3b5009a037e5533eac03a0d4d45ecf1f0 ]
coretemp_get_pdev() returns NULL when topology_logical_die_id(cpu) is
negative (such as -ENODEV or -ERANGE from topology_get_logical_id() on a
firmware/hardware APIC ID mismatch) or exceeds max_zones (for example,
under asymmetric or anomalous ACPI die topologies where
topology_max_packages() * topology_max_dies_per_package() is smaller
than the logical die count).
Commit 6d03bbff456b ("hwmon: (coretemp) Simplify platform device
handling") pre-allocated zone_devices[0 .. max_zones - 1] during module
init and dropped the NULL checks on pdev in coretemp_cpu_online() and
coretemp_cpu_offline(), passing pdev unconditionally to
platform_get_drvdata(). When coretemp_get_pdev() returns NULL,
platform_get_drvdata(pdev) dereferences &pdev->dev and triggers a kernel
NULL pointer dereference.
Check for a NULL pdev and return 0 in both coretemp_cpu_online() and
coretemp_cpu_offline() before calling platform_get_drvdata(). Returning
0 in coretemp_cpu_online() ignores the unmapped CPU without blocking CPU
bringup or tearing down valid thermal zones on other dies.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Fixes: 6d03bbff456b ("hwmon: (coretemp) Simplify platform device handling")
Cc: stable@vger.kernel.org
Tested-by: Asaf Nuri Bertizlioğlu <ycistak@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/coretemp.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 9ed21c8c093a5..17b9b63440f81 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -695,6 +695,9 @@ static int coretemp_cpu_online(unsigned int cpu)
if (!housekeeping_cpu(cpu, HK_TYPE_MISC))
return 0;
+ if (!pdev)
+ return 0;
+
pdata = platform_get_drvdata(pdev);
if (!pdata->hwmon_dev) {
struct device *hwmon;
@@ -746,6 +749,9 @@ static int coretemp_cpu_offline(unsigned int cpu)
return 0;
/* If the physical CPU device does not exist, just return */
+ if (!pdev)
+ return 0;
+
pd = platform_get_drvdata(pdev);
if (!pd->hwmon_dev)
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 199/507] hwmon: (coretemp) Set nr_cores only after core_data allocation succeeds
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (197 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 198/507] hwmon: (coretemp) Check for NULL platform device in hotplug callbacks Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 200/507] hwmon: (sht4x) Convert update_interval to jiffies in pending data check Greg Kroah-Hartman
` (307 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Asaf Nuri Bertizlioğlu,
Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 95638f1f05ced75a82e83f610cd01b636d2a21b1 ]
In init_temp_data(), pdata->nr_cores is populated from
topology_num_cores_per_package() before allocating pdata->core_data. If
that allocation fails, init_temp_data() returns NULL with
pdata->core_data still NULL and pdata->nr_cores set to a positive value.
coretemp_add_core() logs the error without failing coretemp_cpu_online(),
so the CPU still comes online with pdata->hwmon_dev registered. When the
CPU is later taken offline (or the module is unloaded),
coretemp_cpu_offline() calls get_temp_data(pd, cpu), which loops up to
pdata->nr_cores and dereferences the NULL pdata->core_data pointer.
Store the core count in a local variable and assign pdata->nr_cores only
after pdata->core_data is allocated, preserving the invariant that
pdata->nr_cores is zero whenever pdata->core_data is NULL.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Fixes: 1a793caf6f69 ("hwmon: (coretemp) Use dynamic allocated memory for core temp_data")
Cc: stable@vger.kernel.org
Tested-by: Asaf Nuri Bertizlioğlu <ycistak@gmail.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/coretemp.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index 17b9b63440f81..2d7487b2f80a1 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -491,11 +491,12 @@ init_temp_data(struct platform_data *pdata, unsigned int cpu, int pkg_flag)
struct temp_data *tdata;
if (!pdata->core_data) {
- pdata->nr_cores = topology_num_cores_per_package();
- pdata->core_data = kzalloc_objs(struct temp_data *,
- pdata->nr_cores);
+ int nr_cores = topology_num_cores_per_package();
+
+ pdata->core_data = kzalloc_objs(struct temp_data *, nr_cores);
if (!pdata->core_data)
return NULL;
+ pdata->nr_cores = nr_cores;
}
tdata = kzalloc_obj(struct temp_data);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 200/507] hwmon: (sht4x) Convert update_interval to jiffies in pending data check
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (198 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 199/507] hwmon: (coretemp) Set nr_cores only after core_data allocation succeeds Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 201/507] hwmon: (aquacomputer_d5next) Avoid truncating scaled sensor readings Greg Kroah-Hartman
` (306 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Guenter Roeck, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 1a30ea0be623b7443edb6adc79e07632418cefdc ]
In sht4x_read_values(), the check for whether a pending post-heater
measurement is still fresh compares get_jiffies_64() against
data->heating_complete + data->update_interval. However,
data->heating_complete is stored in jiffies whereas data->update_interval
is stored in milliseconds.
Whenever HZ != 1000, adding data->update_interval directly without
msecs_to_jiffies() mixes incompatible time units. For example, with the
default 2000 ms update_interval, the validity window is inflated to 8
seconds at HZ=250 and 20 seconds at HZ=100 instead of 2 seconds. A read
within that extended window skips triggering a fresh measurement and
instead returns and caches the stale post-heating measurement left in the
sensor's output buffer.
Convert data->update_interval to jiffies using msecs_to_jiffies() when
computing the pending measurement expiration deadline, matching the
next_update calculation right below it.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Fixes: 0eed6fc3d2b9 ("hwmon: (sht4x): add heater support")
Cc: stable@vger.kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/sht4x.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/sht4x.c b/drivers/hwmon/sht4x.c
index 0bb9227674a85..f38c106b7090f 100644
--- a/drivers/hwmon/sht4x.c
+++ b/drivers/hwmon/sht4x.c
@@ -99,7 +99,9 @@ static int sht4x_read_values(struct sht4x_data *data)
msleep(jiffies_to_msecs(data->heating_complete - curr_jiffies));
if (data->data_pending &&
- time_before64(get_jiffies_64(), data->heating_complete + data->update_interval)) {
+ time_before64(get_jiffies_64(),
+ data->heating_complete +
+ msecs_to_jiffies(data->update_interval))) {
data->data_pending = false;
} else {
next_update = data->last_updated +
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 201/507] hwmon: (aquacomputer_d5next) Avoid truncating scaled sensor readings
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (199 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 200/507] hwmon: (sht4x) Convert update_interval to jiffies in pending data check Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 202/507] net: qrtr: announce local services again once our HELLO is sent Greg Kroah-Hartman
` (305 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vas Zayarskiy, Guenter Roeck,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vas Zayarskiy <contact@vasily.cc>
[ Upstream commit c221091f7e30c64280e4cbfa27dc4c05edc96d0c ]
High Flow Next power is reported in watts. Multiplying the 16-bit value
by one million can overflow both the signed intermediate and the u32
cache. Store power in long, perform the conversion in u64, and clamp to
LONG_MAX. The other existing power conversions fit in a signed 32-bit
value. Return -ENODATA for unavailable power instead of exposing the
stored error as a reading.
The power cache is updated by HID reports without the hwmon read mutex.
Read it once with READ_ONCE() and use that snapshot for both the
availability check and the returned value. Mark the corresponding
updates with WRITE_ONCE() so that the shared accesses are explicit.
Widen the shared current cache to u32. The Aquastream XT conversion to
milliamperes can exceed 65535 mA; clamp its negative conversion results
to zero before assigning to the unsigned cache. This also permits devices
with scaled aggregate currents to store milliamperes directly.
Fixes: aed80bb91de8 ("hwmon: (aquacomputer_d5next) Add support for Aquacomputer High Flow Next")
Cc: stable@vger.kernel.org
Signed-off-by: Vas Zayarskiy <contact@vasily.cc>
Link: https://patch.msgid.link/20260927191316.4137752-2-contact@vasily.cc
[groeck: Dropped obsolete 'Assisted-by: tag]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/aquacomputer_d5next.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c
index 6565731b0e71f..3d3786c829317 100644
--- a/drivers/hwmon/aquacomputer_d5next.c
+++ b/drivers/hwmon/aquacomputer_d5next.c
@@ -19,6 +19,7 @@
#include <linux/hwmon.h>
#include <linux/jiffies.h>
#include <linux/ktime.h>
+#include <linux/limits.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/unaligned.h>
@@ -612,9 +613,9 @@ struct aqc_data {
u32 speed_input_min[1];
u32 speed_input_target[1];
u32 speed_input_max[1];
- u32 power_input[8];
+ long power_input[8];
u16 voltage_input[8];
- u16 current_input[8];
+ u32 current_input[8];
/* Label values */
const char *const *temp_label;
@@ -989,7 +990,7 @@ static int aqc_legacy_read(struct aqc_data *priv)
/* Calculation derived from linear regression */
sensor_value = get_unaligned_le16(priv->buffer + AQUASTREAMXT_PUMP_CURR_OFFSET);
- priv->current_input[0] = DIV_ROUND_CLOSEST(sensor_value * 176, 100) - 52;
+ priv->current_input[0] = max(DIV_ROUND_CLOSEST(sensor_value * 176, 100) - 52, 0);
sensor_value = get_unaligned_le16(priv->buffer + AQUASTREAMXT_PUMP_VOLTAGE_OFFSET);
priv->voltage_input[0] = DIV_ROUND_CLOSEST(sensor_value * 1000, 61);
@@ -1019,6 +1020,7 @@ static int aqc_legacy_read(struct aqc_data *priv)
static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
int channel, long *val)
{
+ long power;
int ret;
struct aqc_data *priv = dev_get_drvdata(dev);
@@ -1083,7 +1085,10 @@ static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
}
break;
case hwmon_power:
- *val = priv->power_input[channel];
+ power = READ_ONCE(priv->power_input[channel]);
+ if (power == -ENODATA)
+ return -ENODATA;
+ *val = power;
break;
case hwmon_pwm:
switch (priv->kind) {
@@ -1383,9 +1388,9 @@ static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8
priv->speed_input[i] =
get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
priv->fan_structure->speed);
- priv->power_input[i] =
- get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
- priv->fan_structure->power) * 10000;
+ WRITE_ONCE(priv->power_input[i],
+ get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
+ priv->fan_structure->power) * 10000);
priv->voltage_input[i] =
get_unaligned_be16(data + priv->fan_sensor_offsets[i] +
priv->fan_structure->voltage) * 10;
@@ -1425,7 +1430,8 @@ static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8
priv->speed_input[2] = get_unaligned_be16(data + AQUASTREAMULT_PRESSURE_OFFSET);
priv->speed_input[3] = get_unaligned_be16(data + AQUASTREAMULT_FLOW_SENSOR_OFFSET);
- priv->power_input[1] = get_unaligned_be16(data + AQUASTREAMULT_PUMP_POWER) * 10000;
+ WRITE_ONCE(priv->power_input[1],
+ get_unaligned_be16(data + AQUASTREAMULT_PUMP_POWER) * 10000);
priv->voltage_input[1] = get_unaligned_be16(data + AQUASTREAMULT_PUMP_VOLTAGE) * 10;
@@ -1438,10 +1444,11 @@ static int aqc_raw_event(struct hid_device *hdev, struct hid_report *report, u8
case highflownext:
/* If external temp sensor is not connected, its power reading is also N/A */
if (priv->temp_input[1] == -ENODATA)
- priv->power_input[0] = -ENODATA;
+ WRITE_ONCE(priv->power_input[0], -ENODATA);
else
- priv->power_input[0] =
- get_unaligned_be16(data + HIGHFLOWNEXT_POWER) * 1000000;
+ WRITE_ONCE(priv->power_input[0],
+ min_t(u64, get_unaligned_be16(data + HIGHFLOWNEXT_POWER) *
+ 1000000ULL, LONG_MAX));
priv->voltage_input[0] = get_unaligned_be16(data + HIGHFLOWNEXT_5V_VOLTAGE) * 10;
priv->voltage_input[1] =
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 202/507] net: qrtr: announce local services again once our HELLO is sent
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (200 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 201/507] hwmon: (aquacomputer_d5next) Avoid truncating scaled sensor readings Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 203/507] nvme-rdma: fix NULL queue->ctrl dereference on reconnect Greg Kroah-Hartman
` (304 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joonhoe Kim, Paolo Abeni,
Sasha Levin, Filippo Falezza
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joonhoe Kim <26rote@gmail.com>
[ Upstream commit 743b5c86276b1c3241e6f0f395b55f98f0756ef0 ]
Since commit 544d85de4dc2 ("net: qrtr: Send HELLO message on endpoint
register"), qrtr_node_enqueue() drops every packet but HELLO with
-EAGAIN until our HELLO has gone out to the node. When the remote's
HELLO arrives first, the NEW_SERVER replies from the name service are
dropped, and so are the broadcasts for services registered before our
HELLO goes out. Nothing announces these services again, so the remote
never learns about them.
On Kaanapali the modem sends its HELLO before it accepts ours. With
rmtfs started first, the modem never learns about rmtfs and its
watchdog resets the SoC about 40 s later.
Remember that the remote has sent a HELLO. Once our HELLO has been
sent to such a node, pass a HELLO from it to the local name service
again, so that it announces the services it has at that point. Retry
the replay if it cannot be queued, and queue it under ep_lock only
while the endpoint is registered, so that it cannot follow the BYE
from qrtr_endpoint_unregister().
The flag is not cleared when qrtr_endpoint_hello() restarts the
handshake on resume, so a HELLO that the remote sent before then is
not lost. The cost is that the remote gets the same NEW_SERVER
announcements twice when its HELLO arrives before ours goes out but
the name service handles it after, and on every resume.
Fixes: 544d85de4dc2 ("net: qrtr: Send HELLO message on endpoint register")
Cc: stable@vger.kernel.org
Tested-by: Filippo Falezza <effeffe99@gmail.com> # Motorola Moto G 5G Plus nairo (SM7250)
Signed-off-by: Joonhoe Kim <26rote@gmail.com>
Link: https://patch.msgid.link/20261029105142.2503-1-26rote@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/qrtr/af_qrtr.c | 53 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 45 insertions(+), 8 deletions(-)
diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c
index e7b3647424b8f..45cb8e8c36ca2 100644
--- a/net/qrtr/af_qrtr.c
+++ b/net/qrtr/af_qrtr.c
@@ -122,6 +122,7 @@ static DEFINE_XARRAY_ALLOC(qrtr_ports);
* @qrtr_tx_flow: xarray of qrtr_tx_flow, keyed by node << 32 | port
* @qrtr_tx_lock: lock for qrtr_tx_flow inserts
* @hello_sent: hello packet send successful
+ * @hello_rcvd: remote has sent a hello packet
* @rx_queue: receive queue
* @item: list item for broadcast list
* @say_hello: delayed work for sending hello packet
@@ -136,6 +137,7 @@ struct qrtr_node {
struct mutex qrtr_tx_lock; /* for qrtr_tx_flow */
bool hello_sent;
+ bool hello_rcvd;
struct sk_buff_head rx_queue;
struct list_head item;
@@ -541,6 +543,11 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
qrtr_node_assign(node, le32_to_cpu(pkt->server.node));
}
+ if (cb->type == QRTR_TYPE_HELLO) {
+ /* Pairs with smp_load_acquire() in qrtr_hello_work() */
+ smp_store_release(&node->hello_rcvd, true);
+ }
+
if (cb->type == QRTR_TYPE_RESUME_TX) {
qrtr_tx_resume(node, skb);
} else {
@@ -599,6 +606,8 @@ static void qrtr_hello_work(struct work_struct *work)
struct qrtr_node *node;
struct qrtr_sock *ctrl;
struct sk_buff *skb;
+ bool hello_sent;
+ int rc = 0;
node = container_of(to_delayed_work(work), struct qrtr_node, say_hello);
@@ -609,17 +618,45 @@ static void qrtr_hello_work(struct work_struct *work)
return;
}
- skb = qrtr_alloc_ctrl_packet(&pkt, GFP_KERNEL);
- if (!skb) {
- qrtr_port_put(ctrl);
- schedule_delayed_work(&node->say_hello, msecs_to_jiffies(100));
- return;
+ mutex_lock(&node->ep_lock);
+ hello_sent = node->hello_sent;
+ mutex_unlock(&node->ep_lock);
+
+ from.sq_node = qrtr_local_nid;
+ if (!hello_sent) {
+ skb = qrtr_alloc_ctrl_packet(&pkt, GFP_KERNEL);
+ if (!skb)
+ goto retry;
+
+ pkt->cmd = cpu_to_le32(QRTR_TYPE_HELLO);
+ to.sq_node = node->nid;
+ if (qrtr_node_enqueue(node, skb, QRTR_TYPE_HELLO, &from, &to))
+ goto out;
}
+ /* Pairs with smp_store_release() in qrtr_endpoint_post() */
+ if (!smp_load_acquire(&node->hello_rcvd))
+ goto out;
+
+ skb = qrtr_alloc_ctrl_packet(&pkt, GFP_KERNEL);
+ if (!skb)
+ goto retry;
+
pkt->cmd = cpu_to_le32(QRTR_TYPE_HELLO);
- from.sq_node = qrtr_local_nid;
- to.sq_node = node->nid;
- qrtr_node_enqueue(node, skb, QRTR_TYPE_HELLO, &from, &to);
+ to.sq_node = READ_ONCE(node->nid);
+
+ mutex_lock(&node->ep_lock);
+ if (node->ep)
+ rc = qrtr_local_enqueue(NULL, skb, QRTR_TYPE_HELLO, &to, &from);
+ else
+ kfree_skb(skb);
+ mutex_unlock(&node->ep_lock);
+ if (!rc)
+ goto out;
+
+retry:
+ schedule_delayed_work(&node->say_hello, msecs_to_jiffies(100));
+out:
qrtr_port_put(ctrl);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 203/507] nvme-rdma: fix NULL queue->ctrl dereference on reconnect
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (201 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 202/507] net: qrtr: announce local services again once our HELLO is sent Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 204/507] nvme: unregister when pr_register() is given a zero new key Greg Kroah-Hartman
` (303 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nilay Shroff,
Christian Aurich Zanettini Martins, Keith Busch, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Aurich Zanettini Martins <christian.aurichzm@gmail.com>
[ Upstream commit 3ee50a2d76f278ea0ced45716a62730059283787 ]
Since commit 2a8513091d2f ("nvme-rdma: parallelize I/O queue allocation
and startup"), a reconnect that gets more I/O queues than before grows
the tag set before the new queues are set up. queue->ctrl is only set
by nvme_rdma_setup_io_queues(), so I/O submitted in between reaches
nvme_rdma_queue_rq() on a queue that was never allocated and
dereferences a NULL queue->ctrl:
BUG: kernel NULL pointer dereference, address: 000000000000034c
RIP: 0010:nvme_rdma_queue_rq+0x52/0xb90
Set queue->ctrl for every queue when allocating the controller. Such
requests are then requeued like on any other queue that is not live.
Fixes: 2a8513091d2f ("nvme-rdma: parallelize I/O queue allocation and startup")
Cc: stable@vger.kernel.org
Reviewed-by: Nilay Shroff <nilay@linux.ibm.com>
Signed-off-by: Christian Aurich Zanettini Martins <christian.aurichzm@gmail.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/rdma.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 5b9b540693b51..ff7b9e3796140 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -735,7 +735,6 @@ static int nvme_rdma_setup_io_queues(struct nvme_rdma_ctrl *ctrl,
for (i = 0; i < nr_queues; i++) {
struct nvme_rdma_queue *queue = &ctrl->queues[first + i];
- queue->ctrl = ctrl;
queue->queue_size = queue_size;
ctxs[i].queue = queue;
@@ -798,7 +797,6 @@ static int nvme_rdma_configure_admin_queue(struct nvme_rdma_ctrl *ctrl,
bool pi_capable = false;
int error;
- ctrl->queues[0].ctrl = ctrl;
ctrl->queues[0].queue_size = NVME_AQ_DEPTH;
error = nvme_rdma_alloc_queue(&ctrl->queues[0]);
if (error)
@@ -2284,7 +2282,7 @@ static struct nvme_rdma_ctrl *nvme_rdma_alloc_ctrl(struct device *dev,
struct nvmf_ctrl_options *opts)
{
struct nvme_rdma_ctrl *ctrl;
- int ret;
+ int ret, i;
ctrl = kzalloc_obj(*ctrl);
if (!ctrl)
@@ -2343,6 +2341,9 @@ static struct nvme_rdma_ctrl *nvme_rdma_alloc_ctrl(struct device *dev,
if (!ctrl->queues)
goto out_free_ctrl;
+ for (i = 0; i < ctrl->ctrl.queue_count; i++)
+ ctrl->queues[i].ctrl = ctrl;
+
ret = nvme_init_ctrl(&ctrl->ctrl, dev, &nvme_rdma_ctrl_ops,
0 /* no quirks, we're perfect! */);
if (ret)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 204/507] nvme: unregister when pr_register() is given a zero new key
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (202 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 203/507] nvme-rdma: fix NULL queue->ctrl dereference on reconnect Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 205/507] nvme: Do not drop the cdev reference twice when cdev_device_add() fails Greg Kroah-Hartman
` (302 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Daejun Park,
Keith Busch, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daejun Park <daejun7.park@samsung.com>
[ Upstream commit a9d431124fb2e58215daf0299d6fcf47bbc2d6b1 ]
The block layer PR API defines a zero new_key in pr_register() as
unregistering old_key. nvme_pr_register() sends Replace Reservation
Key with a zero NRKEY instead. The host stays registered with key 0,
and its next registration with another key fails with Reservation
Conflict.
The pNFS SCSI layout client unregisters this way at umount. A later
mount cannot register and sends all I/O through the metadata server.
Send Unregister Reservation Key when new_key is zero.
Fixes: 1d277a637a71 ("NVMe: Add persistent reservation ops")
Cc: stable@vger.kernel.org
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Daejun Park <daejun7.park@samsung.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/pr.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/host/pr.c b/drivers/nvme/host/pr.c
index fe7dbe2648158..d8b6ac4d83bb9 100644
--- a/drivers/nvme/host/pr.c
+++ b/drivers/nvme/host/pr.c
@@ -128,8 +128,12 @@ static int nvme_pr_register(struct block_device *bdev, u64 old_key, u64 new_key,
data.crkey = cpu_to_le64(old_key);
data.nrkey = cpu_to_le64(new_key);
- cdw10 = old_key ? NVME_PR_REGISTER_ACT_REPLACE :
- NVME_PR_REGISTER_ACT_REG;
+ if (!new_key)
+ cdw10 = NVME_PR_REGISTER_ACT_UNREG;
+ else if (old_key)
+ cdw10 = NVME_PR_REGISTER_ACT_REPLACE;
+ else
+ cdw10 = NVME_PR_REGISTER_ACT_REG;
cdw10 |= (flags & PR_FL_IGNORE_KEY) ? NVME_PR_IGNORE_KEY : 0;
cdw10 |= NVME_PR_CPTPL_PERSIST;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 205/507] nvme: Do not drop the cdev reference twice when cdev_device_add() fails
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (203 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 204/507] nvme: unregister when pr_register() is given a zero new key Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 206/507] KVM: x86/mmu: Conditionally resched when retrying gPTE walk on A/D update failure Greg Kroah-Hartman
` (301 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, John Garry, Yuqiang Sun, Keith Busch,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuqiang Sun <izaiahsun@gmail.com>
[ Upstream commit 7dfe79db5615df8d37ae7de6d3ec099b71bf3e03 ]
Since commit 9952f3882ecb ("nvme: fix cdev lifetime"),
nvme_add_ns_cdev() and nvme_add_ns_head_cdev() take a reference to the
namespace (or namespace head) before calling nvme_cdev_add(), to be
dropped by the char device's release, nvme_cdev_rel(), and drop it
themselves when nvme_cdev_add() fails. But when cdev_device_add()
fails, nvme_cdev_add() has already put the device, and nvme_cdev_rel()
has already dropped that reference: the caller drops it a second time.
With one allocation failure injected into cdev_device_add() for a
namespace on an NVMe over loop controller, deleting the controller
gives, with native multipath:
BUG: KASAN: slab-use-after-free in nvme_put_ns_head+0x21/0x140
Write of size 4 at addr ff1100000a4ea078 by task init/1
nvme_put_ns_head
nvme_put_ns
nvme_remove_namespaces
nvme_do_delete_ctrl
nvme_delete_ctrl_sync
nvme_sysfs_delete
Freed by task 1:
kfree
nvme_ns_remove
nvme_remove_namespaces
refcount_t: underflow; use-after-free.
Take the reference in nvme_cdev_add() instead, right before
cdev_device_add(), and let the callers neither take nor drop it. Add
nvme_is_ns_cdev() for the check that nvme_cdev_rel() and nvme_cdev_add()
now share.
Fixes: 9952f3882ecb ("nvme: fix cdev lifetime")
Cc: stable@vger.kernel.org
Reviewed-by: John Garry <john.garry@linux.dev>
Signed-off-by: Yuqiang Sun <izaiahsun@gmail.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/core.c | 18 +++++++++++++++---
drivers/nvme/host/multipath.c | 2 --
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index af71d02b84765..9ea9db0271c2d 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -3941,10 +3941,16 @@ static int nvme_subsys_check_duplicate_ids(struct nvme_subsystem *subsys,
return 0;
}
+/* The char device of a namespace rather than of a namespace head */
+static bool nvme_is_ns_cdev(struct device *dev)
+{
+ return dev->parent->class == &nvme_class;
+}
+
static void nvme_cdev_rel(struct device *dev)
{
ida_free(&nvme_ns_chr_minor_ida, MINOR(dev->devt));
- if (dev->parent->class == &nvme_class)
+ if (nvme_is_ns_cdev(dev))
nvme_put_ns(container_of(dev, struct nvme_ns, cdev_device));
else
nvme_put_ns_head(container_of(dev, struct nvme_ns_head,
@@ -3978,6 +3984,14 @@ int nvme_cdev_add(struct cdev *cdev, struct device *cdev_device,
device_initialize(cdev_device);
cdev_init(cdev, fops);
cdev->owner = owner;
+ /* Undone in nvme_cdev_rel() */
+ if (nvme_is_ns_cdev(cdev_device))
+ nvme_get_ns(container_of(cdev_device, struct nvme_ns,
+ cdev_device));
+ else
+ nvme_get_ns_head(container_of(cdev_device,
+ struct nvme_ns_head,
+ cdev_device));
ret = cdev_device_add(cdev, cdev_device);
if (ret)
put_device(cdev_device);
@@ -4010,13 +4024,11 @@ static void nvme_add_ns_cdev(struct nvme_ns *ns)
{
ns->cdev_device.parent = ns->ctrl->device;
- nvme_get_ns(ns); /* Undone in nvme_cdev_rel() */
if (nvme_cdev_add(&ns->cdev, &ns->cdev_device,
&nvme_ns_chr_fops, ns->ctrl->ops->module,
ns->ctrl->instance, ns->head->instance)) {
dev_err(ns->ctrl->device, "Unable to create the ng%dn%d device\n",
ns->ctrl->instance, ns->head->instance);
- nvme_put_ns(ns);
return;
}
set_bit(NVME_NS_CDEV_LIVE, &ns->flags);
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
index 99ecc73393e58..0920fa9616de0 100644
--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -648,14 +648,12 @@ static void nvme_add_ns_head_cdev(struct nvme_ns_head *head)
{
head->cdev_device.parent = &head->subsys->dev;
- nvme_get_ns_head(head); /* Undone in nvme_cdev_rel() */
if (nvme_cdev_add(&head->cdev, &head->cdev_device,
&nvme_ns_head_chr_fops, THIS_MODULE,
head->subsys->instance, head->instance)) {
dev_err(disk_to_dev(head->disk),
"Unable to create the ng%dn%d device\n",
head->subsys->instance, head->instance);
- nvme_put_ns_head(head);
return;
}
set_bit(NVME_NSHEAD_CDEV_LIVE, &head->flags);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 206/507] KVM: x86/mmu: Conditionally resched when retrying gPTE walk on A/D update failure
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (204 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 205/507] nvme: Do not drop the cdev reference twice when cdev_device_add() fails Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 207/507] KVM: x86: Conditionally resched when restarting REP string emulation Greg Kroah-Hartman
` (300 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stefan Teodorescu,
Sean Christopherson, Paolo Bonzini, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit b2691b3a6cd230209736c89684dab90d939aa56b ]
Conditionally reschedule when retrying a guest PTE walk because the CMPXCHG
to update A/D bits failed, e.g. because a different task/vCPU modified the
relevant gPTEs. On kernels without involuntary preemption of some kind, a
misbehaving guest can "capture" a pCPU effectively indefinitely and trigger
soft lockups by continuously modifying its gPTEs such that the result of
the walk is remains valid.
Fixes: b3e4e63fd9ee ("KVM: MMU: Use cmpxchg for pte updates on walk_addr()")
Cc: stable@vger.kernel.org
Reported-by: Stefan Teodorescu <fane@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-ID: <20261022015903.282261-1-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/mmu/paging_tmpl.h | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h
index 6e0153f231363..7454dac59b3a8 100644
--- a/arch/x86/kvm/mmu/paging_tmpl.h
+++ b/arch/x86/kvm/mmu/paging_tmpl.h
@@ -339,6 +339,13 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
gpa_t real_gpa;
gfn_t gfn;
+ /*
+ * KVM might sleep/resched when retrying the walk if the updating A/D
+ * fails because the gPTE changed between reading the gPTE and trying
+ * the CMPXHG to set A/D bits.
+ */
+ might_sleep();
+
trace_kvm_mmu_pagetable_walk(addr, access);
retry_walk:
walker->level = w->cpu_role.base.level;
@@ -479,8 +486,10 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker,
addr, write_fault);
if (unlikely(ret < 0))
goto error;
- else if (ret)
+ else if (ret) {
+ cond_resched();
goto retry_walk;
+ }
}
return 1;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 207/507] KVM: x86: Conditionally resched when restarting REP string emulation
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (205 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 206/507] KVM: x86/mmu: Conditionally resched when retrying gPTE walk on A/D update failure Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 208/507] KVM: nVMX: Process each host MSR entry at most once when unwinding failed VM-Entry Greg Kroah-Hartman
` (299 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Woodhouse, Stefan Teodorescu,
Sean Christopherson, Paolo Bonzini, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit ae85ac25eb671d174811cc3101549448671fd505 ]
When restarting emulation, e.g. of a REP-prefixed string instruction,
conditionally reschedule as emulating guest writes can be deceptively slow
and expensive, e.g. when shadow paging is in use and each write can trigger
write tracking.
In a perfect world, restarting emulation (or not) would be less arbitrary,
e.g. would honor not only host events (NEED_RESCHED, signals, etc.) but
also guest events (e.g. by checking kvm_vcpu_has_events()). Unfortunately,
as pointed out by Sashiko, pio_in_emulated()'s read-ahead logic is baked
into the restart logic, as KVM relies on restarting emulation to drain the
cache and avoid duplicate reads from the I/O port. I.e. re-entering the
guest on kvm_vcpu_has_events() or __xfer_to_guest_mode_work_pending() would
introduce architecturally-incorrect, guest-visible changes.
Fixes: 5cd21917da24 ("KVM: x86 emulator: restart string instruction without going back to a guest.")
Cc: stable@vger.kernel.org
Cc: David Woodhouse <dwmw2@infradead.org>
Reported-by: Stefan Teodorescu <fane@google.com>
Suggested-by: Stefan Teodorescu <fane@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-ID: <20261028173638.1765329-1-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/x86.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index c76498d1a162e..00e2e4587543b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -6515,10 +6515,12 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
} else if (vcpu->arch.complete_userspace_io) {
writeback = false;
r = 0;
- } else if (r == EMULATION_RESTART)
+ } else if (r == EMULATION_RESTART) {
+ cond_resched();
goto restart;
- else
+ } else {
r = 1;
+ }
writeback:
if (writeback) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 208/507] KVM: nVMX: Process each host MSR entry at most once when unwinding failed VM-Entry
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (206 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 207/507] KVM: x86: Conditionally resched when restarting REP string emulation Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 209/507] KVM: x86/mmu: Cap number of parent PTEs per SP at 1000 (the arbitrary rmap limit) Greg Kroah-Hartman
` (298 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Woodhouse, Stefan Teodorescu,
Sean Christopherson, Paolo Bonzini, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit c33ef9d334059f7cb167569ed7b4779752fe4425 ]
Add a missing "break" in the inner for-loop of the open coded mess that
unwinds MSRs back to the pre-VM-Enter state when VMLAUNCH/VMRESUME VM-Fails
due to a consistency check that is caught by hardware but missed by KVM.
I.e. move on to the next MSR in the VM-Entry load list after performing a
write using a value found in the VM-Exit load list. Processing *every*
matching entry in the VM-Exit load list makes the processing quadratic,
which is problematic if the load lists are full of MSRs that are expensive
to emulate. E.g. writing APIC_BASE triggers kvm_recalculate_apic_map() and
a whole pile of unnecessary work.
Functionally, arbitrarily restoring the value of the first matching entry
is "fine", because none of this is architecturally correct: the load lists
are never supposed to have been used in the first place. In practice, it's
likely a moot point as no well-behaved VMM will have multiple, diverging
entries in the load lists.
Fixes: bd18bffca353 ("KVM: nVMX: restore host state in nested_vmx_vmexit for VMFail")
Cc: stable@vger.kernel.org
Cc: David Woodhouse <dwmw2@infradead.org>
Reported-by: Stefan Teodorescu <fane@google.com>
Suggested-by: Stefan Teodorescu <fane@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-ID: <20261027185917.1478906-1-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/vmx/nested.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 5165275128fce..a1450c55e946c 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -5059,6 +5059,7 @@ static void nested_vmx_restore_host_state(struct kvm_vcpu *vcpu)
__func__, j, h.index, h.value);
goto vmabort;
}
+ break;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 209/507] KVM: x86/mmu: Cap number of parent PTEs per SP at 1000 (the arbitrary rmap limit)
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (207 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 208/507] KVM: nVMX: Process each host MSR entry at most once when unwinding failed VM-Entry Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 210/507] KVM: x86: Unconditionally reset MMU context when emulating INIT Greg Kroah-Hartman
` (297 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jim Mattson, James Houghton,
Yosry Ahmed, David Woodhouse, Stefan Teodorescu,
Sean Christopherson, Paolo Bonzini, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit e4558c3d7198ed9a0adc3304681f561f4e4d80e1 ]
When potentially reusing a shadow page, zap the shadow page if its number
of parent PTEs exceeds KVM's (mostly) arbitrary rmap recycling threshold.
Letting the guest create a (mostly) unbounded number of parent PTEs allows
the guest to coerce KVM into creating lists containing millions of PTEs,
effectively bounded only by the maximum number of shadow pages.
Because PTE lists are simple singly linked lists, removal is O(n). Even
worse, if a list is constructed just so, teardown can be O(n^2), e.g. if
SPTEs are built such that zapping child SPTEs always zaps the last entry
in the list. To cap things off, all paths that walk PTE lists do so
while holding mmu_lock, without conditionally rescheduling.
Using a doubly linked list would not address the issue, as removal would
remain O(n) since KVM still wouldn't know where in the list to remove from.
Removal could be made O(1) by storing a per-SPTE pointer, but that would
largely defeat the purpose of reusing SPs, and would penalize well-behaved
guests, especially for nested TDP where aliasing page tables is uncommon.
So, cap the maximum number of parent PTEs at the rmap limit. In practice,
well-behaved guests will likely never run afoul of the limit. E.g. when
running Linux as L1 with TDP, the number of parent PTEs for a single SP
tops out at under 200 (though undoubtedly obscure workloads can push it
higher). Deliberately use a "greater than or equal" as opposed to rmap's
strictly "greater than", as the rmap code checks the threshold immediately
*after* inserting into the list, i.e. the limit is 1000 for rmaps, KVM just
very briefly blows past it.
Apply the check to both indirect and direct SPs, because while a fully
direct MMU naturally limits the number of parent PTEs to '1', direct SPs in
indirect MMUs have no such constraint. E.g. if the guest maps a huge PTE
into many locations in its page tables, and KVM is backing the hugepage
with a direct SP, i.e. with a series of smaller pages, then KVM could end
up with a direct SP with many parents.
Note, shadow_mmu_try_split_huge_pages() always restarts the rmap walk or
bails entirely if it gets to the point where it tries to grab a SP, i.e.
there is *no* pre-existing bug that would be tripped by zapping a SP and
thus rmaps when getting a SP.
Cc: Jim Mattson <jmattson@google.com>
Cc: James Houghton <jthoughton@google.com>
Cc: Yosry Ahmed <yosry@kernel.org>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: stable@vger.kernel.org
Reported-by: Stefan Teodorescu <fane@google.com>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-ID: <20261027171518.1432557-1-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/mmu/mmu.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index e56497089b599..2c2ff20f8ad0f 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -2310,6 +2310,16 @@ static struct kvm_mmu_page *kvm_mmu_find_shadow_page(struct kvm *kvm,
continue;
}
+ /*
+ * Note! Unlike fully direct MMUs, direct SPs in indirect MMUs
+ * can have an arbitrary number of parents, e.g if the guest is
+ * mapping a huge PTE at many points in its page tables.
+ */
+ if (pte_list_count(&sp->parent_ptes) >= RMAP_RECYCLE_THRESHOLD) {
+ kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list);
+ break;
+ }
+
/* unsync and write-flooding only apply to indirect SPs. */
if (sp->role.direct)
goto out;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 210/507] KVM: x86: Unconditionally reset MMU context when emulating INIT
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (208 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 209/507] KVM: x86/mmu: Cap number of parent PTEs per SP at 1000 (the arbitrary rmap limit) Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 211/507] ASoC: tas2770: Fix error detection in tas2770_set_dai_tdm_idle Greg Kroah-Hartman
` (296 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stefan Teodorescu, Oren Yomtov,
Chris Mason, Yosry Ahmed, Sean Christopherson, Paolo Bonzini,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit c7c288d178cb0b78d3464a616b16b1aa0b316049 ]
Force an MMU reset when emulating an INIT even if paging was already
disabled, as the MMU page role includes guest_mode (L2), i.e. an INIT while
L2 is running with CR0.PG=0 will result in KVM running L1 with a stale MMU
context.
Alternatively, the reset could be scoped strictly to paging being enabled
or L2 being active, but SMM is also encoded in the page role. Even though
it _should_ be impossible for the vCPU to be INIT'd while SMM is active,
there's zero value in not handling SMM. At that point, the only scenario
where KVM _doesn't_ need to reset the MMU context is on an INIT with the
vCPU running in Real Mode or Unpaged Protect Mode, and while INIT in those
modes is somewhat common, it's far from a hot path and re-initializing the
MMU is not expensive, especially when the role isn't changing (KVM elides
most of the re-configuration in that case).
Note, like the Fixes commit, this bug only affects nested SVM as INIT is an
unconditional intercept on VMX, i.e. it's impossible to emulate INIT while
L2 is active.
Temporarily keep the guest TLB flush when CR0.PG is being cleared even
though it is fully redundant with the flush that is emitted on all INIT
events (KVM itself only does RESET when a vCPU is being created, i.e. when
CR0.PG must be '0').
Fixes: ed129ec9057f ("KVM: x86: forcibly leave nested mode on vCPU reset")
Reported-by: Stefan Teodorescu <fane@google.com>
Reported-by: Oren Yomtov <thenameisoren@gmail.com>
Reported-by: Chris Mason <mason@kernel.org>
Cc: stable@vger.kernel.org
Cc: Yosry Ahmed <yosry@kernel.org>
Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-ID: <20261022015407.279870-2-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/x86.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 00e2e4587543b..56a19a7260d3d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -9663,18 +9663,23 @@ void kvm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
kvm_x86_call(set_efer)(vcpu, 0);
kvm_x86_call(update_exception_bitmap)(vcpu);
+ if (old_cr0 & X86_CR0_PG)
+ kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
+
/*
- * On the standard CR0/CR4/EFER modification paths, there are several
- * complex conditions determining whether the MMU has to be reset and/or
- * which PCIDs have to be flushed. However, CR0.WP and the paging-related
- * bits in CR4 and EFER are irrelevant if CR0.PG was '0'; and a reset+flush
- * is needed anyway if CR0.PG was '1' (which can only happen for INIT, as
- * CR0 will be '0' prior to RESET). So we only need to check CR0.PG here.
+ * Unconditionally reset the MMU, even though super strictly speaking,
+ * a MMU reset is only necessary if and only one of the page role bits
+ * is changing. All of the CR0/CR4/EFER bits effectively get covered
+ * by checking CR0.PG=1, as CR0.WP and the paging-related bits in CR4
+ * and EFER are irrelevant if CR0.PG was '0'. Subtly, if the vCPU was
+ * in guest mode (L2) or SMM (although emulating INIT in SMM _should_
+ * be impossible), an MMU reset is also necessary as "guest mode" and
+ * "smm" are both encoded in the shadow page role. As a result, the
+ * only scenarios where an MMU reset is *not* needed is if the vCPU is
+ * in Real Mode or Unpaged Protected Mode, and micro-optimizing those
+ * paths are not worth the risk of running with a stale MMU context.
*/
- if (old_cr0 & X86_CR0_PG) {
- kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
- kvm_mmu_reset_context(vcpu);
- }
+ kvm_mmu_reset_context(vcpu);
/*
* Intel's SDM states that all TLB entries are flushed on INIT. AMD's
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 211/507] ASoC: tas2770: Fix error detection in tas2770_set_dai_tdm_idle
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (209 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 210/507] KVM: x86: Unconditionally reset MMU context when emulating INIT Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 212/507] inet: frags: limit the truesize of a reassembly queue Greg Kroah-Hartman
` (295 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, James Calligeros, Mark Brown,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Calligeros <jcalligeros99@gmail.com>
[ Upstream commit f65f866dacbb10a37e4fae4076627c767afd3cbb ]
snd_soc_component_update_bits returns 1 on a successful update, and
we were returning from tas2770_set_dai_tdm_idle early on any nonzero
return code. Change this so that only negative return codes are
treated as errors.
Fixes: af176d0787d2 ("ASoC: tas2770: expose SDOUT bus keeper via set_tdm_idle")
Cc: stable@vger.kernel.org
Signed-off-by: James Calligeros <jcalligeros99@gmail.com>
Link: https://patch.msgid.link/20261025-tas2770-idle-fix-v2-1-6c8096a87f44@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/tas2770.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c
index e79754edac5ca..355fcbfd01c79 100644
--- a/sound/soc/codecs/tas2770.c
+++ b/sound/soc/codecs/tas2770.c
@@ -513,7 +513,7 @@ static int tas2770_set_dai_tdm_idle(struct snd_soc_dai *dai,
ret = snd_soc_component_update_bits(component, TAS2770_DIN_PD,
TAS2770_DIN_PD_SDOUT,
TAS2770_DIN_PD_SDOUT);
- if (ret)
+ if (ret < 0)
return ret;
break;
@@ -521,12 +521,12 @@ static int tas2770_set_dai_tdm_idle(struct snd_soc_dai *dai,
ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG4,
TAS2770_TDM_CFG_REG4_TX_KEEPER,
TAS2770_TDM_CFG_REG4_TX_KEEPER);
- if (ret)
+ if (ret < 0)
return ret;
ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG4,
TAS2770_TDM_CFG_REG4_TX_FILL, 0);
- if (ret)
+ if (ret < 0)
return ret;
break;
@@ -534,25 +534,25 @@ static int tas2770_set_dai_tdm_idle(struct snd_soc_dai *dai,
ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG4,
TAS2770_TDM_CFG_REG4_TX_KEEPER,
TAS2770_TDM_CFG_REG4_TX_KEEPER);
- if (ret)
+ if (ret < 0)
return ret;
ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG4,
TAS2770_TDM_CFG_REG4_TX_FILL,
TAS2770_TDM_CFG_REG4_TX_FILL);
- if (ret)
+ if (ret < 0)
return ret;
break;
case SND_SOC_DAI_TDM_IDLE_OFF:
ret = snd_soc_component_update_bits(component, TAS2770_DIN_PD,
TAS2770_DIN_PD_SDOUT, 0);
- if (ret)
+ if (ret < 0)
return ret;
ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG4,
TAS2770_TDM_CFG_REG4_TX_KEEPER, 0);
- if (ret)
+ if (ret < 0)
return ret;
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 212/507] inet: frags: limit the truesize of a reassembly queue
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (210 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 211/507] ASoC: tas2770: Fix error detection in tas2770_set_dai_tdm_idle Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 213/507] ipv6: reject wrapped temporary address preferred lifetimes Greg Kroah-Hartman
` (294 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyle Zeng, Florian Westphal,
Eric Dumazet, Ido Schimmel, Jiayuan Chen, Wang Zhan, Paolo Abeni,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@kernel.org>
[ Upstream commit 3ae20e4697eb969104fe4b1e98a675f0100382b6 ]
The truesize of fragments in a reassembly queue is only bounded by
the per netns ipfrag_high_thresh sysctl, which has no upper limit.
inet_frag_reasm_finish() sums the truesize of all fragments in an int.
If this sum reaches 2^32, it wraps, and the final sk_wmem_alloc
adjustment of the socket owning the reassembled skb can cancel its own
reference, leading to a use-after-free of this socket.
This can be triggered from an unprivileged user/network namespace,
raising ipfrag_high_thresh and using padded TUN packets, which keep
a large truesize after being trimmed by ip_rcv_core().
Track the sum of the truesize of fragments in each queue, and refuse
a fragment that would make it bigger than INT_MAX / 2. Callers kill
the queue on this error. This bound is far above the needs of
legitimate traffic.
Fixes: 18685451fc4e ("inet: inet_defrag: prevent sk release while still in use")
Cc: stable@vger.kernel.org
Reported-by: Kyle Zeng <kylebot@openai.com>
Cc: Florian Westphal <fw@strlen.de>
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Tested-by: Wang Zhan <wang.zhan@smartx.com>
Link: https://patch.msgid.link/20261030081225.2575462-1-edumazet@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/inet_frag.h | 9 +++++++++
net/ipv4/inet_fragment.c | 5 +++++
2 files changed, 14 insertions(+)
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index b02d2472b003e..c1fb419a9cf03 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -79,6 +79,7 @@ struct frag_v6_compare_key {
* @tstamp_type: stamp has a mono delivery time (EDT)
* @flags: fragment queue flags
* @max_size: maximum received fragment size
+ * @truesize: sum of the truesize of queued fragments
* @fqdir: pointer to struct fqdir
* @rcu: rcu head for freeing deferall
*/
@@ -100,6 +101,7 @@ struct inet_frag_queue {
u8 tstamp_type;
__u8 flags;
u16 max_size;
+ unsigned int truesize;
struct fqdir *fqdir;
struct rcu_head rcu;
};
@@ -172,6 +174,13 @@ extern const u8 ip_frag_ecn_table[16];
#define IPFRAG_DUP 1
#define IPFRAG_OVERLAP 2
#define IPFRAG_MIXED_SECPATH 3
+#define IPFRAG_TOOBIG 4
+
+/* Max sum of the truesize of fragments in a queue. This keeps the sums
+ * done in inet_frag_reasm_prepare() and inet_frag_reasm_finish() well
+ * below INT_MAX. Legitimate traffic stays far below this limit.
+ */
+#define INET_FRAG_MAX_TRUESIZE (INT_MAX / 2)
int inet_frag_queue_insert(struct inet_frag_queue *q, struct sk_buff *skb,
int offset, int end);
void *inet_frag_reasm_prepare(struct inet_frag_queue *q, struct sk_buff *skb,
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index c18da91c1f031..0b8d22ffafca6 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -336,6 +336,7 @@ void inet_frag_queue_flush(struct inet_frag_queue *q,
q->rb_fragments = RB_ROOT;
q->fragments_tail = NULL;
q->last_run_head = NULL;
+ q->truesize = 0;
}
EXPORT_SYMBOL(inet_frag_queue_flush);
@@ -446,6 +447,9 @@ int inet_frag_queue_insert(struct inet_frag_queue *q, struct sk_buff *skb,
if (last && !secpath_equal(last, skb))
return IPFRAG_MIXED_SECPATH;
+ if (skb->truesize > INET_FRAG_MAX_TRUESIZE - q->truesize)
+ return IPFRAG_TOOBIG;
+
/* An IP fragment is never a GSO packet, but an untrusted source
* (virtio_net_hdr) may have attached GSO metadata to it. Do not let
* that reach the reassembled skb, whose head keeps the first
@@ -510,6 +514,7 @@ int inet_frag_queue_insert(struct inet_frag_queue *q, struct sk_buff *skb,
if (offset)
nf_reset_ct(skb);
+ q->truesize += skb->truesize;
return IPFRAG_OK;
}
EXPORT_SYMBOL(inet_frag_queue_insert);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 213/507] ipv6: reject wrapped temporary address preferred lifetimes
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (211 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 212/507] inet: frags: limit the truesize of a reassembly queue Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 214/507] x86/vmware: Fix i386 high-bandwidth hypercall arguments Greg Kroah-Hartman
` (293 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Yingjie Wang,
Alex Henrie, Paolo Abeni, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yingjie Wang <1075151112@qq.com>
[ Upstream commit c3e67bd82b9b9b1a5118f09a429ccefe2aab0741 ]
ipv6_create_tempaddr() raises a temporary address's preferred lifetime to
regen_advance + age + 1 when the configured lifetime is too short. The
result is stored in a u32, while regen_advance and age are unsigned long.
If the sum wraps or is truncated, the stored lifetime can still be less
than or equal to regen_advance + age.
addrconf_verify_rtnl() then sees the new address as due for regeneration
and creates another one. Temporary addresses are not limited by
max_addresses since commit 4b08a8f1bd8c ("ipv6: remove max_addresses
check from ipv6_create_tempaddr"), so this can cause unbounded address
growth. With dad_transmits set to -1, a baseline kernel reached 2859
loopback addresses in two seconds.
After storing the adjusted lifetime, verify that it is still greater than
regen_advance + age. Reject the new address if the check fails.
On an x86-64 KASAN kernel, the normal configuration created three IPv6
addresses. The negative dad_transmits, positive multiplication overflow,
and large retransmission-time cases each left only the loopback and public
addresses. An i386 defconfig and an x86-64 allmodconfig both built
addrconf.o with W=1.
Fixes: f4bcbf360ac8 ("net: ipv6/addrconf: clamp preferred_lft to the minimum required")
Cc: stable@vger.kernel.org
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/netdev/20261029175827.GA1411453@shredder/
Signed-off-by: Yingjie Wang <1075151112@qq.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Alex Henrie <alexhenrie24@gmail.com>
Link: https://patch.msgid.link/tencent_7A270291DDE5CD89DAFFE8A745D094D5BD06@qq.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/addrconf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a2d3fb187f768..3350330c3f1c2 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1484,7 +1484,8 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, bool block)
age = (now - tmp_tstamp + ADDRCONF_TIMER_FUZZ_MINUS) / HZ;
if (cfg.preferred_lft <= regen_advance + age) {
cfg.preferred_lft = regen_advance + age + 1;
- if (cfg.preferred_lft > cfg.valid_lft ||
+ if (cfg.preferred_lft <= regen_advance + age ||
+ cfg.preferred_lft > cfg.valid_lft ||
cfg.preferred_lft > if_public_preferred_lft) {
in6_ifa_put(ifp);
in6_dev_put(idev);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 214/507] x86/vmware: Fix i386 high-bandwidth hypercall arguments
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (212 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 213/507] ipv6: reject wrapped temporary address preferred lifetimes Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 215/507] Bluetooth: hci_sync: re-enable legacy advertising on resume Greg Kroah-Hartman
` (292 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zack Rusin, Borislav Petkov (AMD),
Maaz Mombasawala, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zack Rusin <zack.rusin@broadcom.com>
[ Upstream commit e0e022004bbedc7caf1c18770980eb5372019189 ]
The high-bandwidth hypercall helpers push %ebp before loading the in6
operand into it. On i386 without frame pointers, both GCC and Clang can
address the memory-constrained operand relative to %esp. The push then
moves the stack and the helpers load the wrong value.
Typical i386 configurations use the frame-pointer unwinder and happen to
address the operand through %ebp. However, UNWINDER_GUESS is available
with EXPERT and permits the affected frame-pointer-disabled configuration.
vmwgfx is also available on i386 and calls both helpers.
Stage in6 through %eax before changing either stack register, then save
%ebp and copy the staged value into it. Load the VMware magic immediately
before the string I/O instruction. Mark %eax early-clobber so it cannot
also provide in6 or an address register for it. Use the same sequence on
x86-64, where the full-width register preserves in6.
Fixes: 34bf25e820ae ("x86/vmware: Introduce VMware hypercall API")
Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Maaz Mombasawala <maaz.mombasawala@broadcom.com>
Cc: stable@vger.kernel.org # 6.11+
Link: https://patch.msgid.link/4ab10678a8f50053934b62b56af81f881c1d3798.1788414669.git.zack.rusin@broadcom.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/include/asm/vmware.h | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/arch/x86/include/asm/vmware.h b/arch/x86/include/asm/vmware.h
index 4220dae14a2d9..fb011cef01e76 100644
--- a/arch/x86/include/asm/vmware.h
+++ b/arch/x86/include/asm/vmware.h
@@ -276,20 +276,22 @@ unsigned long vmware_hypercall_hb_out(unsigned long cmd, unsigned long in2,
asm_inline volatile (
UNWIND_HINT_SAVE
+ "mov %[in6], %%" _ASM_AX "\n\t"
"push %%" _ASM_BP "\n\t"
UNWIND_HINT_UNDEFINED
- "mov %[in6], %%" _ASM_BP "\n\t"
+ "mov %%" _ASM_AX ", %%" _ASM_BP "\n\t"
+ "mov %[magic], %%eax\n\t"
"rep outsb\n\t"
"pop %%" _ASM_BP "\n\t"
UNWIND_HINT_RESTORE
- : "=a" (out0), "=b" (*out1)
- : "a" (VMWARE_HYPERVISOR_MAGIC),
- "b" (cmd),
+ : "=&a" (out0), "=b" (*out1)
+ : "b" (cmd),
"c" (in2),
"d" (in3 | VMWARE_HYPERVISOR_PORT_HB),
"S" (in4),
"D" (in5),
- [in6] VMW_BP_CONSTRAINT (in6)
+ [in6] VMW_BP_CONSTRAINT(in6),
+ [magic] "i" (VMWARE_HYPERVISOR_MAGIC)
: "cc", "memory");
return out0;
}
@@ -304,20 +306,22 @@ unsigned long vmware_hypercall_hb_in(unsigned long cmd, unsigned long in2,
asm_inline volatile (
UNWIND_HINT_SAVE
+ "mov %[in6], %%" _ASM_AX "\n\t"
"push %%" _ASM_BP "\n\t"
UNWIND_HINT_UNDEFINED
- "mov %[in6], %%" _ASM_BP "\n\t"
+ "mov %%" _ASM_AX ", %%" _ASM_BP "\n\t"
+ "mov %[magic], %%eax\n\t"
"rep insb\n\t"
"pop %%" _ASM_BP "\n\t"
UNWIND_HINT_RESTORE
- : "=a" (out0), "=b" (*out1)
- : "a" (VMWARE_HYPERVISOR_MAGIC),
- "b" (cmd),
+ : "=&a" (out0), "=b" (*out1)
+ : "b" (cmd),
"c" (in2),
"d" (in3 | VMWARE_HYPERVISOR_PORT_HB),
"S" (in4),
"D" (in5),
- [in6] VMW_BP_CONSTRAINT (in6)
+ [in6] VMW_BP_CONSTRAINT(in6),
+ [magic] "i" (VMWARE_HYPERVISOR_MAGIC)
: "cc", "memory");
return out0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 215/507] Bluetooth: hci_sync: re-enable legacy advertising on resume
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (213 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 214/507] x86/vmware: Fix i386 high-bandwidth hypercall arguments Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 216/507] Bluetooth: hci_sync: pause advertising for the scan address update Greg Kroah-Hartman
` (291 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Valentin Kindschi,
Luiz Augusto von Dentz, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Valentin Kindschi <valentin.kindschi@fiveco.ch>
[ Upstream commit 737139f4157d302292a6b937d96922879ecabfa3 ]
hci_resume_advertising_sync() never re-enables advertising on a
controller without extended advertising.
It restores HCI_ADVERTISING from advertising_old_state, then calls
hci_schedule_adv_instance_sync(), which starts with:
if (hci_dev_test_flag(hdev, HCI_ADVERTISING) && !ext_adv_capable(hdev))
return -EPERM;
The flag it tests was set a few lines earlier by the resume itself, so
the call returns -EPERM without sending anything. The return value is
discarded by every caller, so the failure is silent: advertising_paused
is cleared, HCI_ADVERTISING is set, and the controller is not
advertising.
Observed on a BCM43455 (no extended advertising) after an active scan:
btmon shows the pause disabling advertising and no re-enable in the ten
seconds that follow, the device does not appear in another controller's
scan, and btmgmt info still reports "advertising" in current settings.
Enable instance 0x00 directly in that case, the way reenable_adv_sync()
already does for the same situation. Instances continue to go through
hci_schedule_adv_instance_sync() so the software rotation loop is
rearmed.
This affects every caller of hci_resume_advertising_sync(), not only the
scan path: address resolution changes, accept list updates, discovery
stop, suspend/resume and the end of an LE connection attempt all leave
advertising disabled on such a controller today.
The resume does nothing when the controller is already advertising, as
it is after directed advertising was started for a peripheral
connection, so it does not replace that advertising.
err is initialised because the extended branch leaves it unset when
adv_instances is empty and HCI_LE_ADV_0 is clear.
Fixes: ad383c2c65a5 ("Bluetooth: hci_sync: Enable advertising when LL privacy is enabled")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5.5 btmon
Signed-off-by: Valentin Kindschi <valentin.kindschi@fiveco.ch>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_sync.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index a92a81846e9df..4468c1d0b5e58 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -2687,7 +2687,7 @@ static int hci_pause_advertising_sync(struct hci_dev *hdev)
static int hci_resume_advertising_sync(struct hci_dev *hdev)
{
struct adv_info *adv, *tmp;
- int err;
+ int err = 0;
/* If advertising has not been paused there is nothing to do. */
if (!hdev->advertising_paused)
@@ -2720,13 +2720,19 @@ static int hci_resume_advertising_sync(struct hci_dev *hdev)
*/
if (hci_dev_test_and_clear_flag(hdev, HCI_LE_ADV_0))
err = hci_enable_ext_advertising_sync(hdev, 0x00);
- } else {
+ } else if (hdev->cur_adv_instance) {
/* Schedule for most recent instance to be restarted and begin
* the software rotation loop
*/
err = hci_schedule_adv_instance_sync(hdev,
hdev->cur_adv_instance,
true);
+ } else if (hci_dev_test_flag(hdev, HCI_ADVERTISING) &&
+ !hci_dev_test_flag(hdev, HCI_LE_ADV)) {
+ /* hci_schedule_adv_instance_sync() rejects instance 0x00 while
+ * HCI_ADVERTISING is set, so enable it directly.
+ */
+ err = hci_start_adv_sync(hdev, 0x00);
}
hdev->advertising_paused = false;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 216/507] Bluetooth: hci_sync: pause advertising for the scan address update
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (214 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 215/507] Bluetooth: hci_sync: re-enable legacy advertising on resume Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 217/507] Bluetooth: qca: Fix the WCN3950 NVM baud rate offset Greg Kroah-Hartman
` (290 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Valentin Kindschi,
Luiz Augusto von Dentz, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Valentin Kindschi <valentin.kindschi@fiveco.ch>
[ Upstream commit 56ed6b127a27c418dc2daa3fd076539d8fe69c4c ]
hci_active_scan_sync() programs a non-resolvable private address with LE
Set Random Address on every active scan start.
BLUETOOTH CORE SPECIFICATION Vol 4, Part E, 7.8.4 says the controller
shall return Command Disallowed (0x0C) for that command while legacy
advertising or scanning is enabled. hci_pause_addr_resolution(), called
just above, only stops advertising when LL privacy is in use, so on a
controller without it the command is issued while advertising is still
on:
Bluetooth: hci0: Opcode 0x2005 failed: -16
It does not converge either. hdev->random_addr is only set on a
successful command complete, so it stays BDADDR_ANY, and the deferral
added by commit c2994b008492 ("Bluetooth: hci_sync: Fix not setting
Random Address when required") requires it to be set. Unlike the
resolvable address a few lines above, which is reused while rpa_valid(),
the non-resolvable one is regenerated and rewritten on every call, so a
controller that refuses the write is asked again at the scan restart
period of about 10 s, for as long as discovery keeps restarting.
Observed on a BCM43455, which has no LL privacy and no extended
advertising, 190 rejections in one capture, every one retrying the same
address:
< LE Set Random Address Address: 02:16:91:90:F1:D4 (Non-Resolvable)
> Command Complete LE Set Random Address, Command Disallowed
< LE Set Random Address Address: 26:90:57:96:9A:3E (Non-Resolvable)
> Command Complete LE Set Random Address, Command Disallowed
Pause advertising for the address update, and resume it once the update
is done and before the scan is started. The pause does not outlive the
function: it is taken only when nothing else holds it, and every exit
resumes advertising, which also releases the pause taken by
hci_pause_addr_resolution(). A failed pause returns before marking
anything paused, so the error path is a no-op.
The resume in the error path is no longer guarded by ll_privacy_capable().
That guard matched a pause taken only under LL privacy; the pause added
here is unconditional, and hci_resume_advertising_sync() returns early
when nothing was paused.
One caveat this widens, raised on the previous posting. When
HCI_ADVERTISING is set, hci_pause_advertising_sync() also clears
HCI_DISCOVERABLE and HCI_LIMITED_DISCOVERABLE and zeroes discov_timeout,
and hci_resume_advertising_sync() restores only HCI_ADVERTISING, so the
discoverable state is lost. It reproduces today on an LL privacy
controller through hci_pause_addr_resolution(); the unconditional pause
makes it reachable without LL privacy as well. hci_suspend_sync() also
pauses unconditionally, so a device that suspends loses the same state
on any controller today. That asymmetry is pre-existing and is left
alone here rather than folded into a scan path fix.
Legacy controllers have one random address register, shared by the
scanner and the advertiser. Restoring the advertiser here can reprogram
it when the advertiser is non-connectable, so the scan then uses that
address rather than the one generated for it. Both are non-resolvable
and neither is linkable to the identity address. With privacy enabled
both roles already share one resolvable address the same way.
With the patch, on the same hardware:
< LE Set Advertising Enable Enable: 0x00 Success
< LE Set Random Address Success
< LE Set Advertising Parameters Success
< LE Set Advertising Enable Enable: 0x01 Success
< LE Set Scan Parameters Success
< LE Set Scan Enable Enable: 0x01 Success
The address write is accepted, and advertising is restored before the
scan is started.
Over 119369 btmon records and about 12 minutes of the normal workload of
that device, alternating active and passive scanning with ten outgoing
connection attempts, every LE Set Random Address succeeded and there were
no Command Disallowed responses of any opcode, against one per scan
restart before.
Patch 1 is required: without it the resume added here returns -EPERM on
the controllers this fixes and leaves advertising disabled.
Fixes: 3c44a431d62b ("Bluetooth: hci_sync: Resume adv with no RPA when active scan")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5.5 btmon
Signed-off-by: Valentin Kindschi <valentin.kindschi@fiveco.ch>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_sync.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 4468c1d0b5e58..5b99da7028b9d 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -6278,6 +6278,7 @@ static int hci_active_scan_sync(struct hci_dev *hdev, uint16_t interval)
u8 filter_policy = 0x00;
/* Default is to enable duplicates filter */
u8 filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
+ bool paused;
int err;
bt_dev_dbg(hdev, "");
@@ -6301,6 +6302,12 @@ static int hci_active_scan_sync(struct hci_dev *hdev, uint16_t interval)
if (err)
goto failed;
+ /* LE Set Random Address is disallowed while advertising is enabled. */
+ paused = !hdev->advertising_paused;
+ err = hci_pause_advertising_sync(hdev);
+ if (err)
+ goto failed;
+
/* All active scans will be done with either a resolvable private
* address (when privacy feature has been enabled) or non-resolvable
* private address.
@@ -6310,6 +6317,9 @@ static int hci_active_scan_sync(struct hci_dev *hdev, uint16_t interval)
if (err < 0)
own_addr_type = ADDR_LE_DEV_PUBLIC;
+ if (paused)
+ hci_resume_advertising_sync(hdev);
+
if (hci_is_adv_monitoring(hdev) ||
(hci_test_quirk(hdev, HCI_QUIRK_STRICT_DUPLICATE_FILTER) &&
hdev->discovery.result_filtering)) {
@@ -6333,9 +6343,8 @@ static int hci_active_scan_sync(struct hci_dev *hdev, uint16_t interval)
return err;
failed:
- /* Resume advertising if it was paused */
- if (ll_privacy_capable(hdev))
- hci_resume_advertising_sync(hdev);
+ /* No-op when advertising was not paused. */
+ hci_resume_advertising_sync(hdev);
/* Resume passive scanning */
hci_update_passive_scan_sync(hdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 217/507] Bluetooth: qca: Fix the WCN3950 NVM baud rate offset
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (215 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 216/507] Bluetooth: hci_sync: pause advertising for the scan address update Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 218/507] ASoC: qcom: q6apm: Guard callbacks until probe data is ready Greg Kroah-Hartman
` (289 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael McAllister,
Bartosz Golaszewski, Luiz Augusto von Dentz, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael McAllister <me@michaelmcallister.org>
[ Upstream commit 5b7d0386a4e75c85479da0fbd9fd66a3e9201375 ]
WCN3950 uses the HCI transport tag layout that stores the UART baud rate
at byte 1, like WCN3991. However, QCA_WCN3950 precedes QCA_WCN3991 in
qca_btsoc_type, so qca_tlv_check_data() writes the baud rate to byte 2
instead.
On a Motorola Moto G10 with WCN3950 and cmnv12.bin, configuring a 3 Mbps
UART therefore leaves the NVM baud rate at its default 3.2 Mbps and
overwrites the following byte. Firmware download completes, but the
subsequent HCI_RESET times out and Bluetooth initialization fails.
Include WCN3950 in the byte-1 case so the NVM baud rate matches the host
UART without altering the following transport parameter.
Fixes: d5712c511cb3 ("Bluetooth: qca: add WCN3950 support")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Michael McAllister <me@michaelmcallister.org>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btqca.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
index 22b08ab05b829..002307000d3cd 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -426,7 +426,8 @@ static int qca_tlv_check_data(struct hci_dev *hdev,
tlv_nvm->data[0] |= 0x80;
/* UART Baud Rate */
- if (soc_type >= QCA_WCN3991)
+ if (soc_type == QCA_WCN3950 ||
+ soc_type >= QCA_WCN3991)
tlv_nvm->data[1] = nvm_baud_rate;
else
tlv_nvm->data[2] = nvm_baud_rate;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 218/507] ASoC: qcom: q6apm: Guard callbacks until probe data is ready
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (216 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 217/507] Bluetooth: qca: Fix the WCN3950 NVM baud rate offset Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 219/507] x86/resctrl: Correct ABMC counter ID field width Greg Kroah-Hartman
` (288 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ajay Kumar Nandam, Mohit Sharma,
Mark Brown, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mohit Sharma <mohit.sharma@oss.qualcomm.com>
[ Upstream commit ef7062864c0511bba52775d0eb3aa72d886b5f3a ]
The GPR bus needs to make response callbacks available before invoking a
client probe because clients can issue synchronous commands from probe.
This creates a short interval where a callback can run before the client
has published its private data.
Make q6apm publish its driver data only after all callback-visible state
has been initialized. Have the q6apm and q6prm callbacks ignore packets
received before driver data is available.
Fixes: ec1471a898cc ("soc: qcom: apr: Add GPR support")
Cc: stable@vger.kernel.org
Co-developed-by: Ajay Kumar Nandam <ajay.nandam@oss.qualcomm.com>
Signed-off-by: Ajay Kumar Nandam <ajay.nandam@oss.qualcomm.com>
Signed-off-by: Mohit Sharma <mohit.sharma@oss.qualcomm.com>
Link: https://patch.msgid.link/20261022144130.2443667-2-mohit.sharma@oss.qualcomm.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/qcom/qdsp6/q6apm.c | 6 ++++--
sound/soc/qcom/qdsp6/q6prm.c | 3 +++
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c
index a79bbb34c777e..8a756249e5884 100644
--- a/sound/soc/qcom/qdsp6/q6apm.c
+++ b/sound/soc/qcom/qdsp6/q6apm.c
@@ -884,8 +884,6 @@ static int apm_probe(gpr_device_t *gdev)
if (!apm)
return -ENOMEM;
- dev_set_drvdata(dev, apm);
-
mutex_init(&apm->lock);
apm->dev = dev;
apm->gdev = gdev;
@@ -899,6 +897,7 @@ static int apm_probe(gpr_device_t *gdev)
idr_init(&apm->modules_idr);
+ dev_set_drvdata(dev, apm);
g_apm = apm;
q6apm_get_apm_state(apm);
@@ -942,6 +941,9 @@ static int apm_callback(const struct gpr_resp_pkt *data, void *priv, int op)
const struct gpr_hdr *hdr = &data->hdr;
int graph_id, is_pos_buf;
+ if (!apm)
+ return 0;
+
result = data->payload;
switch (hdr->opcode) {
diff --git a/sound/soc/qcom/qdsp6/q6prm.c b/sound/soc/qcom/qdsp6/q6prm.c
index 1f3ce4cc08370..bcc73127d54db 100644
--- a/sound/soc/qcom/qdsp6/q6prm.c
+++ b/sound/soc/qcom/qdsp6/q6prm.c
@@ -192,6 +192,9 @@ static int prm_callback(const struct gpr_resp_pkt *data, void *priv, int op)
const struct gpr_ibasic_rsp_result_t *result;
const struct gpr_hdr *hdr = &data->hdr;
+ if (!prm)
+ return 0;
+
switch (hdr->opcode) {
case PRM_CMD_RSP_REQUEST_HW_RSC:
case PRM_CMD_RSP_RELEASE_HW_RSC:
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 219/507] x86/resctrl: Correct ABMC counter ID field width
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (217 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 218/507] ASoC: qcom: q6apm: Guard callbacks until probe data is ready Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 220/507] x86,fs/resctrl: Keep mbm_assign_mode in default mode at boot Greg Kroah-Hartman
` (287 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Babu Moger, Borislav Petkov (AMD),
Reinette Chatre, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Babu Moger <babu.moger@amd.com>
[ Upstream commit 84b4b620af7d24916add5d45104023bc5d804f53 ]
AMD's Assignable Bandwidth Monitoring Counters (ABMC) are configured via
MSR_IA32_L3_QOS_ABMC_CFG. The cntr_id field selects the counter the
configuration applies to. The number of counters a platform supports (the
number of possible values written into that field) is enumerated separately
via CPUID.
On platforms that enumerate more than 32 counters, the current 5-bit encoding
truncates the counter ID and misprograms ABMC.
The section "Assignable Bandwidth Monitoring (ABMC)" in the APM has been
updated to widen MSR_IA32_L3_QOS_ABMC_CFG.cntr_id from 5 bits to 12 bits.
The CPUID enumeration reports the maximum counter ID in a 16-bit field and may
therefore report more counters than a 12-bit MSR_IA32_L3_QOS_ABMC_CFG.cntr_id
can address.
Widen MSR_IA32_L3_QOS_ABMC_CFG.cntr_id to 12 bits to match the architecture.
Cap the enumerated counter count at BIT(12) so every counter ID used by
resctrl can be written to MSR_IA32_L3_QOS_ABMC_CFG.cntr_id without truncation.
[ bp: Massage and simplify commit message. ]
Fixes: 84ecefb76674 ("x86/resctrl: Add data structures and definitions for ABMC assignment")
Signed-off-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/3a5e99300f1309ae279beb058ef0438516b2bdcd.1793392128.git.babu.moger@amd.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kernel/cpu/resctrl/internal.h | 4 ++--
arch/x86/kernel/cpu/resctrl/monitor.c | 3 ++-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index e3cfa0c10e92d..ffd74a68671b0 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -214,8 +214,8 @@ union l3_qos_abmc_cfg {
bw_src :12,
reserved1: 3,
is_clos : 1,
- cntr_id : 5,
- reserved : 9,
+ cntr_id :12,
+ reserved : 2,
cntr_en : 1,
cfg_en : 1;
} split;
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index 3838e0a13d36f..5d0d3b18f9b82 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -470,7 +470,8 @@ int __init rdt_get_l3_mon_config(struct rdt_resource *r)
r->mon.mbm_cntr_assignable = true;
r->mon.mbm_cntr_configurable = true;
cpuid_count(0x80000020, 5, &eax, &ebx, &ecx, &edx);
- r->mon.num_mbm_cntrs = (ebx & GENMASK(15, 0)) + 1;
+ /* cntr_id is 12 bits and can only encode 4096 counters. */
+ r->mon.num_mbm_cntrs = min((ebx & GENMASK(15, 0)) + 1, BIT(12));
hw_res->mbm_cntr_assign_enabled = true;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 220/507] x86,fs/resctrl: Keep mbm_assign_mode in default mode at boot
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (218 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 219/507] x86/resctrl: Correct ABMC counter ID field width Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 221/507] mm/khugepaged: flush deferred unmaps before dropping a failed folio Greg Kroah-Hartman
` (286 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Babu Moger, Borislav Petkov (AMD),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Babu Moger <babu.moger@amd.com>
[ Upstream commit 7782a6a8dfc05f5622fdf616e5cf3df7d16eaef5 ]
The mbm_event mode assigns hardware MBM counters to RMID/event pairs. It is
intended for deployments that need to manage counter assignment on platforms
where the number of monitoring groups exceeds the available hardware counters.
Hardware counters are scarce on these platforms, so mbm_event mode suits
workflows that monitor a subset of groups at a time and rotate assignments as
needed.
x86 resctrl enables the mbm_event mode by default on hardware that supports
it. This breaks the pqos tool¹, which assumes the historical default mode.
It creates 16 or more monitoring groups and uses two counters per group. On
a platform with 32 counters per domain, that exhausts the mbm_event counters
pool, causing additional groups to read "Unassigned". pqos interprets
a non-numeric event read as zero bandwidth and reports 0 MB/s for those
groups:
$ sudo pqos -m all:0-4
CORE IPC MISSES LLC[KB] MBL[MB/s] MBR[MB/s]
0 0.69 16k 192.0 0.0 0.0
1 0.40 3k 0.0 0.0 0.0
2 0.44 1k 64.0 0.0 0.0
3 0.39 1k 64.0 0.0 0.0
4 0.43 1k 0.0 0.0 0.0
Leave mbm_assign_mode in default mode during initialization as decided in the
thread at the Link tag. Default mode uses one counter per monitoring group. On
existing AMD platforms, the default active counters pool is 64 and may be
larger on newer hardware. The active counters pool is the number of counters
that the hardware can actively track in default mode.
Deployments within the active counters pool receive accurate bandwidth
measurements in the default mode. Users can create more monitoring groups (for
example, 4096 on current hardware) than there are active counters in the pool.
Beyond that pool, readings may be misleading or report as "Unavailable", with
no user-visible indication.
Default mode is still limited once the number of monitoring groups exceeds
that active counters pool. After hardware re-allocates a counter, a read
may return "Unavailable". pqos still treats "Unavailable" as zero.
Successive reads can be a count, "Unavailable", then another count. pqos
treats those jumps as wraparound and can report an inconsistent rate:
$ sudo pqos -m all:0-4
CORE IPC MISSES LLC[KB] MBL[MB/s] MBR[MB/s]
0 0.76 60k 32.0 0.0 0.0
1 0.45 1k 32.0 0.0 0.0
2 1.57 107k 64.0 0.0 17592186044184.9
3 1.62 276k 4928.0 3.2 0.5
Users that need stable measurements beyond the active counters pool should
use mbm_event mode and rotate assignments as needed. Enable it with:
# echo mbm_event > /sys/fs/resctrl/info/L3_MON/mbm_assign_mode
¹https://github.com/intel/intel-cmt-cat
[ bp: Massage commit message. ]
Fixes: 0f1576e43adc ("x86/resctrl: Configure mbm_event mode if supported")
Closes: https://github.com/intel/intel-cmt-cat/issues/311
Signed-off-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/all/20260804191608.GDanI6eK2Q07w6pNcb@fat_crate.local
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/filesystems/resctrl.rst | 87 ++++++++++++++++-----------
arch/x86/kernel/cpu/resctrl/monitor.c | 1 -
2 files changed, 51 insertions(+), 37 deletions(-)
diff --git a/Documentation/filesystems/resctrl.rst b/Documentation/filesystems/resctrl.rst
index e4b66af55ffba..6b641c3cee644 100644
--- a/Documentation/filesystems/resctrl.rst
+++ b/Documentation/filesystems/resctrl.rst
@@ -351,12 +351,12 @@ with the following files:
"mbm_assign_mode":
The supported counter assignment modes. The enclosed brackets indicate which mode
is enabled. The MBM events associated with counters may reset when "mbm_assign_mode"
- is changed.
+ is changed. See architecture specific notes below.
::
# cat /sys/fs/resctrl/info/L3_MON/mbm_assign_mode
- [mbm_event]
- default
+ [default]
+ mbm_event
"mbm_event":
@@ -374,20 +374,17 @@ with the following files:
Moving to mbm_event counter assignment mode requires users to assign the counters
to the events. Otherwise, the MBM event counters will return 'Unassigned' when read.
- The mode is beneficial for AMD platforms that support more CTRL_MON
- and MON groups than available hardware counters. By default, this
- feature is enabled on AMD platforms with the ABMC (Assignable Bandwidth
- Monitoring Counters) capability, ensuring counters remain assigned even
- when the corresponding RMID is not actively used by any processor.
+ It is intended for deployments that need to manage counter assignment on
+ platforms where the number of monitoring groups exceeds the available
+ hardware counters. Hardware counters are scarce on these platforms, so
+ mbm_event mode suits workflows that monitor a subset of groups at a time and
+ rotate assignments as needed. The mbm_event mode ensures counters remain
+ assigned even when the corresponding RMID is not actively used.
"default":
In default mode, resctrl assumes there is a hardware counter for each
- event within every CTRL_MON and MON group. On AMD platforms, it is
- recommended to use the mbm_event mode, if supported, to prevent reset of MBM
- events between reads resulting from hardware re-allocating counters. This can
- result in misleading values or display "Unavailable" if no counter is assigned
- to the event.
+ event within every CTRL_MON and MON group.
* To enable "mbm_event" counter assignment mode:
::
@@ -399,6 +396,24 @@ with the following files:
# echo "default" > /sys/fs/resctrl/info/L3_MON/mbm_assign_mode
+ In default mode on AMD platforms that support more CTRL_MON and MON groups
+ than hardware counters, hardware dynamically shares a smaller pool of
+ counters among RMIDs. One counter from this pool is used per monitoring
+ group and counts every MBM event of that group's RMID. The size of the pool
+ is not enumerated to software (unlike "num_mbm_cntrs"), and "num_rmids" may
+ be much larger. For example, 64 counters in this pool monitor 64 groups.
+ Newer hardware may provide a larger pool.
+
+ On such platforms, while the number of monitoring groups does not exceed
+ that pool, a counter stays attached to each RMID and readings remain
+ accurate. Creating more groups than the pool can cause hardware to
+ re-allocate those counters between successive reads of an event. Bandwidth
+ values may then be misleading, or a read may return "Unavailable" if no
+ counter is allocated to the RMID. There is no user-visible indication when
+ this begins. Users who need stable readings beyond that pool should switch
+ to mbm_event mode, if supported, and assign counters to the groups of
+ interest (rotating assignments as needed).
+
"num_mbm_cntrs":
The maximum number of counters (total of available and assigned counters) in
each domain when the system supports mbm_event mode.
@@ -1783,17 +1798,19 @@ View the llc occupancy snapshot::
Examples on working with mbm_assign_mode
========================================
-a. Check if MBM counter assignment mode is supported.
+a. Check if MBM counter assignment mode is supported. Enable "mbm_event"
+mode. Switching the mbm_assign_mode may reset all the MBM counters (and
+thus all MBM events) of all the resctrl groups.
::
- # mount -t resctrl resctrl /sys/fs/resctrl/
-
+ # cat /sys/fs/resctrl/info/L3_MON/mbm_assign_mode
+ [default]
+ mbm_event
+ # echo "mbm_event" > /sys/fs/resctrl/info/L3_MON/mbm_assign_mode
# cat /sys/fs/resctrl/info/L3_MON/mbm_assign_mode
[mbm_event]
default
-The "mbm_event" mode is detected and enabled.
-
b. Check how many assignable counters are supported.
::
@@ -1804,36 +1821,39 @@ c. Check how many assignable counters are available for assignment in each domai
::
# cat /sys/fs/resctrl/info/L3_MON/available_mbm_cntrs
- 0=30;1=30
+ 0=32;1=32
-d. To list the default group's assign states.
+d. To list the default group's assign states. Counters are unassigned when the mode
+is switched to "mbm_event".
::
# cat /sys/fs/resctrl/mbm_L3_assignments
- mbm_total_bytes:0=e;1=e
- mbm_local_bytes:0=e;1=e
+ mbm_total_bytes:0=_;1=_
+ mbm_local_bytes:0=_;1=_
-e. To unassign the counter associated with the mbm_total_bytes event on domain 0.
+e. To assign the counter associated with the mbm_total_bytes event on domain 0
+in exclusive mode.
::
- # echo "mbm_total_bytes:0=_" > /sys/fs/resctrl/mbm_L3_assignments
+ # echo "mbm_total_bytes:0=e" > /sys/fs/resctrl/mbm_L3_assignments
# cat /sys/fs/resctrl/mbm_L3_assignments
- mbm_total_bytes:0=_;1=e
- mbm_local_bytes:0=e;1=e
+ mbm_total_bytes:0=e;1=_
+ mbm_local_bytes:0=_;1=_
f. To unassign the counter associated with the mbm_total_bytes event on all domains.
::
# echo "mbm_total_bytes:*=_" > /sys/fs/resctrl/mbm_L3_assignments
- # cat /sys/fs/resctrl/mbm_L3_assignment
+ # cat /sys/fs/resctrl/mbm_L3_assignments
mbm_total_bytes:0=_;1=_
- mbm_local_bytes:0=e;1=e
+ mbm_local_bytes:0=_;1=_
-g. To assign a counter associated with the mbm_total_bytes event on all domains in
-exclusive mode.
+g. To assign a counter associated with the mbm_total_bytes and mbm_local_bytes
+events on all domains in exclusive mode.
::
# echo "mbm_total_bytes:*=e" > /sys/fs/resctrl/mbm_L3_assignments
+ # echo "mbm_local_bytes:*=e" > /sys/fs/resctrl/mbm_L3_assignments
# cat /sys/fs/resctrl/mbm_L3_assignments
mbm_total_bytes:0=e;1=e
mbm_local_bytes:0=e;1=e
@@ -1890,13 +1910,8 @@ the MBM counters (and thus all MBM events) of all the resctrl groups.
# echo "default" > /sys/fs/resctrl/info/L3_MON/mbm_assign_mode
# cat /sys/fs/resctrl/info/L3_MON/mbm_assign_mode
- mbm_event
[default]
-
-m. Unmount the resctrl filesystem.
-::
-
- # umount /sys/fs/resctrl/
+ mbm_event
Intel RDT Errata
================
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index 5d0d3b18f9b82..a6a9090c4808c 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -472,7 +472,6 @@ int __init rdt_get_l3_mon_config(struct rdt_resource *r)
cpuid_count(0x80000020, 5, &eax, &ebx, &ecx, &edx);
/* cntr_id is 12 bits and can only encode 4096 counters. */
r->mon.num_mbm_cntrs = min((ebx & GENMASK(15, 0)) + 1, BIT(12));
- hw_res->mbm_cntr_assign_enabled = true;
}
r->mon_capable = true;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 221/507] mm/khugepaged: flush deferred unmaps before dropping a failed folio
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (219 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 220/507] x86,fs/resctrl: Keep mbm_assign_mode in default mode at boot Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 222/507] mm: fix address wraparound when scanning large folio PTEs Greg Kroah-Hartman
` (285 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyle Zeng, Andrew Morton,
David Hildenbrand (Arm), Zi Yan, Baolin Wang, Hugh Dickins,
Barry Song, Dev Jain, Kiryl Shutsemau, Lance Yang,
Liam R. Howlett, Nico Pache, Ryan Roberts, Usama Arif,
Matthew Wilcox (Oracle), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kyle Zeng <kylebot@openai.com>
[ Upstream commit 854e5ff8b3ce2a776586cabebaeae645c992345b ]
collapse_file() can fail its reference-count or dirty-folio check after
unmapping with TTU_BATCH_FLUSH. Both paths put back the isolated folio,
then unlock it and drop the lookup reference before reaching the common
try_to_unmap_flush().
The page-cache reference does not keep the folio stable once the lock is
released. Another collapse can replace and free it. With its PTEs
already gone, that collapse cannot flush the first task's per-task TLB
batch, and retract_page_tables() skips short or unaligned VMAs. A CPU can
therefore retain a user translation to the freed folio. This has been
reproduced with unprivileged MADV_COLLAPSE on a memfd.
Flush at out_unlock while the lookup reference and folio lock are still
held. The common flush continues to cover the accumulated pagelist on
both success and rollback, preserving batching on successful collapses.
Link: https://lore.kernel.org/20261007041001.43181-1-kylebot@openai.com
Fixes: 6d9df8a5889c ("mm/thp: collapse_file() do try_to_unmap(TTU_BATCH_FLUSH)")
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Acked-by: Hugh Dickins <hughd@google.com>
Assisted-by: LLM
Cc: Barry Song <baohua@kernel.org>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Kiryl Shutsemau <kas@kernel.org>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: "Liam R. Howlett" <liam@infradead.org>
Cc: Nico Pache <nico.pache@linux.dev>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Usama Arif <usama.arif@linux.dev>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/khugepaged.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index b717de08e3c8b..16444bd7f1c0a 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -2488,6 +2488,11 @@ static enum scan_result collapse_file(struct mm_struct *mm, unsigned long addr,
index += folio_nr_pages(folio);
continue;
out_unlock:
+ /*
+ * The folio may have been unmapped with TTU_BATCH_FLUSH.
+ * Flush before releasing the lock and our last reference.
+ */
+ try_to_unmap_flush();
folio_unlock(folio);
folio_put(folio);
goto xa_unlocked;
@@ -2498,9 +2503,8 @@ static enum scan_result collapse_file(struct mm_struct *mm, unsigned long addr,
xa_unlocked:
/*
- * If collapse is successful, flush must be done now before copying.
- * If collapse is unsuccessful, does flush actually need to be done?
- * Do it anyway, to clear the state.
+ * Flush before copying the folios, or releasing them in rollback.
+ * This is a no-op if out_unlock already flushed the batch.
*/
try_to_unmap_flush();
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 222/507] mm: fix address wraparound when scanning large folio PTEs
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (220 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 221/507] mm/khugepaged: flush deferred unmaps before dropping a failed folio Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 223/507] mm: memory: fix truncation removing mapped folios Greg Kroah-Hartman
` (284 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Hildenbrand (Arm),
Andrew Morton, Kyle Zeng, Lorenzo Stoakes (ARM),
Kiryl Shutsemau (Meta), Baolin Wang, Lance Yang, Barry Song,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Ying Huang, Ryan Roberts,
Chuanhua Han, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit f681d4580d5c3c749f623cda722a21aefd3147b3 ]
numa_rebuild_large_mapping() and do_swap_page() can be tricked into
generating an address wraparound, crashing the kernel. All that's required
is to map a tail page of a large folio close enough to the start/end of
the address space to e.g., make
unsigned long addr_start = addr - (nr << PAGE_SHIFT);
to wrap around.
Let's fix it by providing a better helper, folio_scan_range(), that
takes care of staying within VMA and page table boundaries while
handling possible wraparounds.
There are some nasty details, like not being able to use pmd_addr_end()
in this context. Add some helpful comments for these cases.
Link: https://lore.kernel.org/20261014-folio_pte_scan_range-v2-1-00cf9bbaa364@kernel.org
Fixes: d2136d749d76 ("mm: support multi-size THP numa balancing")
Fixes: 508758960b8d ("mm: swap: entirely map large folios found in swapcache")
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: Kyle Zeng <kylebot@openai.com>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Reviewed-by: Barry Song <baohua@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Ying Huang <huang.ying.caritas@gmail.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Chuanhua Han <hanchuanhua@oppo.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/memory.c | 50 ++++++++++++++++++++++++++++++++++++--------------
1 file changed, 36 insertions(+), 14 deletions(-)
diff --git a/mm/memory.c b/mm/memory.c
index 9eb7975e4a45e..ca6d7e08635ff 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4868,6 +4868,34 @@ static void check_swap_exclusive(struct folio *folio, swp_entry_t entry,
} while (--nr_pages);
}
+/*
+ * Get the address range in which a folio might be mapped, assuming its pages
+ * are mapped consecutively and the folio page at the given idx is mapped at
+ * the given address.
+ */
+static void folio_pte_range(const struct folio *folio,
+ const struct vm_area_struct *vma, unsigned long addr,
+ unsigned long idx, unsigned long *start, unsigned long *end)
+{
+ /* Stay within the page table and VMA boundaries. */
+ const unsigned long pmd_start = addr & PMD_MASK;
+ const unsigned long pmd_end = pmd_start + PMD_SIZE;
+ const unsigned long lower = max(pmd_start, vma->vm_start);
+ /*
+ * We cannot use pmd_addr_end(), as it does not clamp reliably. To
+ * avoid wraparounds, compute using the inclusive end.
+ */
+ const unsigned long upper = min(pmd_end - 1, vma->vm_end - 1) + 1;
+ const unsigned long offset = idx << PAGE_SHIFT;
+
+ /*
+ * Avoid start/end addresses wrapping by not adding/subtracting more
+ * than the lower/upper limits would allow.
+ */
+ *start = addr - min(addr - lower, offset);
+ *end = addr + min(upper - addr, folio_size(folio) - offset);
+}
+
/*
* We enter with either the VMA lock or the mmap_lock held (see
* FAULT_FLAG_VMA_LOCK), and pte mapped but not yet locked.
@@ -5050,16 +5078,15 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
address = vmf->address;
ptep = vmf->pte;
if (folio_test_large(folio) && folio_test_swapcache(folio)) {
- int nr = folio_nr_pages(folio);
- unsigned long idx = folio_page_idx(folio, page);
- unsigned long folio_start = address - idx * PAGE_SIZE;
- unsigned long folio_end = folio_start + nr * PAGE_SIZE;
+ const int nr = folio_nr_pages(folio);
+ const unsigned long idx = folio_page_idx(folio, page);
+ unsigned long folio_start, folio_end;
pte_t *folio_ptep;
pte_t folio_pte;
- if (unlikely(folio_start < max(address & PMD_MASK, vma->vm_start)))
- goto check_folio;
- if (unlikely(folio_end > pmd_addr_end(address, vma->vm_end)))
+ folio_pte_range(folio, vma, address, idx, &folio_start,
+ &folio_end);
+ if (unlikely((folio_end - folio_start) >> PAGE_SHIFT != nr))
goto check_folio;
folio_ptep = vmf->pte - idx;
@@ -6209,16 +6236,11 @@ static void numa_rebuild_large_mapping(struct vm_fault *vmf, struct vm_area_stru
struct folio *folio, pte_t fault_pte,
bool ignore_writable, bool pte_write_upgrade)
{
- int nr = pte_pfn(fault_pte) - folio_pfn(folio);
+ const unsigned long idx = pte_pfn(fault_pte) - folio_pfn(folio);
unsigned long start, end, addr = vmf->address;
- unsigned long addr_start = addr - (nr << PAGE_SHIFT);
- unsigned long pt_start = ALIGN_DOWN(addr, PMD_SIZE);
pte_t *start_ptep;
- /* Stay within the VMA and within the page table. */
- start = max3(addr_start, pt_start, vma->vm_start);
- end = min3(addr_start + folio_size(folio), pt_start + PMD_SIZE,
- vma->vm_end);
+ folio_pte_range(folio, vma, addr, idx, &start, &end);
start_ptep = vmf->pte - ((addr - start) >> PAGE_SHIFT);
/* Restore all PTEs' mapping of the large folio */
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 223/507] mm: memory: fix truncation removing mapped folios
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (221 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 222/507] mm: fix address wraparound when scanning large folio PTEs Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 224/507] mm/page-writeback: avoid 32-bit overflow in dirty threshold shares Greg Kroah-Hartman
` (283 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baolin Wang, Andrew Morton,
Ayush Ranjan, Qi Zheng, Pedro Falcato, Lorenzo Stoakes (ARM),
David Hildenbrand (Arm), Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Jan Kara,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baolin Wang <baolin.wang@linux.alibaba.com>
[ Upstream commit 243cf1f67b365668389832463fc31cbb9fec47af ]
Ayush reported an issue that shmem/tmpfs folios are still mapped when
truncating them on production:
"
BUG: Bad page cache in process ... pfn:...
page dumped because: still mapped when deleted
"
I reproduced the issue with Ayush's reproducer [1] with the latest
mm-unstable branch, and I got the following crash info. From the dump
message, we can see that truncate_inode_folio() is really trying to remove
mapped folios, which is incorrect.
"
[ 189.171977] page: refcount:3 mapcount:1 mapping:00000000fe168ee1
index:0x3880 pfn:0x191647
[ 189.171995] memcg:ffff0000cc073d40
[ 189.171997] aops:shmem_aops ino:3c01 dentry name(?):"memfd:runsc-memory"
[ 189.172006] flags: 0x17fffef0002022d(locked|referenced|uptodate|lru|
workingset|swapbacked|node=0|zone=2|lastcpupid=0x3ffff)
.......
[ 189.172017] page dumped because: VM_BUG_ON_FOLIO(folio_mapped(folio))
[ 189.172026] ------------[ cut here ]------------
[ 189.172027] kernel BUG at mm/filemap.c:155!
[ 189.172057] Internal error: Oops - BUG: 00000000f2000800 [#1] SMP
.......
[ 189.177721] CPU: 3 UID: 0 PID: 5521 Comm: repro Kdump: loaded Tainted:
7.3.0-rc4+ #277 PREEMPT(lazy)
.......
[ 189.183986] Call trace:
[ 189.184124] filemap_unaccount_folio+0xf0/0x1e8 (P)
[ 189.184391] __filemap_remove_folio+0x34/0x160
[ 189.184633] filemap_remove_folio+0x4c/0xb0
[ 189.184859] truncate_inode_folio+0x34/0x58
[ 189.185087] shmem_undo_range+0x220/0x658
[ 189.185308] shmem_fallocate+0x2f0/0x470
[ 189.185527] vfs_fallocate+0x128/0x328
......
[ 189.187078] el0t_64_sync+0x184/0x188
"
After analysis, I believe the race exists between truncation and
MADV_DONTNEED, and shmem's ->map_pages() merely makes the issue easier to
reproduce. Since MADV_DONTNEED synchronously releases the pagetable page
before calling tlb_flush_rmaps(), this could cause another thread's
truncation to skip zap_pte_range() (due to pmd is none) but still observe
the folio's mapcount as non-zero. A possible race scenario is as follows:
CPU 0 CPU 1
shmem_fallocate madvise_dontneed_single_vma
unmap_mapping_range .......
......
(filemap_map_pages() remap folios)
zap_pte_range
truncate_inode_folio zap_empty_pte_table(pmd clear)
unmap_mapping_folio
......
zap_pmd_range (saw pmd none, skip)
filemap_remove_folio
BUG_ON(folio_mapped)
tlb_flush_rmaps(remove rmaps)
To fix this issue, we should move the pmd clear operation (via
zap_empty_pte_table()) to after tlb_flush_rmaps() and use
sync_with_folio_pmd_zap() to sync with concurrent zapping, so that when we
find a pmd_none() while unmapping a folio without holding the PTL, the
folio's mappings are guaranteed to have been removed via
tlb_flush_rmaps().
Meanwhile move the second pmd_none() check to where it belongs: if
splitting zapped the PMD.
Link: https://lore.kernel.org/14ebbd556cc4941f0ebc43da59fa6a2fdca25dc8.1793148609.git.baolin.wang@linux.alibaba.com
Link: https://lore.kernel.org/all/20260925065013.3682431-1-ayushr@modal.com/ [1]
Fixes: 6375e95f381e ("mm: pgtable: reclaim empty PTE page in madvise(MADV_DONTNEED)")
Signed-off-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: Ayush Ranjan <ayushr@modal.com>
Closes: https://lore.kernel.org/all/20260924061708.1645968-1-ayushr@modal.com/
Acked-by: Qi Zheng <qi.zheng@linux.dev>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Jan Kara <jack@suse.cz>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/internal.h | 10 ++++++----
mm/memory.c | 35 ++++++++++++++++++++---------------
2 files changed, 26 insertions(+), 19 deletions(-)
diff --git a/mm/internal.h b/mm/internal.h
index 38b1165212c94..a533b56e2f2b9 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -584,14 +584,16 @@ void free_pgtables(struct mmu_gather *tlb, struct unmap_desc *desc);
void pmd_install(struct mm_struct *mm, pmd_t *pmd, pgtable_t *pte);
/**
- * sync_with_folio_pmd_zap - sync with concurrent zapping of a folio PMD
+ * sync_with_folio_pmd_zap - sync with concurrent zapping of folios
* @mm: The mm_struct.
* @pmdp: Pointer to the pmd that was found to be pmd_none().
*
* When we find a pmd_none() while unmapping a folio without holding the PTL,
- * zap_huge_pmd() may have cleared the PMD but not yet modified the folio to
- * indicate that it's unmapped. Skipping the PMD without synchronization could
- * make folio unmapping code assume that unmapping failed.
+ * zap_huge_pmd() may have cleared the PMD but not yet updated the folio
+ * mapcount, and zap_empty_pte_table() clears the PMD only after the rmaps
+ * for the table have been removed, but nothing orders the pmd_none() read
+ * against later mapcount reads. Skipping the PMD without synchronization
+ * could make folio unmapping code assume that unmapping failed.
*
* Wait for concurrent zapping to complete by grabbing the PTL.
*/
diff --git a/mm/memory.c b/mm/memory.c
index ca6d7e08635ff..243b34f2e54fa 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -2071,6 +2071,15 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
}
} while (pte += nr, addr += PAGE_SIZE * nr, addr != end);
+ add_mm_rss_vec(mm, rss);
+ lazy_mmu_mode_disable();
+
+ /* Do the actual TLB flush before dropping ptl */
+ if (force_flush) {
+ tlb_flush_mmu_tlbonly(tlb);
+ tlb_flush_rmaps(tlb, vma);
+ }
+
/*
* Fast path: try to hold the pmd lock and unmap the PTE page.
*
@@ -2078,18 +2087,12 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
* to hold the pmd lock failed, then we need to recheck all pte entries
* to ensure they are still none, thereby preventing the pte entries
* from being repopulated by another thread.
+ *
+ * Clear the PMD after the rmaps for the table have been removed, in case
+ * an incorrect mapcount is observed after unmapping the folio.
*/
if (can_reclaim_pt && direct_reclaim && addr == end)
direct_reclaim = zap_empty_pte_table(mm, pmd, ptl, &pmdval);
-
- add_mm_rss_vec(mm, rss);
- lazy_mmu_mode_disable();
-
- /* Do the actual TLB flush before dropping ptl */
- if (force_flush) {
- tlb_flush_mmu_tlbonly(tlb);
- tlb_flush_rmaps(tlb, vma);
- }
pte_unmap_unlock(start_pte, ptl);
/*
@@ -2136,13 +2139,15 @@ static inline unsigned long zap_pmd_range(struct mmu_gather *tlb,
addr = next;
continue;
}
+ /* We already synchronized with concurrent zapping. */
+ if (pmd_none(*pmd)) {
+ addr = next;
+ continue;
+ }
/* fall through */
- } else if (details && details->single_folio &&
- folio_test_pmd_mappable(details->single_folio) &&
- next - addr == HPAGE_PMD_SIZE && pmd_none(*pmd)) {
- sync_with_folio_pmd_zap(tlb->mm, pmd);
- }
- if (pmd_none(*pmd)) {
+ } else if (pmd_none(*pmd)) {
+ if (details && details->single_folio)
+ sync_with_folio_pmd_zap(tlb->mm, pmd);
addr = next;
continue;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 224/507] mm/page-writeback: avoid 32-bit overflow in dirty threshold shares
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (222 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 223/507] mm: memory: fix truncation removing mapped folios Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 225/507] mm/page_alloc: let the highest memory node recover from hopeless state Greg Kroah-Hartman
` (282 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hungyu Lin, Andrew Morton, Jan Kara,
Gregory Price (Meta), Matthew Wilcox (Oracle), Stefan Roesch,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hungyu Lin <dennylin0707@gmail.com>
[ Upstream commit 9597c2056e05bd79df9d343a9b42e84a54de1c52 ]
The ratios used by __wb_calc_thresh() are scaled to parts per million, but
the threshold and ratio operands are unsigned long. On 32-bit kernels,
their multiplication can wrap before the result is assigned to u64.
For example, with a threshold of 25600 pages and the default maximum ratio
of 1000000, wb_max_thresh becomes 4125 pages instead of 25600. The shared
threshold and minimum share calculations can overflow in the same way,
producing incorrect per-writeback dirty limits.
Use a u64 threshold for the three ratio multiplications and div_u64() to
retain the existing division order and rounding.
Link: https://lore.kernel.org/20261021060654.27855-1-dennylin0707@gmail.com
Fixes: ae82291e9ca4 ("mm: use part per 1000000 for bdi ratios")
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Gregory Price (Meta) <gourry@gourry.net>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Stefan Roesch <shr@devkernel.io>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/page-writeback.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index eeab25d6ce364..1d6aab8781a57 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -883,6 +883,7 @@ static unsigned long __wb_calc_thresh(struct dirty_throttle_control *dtc,
{
struct wb_domain *dom = dtc_dom(dtc);
struct bdi_writeback *wb = dtc->wb;
+ u64 threshold = thresh;
u64 wb_thresh;
u64 wb_max_thresh;
unsigned long numerator, denominator;
@@ -894,13 +895,14 @@ static unsigned long __wb_calc_thresh(struct dirty_throttle_control *dtc,
fprop_fraction_percpu(&dom->completions, dtc->wb_completions,
&numerator, &denominator);
- wb_thresh = (thresh * (100 * BDI_RATIO_SCALE - bdi_min_ratio)) / (100 * BDI_RATIO_SCALE);
+ wb_thresh = div_u64(threshold * (100 * BDI_RATIO_SCALE - bdi_min_ratio),
+ 100 * BDI_RATIO_SCALE);
wb_thresh *= numerator;
wb_thresh = div64_ul(wb_thresh, denominator);
wb_min_max_ratio(wb, &wb_min_ratio, &wb_max_ratio);
- wb_thresh += (thresh * wb_min_ratio) / (100 * BDI_RATIO_SCALE);
+ wb_thresh += div_u64(threshold * wb_min_ratio, 100 * BDI_RATIO_SCALE);
/*
* It's very possible that wb_thresh is close to 0 not because the
@@ -916,7 +918,7 @@ static unsigned long __wb_calc_thresh(struct dirty_throttle_control *dtc,
wb_thresh = max(wb_thresh, (thresh - dtc->dirty) / 8);
}
- wb_max_thresh = thresh * wb_max_ratio / (100 * BDI_RATIO_SCALE);
+ wb_max_thresh = div_u64(threshold * wb_max_ratio, 100 * BDI_RATIO_SCALE);
if (wb_thresh > wb_max_thresh)
wb_thresh = wb_max_thresh;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 225/507] mm/page_alloc: let the highest memory node recover from hopeless state
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (223 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 224/507] mm/page-writeback: avoid 32-bit overflow in dirty threshold shares Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 226/507] mm/hugetlb: fix mremap move length truncation Greg Kroah-Hartman
` (281 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gregory Price (Meta), Andrew Morton,
Zi Yan, Vlastimil Babka (SUSE), Suren Baghdasaryan, Michal Hocko,
Brendan Jackman, Johannes Weiner, Chanwon Park, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gregory Price (Meta) <gourry@gourry.net>
[ Upstream commit 83367658a01087375ede31ae343c99da03f72ac8 ]
free_frozen_page_commit() clears a hopeless node's kswapd failures once
its zone recovers above the high watermark, but only if another memory
node exists for allocations to fall back to.
The test `next_memory_node(nid) < MAX_NUMNODES` finds only memory nodes
with a higher id. The highest-numbered memory node therefore never
recovers on this path, and its kswapd stays disabled until reclaim on that
node makes progress and balances it, or demotion is re-enabled.
In many cases, direct reclaim many never fully run against a lower node
(CXL/kmem), and that means its kswapd can end up full disabled in rare
situations.
To reproduce, fill the highest memory node with bound, non-THP anonymous
memory and no swap until kswapd gives up, then free it: /proc/zoneinfo
keeps showing node_unreclaimable 1 for that node. A lower node recovers.
Count the memory nodes instead. Adding first_memory_node != nid to the
existing test would also work, but a count says directly what the check
means: some other memory node exists.
Link: https://lore.kernel.org/20261019184850.3427905-1-gourry@gourry.net
Fixes: e7a5f249e6db ("mm: re-enable kswapd when memory pressure subsides or demotion is toggled")
Signed-off-by: Gregory Price (Meta) <gourry@gourry.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Zi Yan <ziy@nvidia.com>
Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Brendan Jackman <brendan.jackman@linux.dev>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Chanwon Park <flyinrm@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/page_alloc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8ca2289d0491b..319053c6a9c0f 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -2947,7 +2947,7 @@ static bool free_frozen_page_commit(struct zone *zone,
* kswapd work again by resetting kswapd_failures.
*/
if (kswapd_test_hopeless(pgdat) &&
- next_memory_node(pgdat->node_id) < MAX_NUMNODES)
+ num_node_state(N_MEMORY) > 1)
kswapd_clear_hopeless(pgdat, KSWAPD_CLEAR_HOPELESS_PCP);
}
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 226/507] mm/hugetlb: fix mremap move length truncation
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (224 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 225/507] mm/page_alloc: let the highest memory node recover from hopeless state Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 227/507] mm/hugetlb: fix mremap deadlock when PMD sharing is possible Greg Kroah-Hartman
` (280 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Li Zhe, Andrew Morton,
David Hildenbrand (Arm), Muchun Song, Oscar Salvador, Peter Xu,
Mike Rapoport, Jose A. Perez de Azpillaga, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Zhe <lizhe.67@bytedance.com>
[ Upstream commit dfb190302d2b4af86c6ae48af0d3b09f28b35460 ]
Patch series "mm/hugetlb: fix mremap bugs", v3.
This series fixes a few hugetlb mremap bugs.
Patch 1 fixes the return type of move_hugetlb_page_tables(), so large
hugetlb moves cannot be truncated when reported back to the generic
mremap code.
Patch 2 disables hugetlb PMD sharing for UFFD missing mode, so
UFFDIO_POISON markers cannot become visible through shared PMD page
tables.
Patch 3 fixes the recursive i_mmap_rwsem deadlock in the hugetlb mremap
path by avoiding the destination PMD sharing allocation path while the
mapping lock is already held for write.
This patch (of 3):
move_hugetlb_page_tables() returns the number of bytes moved, but
its return type is int while the generic move_page_tables() path uses
unsigned long lengths.
A hugetlb mremap() move length above INT_MAX can therefore be
misreported to copy_vma_and_data(). The out-of-range conversion to int
is implementation-defined; on common 64-bit builds, for example, a
4 GiB move can be reported as zero, making the caller treat the move as
a failure and use the wrong length for rollback.
Return unsigned long from move_hugetlb_page_tables(), matching
move_page_tables() and preserving the full byte count.
Link: https://lore.kernel.org/20261022034543.51226-1-lizhe.67@bytedance.com
Link: https://lore.kernel.org/20261022034543.51226-2-lizhe.67@bytedance.com
Fixes: 550a7d60bd5e ("mm, hugepages: add mremap() support for hugepage backed vma")
Signed-off-by: Li Zhe <lizhe.67@bytedance.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Peter Xu <peterx@redhat.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Jose A. Perez de Azpillaga <azpijr@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/hugetlb.h | 15 ++++++---------
mm/hugetlb.c | 7 +++----
2 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 45ada75dc04e9..77d62c930dc37 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -121,10 +121,9 @@ void hugepage_put_subpool(struct hugepage_subpool *spool);
void hugetlb_dup_vma_private(struct vm_area_struct *vma);
void clear_vma_resv_huge_pages(struct vm_area_struct *vma);
-int move_hugetlb_page_tables(struct vm_area_struct *vma,
- struct vm_area_struct *new_vma,
- unsigned long old_addr, unsigned long new_addr,
- unsigned long len);
+unsigned long move_hugetlb_page_tables(struct vm_area_struct *vma,
+ struct vm_area_struct *new_vma, unsigned long old_addr,
+ unsigned long new_addr, unsigned long len);
int copy_hugetlb_page_range(struct mm_struct *, struct mm_struct *,
struct vm_area_struct *, struct vm_area_struct *);
void unmap_hugepage_range(struct vm_area_struct *,
@@ -339,11 +338,9 @@ static inline int copy_hugetlb_page_range(struct mm_struct *dst,
return 0;
}
-static inline int move_hugetlb_page_tables(struct vm_area_struct *vma,
- struct vm_area_struct *new_vma,
- unsigned long old_addr,
- unsigned long new_addr,
- unsigned long len)
+static inline unsigned long move_hugetlb_page_tables(struct vm_area_struct *vma,
+ struct vm_area_struct *new_vma, unsigned long old_addr,
+ unsigned long new_addr, unsigned long len)
{
BUG();
return 0;
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index e71e0ab116bfb..8eff9249dfb2b 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5157,10 +5157,9 @@ static void move_huge_pte(struct vm_area_struct *vma, unsigned long old_addr,
spin_unlock(dst_ptl);
}
-int move_hugetlb_page_tables(struct vm_area_struct *vma,
- struct vm_area_struct *new_vma,
- unsigned long old_addr, unsigned long new_addr,
- unsigned long len)
+unsigned long move_hugetlb_page_tables(struct vm_area_struct *vma,
+ struct vm_area_struct *new_vma, unsigned long old_addr,
+ unsigned long new_addr, unsigned long len)
{
struct hstate *h = hstate_vma(vma);
struct address_space *mapping = vma->vm_file->f_mapping;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 227/507] mm/hugetlb: fix mremap deadlock when PMD sharing is possible
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (225 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 226/507] mm/hugetlb: fix mremap move length truncation Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 228/507] mm/page_alloc: mark pages freed by __free_pages_core() as not tagged Greg Kroah-Hartman
` (279 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Li Zhe, David Hildenbrand (Arm),
Andrew Morton, Muchun Song, Oscar Salvador, Peter Xu,
Mike Rapoport, Jose A. Perez de Azpillaga, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Zhe <lizhe.67@bytedance.com>
[ Upstream commit 92daa8652f88c8cfc05f4899a8408a04b02f211e ]
move_hugetlb_page_tables() holds the mapping's i_mmap_rwsem for
write while moving hugetlb PTEs. This prevents races with truncation
and protects huge_pmd_unshare(), but the move loop must not call
helpers that can acquire the same rwsem for read.
huge_pte_alloc() can do that when the destination can use PMD
sharing: it may call huge_pmd_share(), which takes i_mmap_rwsem for
read while searching for a shareable PMD table. Calling it while the
move path already holds i_mmap_rwsem for write can deadlock.
Avoid that path for PMD-sized hugetlb mappings that can use PMD
sharing. Instead of allocating or sharing the destination page table
while moving, zap the source range and let the destination fault path
populate or share the PMD lazily.
Reuse the hugetlb unmap logic for the source-side zap by splitting
the core loop out of __unmap_hugepage_range(). The wrapper keeps the
existing tlb_start_vma(), tlb_end_vma() and huge_pmd_unshare_flush()
behavior, while move_hugetlb_page_tables() can reuse the unmap loop
with its existing mmu_gather.
Link: https://lore.kernel.org/20261022034543.51226-4-lizhe.67@bytedance.com
Fixes: 550a7d60bd5e ("mm, hugepages: add mremap() support for hugepage backed vma")
Signed-off-by: Li Zhe <lizhe.67@bytedance.com>
Co-developed-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Peter Xu <peterx@redhat.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Jose A. Perez de Azpillaga <azpijr@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/hugetlb.c | 47 +++++++++++++++++++++++++++++++++++++----------
1 file changed, 37 insertions(+), 10 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 8eff9249dfb2b..532cc42662a69 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -125,6 +125,10 @@ static int __huge_pmd_unshare(struct mmu_gather *tlb,
bool check_locks);
static void hugetlb_unshare_pmds(struct vm_area_struct *vma,
unsigned long start, unsigned long end, bool take_locks);
+static void hugetlb_unmap_range(struct mmu_gather *tlb,
+ struct vm_area_struct *vma, unsigned long start,
+ unsigned long end, struct folio *folio,
+ zap_flags_t zap_flags);
static struct resv_map *vma_resv_map(struct vm_area_struct *vma);
static inline bool subpool_is_free(struct hugepage_subpool *spool)
@@ -5189,6 +5193,8 @@ unsigned long move_hugetlb_page_tables(struct vm_area_struct *vma,
for (; old_addr < old_end; old_addr += sz, new_addr += sz) {
const unsigned long offset_to_last_entry =
(old_addr | last_addr_mask) - old_addr;
+ const unsigned long offset_to_last_dst_entry =
+ (new_addr | last_addr_mask) - new_addr;
src_pte = hugetlb_walk(vma, old_addr, sz);
if (!src_pte) {
@@ -5205,6 +5211,24 @@ unsigned long move_hugetlb_page_tables(struct vm_area_struct *vma,
continue;
}
+ /*
+ * Avoid entering the destination PMD sharing path while holding
+ * i_mmap_rwsem for write. Leave destination page table
+ * population to the fault path, which can share the PMD lazily.
+ */
+ if (sz == PMD_SIZE && want_pmd_share(new_vma, new_addr)) {
+ const unsigned long unmap_size =
+ min(old_end - old_addr,
+ offset_to_last_dst_entry + sz);
+
+ hugetlb_unmap_range(&tlb, vma, old_addr,
+ old_addr + unmap_size, NULL,
+ ZAP_FLAG_DROP_MARKER);
+ old_addr += unmap_size - sz;
+ new_addr += unmap_size - sz;
+ continue;
+ }
+
dst_pte = huge_pte_alloc(mm, new_vma, new_addr, sz);
if (!dst_pte)
break;
@@ -5224,9 +5248,10 @@ unsigned long move_hugetlb_page_tables(struct vm_area_struct *vma,
return len + old_addr - old_end;
}
-void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
- unsigned long start, unsigned long end,
- struct folio *folio, zap_flags_t zap_flags)
+static void hugetlb_unmap_range(struct mmu_gather *tlb,
+ struct vm_area_struct *vma, unsigned long start,
+ unsigned long end, struct folio *folio,
+ zap_flags_t zap_flags)
{
struct mm_struct *mm = vma->vm_mm;
const bool folio_provided = !!folio;
@@ -5244,13 +5269,6 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
BUG_ON(start & ~huge_page_mask(h));
BUG_ON(end & ~huge_page_mask(h));
- /*
- * This is a hugetlb vma, all the pte entries should point
- * to huge page.
- */
- tlb_change_page_size(tlb, sz);
- tlb_start_vma(tlb, vma);
-
last_addr_mask = hugetlb_mask_last_page(h);
address = start;
for (; address < end; address += sz) {
@@ -5379,6 +5397,15 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
if (folio_provided)
break;
}
+}
+
+void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
+ unsigned long start, unsigned long end,
+ struct folio *folio, zap_flags_t zap_flags)
+{
+ tlb_change_page_size(tlb, huge_page_size(hstate_vma(vma)));
+ tlb_start_vma(tlb, vma);
+ hugetlb_unmap_range(tlb, vma, start, end, folio, zap_flags);
tlb_end_vma(tlb, vma);
huge_pmd_unshare_flush(tlb, vma);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 228/507] mm/page_alloc: mark pages freed by __free_pages_core() as not tagged
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (226 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 227/507] mm/hugetlb: fix mremap deadlock when PMD sharing is possible Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 229/507] mm/vma: write lock source VMA before duplicating it in __split_vma() Greg Kroah-Hartman
` (278 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zenghui Yu (Huawei), Andrew Morton,
Johannes Weiner, Mike Rapoport, Vlastimil Babka,
Suren Baghdasaryan, Michal Hocko, Brendan Jackman, Zi Yan,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zenghui Yu (Huawei) <zenghui.yu@linux.dev>
[ Upstream commit b6732c6d43139ea56de8bc62e87ace8543ef784f ]
Onlining hotplugged memory (e.g., a dev_dax device bound to kmem) with
CONFIG_MEM_ALLOC_PROFILING_DEBUG triggers:
alloc_tag was not set
WARNING: ./include/linux/alloc_tag.h:166 at __pgalloc_tag_sub+0x1fc/0x254
Call trace:
__pgalloc_tag_sub+0x1fc/0x254 (P)
__free_pages_ok+0x14c/0x6ac
__free_pages_core+0xa8/0x188
generic_online_page+0x14/0x20
online_pages+0x220/0x3b0
memory_subsys_online+0xfc/0x198
device_online+0x58/0xe0
state_store+0xf0/0xf8
Pages entering the buddy through __free_pages_core() have never been
allocated, so their allocation tag references are NULL. The free path,
__free_pages_prepare() -> pgalloc_tag_sub(), expects a valid tag or a
CODETAG_EMPTY mark and warns otherwise. Paths feeding never-allocated
pages into the buddy are therefore expected to mark them with
clear_page_tag_ref() first, like init_cma_reserved_pageblock() and
free_reserved_pages() do; of __free_pages_core()'s callers only
memblock_free_pages() clears the tag ref itself, and the hotplug
onlining path was missed.
Since all __free_pages_core() callers free never-allocated pages, mark the
head page as not tagged in __free_pages_core() itself instead of relying on
each caller, and drop the now-redundant clearing from
memblock_free_pages().
Link: https://lore.kernel.org/20261022122752.74774-1-zenghui.yu@linux.dev
Fixes: dcfe378c81f7 ("lib: introduce support for page allocation tagging")
Signed-off-by: Zenghui Yu (Huawei) <zenghui.yu@linux.dev>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Brendan Jackman <brendan.jackman@linux.dev>
Cc: Zi Yan <ziy@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/mm_init.c | 2 --
mm/page_alloc.c | 3 +++
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/mm/mm_init.c b/mm/mm_init.c
index 1533aebafb688..36ec1ef0712cb 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -2422,8 +2422,6 @@ void __init memblock_free_pages(unsigned long pfn, unsigned int order)
return;
}
- /* pages were reserved and not allocated */
- clear_page_tag_ref(page);
__free_pages_core(page, order, MEMINIT_EARLY);
}
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 319053c6a9c0f..d8adf19eaeea6 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1634,6 +1634,9 @@ void __meminit __free_pages_core(struct page *page, unsigned int order,
atomic_long_add(nr_pages, &page_zone(page)->managed_pages);
}
+ /* pages were never allocated */
+ clear_page_tag_ref(page);
+
if (page_contains_unaccepted(page, order)) {
if (order == MAX_PAGE_ORDER && __free_unaccepted(page))
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 229/507] mm/vma: write lock source VMA before duplicating it in __split_vma()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (227 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 228/507] mm/page_alloc: mark pages freed by __free_pages_core() as not tagged Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 230/507] mm/ksm: keep soft-dirty when merging a page Greg Kroah-Hartman
` (277 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Hildenbrand (Arm),
Lorenzo Stoakes (ARM), Andrew Morton, Davidlohr Bueso,
Pedro Falcato, Gregory Price (Meta), Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Jann Horn, SJ Park, Kees Cook, Colin Cross, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 769417e410dd19b2a438c6addb61b194b7a4c387 ]
__split_vma() duplicates the source VMA before taking its VMA write lock,
and until the VMA is write-locked, a concurrent thread might set
VMA_MAYBE_GUARD_BIT, resulting in the duplication missing the flag.
If this happens, then fork may fail to duplicate guard markers and, if a
file-backed mapping, THP collapse may also discard the markers.
Resolve this by taking the VMA write lock before vm_area_dup() and, since
all callers of vm_area_dup() now hold the VMA write lock, assert that this
is the case there, and add a comment to explain why it's needed.
[ljs@kernel.org: add VMA write assert in vm_area_dup(), commit message touchup]
Link: https://lore.kernel.org/20261023-fix-vma-atomic-v1-2-8ff4fae1fc85@kernel.org
Fixes: 2ab7f1bbafc9 ("mm/madvise: allow guard page install/remove under VMA lock")
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Davidlohr Bueso <dave@stgolabs.net>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Jann Horn <jannh@google.com>
Cc: SJ Park <sj@kernel.org>
Cc: Kees Cook <kees@kernel.org>
Cc: Colin Cross <ccross@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/vma.c | 2 +-
mm/vma_init.c | 3 +++
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/mm/vma.c b/mm/vma.c
index 3d63f73e723b9..e2ce21afe44a6 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -557,6 +557,7 @@ __split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma,
return err;
}
+ vma_start_write(vma);
new = vm_area_dup(vma);
if (!new)
return -ENOMEM;
@@ -587,7 +588,6 @@ __split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma,
if (new->vm_ops && new->vm_ops->open)
new->vm_ops->open(new);
- vma_start_write(vma);
vma_start_write(new);
init_vma_prep(&vp, vma);
diff --git a/mm/vma_init.c b/mm/vma_init.c
index baa7e82f47e3f..d661f229a734f 100644
--- a/mm/vma_init.c
+++ b/mm/vma_init.c
@@ -127,6 +127,9 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig)
{
struct vm_area_struct *new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
+ /* Must hold a write lock to stabilise atomic VMA flags. */
+ vma_assert_write_locked(orig);
+
if (!new)
return NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 230/507] mm/ksm: keep soft-dirty when merging a page
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (228 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 229/507] mm/vma: write lock source VMA before duplicating it in __split_vma() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 231/507] fs/proc/task_mmu: return -ENOTTY for unknown pagemap ioctls Greg Kroah-Hartman
` (276 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Samarth Narang, Andrew Morton,
Lance Yang, David Hildenbrand (Arm), Xu Xin, Chengming Zhou,
Peter Xu, Kiryl Shutsemau, Mike Rapoport, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Samarth Narang <samarth.colleges@gmail.com>
[ Upstream commit 2efc6332f18bfd848f74f3d5ba45b31450601faa ]
replace_page() maps the KSM page with a PTE built from scratch, so the
soft-dirty bit of the PTE it replaces is lost. A page written since
"clear_refs 4" then no longer shows as soft-dirty once it is merged, and a
soft-dirty based dumper treats it as unchanged.
Copy the soft-dirty bit from the original PTE to the new PTE.
Link: https://lore.kernel.org/20261021182157.1873726-1-samarth.colleges@gmail.com
Fixes: 0f8975ec4db2 ("mm: soft-dirty bits for user memory changes tracking")
Signed-off-by: Samarth Narang <samarth.colleges@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Assisted-by: LLM
Cc: Xu Xin <xu.xin@linux.dev>
Cc: Chengming Zhou <chengming.zhou@linux.dev>
Cc: Peter Xu <peterx@redhat.com>
Cc: Kiryl Shutsemau <kas@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/ksm.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/mm/ksm.c b/mm/ksm.c
index fe42c17490b89..b1f361983e553 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1462,6 +1462,10 @@ static int replace_page(struct vm_area_struct *vma, struct page *page,
dec_mm_counter(mm, MM_ANONPAGES);
}
+ /* Preserve soft-dirty when replacing the page. */
+ if (pte_soft_dirty(orig_pte))
+ newpte = pte_mksoft_dirty(newpte);
+
flush_cache_page(vma, addr, pte_pfn(ptep_get(ptep)));
/*
* No need to notify as we are replacing a read only page with another
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 231/507] fs/proc/task_mmu: return -ENOTTY for unknown pagemap ioctls
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (229 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 230/507] mm/ksm: keep soft-dirty when merging a page Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 232/507] mm/damon/sysfs-schemes: hold damon_sysfs_lock in target_metric_store() Greg Kroah-Hartman
` (275 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hengyu Liang, Andrew Morton,
David Hildenbrand (Arm), Pedro Falcato, Lorenzo Stoakes (ARM),
Liam R. Howlett, Vlastimil Babka, Jann Horn, Muhammad Usama Anjum,
Andrei Vagin, Michał Mirosław, Arnd Bergmann,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengyu Liang <hengyul@cs.unc.edu>
[ Upstream commit bfc1d9724c78aa7570dbeb17207a21089f2d1b1a ]
Commit 52526ca7fdb9 ("fs/proc/task_mmu: implement IOCTL to get and
optionally clear info about PTEs") made do_pagemap_cmd() the ioctl
handler of /proc/<pid>/pagemap.
However, do_pagemap_cmd() returns -EINVAL for every command other than
PAGEMAP_SCAN. Before that commit, pagemap had no ioctl handler, and
the VFS returned -ENOTTY for these commands. As of now, they fail with
EINVAL, so tcgetattr() and isatty() on pagemap report EINVAL instead
of ENOTTY.
The issue can be reproduced with a simple C program:
#include <fcntl.h>
#include <stdio.h>
#include <termios.h>
int main(void)
{
struct termios t;
int fd = open("/proc/self/pagemap", O_RDONLY);
if (tcgetattr(fd, &t) < 0)
perror("tcgetattr");
return 0;
}
Before that commit, the result is:
tcgetattr: Inappropriate ioctl for device
After that commit, the result is:
tcgetattr: Invalid argument
This patch will return -ENOIOCTLCMD for unknown commands, as
procfs_procmap_ioctl() in the same file does, so that the VFS turns it
into -ENOTTY.
Link: https://lore.kernel.org/20261023181300.3366487-1-hengyul@cs.unc.edu
Fixes: 52526ca7fdb9 ("fs/proc/task_mmu: implement IOCTL to get and optionally clear info about PTEs")
Signed-off-by: Hengyu Liang <hengyul@cs.unc.edu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Jann Horn <jannh@google.com>
Cc: Muhammad Usama Anjum <usama.anjum@arm.com>
Cc: Andrei Vagin <avagin@gmail.com>
Cc: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/proc/task_mmu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index a2db957aa7996..2eaa79ab11389 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -3314,7 +3314,7 @@ static long do_pagemap_cmd(struct file *file, unsigned int cmd,
return do_pagemap_scan(mm, arg);
default:
- return -EINVAL;
+ return -ENOIOCTLCMD;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 232/507] mm/damon/sysfs-schemes: hold damon_sysfs_lock in target_metric_store()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (230 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 231/507] fs/proc/task_mmu: return -ENOTTY for unknown pagemap ioctls Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 233/507] mm/damon/core: move static variable last_nr_regions to damon_ctx Greg Kroah-Hartman
` (274 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, SJ Park, Andrew Morton, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: SJ Park <sj@kernel.org>
[ Upstream commit a76adcace3550b16e5735ba4a5e95a9c2664e113 ]
Patch series "mm/damon: fix three race bugs in sysfs and core", v1.
There are three race condition bugs in DAMON sysfs interface and the
core layer. User impacts are not critical but better to fix sooner than
later.
Patch 1 fixes a toctou bug in DAMON sysfs interface that can mess up
DAMOS auto-tuning. Patches 2 and 3 move static variables that can be
wrongly shared with multiple kdamonds and therefore make DAMON
monitoring results be a little more indeterministic.
This patch (of 3):
damon_sysfs_add_quota_score() reads damos_sysfs_quota_goal->metric
twice, once to set damos_quota_goal->metric to the value, and once again
to set the metric-dependent damos_quota_goal unions based on the value.
target_metrics_score() can update damos_sysfs_quota_goal->metric between
the two reads. This time-of-check to time-of-use (toctou) race can make
the union fields incorrectly set. The incorrect damos_quota_goal will
be passed to the core layer and make DAMOS incorrectly behave.
Users could reproduce the race by writing a new value to the
target_metric sysfs file while DAMON is starting, or online parameters
update is ongoing. The issue will only rarely happen in the real use
cases. It requires sysfs write permission. The race window is short.
Sane users wouldn't do such writes while DAMON enablement and/or online
parameters update is ongoing.
The user impact is not very critical. The race is not easy to
unintentionally trigger. No leak or crash happens. Nonetheless, DAMOS
could be unexpectedly more or less aggressive and does not achieve the
auto-tune goal. Because of the nature of races, investigating will be
difficult. Users can control the impact from unexpected aggressiveness
using additional quotas and resolve the issue in runtime by
re-installing the quota goal, though.
Avoid the race by protecting damos_sysfs_quota_goal->metric write in
target_metric_store() with damon_sysfs_lock. Because
damon_sysfs_add_quota_score() is called while holding the same lock, the
race is removed.
The issue was discovered as a part of a bug report [1] from Sashiko,
which is partially outdated. In more detail, the Sashiko report [1] was
mainly for an outdated bug [2]. But it was also mentioning the issue of
this patch as a similar class bug.
Link: https://lore.kernel.org/20261025164808.152048-1-sj@kernel.org
Link: https://lore.kernel.org/20261025164808.152048-2-sj@kernel.org
Link: https://sashiko.dev/#/bug/linux-7f814c9a-986f-4103-a55a-ef9537dcf62b [1]
Link: https://lore.kernel.org/20261021005234.94107-1-sj@kernel.org [2]
Fixes: 85fcf0ffc460 ("mm/damon/sysfs-schemes: connect damos_quota_goal nid with core layer")
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: <stable@vger.kernel.org> # 6.16.x
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/damon/sysfs-schemes.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c
index 4ffc13ab95e65..20eb8c242f2f8 100644
--- a/mm/damon/sysfs-schemes.c
+++ b/mm/damon/sysfs-schemes.c
@@ -1300,7 +1300,10 @@ static ssize_t target_metric_store(struct kobject *kobj,
metric_name = &damos_sysfs_qgoal_metric_names[i];
if (sysfs_streq(buf, metric_name->name)) {
+ if (!mutex_trylock(&damon_sysfs_lock))
+ return -EBUSY;
goal->metric = metric_name->metric;
+ mutex_unlock(&damon_sysfs_lock);
return count;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 233/507] mm/damon/core: move static variable last_nr_regions to damon_ctx
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (231 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 232/507] mm/damon/sysfs-schemes: hold damon_sysfs_lock in target_metric_store() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 234/507] mm/damon/core: move static variable rotation " Greg Kroah-Hartman
` (273 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, SJ Park, Andrew Morton,
Fernand Sieber, SeongJae Park, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: SJ Park <sj@kernel.org>
[ Upstream commit 26ae50a0901a44f7d50053f87dc38abd9f9a269c ]
kdamond_split_regions() uses a static variable last_nr_regions, to infer
if the region boundaries are too stable. If it looks too stable, it
does a more aggressive region split because it might be a fake stability
coming from non-aggressive split. Because the variable is static, the
inference can be racy and wrong when multiple kdamonds are running in
parallel.
The user impact is not critical. No crash, no leak. DAMON's
best-effort monitoring accuracy can be degraded when multiple kdamonds
are used in parallel and the workload has certain access patterns. Still
it is a bug that is better to fix.
Move the variable into the damon_ctx struct to fix the problem.
Link: https://lore.kernel.org/20261025164808.152048-3-sj@kernel.org
Fixes: 75c1c2b53c78 ("mm/damon/dbgfs: support multiple contexts")
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Closes: https://sashiko.dev/#/bug/linux-eebfcdde-2881-48ef-8df1-e2019d2a47f2
Cc: Fernand Sieber <sieberf@amazon.com>
Cc: SeongJae Park <sjpark@amazon.de>
Cc: <stable@vger.kernel.org> # 5.15.x
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/damon.h | 5 +++++
mm/damon/core.c | 5 ++---
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/include/linux/damon.h b/include/linux/damon.h
index 0c8b7ddef9abb..c6de3ac2f4453 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -914,6 +914,11 @@ struct damon_ctx {
/* @rnd_state: Per-ctx PRNG state for damon_rand(). */
struct rnd_state rnd_state;
+ /*
+ * number of regions after last merge. Read kdamond_split_regions()
+ * for more details.
+ */
+ unsigned long last_nr_regions;
};
/* Get a random number in [@l, @r) using @ctx's lockless PRNG. */
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 229ab1674b4c1..6db6d2a80e812 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -3610,7 +3610,6 @@ static void kdamond_split_regions(struct damon_ctx *ctx)
struct damon_target *t;
unsigned long nr_regions = 0;
unsigned long max_nr_regions = ctx->attrs.max_nr_regions;
- static unsigned long last_nr_regions;
int nr_subregions = 2;
damon_for_each_target(t, ctx)
@@ -3626,7 +3625,7 @@ static void kdamond_split_regions(struct damon_ctx *ctx)
}
/* Maybe the middle of the region has different access frequency */
- if (last_nr_regions == nr_regions &&
+ if (ctx->last_nr_regions == nr_regions &&
nr_regions < max_nr_regions / 3)
nr_subregions = 3;
@@ -3635,7 +3634,7 @@ static void kdamond_split_regions(struct damon_ctx *ctx)
ctx->min_region_sz);
done:
- last_nr_regions = nr_regions;
+ ctx->last_nr_regions = nr_regions;
}
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 234/507] mm/damon/core: move static variable rotation to damon_ctx
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (232 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 233/507] mm/damon/core: move static variable last_nr_regions to damon_ctx Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 235/507] mm: make swapoff interruptible when unusing mms/shmem Greg Kroah-Hartman
` (272 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, SJ Park, Andrew Morton, Jiayuan Chen,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: SJ Park <sj@kernel.org>
[ Upstream commit c4ff3ea30640b394df4156d7ddf60ad8ffe765f1 ]
damon_split_some_reigons() uses a static variable, rotation, to remember
how many times it was called. It is again used to determine fair
selection of regions to split. Since it is a static variable, it can be
indeterministic and therefore less fair.
The user impact is not critical. No crash, no leak. DAMON's
best-effort and indeterministic monitoring accuracy could be slightly
more indeterministic when multiple kdamonds are used in parallel.
Fix the problem by moving the static variable into the damon_ctx struct.
Link: https://lore.kernel.org/20261025164808.152048-4-sj@kernel.org
Fixes: 1a582e6e0174 ("mm/damon/core: split a fraction of regions when nr_regions exceeds max/2")
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Closes: https://sashiko.dev/#/bug/linux-eebfcdde-2881-48ef-8df1-e2019d2a47f2
Cc: Jiayuan Chen <jiayuan.chen@shopee.com>
Cc: <stable@vger.kernel.org> # 7.3.x
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/damon.h | 5 +++++
mm/damon/core.c | 5 +++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/include/linux/damon.h b/include/linux/damon.h
index c6de3ac2f4453..9772309b2b587 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -919,6 +919,11 @@ struct damon_ctx {
* for more details.
*/
unsigned long last_nr_regions;
+ /*
+ * number of damon_split_some_regions() invocations for this context.
+ * Read damon_split_some_regions() for more details.
+ */
+ unsigned long region_split_rotation;
};
/* Get a random number in [@l, @r) using @ctx's lockless PRNG. */
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 6db6d2a80e812..85bcb6da9ad0b 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -3568,12 +3568,13 @@ static void damon_split_regions_of(struct damon_ctx *ctx,
static void damon_split_some_regions(struct damon_ctx *ctx,
unsigned long split_step)
{
- static unsigned long rotation;
struct damon_target *t;
struct damon_region *r, *next;
- unsigned long offset = rotation++ % split_step;
+ unsigned long offset;
unsigned long idx = 0;
+ offset = ctx->region_split_rotation++ % split_step;
+
damon_for_each_target(t, ctx) {
damon_for_each_region_safe(r, next, t) {
unsigned long sz_region, sz_sub;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 235/507] mm: make swapoff interruptible when unusing mms/shmem
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (233 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 234/507] mm/damon/core: move static variable rotation " Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 236/507] mm/migrate: untag addresses when querying page nodes Greg Kroah-Hartman
` (271 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Down, Andrew Morton,
Vineeth Pillai (Google), Baolin Wang, Kairui Song, Hugh Dickins,
Chris Li, Nhat Pham, Baoquan He, Barry Song, Youngjun Park,
Ying Huang, Kelley Nielsen, Rafael J. Wysocki, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Down <chris@chrisdown.name>
[ Upstream commit 740128dd1a3f2bd81a80314d079b6b03c39ba3af ]
try_to_unuse() only checks for a pending signal between mms, and
shmem_unuse() doesn't check at all. That means that once swapoff gets to
a process or a shmem file with a lot swapped out, nothing can interrupt it
until every last page of it has been read back in.
Just as one example of where this can concretely show up, freezing tasks
for suspend or hibernation has to wait for swapoff to notice the freezer's
fake signal, and gives up after freeze_timeout_msecs (20 seconds by
default).
Here's a facetious example where one swaps out 2GiB of one process to a
swap file on ext4, starts swapoff, and half a second later tries to freeze
with pm_test=freezer. Writing to /sys/power/state then fails with EBUSY
and this in dmesg:
Freezing user space processes failed after 20.003 seconds (1 tasks refusing to freeze, wq_busy=0):
task:swapoff state:D stack:0 pid:3175 tgid:3175 ppid:2955 task_flags:0x400100 flags:0x00000419
Call trace:
[...]
io_schedule+0x44/0x70
folio_wait_bit_common+0x1ec/0x3d0
__folio_lock+0x24/0x40
unuse_pte_range+0x2d0/0x348
unuse_vma+0x158/0x248
unuse_mm+0xfc/0x150
try_to_unuse+0x104/0x3f8
__do_sys_swapoff+0x220/0x5d8
[...]
The same goes for anything else that wants swapoff to stop, like an admin
hitting ^C in a panic, of course.
Prior to commit b56a2d8af914 ("mm: rid swapoff of quadratic complexity")
try_to_unuse() was driven by find_next_to_unuse() which checks for a
signal before every entry, so let's restore that behaviour.
Just as an example of the improvements, here's how long freezing takes
in the same test while swapoff is happening on my computer:
before after
400MiB anon 8.925s 0.028s
400MiB shmem 1.639s 0.003s
2GiB anon failed after 20.003s 0.011s
Link: https://lore.kernel.org/at9kJwdGkHPsWwgG@chrisdown.name
Fixes: b56a2d8af914 ("mm: rid swapoff of quadratic complexity")
Signed-off-by: Chris Down <chris@chrisdown.name>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Vineeth Pillai (Google) <vineeth@bitbyteword.org>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Reviewed-by: Kairui Song <kasong@tencent.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Chris Li <chrisl@kernel.org>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Barry Song <baohua@kernel.org>
Cc: Youngjun Park <youngjun.park@lge.com>
Cc: Ying Huang <huang.ying.caritas@gmail.com>
Cc: Kelley Nielsen <kelleynnn@gmail.com>
Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/shmem.c | 4 ++++
mm/swapfile.c | 4 +++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/mm/shmem.c b/mm/shmem.c
index edda9f90b3d89..825a5a961086d 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1561,6 +1561,10 @@ static int shmem_unuse_inode(struct inode *inode, unsigned int type)
if (ret < 0)
break;
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ break;
+ }
start = indices[folio_batch_count(&fbatch) - 1];
} while (true);
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 601979b97f95b..fbb4b3dcf9562 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -2609,6 +2609,8 @@ static inline int unuse_pmd_range(struct vm_area_struct *vma, pud_t *pud,
pmd = pmd_offset(pud, addr);
do {
cond_resched();
+ if (signal_pending(current))
+ return -ERESTARTSYS;
next = pmd_addr_end(addr, end);
ret = unuse_pte_range(vma, pmd, addr, next, type);
if (ret)
@@ -2823,7 +2825,7 @@ static int try_to_unuse(unsigned int type)
if (swap_usage_in_pages(si)) {
if (!signal_pending(current))
goto retry;
- return -EINTR;
+ return -ERESTARTSYS;
}
success:
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 236/507] mm/migrate: untag addresses when querying page nodes
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (234 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 7.3 235/507] mm: make swapoff interruptible when unusing mms/shmem Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 237/507] mm/ksm: fix userfaultfd protection during merge and unmerge Greg Kroah-Hartman
` (270 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hungyu Lin, Andrew Morton, Sashiko,
Zi Yan, David Hildenbrand (Arm), Catalin Marinas, Matthew Brost,
Joshua Hahn, Byungchul Park, Gregory Price, Ying Huang,
Alistair Popple, Andrey Konovalov, Vincenzo Frascino, odys.yuan,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hungyu Lin <dennylin0707@gmail.com>
[ Upstream commit 7d8746d7dc9cc4003661011424e5880ea7ae364b ]
When move_pages() is used with nodes == NULL, do_pages_stat_array() passes
each page address directly to vma_lookup(). A valid tagged address
therefore fails the VMA lookup and gets -EFAULT in its status entry,
instead of the node reported for the corresponding untagged address.
The tagged address ABI permits these pointers, and the migration path
already removes their tags. Apply the target mm's untagging rules to the
query path as well, while holding its mmap read lock.
Link: https://lore.kernel.org/20261026195330.46757-1-dennylin0707@gmail.com
Fixes: 057d3389108e ("mm: untag user pointers passed to memory syscalls")
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/r/20260721183257.706661F000E9@smtp.kernel.org
Acked-by: Zi Yan <ziy@nvidia.com>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Joshua Hahn <joshua.hahnjy@gmail.com>
Cc: Byungchul Park <byungchul@sk.com>
Cc: Gregory Price <gourry@gourry.net>
Cc: Ying Huang <ying.huang@linux.alibaba.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Cc: <odys.yuan@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/migrate.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/migrate.c b/mm/migrate.c
index 15b45832bcfa7..296f39a73d492 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -2462,7 +2462,7 @@ static void do_pages_stat_array(struct mm_struct *mm, unsigned long nr_pages,
mmap_read_lock(mm);
for (i = 0; i < nr_pages; i++) {
- unsigned long addr = (unsigned long)(*pages);
+ unsigned long addr = (unsigned long)untagged_addr_remote(mm, *pages);
struct vm_area_struct *vma;
struct folio_walk fw;
struct folio *folio;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 237/507] mm/ksm: fix userfaultfd protection during merge and unmerge
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (235 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 236/507] mm/migrate: untag addresses when querying page nodes Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 238/507] mm/migrate: snapshot the source nid before the misplaced migration Greg Kroah-Hartman
` (269 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Samarth Narang, Lance Yang,
Andrew Morton, Lorenzo Stoakes (ARM), Kiryl Shutsemau (Meta),
David Hildenbrand (Arm), Mel Gorman, Chengming Zhou,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Jérôme Glisse,
Andrea Arcangeli, Peter Xu, Bobby Powers, Brian Geffon,
Denis Plotnikov, Doug Gilbert, Hugh Dickins, Johannes Weiner,
Martin Cracauer, Marty McFadden, Maya Gokhale, Pavel Emelyanov,
Rik van Riel, Shaohua Li, James Houghton, Jonathan Corbet,
Paolo Bonzini, Sean Christopherson, SJ Park, Zi Yan,
Mohammed EL Kadiri, Sasha Levin, Xu Xin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lance Yang <lance.yang@linux.dev>
[ Upstream commit 990d6c2194a938a19a8cf94c6cfd75171345089b ]
KSM loses userfaultfd protection when replace_page() builds a new PTE from
vma->vm_page_prot. Dropping its uffd bit lets a subsequent write go
through ordinary COW instead of userfaultfd write protection handling.
For RWP, a merged page also becomes readable without faulting.
Keeping the uffd bit and restoring PAGE_NONE fixes merging, but we also
have to handle unmerging. An existing KSM page can be protected with RWP
before MADV_UNMERGEABLE, so unmerging already needs fixing independently
of preserving RWP during merging.
Unsharing replaces a shared page with a private one and should leave
userfaultfd protection in place, as do_wp_page() already does for write
protection. Currently, an unshare fault reaches do_uffd_rwp() before it
can proceed to do_wp_page().
- With synchronous RWP, handle_userfault() returns VM_FAULT_SIGBUS.
break_ksm() then reports success with a KSM page still merged.
- With asynchronous RWP, protection is cleared before unsharing.
Preserve the uffd bit when merging, and restore PAGE_NONE for RWP. Let
FAULT_FLAG_UNSHARE skip RWP fault handling and keep PAGE_NONE on each
private copy as well. Unsharing can then complete with RWP still armed
for a subsequent access.
Link: https://lore.kernel.org/20261026130054.91461-1-lance.yang@linux.dev
Link: https://lore.kernel.org/all/20261019010934.697895-1-samarth.colleges@gmail.com/
Link: https://lore.kernel.org/all/20261020055518.36087-1-lance.yang@linux.dev/
Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
Fixes: 2d427bb01639 ("mm/userfaultfd: add RWP fault delivery and expose UFFDIO_REGISTER_MODE_RWP")
Signed-off-by: Samarth Narang <samarth.colleges@gmail.com>
Signed-off-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Co-developed-by: Samarth Narang <samarth.colleges@gmail.com>
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Xu Xin <xu.xin@linux.dev>"
Cc: Chengming Zhou <chengming.zhou@linux.dev>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Jérôme Glisse <jglisse@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Bobby Powers <bobbypowers@gmail.com>
Cc: Brian Geffon <bgeffon@google.com>
Cc: Denis Plotnikov <dplotnikov@virtuozzo.com>
Cc: Doug Gilbert <dgilbert@interlog.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Martin Cracauer <cracauer@cons.org>
Cc: Marty McFadden <mcfadden8@llnl.gov>
Cc: Maya Gokhale <gokhale2@llnl.gov>
Cc: Pavel Emelyanov <xemul@openvz.org>
Cc: Rik van Riel <riel@surriel.com>
Cc: Shaohua Li <shli@fb.com>
Cc: James Houghton <jthoughton@google.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Sean Christopherson <seanjc@google.com>
Cc: SJ Park <sj@kernel.org>
Cc: Zi Yan <ziy@nvidia.com>
Cc: Mohammed EL Kadiri <med08elkadiri@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/ksm.c | 8 +++++++-
mm/memory.c | 14 ++++++++++----
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/mm/ksm.c b/mm/ksm.c
index b1f361983e553..5b3559bf4c8f8 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -34,6 +34,7 @@
#include <linux/memory.h>
#include <linux/mmu_notifier.h>
#include <linux/swap.h>
+#include <linux/userfaultfd_k.h>
#include <linux/ksm.h>
#include <linux/hashtable.h>
#include <linux/freezer.h>
@@ -1462,9 +1463,14 @@ static int replace_page(struct vm_area_struct *vma, struct page *page,
dec_mm_counter(mm, MM_ANONPAGES);
}
- /* Preserve soft-dirty when replacing the page. */
+ /* Preserve soft-dirty and uffd protection when replacing the page. */
if (pte_soft_dirty(orig_pte))
newpte = pte_mksoft_dirty(newpte);
+ if (pte_uffd(orig_pte)) {
+ newpte = pte_mkuffd(newpte);
+ if (userfaultfd_rwp(vma))
+ newpte = pte_modify(newpte, PAGE_NONE);
+ }
flush_cache_page(vma, addr, pte_pfn(ptep_get(ptep)));
/*
diff --git a/mm/memory.c b/mm/memory.c
index 243b34f2e54fa..88f7953afbabc 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4060,8 +4060,11 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
if (unlikely(unshare)) {
if (pte_soft_dirty(vmf->orig_pte))
entry = pte_mksoft_dirty(entry);
- if (pte_uffd(vmf->orig_pte))
+ if (pte_uffd(vmf->orig_pte)) {
entry = pte_mkuffd(entry);
+ if (userfaultfd_rwp(vma))
+ entry = pte_modify(entry, PAGE_NONE);
+ }
} else {
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
}
@@ -6591,9 +6594,12 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
* VM_UFFD_RWP VMA, a protnone PTE without the uffd bit is
* NUMA hinting and must still fall through to do_numa_page().
*/
- if (userfaultfd_pte_rwp(vmf->vma, vmf->orig_pte))
- return do_uffd_rwp(vmf);
- return do_numa_page(vmf);
+ if (userfaultfd_pte_rwp(vmf->vma, vmf->orig_pte)) {
+ if (!(vmf->flags & FAULT_FLAG_UNSHARE))
+ return do_uffd_rwp(vmf);
+ } else {
+ return do_numa_page(vmf);
+ }
}
spin_lock(vmf->ptl);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 238/507] mm/migrate: snapshot the source nid before the misplaced migration
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (236 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 237/507] mm/ksm: fix userfaultfd protection during merge and unmerge Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 239/507] mm/vma: update VMA iterator state on error in new VMA merge Greg Kroah-Hartman
` (268 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yafang Shao, Andrew Morton, Zi Yan,
David Hildenbrand (Arm), Ying Huang, Matthew Wilcox,
Matthew Brost, Joshua Hahn, Byungchul Park, Gregory Price,
Alistair Popple, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yafang Shao <laoar.shao@gmail.com>
[ Upstream commit fe623a81ad9eddf10059b4e44bca0440d9120613 ]
A successful migration frees the source folio before the promotion
counter update, so the folio_nid() read there operates on a freed
folio — which may already have been reallocated. It happens to work
today, as Zi explained:
: Strictly speaking, it can be seen as a benign UAF. It works, because
: 1. folio->flags happens to be the same as page->flags,
: 2. folio/page nid is stored in the ->flags and never changed.
:
: In memdesc world, after a folio is freed, I assume folio->flags would be
: zeroed since struct folio is freed and calling folio_nid() on a freed
: folio would give a bogus result (yeah, it can be mitigated by not
: zeroing node field and each node has its own struct folio pool, but that
: makes folio_nid() implementation dependent).
and Matthew explained further:
: once struct folio is separately allocated, it's a UAF. It could be
: recycled to a different NID or maybe the slab containing the folio could
: be freed (assuming we're not holding the RCU read lock at this point in
: migration, and I don't see why we would be).
A separate concern is memory hot-removal. With memory-tiering mode
enabled, successful migration can release the source before the
promotion-accounting folio_nid() read. If the task is preempted there,
an otherwise-free source block can be offlined and removed first. On
the x86 path, removal can unmap the source's vmemmap, so the later read
can fault. The snapshot avoids that read.
Link: https://lore.kernel.org/20261027021721.95781-1-laoar.shao@gmail.com
Fixes: e39bb6be9f2b ("NUMA Balancing: add page promotion counter")
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Suggested-by: Zi Yan <ziy@nvidia.com>
Suggested-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Zi Yan <ziy@nvidia.com>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Ying Huang <ying.huang@linux.alibaba.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Joshua Hahn <joshua.hahnjy@gmail.com>
Cc: Byungchul Park <byungchul@sk.com>
Cc: Gregory Price <gourry@gourry.net>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/migrate.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mm/migrate.c b/mm/migrate.c
index 296f39a73d492..ee78577177d65 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -2757,6 +2757,7 @@ int migrate_misplaced_folio(struct folio *folio, int node)
pg_data_t *pgdat = NODE_DATA(node);
int nr_remaining;
unsigned int nr_succeeded;
+ int src_node = folio_nid(folio);
LIST_HEAD(migratepages);
struct mem_cgroup *memcg = get_mem_cgroup_from_folio(folio);
struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat);
@@ -2771,7 +2772,7 @@ int migrate_misplaced_folio(struct folio *folio, int node)
count_vm_numa_events(NUMA_PAGE_MIGRATE, nr_succeeded);
count_memcg_events(memcg, NUMA_PAGE_MIGRATE, nr_succeeded);
if ((sysctl_numa_balancing_mode & NUMA_BALANCING_MEMORY_TIERING)
- && !node_is_toptier(folio_nid(folio))
+ && !node_is_toptier(src_node)
&& node_is_toptier(node))
mod_lruvec_state(lruvec, PGPROMOTE_SUCCESS, nr_succeeded);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 239/507] mm/vma: update VMA iterator state on error in new VMA merge
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (237 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 238/507] mm/migrate: snapshot the source nid before the misplaced migration Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 240/507] mm/hugetlb_vmemmap: map the shared tail page writable Greg Kroah-Hartman
` (267 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM), Andrew Morton,
Li Jinyue, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Pedro Falcato, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes (ARM) <ljs@kernel.org>
[ Upstream commit 168ed9c5d5ec2fd326715eba5750c2b69e559ff3 ]
Commit cacded5e42b9 ("mm: avoid using vma_merge() for new VMAs") shared
code between vma_merge_new_range() and vma_expand().
However in doing so, it failed to correctly restore the VMA iterator when
vma_expand() errors out.
This is a problem when the immediately preceding VMA is mergeable and
vmg->just_expand isn't specified, at which point the VMA iterator is moved
to the previous VMA.
(Note that vmg->just_expand is a special case for brk(), where the
iterator will already be positioned at the VMA to be expanded.)
Resolve things by restoring the VMA iterator on error. Use
vma_iter_next_range() to do this, so it will correctly stop on the gap
after the previous VMA, rather than skip to the next VMA after it (this is
a new VMA merge, so is being applied at a gap).
To isolate the error handling, return early when a merge isn't
possible (what the vmg->target check was doing before), then handle the
merge success/failure case explicitly.
While here, update vma_expand() to jump to the nomem case when
dup_anon_vma() fails, so vmg->state is correctly updated.
This doesn't impact anything in practice, but is the correct course and
since it's part of the error path that this patch addresses, it makes sense
to update it also.
Users are very unlikely to have observed the issue this patch addresses in
practice, as it is near-impossible to fail an allocation for an anon_vma,
but a process under memory pressure that receives a fatal signal could
trigger it.
This issue was originally reported by Li Jinyue for which I am grateful. He
indicated this was uncovered by a private syzkaller instance.
Link: https://lore.kernel.org/20261027-fix-new-merge-bug-v1-1-7023a787e6b9@kernel.org
Fixes: cacded5e42b9 ("mm: avoid using vma_merge() for new VMAs")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: Li Jinyue <jinyue.li@linux.alibaba.com>
Closes: https://lore.kernel.org/all/20261025093921.1011927-1-jinyue.li@linux.alibaba.com/
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Jann Horn <jannh@google.com>
Cc: Pedro Falcato <pfalcato@suse.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/vma.c | 28 ++++++++++++++++++----------
1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/mm/vma.c b/mm/vma.c
index e2ce21afe44a6..2962670f27b5e 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -1143,6 +1143,7 @@ struct vm_area_struct *vma_merge_new_range(struct vma_merge_struct *vmg)
struct vm_area_struct *next = vmg->next;
unsigned long end = vmg->end;
bool can_merge_left, can_merge_right;
+ bool move_iter_back = false;
mmap_assert_write_locked(vmg->mm);
VM_WARN_ON_VMG(vmg->middle, vmg);
@@ -1182,23 +1183,30 @@ struct vm_area_struct *vma_merge_new_range(struct vma_merge_struct *vmg)
vmg->end = end;
/* In expand-only case we are already positioned at prev. */
- if (!vmg->just_expand) {
- /* Equivalent to going to the previous range. */
- vma_prev(vmg->vmi);
- }
+ if (!vmg->just_expand)
+ move_iter_back = true;
}
+ if (!can_merge_left && !can_merge_right)
+ return NULL;
+
+ if (move_iter_back)
+ vma_prev(vmg->vmi);
+
/*
* Now try to expand adjacent VMA(s). This takes care of removing the
* following VMA if we have VMAs on both sides.
*/
- if (vmg->target && !vma_expand(vmg)) {
- khugepaged_enter_vma(vmg->target, vmg->vm_flags);
- vmg->state = VMA_MERGE_SUCCESS;
- return vmg->target;
+ if (vma_expand(vmg)) {
+ /* Error occurred, restore iterator. */
+ if (move_iter_back)
+ vma_iter_next_range(vmg->vmi);
+ return NULL;
}
- return NULL;
+ khugepaged_enter_vma(vmg->target, vmg->vm_flags);
+ vmg->state = VMA_MERGE_SUCCESS;
+ return vmg->target;
}
/*
@@ -1293,7 +1301,7 @@ int vma_expand(struct vma_merge_struct *vmg)
if (!ret && vmg->copied_from)
ret = dup_anon_vma(target, vmg->copied_from, &anon_dup);
if (ret)
- return ret;
+ goto nomem;
if (remove_next) {
vma_flags_t next_sticky;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 240/507] mm/hugetlb_vmemmap: map the shared tail page writable
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (238 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 239/507] mm/vma: update VMA iterator state on error in new VMA merge Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 241/507] mm: page_alloc: do not give all non-blocking requests reserve access Greg Kroah-Hartman
` (266 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kiryl Shutsemau (Meta),
Andrew Morton, David Hildenbrand (Arm), Muchun Song,
Oscar Salvador, Peter Zijlstra, Frank van der Linden,
Matthew Wilcox (Oracle), Lorenzo Stoakes, Liam R. Howlett,
Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko,
Jonathan Corbet, Shuah Khan, Randy Dunlap, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiryl Shutsemau (Meta) <kas@kernel.org>
[ Upstream commit 0120a603afadba8ab4954bb1ce60f8195f80efc8 ]
page_ref_add_unless_zero() reads the refcount and then updates it with a
cmpxchg. A lockless get, such as a page cache lookup or a PFN scanner,
can read a non-zero refcount from a page that is then freed and reused as
a hugetlb tail page. If HVO remaps its struct page to the shared tail
page in between, the cmpxchg writes to read-only vmemmap:
CPU0 (lockless get) CPU1
c = atomic_read(&page->_refcount)
page freed
page allocated as a hugetlb tail
HVO remaps the struct page RO
try_cmpxchg(&page->_refcount, &c, c + 1)
-> write fault on read-only vmemmap
The refcount is zero by then and the compare fails, but a compare-and-swap
instruction needs write access whether or not it succeeds. The kernel
oopses when hugetlb pages are allocated at runtime with HVO enabled while
a lockless get races with it.
Commit bd225530a4c7 ("mm/hugetlb_vmemmap: fix race with speculative PFN
walkers") closed the window with RCU on both sides. The RCU was removed
together with fake heads, on the wrong belief that it was only needed for
them.
Map the shared tail page writable instead of restoring the RCU. Every
struct page on it is a tail with a zero refcount, so a late cmpxchg
fails and leaves the page unchanged. RCU would put rcu_read_lock()
back around every get and synchronize_rcu() back into hugetlb
allocation and freeing.
The cost is the protection against stray writes to tail struct pages. The
shared page is shared by all hugetlb folios of the same order in the zone,
so such a write now corrupts all of them instead of oopsing.
Bootmem folios optimized when the memmap is set up keep their tails
read-only. Nothing does a lockless get on them before hugetlb takes them
over.
Link: https://lore.kernel.org/20261028132623.2560146-1-kirill@shutemov.name
Fixes: 32c440d67e6c ("mm: drop fake head checks")
Fixes: 01b1d0ffb6f7 ("hugetlb: remove VMEMMAP_SYNCHRONIZE_RCU")
Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: David Hildenbrand (Arm) <david@kernel.org>
Closes: https://lore.kernel.org/r/ebc7bde1-f52e-4da8-b16f-822d6c0a4d74@kernel.org
Acked-by: Muchun Song <muchun.song@linux.dev>
Reviewed-by: Oscar Salvador <osalvador@suse.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Frank van der Linden <fvdl@google.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/mm/vmemmap_dedup.rst | 15 +++++++++++++--
mm/hugetlb_vmemmap.c | 8 +++++---
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/Documentation/mm/vmemmap_dedup.rst b/Documentation/mm/vmemmap_dedup.rst
index 9fa8642ded483..66d58fbea5b1e 100644
--- a/Documentation/mm/vmemmap_dedup.rst
+++ b/Documentation/mm/vmemmap_dedup.rst
@@ -131,8 +131,19 @@ pages of ``struct page`` (page 1 to page 7) are tail pages.
The optimization is only applied when the size of the struct page is a power
of 2. In this case, all tail pages of the same order are identical. See
compound_head(). This allows us to remap the tail pages of the vmemmap to a
-shared, read-only page. The head page is also remapped to a new page. This
-allows the original vmemmap pages to be freed.
+shared page. The head page is also remapped to a new page. This allows the
+original vmemmap pages to be freed.
+
+The shared page is mapped writable. A lockless get of a page reference can
+read a non-zero refcount before the remap and attempt its atomic update
+after it. The refcount of a tail page is zero, so the update fails without
+changing the page. Nothing else may write to the shared page: it is shared
+by all HugeTLB pages of the same size in the zone, and a stray write would
+corrupt all of them.
+
+HugeTLB pages whose vmemmap is optimized when the memmap is first set up at
+boot keep a read-only mapping of the shared page. Nothing can do a lockless
+get on them before they are handed to HugeTLB.
Here is how things look after remapping::
diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
index 917db0984143c..8e59818889371 100644
--- a/mm/hugetlb_vmemmap.c
+++ b/mm/hugetlb_vmemmap.c
@@ -222,10 +222,12 @@ static void vmemmap_remap_pte(pte_t *pte, unsigned long addr,
VM_WARN_ON_ONCE(!PageTail((const struct page *)addr));
/*
- * Remap the tail pages as read-only to catch illegal write
- * operation to the tail pages.
+ * Map the shared tail page writable. A lockless get that read
+ * a non-zero refcount before the remap can still do its
+ * cmpxchg after it. The refcount is zero, so the cmpxchg
+ * fails and leaves the page unchanged.
*/
- entry = mk_pte(walk->vmemmap_tail, PAGE_KERNEL_RO);
+ entry = mk_pte(walk->vmemmap_tail, PAGE_KERNEL);
}
list_add(&page->lru, walk->vmemmap_pages);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 241/507] mm: page_alloc: do not give all non-blocking requests reserve access
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (239 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 240/507] mm/hugetlb_vmemmap: map the shared tail page writable Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 242/507] mm: page_alloc: remove ALLOC_NON_BLOCK from ALLOC_RESERVES Greg Kroah-Hartman
` (265 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Johannes Weiner, Andrew Morton,
Sashiko, Balbir Singh, Vlastimil Babka (SUSE),
Matthew Wilcox (Oracle), Salvatore Dipietro, Christoph Hellwig,
Dave Chinner, Matt Fleming, Mel Gorman, Michal Hocko,
Suren Baghdasaryan, Brendan Jackman, Zi Yan, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Weiner <hannes@cmpxchg.org>
[ Upstream commit 6ee3d87b940848aaed5d4e8d005c5f674bf2637a ]
Patch series "mm: page_alloc: fix reserve access for non-blocking
requests", v2.
Two fixes for how non-blocking allocations interact with the highatomic
reserve. There are prerequisites for Salvatore's "mm/page_alloc: avoid
direct reclaim and compaction for costly __GFP_NORETRY allocations" [0].
Patch 1 narrows which requests may physically take highatomic pages,
patch 2 narrows which requests may count them in their watermark check.
Both are prerequisites for Salvatore's patch: it clears
__GFP_DIRECT_RECLAIM for costly __GFP_NORETRY requests, which turns every
large page cache folio allocation that reaches the slowpath into a
non-blocking one. Without patch 1, those requests may fall back to the
highatomic freelists reserved for atomic requests. Without patch 2, they
count the free highatomic pages in their watermark check while being
served from regular memory, so they can consume regular high-order blocks
below the min watermark by the size of the reserve. GFP_NOWAIT requests
hit both paths today, so these are existing problems worthy of their own
stable backports; but Salvatore's patch would widen them significantly.
Patch 2 reproduction: a GFP_NOWAIT burst under memory pressure can drain
regular free memory to zero while the highatomic reserve sits idle.
Measured on a 32G box with an anonymous working set, swap, and a full 290M
reserve, three synthetic bursts drove the 28G Normal zone's regular free
memory to 28M, 0.8M and 0.6M against a 60M min watermark. Swapout failed
its swap table allocation inside reclaim, reclaim scanned 13M pages to
free 200k, and page faults stalled for tens to hundreds of milliseconds.
With the fix the burst stops at the min watermark and nothing else
happens. This was found in review and reproduced synthetically; it has
not been observed in production.
GFP_ATOMIC order-0 requests have a milder version of the same problem:
They are entitled to the reserve but are served regular memory first, so
the fix there has to change the watermark check and the freelist order
together. Salvatore's change doesn't interact with this, though; fixing
that is left for a separate patch.
This patch (of 2):
281dd25c1a01 ("mm/page_alloc: let GFP_ATOMIC order-0 allocs access
highatomic reserves") accidentally gave all non-blocking allocation
requests access to highatomic reserves, which includes GFP_NOWAIT and
other sites clearing __GFP_DIRECT_RECLAIM.
While this improved atomic request success rate, it's unintentionally
broad and can actually worsen highatomic requests by squandering the
reserves on requests that don't need it.
There are concurrent efforts to clear __GFP_DIRECT_RECLAIM altogether
for costly order __GFP_NORETRY requests, which would then also fall
into this exemption and deplete reserves even faster.
What GFP_ATOMIC has over the others is __GFP_HIGH, which
alloc_flags_slowpath() translates to ALLOC_MIN_RESERVE.
Narrow the exemption to contexts that have both ALLOC_NON_BLOCK |
ALLOC_MIN_RESERVE.
Link: https://lore.kernel.org/20261001082152.2879289-1-dipiets@amazon.it [0]
Link: https://lore.kernel.org/linux-mm/arFBWvzXPYrKuIYi@cmpxchg.org/ [1]
Link: https://lore.kernel.org/linux-mm/20261001082152.2879289-1-dipiets@amazon.it/ [2]
Link: https://lore.kernel.org/20261028171719.2043421-1-hannes@cmpxchg.org
Link: https://lore.kernel.org/20261028171719.2043421-2-hannes@cmpxchg.org
Fixes: 281dd25c1a01 ("mm/page_alloc: let GFP_ATOMIC order-0 allocs access highatomic reserves")
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260904115629.3993331-1-dipiets@amazon.it
Acked-by: Balbir Singh <balbirs@nvidia.com>
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Salvatore Dipietro <dipiets@amazon.it>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Dave Chinner <dgc@kernel.org>
Cc: Matt Fleming <matt@readmodwrite.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Brendan Jackman <brendan.jackman@linux.dev>
Cc: Zi Yan <ziy@nvidia.com>
Cc: <stable@vger.kernel.org>
regular free memory to zero while the highatomic reserve sits idle.
Measured on a 32G box with an anonymous working set, swap, and a full 290M
reserve, three synthetic bursts drove the 28G Normal zone's regular free
memory to 28M, 0.8M and 0.6M against a 60M min watermark. Swapout failed
its swap table allocation inside reclaim, reclaim scanned 13M pages to
free 200k, and page faults stalled for tens to hundreds of milliseconds.
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/page_alloc.c | 4 +++-
mm/page_alloc.h | 3 +++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index d8adf19eaeea6..ddffc7c8430e8 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3259,7 +3259,9 @@ struct page *rmqueue_buddy(struct zone *preferred_zone, struct zone *zone,
* reserves as failing now is worse than failing a
* high-order atomic allocation in the future.
*/
- if (!page && (alloc_flags & (ALLOC_OOM|ALLOC_NON_BLOCK)))
+ if (!page &&
+ ((alloc_flags & ALLOC_OOM) ||
+ (alloc_flags & ALLOC_MASK_ATOMIC) == ALLOC_MASK_ATOMIC))
page = __rmqueue_smallest(zone, order, MIGRATE_HIGHATOMIC);
if (!page) {
diff --git a/mm/page_alloc.h b/mm/page_alloc.h
index 2b1017a91928c..1ae729be96016 100644
--- a/mm/page_alloc.h
+++ b/mm/page_alloc.h
@@ -60,6 +60,9 @@
/* Flags that allow allocations below the min watermark. */
#define ALLOC_RESERVES (ALLOC_NON_BLOCK|ALLOC_MIN_RESERVE|ALLOC_HIGHATOMIC|ALLOC_OOM)
+/* Flags that mean GFP_ATOMIC */
+#define ALLOC_MASK_ATOMIC (ALLOC_NON_BLOCK|ALLOC_MIN_RESERVE)
+
/*
* Structure for holding the mostly immutable allocation parameters passed
* between functions involved in allocations, including the alloc_pages*
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 242/507] mm: page_alloc: remove ALLOC_NON_BLOCK from ALLOC_RESERVES
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (240 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 241/507] mm: page_alloc: do not give all non-blocking requests reserve access Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 243/507] mm/cma: accept memory of multi-range CMA areas Greg Kroah-Hartman
` (264 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Johannes Weiner, Andrew Morton,
Balbir Singh, Vlastimil Babka (SUSE), Matthew Wilcox (Oracle),
Salvatore Dipietro, Christoph Hellwig, Dave Chinner, Matt Fleming,
Mel Gorman, Michal Hocko, Suren Baghdasaryan, Brendan Jackman,
Zi Yan, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Weiner <hannes@cmpxchg.org>
[ Upstream commit fe21f930d1e64d121191673076fc4ebe79fc82d5 ]
1ebbb21811b7 ("mm/page_alloc: explicitly define how __GFP_HIGH
non-blocking allocations accesses reserves") stopped handing out reserve
access for ALLOC_NON_BLOCK on its own: the extra 25% below the min
watermark is now only granted on top of ALLOC_MIN_RESERVE. But the flag
was left in ALLOC_RESERVES, which produces something odd:
With the ALLOC_RESERVES match, __zone_watermark_unusable_free() doesn't
subtract the free highatomic pages for them. So in the slowpath, they get
to consume regular blocks below the min watermark by the number of free
highatomic pages. The highatomic reserve is capped at 1% of the zone,
which on any decently sized machine is a multiple of the min watermark:
GFP_NOWAIT can drain regular memory to zero.
The user-visible result is brutal hiccups during bursts of GFP_NOWAIT
allocations under memory pressure. This was found in review and
reproduced with a synthetic burst, not observed in production, but the
sequence of events is a realistic one: On a 32G box with an anonymous
working set, swap, and a filled 290M highatomic reserve, a GFP_NOWAIT
burst drove regular free memory in the 28G Normal zone (min=60M) to 28M,
0.8M and 0.6M in three runs. Swapout failed to allocate its swap table,
reclaim scanned 13M pages to reclaim 200k, page faults stalled for tens to
hundreds of milliseconds. The machine survives it, but not by design:
direct reclaimers eventually fail and start unreserving highatomic blocks,
until the allocation succeeds or the reserve is gone and the OOM killer
runs. That reserve exists for high-order atomic allocations; here it is
destroyed to bail out a GFP_NOWAIT consumer that was never entitled to the
memory.
Remove ALLOC_NON_BLOCK from ALLOC_RESERVES. With that, the GFP_NOWAIT
burst is stopped short at the min watermark. No direct reclaim, no
stalls, no failed allocations, and the highatomic reserve stays intact for
the requests it exists for.
__zone_watermark_ok() is unaffected, since everything it keys on
ALLOC_NON_BLOCK is already nested under ALLOC_MIN_RESERVE. Update the
flag comments accordingly: ALLOC_NON_BLOCK just means the caller can't
block; the reserve math belongs with ALLOC_MIN_RESERVE.
GFP_ATOMIC order-0 requests have a milder version of the same problem.
Through ALLOC_MIN_RESERVE they also count the free highatomic pages in
their watermark check, but rmqueue_buddy() serves them regular pages first
and only falls back to the reserve once those are gone. They can still
push regular free memory to 37.5% of min minus the free highatomic pages
before the reserve is touched. Unlike GFP_NOWAIT they are entitled to the
reserve, so this needs the watermark check and the freelist order reworked
together, and is left to a separate patch.
Link: https://lore.kernel.org/20261028171719.2043421-3-hannes@cmpxchg.org
Fixes: 1ebbb21811b7 ("mm/page_alloc: explicitly define how __GFP_HIGH non-blocking allocations accesses reserves")
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Balbir Singh <balbirs@nvidia.com>
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Salvatore Dipietro <dipiets@amazon.it>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Dave Chinner <dgc@kernel.org>
Cc: Matt Fleming <matt@readmodwrite.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Brendan Jackman <brendan.jackman@linux.dev>
Cc: Zi Yan <ziy@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/page_alloc.h | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/mm/page_alloc.h b/mm/page_alloc.h
index 1ae729be96016..a9b72cb9520e1 100644
--- a/mm/page_alloc.h
+++ b/mm/page_alloc.h
@@ -32,12 +32,11 @@
#define ALLOC_OOM ALLOC_NO_WATERMARKS
#endif
-#define ALLOC_NON_BLOCK 0x10 /* Caller cannot block. Allow access
- * to 25% of the min watermark or
- * 62.5% if __GFP_HIGH is set.
- */
+#define ALLOC_NON_BLOCK 0x10 /* Caller cannot block. */
#define ALLOC_MIN_RESERVE 0x20 /* __GFP_HIGH set. Allow access to 50%
- * of the min watermark.
+ * of the min watermark, or 62.5% if
+ * the caller cannot block either
+ * (ALLOC_NON_BLOCK).
*/
#define ALLOC_CPUSET 0x40 /* check for correct cpuset */
#define ALLOC_CMA 0x80 /* allow allocations from CMA areas */
@@ -58,7 +57,7 @@
#define ALLOC_NO_CODETAG 0x1000
/* Flags that allow allocations below the min watermark. */
-#define ALLOC_RESERVES (ALLOC_NON_BLOCK|ALLOC_MIN_RESERVE|ALLOC_HIGHATOMIC|ALLOC_OOM)
+#define ALLOC_RESERVES (ALLOC_MIN_RESERVE|ALLOC_HIGHATOMIC|ALLOC_OOM)
/* Flags that mean GFP_ATOMIC */
#define ALLOC_MASK_ATOMIC (ALLOC_NON_BLOCK|ALLOC_MIN_RESERVE)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 243/507] mm/cma: accept memory of multi-range CMA areas
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (241 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 242/507] mm: page_alloc: remove ALLOC_NON_BLOCK from ALLOC_RESERVES Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 244/507] mm/cma: accept memory of CMA areas reserved at a fixed address Greg Kroah-Hartman
` (263 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mike Rapoport (Microsoft),
Andrew Morton, Kiryl Shutsemau (Meta), Pankaj Gupta,
David Hildenbrand, Liam R. Howlett, Lorenzo Stoakes, Michal Hocko,
Suren Baghdasaryan, Vlastimil Babka, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Rapoport (Microsoft) <rppt@kernel.org>
[ Upstream commit 5d002001601a163b6c3500cdc098ff66c34f62d8 ]
Patch series "mm/cma: accept memory of CMA areas reserved with
memblock_reserve()", v1.
Pages of allocated CMA areas are released to the buddy allocator with
__free_pages(), which does not check for unaccepted memory.
This usually works because memblock accepts the memory it allocates.
However, multi-range CMA areas, used by hugetlb_cma, and fixed CMA areas
requested with cma=<size>@<base> are reserved with memblock_reserve() and
their memory is never accepted.
On TDX and SEV-SNP guests the first access to such a page is fatal.
To ease the backporting, each case is addressed by a separate patch:
- patch 1 accepts the memory of multi-range CMA areas
- patch 2 does the same for the fixed CMA areas
The second patch won't apply cleanly to 6.6 and 6.12, but I believe the
stable team LLMs will take care of that :)
This patch (of 2):
On systems with unaccepted memory, memblock allocations accept the
allocated range, but when cma_declare_contiguous_multi() uses open coded
allocation of multiple ranges, it reserves them with memblock_reserve()
and they are never accepted.
These pages are released to the buddy allocator by cma_activate_area()
with __free_pages() that does not check for unaccepted memory, so the
first access to such a page in a TDX or SEV-SNP guest is fatal.
Accept the memory of each range when it is reserved.
Link: https://lore.kernel.org/20261029-cma-multi-v1-0-2cbced8b5cb7@kernel.org
Link: https://lore.kernel.org/20261029-cma-multi-v1-1-2cbced8b5cb7@kernel.org
Fixes: c009da4258f9 ("mm, cma: support multiple contiguous ranges, if requested")
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Tested-by: Pankaj Gupta <pankaj.gupta@amd.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/cma.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/mm/cma.c b/mm/cma.c
index a10ea37a261da..0035efb1130a5 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -678,6 +678,8 @@ int __init cma_declare_contiguous_multi(phys_addr_t total_size,
break;
}
+ accept_memory(mlp->base, size);
+
pr_debug("created region %d: %016llx - %016llx\n",
nr, (u64)mlp->base, (u64)mlp->base + size);
cmrp = &cma->ranges[nr++];
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 244/507] mm/cma: accept memory of CMA areas reserved at a fixed address
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (242 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 243/507] mm/cma: accept memory of multi-range CMA areas Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 245/507] mm: memcontrol: fix NULL pointer deref and UAF from high_work_func() on dying memcg Greg Kroah-Hartman
` (262 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mike Rapoport (Microsoft),
Andrew Morton, Kiryl Shutsemau (Meta), Pankaj Gupta,
David Hildenbrand, Liam R. Howlett, Lorenzo Stoakes, Michal Hocko,
Suren Baghdasaryan, Vlastimil Babka, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Rapoport (Microsoft) <rppt@kernel.org>
[ Upstream commit f8f9cbc34a309a388c052706f3329d1b52985aa3 ]
CMA areas allocated from memblock have their memory accepted by
memblock_alloc_range_nid(), but areas reserved at a fixed address with
memblock_reserve() are not.
If a fixed CMA area is requested by the cma=<size>@<base> command line
parameter, it may be in regular RAM and on TDX and SEV-SNP guests it
must be accepted.
Accept the memory of fixed CMA areas as well, so that all CMA areas are
accepted regardless of how they were reserved.
Link: https://lore.kernel.org/20261029-cma-multi-v1-2-2cbced8b5cb7@kernel.org
Fixes: 75d090fd167a ("x86/tdx: Add unaccepted memory support")
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Pankaj Gupta <pankaj.gupta@amd.com>
Tested-by: Pankaj Gupta <pankaj.gupta@amd.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/cma.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/mm/cma.c b/mm/cma.c
index 0035efb1130a5..f61d52796f4ef 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -381,6 +381,8 @@ static int __init cma_fixed_reserve(phys_addr_t base, phys_addr_t size)
return -EBUSY;
}
+ accept_memory(base, size);
+
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 245/507] mm: memcontrol: fix NULL pointer deref and UAF from high_work_func() on dying memcg
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (243 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 244/507] mm/cma: accept memory of CMA areas reserved at a fixed address Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 246/507] lib/base64: silence clang-24 -Wconstant-conversion with diag pragmas Greg Kroah-Hartman
` (261 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, T.J. Mercier, Andrew Morton,
Johannes Weiner, Muchun Song, Shakeel Butt, Michal Hocko,
Michal Hocko, Roman Gushchin, Qi Zheng, JP Kobryn, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: T.J. Mercier <tjmercier@google.com>
[ Upstream commit dd94d8c7660a60dbfcd425e0d10120de6d02a7bd ]
When memory.high is exceeded in non-task context, try_charge_memcg()
schedules memcg->high_work without taking a reference on the memcg, and
high_work_func() invokes reclaim_high() without pinning the memcg.
With obj_cgroup reparenting, introduced in commit bf4f059954dc ("mm:
memcg/slab: obj_cgroup API"), objects charged to a child memcg are
reparented to its parent in mem_cgroup_css_offline() instead of holding a
reference on the child until uncharged. Subsequent uncharges of those
objects go to the parent, which can leave the child's memory use
permanently above its high limit, so any later charge on the offlined
memcg in non-task context schedules high_work. This was later widened
from kernel memory to LRU folios when commit f1cf8d2f36dc ("mm:
memcontrol: eliminate the problem of dying memory cgroup for LRU folios")
converted LRU folios to use obj_cgroup reparenting.
cancel_work_sync(&memcg->high_work) only runs at the end of teardown in
mem_cgroup_css_free(), so high_work_func() can start or still be running
reclaim_high() after mem_cgroup_css_released() or shrink_many() has called
lru_gen_release_memcg() and unhashed lruvec->lrugen.list. If reclaim
tries to rotate the memcg, lru_gen_rotate_memcg() dereferences a NULL
pprev pointer. This issue is specific to MGLRU and was introduced with
the memcg LRU in commit e4dde56cd208 ("mm: multi-gen LRU: per-node
lru_gen_folio lists").
With either traditional LRU or MGLRU, css_free_rwork_fn() calls
css_rstat_exit() which frees per-CPU rstat data before calling
mem_cgroup_css_free(). If reclaim_high() is still running, rstat updates
via mod_lruvec_state() -> __css_rstat_updated() cause a use-after-free on
the per-CPU rstat data. This was introduced when commit 5da3bfa029d6
("cgroup: use separate rstat trees for each subsystem") moved
css_rstat_exit() ahead of ss->css_free().
Fix both problems by acquiring a reference with css_tryget_online() in
high_work_func() before calling reclaim_high(), and by resetting
memory.high and swap.high to PAGE_COUNTER_MAX in mem_cgroup_css_offline()
so that charges via references on an offlined memcg do not trigger
high_work on the dead child and skip checking live ancestors in
try_charge_memcg().
Acquiring the reference in high_work_func() rather than before scheduling
high_work is safe because mem_cgroup_css_free() calls irq_work_sync() and
cancel_work_sync() which cancels pending work and waits for an already
running high_work_func() to complete before mem_cgroup_free() frees the
memcg. css_tryget_online() uses percpu_ref_tryget_live() and is safe to
call after percpu_ref_exit() before the cgroup is freed unlike
css_tryget().
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
CPU: 1 UID: 0 PID: 27 Comm: kworker/1:0 Tainted: G B W 7.3.0-rc5-g2bba28e98578 #284 PREEMPT(full)
Tainted: [B]=BAD_PAGE, [W]=WARN <-- Taint from lru_gen_rotate_memcg() VM_WARN_ON_ONCE
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
Workqueue: events high_work_func
RIP: 0010:lru_gen_rotate_memcg+0x1a3/0xe90
Call Trace:
<TASK>
? read_ctrl_pos+0x22f/0x3f0
shrink_lruvec+0x16cb/0x1b80
? ret_from_fork_asm+0x1a/0x30
? lapic_next_event+0x15/0x20
? clockevents_program_event+0x2bb/0x6f0
? lapic_next_event+0x15/0x20
? __pfx_shrink_lruvec+0x10/0x10
? __pfx_clockevents_program_event+0x10/0x10
? _raw_spin_lock+0x84/0xe0
? __pfx__raw_spin_lock+0x10/0x10
? kasan_save_stack+0x30/0x50
? psi_group_change+0x381/0x740
? __pfx_sched_clock_cpu+0x10/0x10
? save_fpregs_to_fpstate+0xc4/0x2c0
? finish_task_switch.isra.0+0x1de/0xac0
? __schedule+0xf62/0x42c0
? __pfx___schedule+0x10/0x10
? __pfx___irq_work_queue_local+0x10/0x10
? shrink_node+0x626/0x31e0
shrink_node+0x626/0x31e0
? ring_buffer_unlock_commit+0x11d/0x5c0
? kswapd_clear_hopeless+0xa0/0x150
? __pfx_shrink_node+0x10/0x10
? 0xffffffffc0000095
do_try_to_free_pages+0x255/0x13b0
? ring_buffer_unlock_commit+0x11d/0x5c0
? reclaim_high+0x10a/0x1b0
try_to_free_mem_cgroup_pages+0x1f9/0x5a0
? __pfx_try_to_free_mem_cgroup_pages+0x10/0x10
? irqentry_exit+0xc6/0x670
reclaim_high+0x10a/0x1b0
? __pfx_reclaim_high+0x10/0x10
? process_one_work+0x5ff/0x1030
? __pfx_high_work_func+0x10/0x10
process_one_work+0x6e2/0x1030
? __pfx___schedule+0x10/0x10
? __pfx_process_one_work+0x10/0x10
worker_thread+0x422/0xbb0
? __pfx_worker_thread+0x10/0x10
kthread+0x2cd/0x3a0
? recalc_sigpending+0x15c/0x200
? __pfx_kthread+0x10/0x10
ret_from_fork+0x368/0x590
? __pfx_ret_from_fork+0x10/0x10
? __switch_to+0x588/0xf50
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Link: https://lore.kernel.org/20261029201858.2932905-1-tjmercier@google.com
Fixes: e4dde56cd208 ("mm: multi-gen LRU: per-node lru_gen_folio lists")
Fixes: 5da3bfa029d6 ("cgroup: use separate rstat trees for each subsystem")
Signed-off-by: T.J. Mercier <tjmercier@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Muchun Song <muchun.song@linux.dev>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Acked-by: Michal Hocko <mhocko@suse.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Qi Zheng <qi.zheng@linux.dev>
Cc: JP Kobryn <jp.kobryn@linux.dev>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/memcontrol.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index b5137e86bed70..b303bfc6b46ea 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2419,7 +2419,10 @@ static void high_work_func(struct work_struct *work)
struct mem_cgroup *memcg;
memcg = container_of(work, struct mem_cgroup, high_work);
+ if (!css_tryget_online(&memcg->css))
+ return;
reclaim_high(memcg, MEMCG_CHARGE_BATCH, GFP_KERNEL);
+ css_put(&memcg->css);
}
/*
@@ -4369,6 +4372,8 @@ static void mem_cgroup_css_offline(struct cgroup_subsys_state *css)
page_counter_set_min(&memcg->memory, 0);
page_counter_set_low(&memcg->memory, 0);
+ page_counter_set_high(&memcg->memory, PAGE_COUNTER_MAX);
+ page_counter_set_high(&memcg->swap, PAGE_COUNTER_MAX);
zswap_memcg_offline_cleanup(memcg);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 246/507] lib/base64: silence clang-24 -Wconstant-conversion with diag pragmas
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (244 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 245/507] mm: memcontrol: fix NULL pointer deref and UAF from high_work_func() on dying memcg Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 247/507] openrisc: export __mulsi3 for modules Greg Kroah-Hartman
` (260 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nathan Chancellor, Andrew Morton,
Kuan-Wei Chiu, Nick Desaulniers, Bill Wendling, Justin Stitt,
Guan-Chun Wu, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <nathan@kernel.org>
[ Upstream commit 3af83c11cf5990fda0bfe3959aa6391ff903ffdd ]
After a recent change in clang to warn on signed char conversions within
array initializers [1], there are several instances of this warning from
base64_rev_maps in lib/base64.c, which can break the build with W=e or
CONFIG_WERROR=y:
lib/base64.c:58:18: error: implicit conversion from 'int' to 's8' (aka 'signed char') changes value from 131 to -125 [-Werror,-Wconstant-conversion]
58 | [BASE64_IMAP] = BASE64_REV_INIT('+', ',')
| ^~~~~~~~~~~~~~~~~~~~~~~~~
lib/base64.c:52:2: note: expanded from macro 'BASE64_REV_INIT'
48 | #define BASE64_REV_INIT(ch_62, ch_63) { \
| ~
49 | [0 ... 0x1f] = -1, \
50 | INIT_32(0x20, ch_62, ch_63), \
51 | INIT_32(0x40, ch_62, ch_63), \
52 | INIT_32(0x60, ch_62, ch_63), \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
...
lib/base64.c:34:42: note: expanded from macro 'INIT_1'
34 | : (v) >= '0' && (v) <= '9' ? (v) - '0' + 52 \
| ~~~~~~~~~~^~~~
lib/base64.c:58:18: error: implicit conversion from 'int' to 's8' (aka 'signed char') changes value from 130 to -126 [-Werror,-Wconstant-conversion]
58 | [BASE64_IMAP] = BASE64_REV_INIT('+', ',')
| ^~~~~~~~~~~~~~~~~~~~~~~~~
lib/base64.c:52:2: note: expanded from macro 'BASE64_REV_INIT'
48 | #define BASE64_REV_INIT(ch_62, ch_63) { \
| ~
49 | [0 ... 0x1f] = -1, \
50 | INIT_32(0x20, ch_62, ch_63), \
51 | INIT_32(0x40, ch_62, ch_63), \
52 | INIT_32(0x60, ch_62, ch_63), \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
...
lib/base64.c:34:42: note: expanded from macro 'INIT_1'
34 | : (v) >= '0' && (v) <= '9' ? (v) - '0' + 52 \
| ~~~~~~~~~~^~~~
...
These are false positives, as the branch where the wraparound could happen
is unreachable with the values that clang reports. This is not considered
a bug by some clang folks [2][3], so silence the warnings using the __diag
macros the kernel has to workaround compiler warnings when necessary.
Link: https://lore.kernel.org/20261008-base64-silence-clang-24-constant-conversion-v1-1-0858b60b23c8@kernel.org
Link: https://github.com/llvm/llvm-project/commit/a5ef934a8d295dc03be3960f2b3744ec2e53238e [1]
Link: https://github.com/llvm/llvm-project/issues/223923#issuecomment-6056856245 [2]
Link: https://github.com/llvm/llvm-project/pull/226775#pullrequestreview-5454407389 [3]
Fixes: c4eb7ad32eab ("lib/base64: optimize base64_decode() with reverse lookup tables")
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Closes: https://github.com/ClangBuiltLinux/linux/issues/2181
Acked-by: Kuan-Wei Chiu <visitorckw@gmail.com>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Bill Wendling <morbo@google.com>
Cc: Justin Stitt <justinstitt@google.com>
Cc: Guan-Chun Wu <409411716@gms.tku.edu.tw>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
lib/base64.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/base64.c b/lib/base64.c
index 325c7332b0492..e46be3a55585c 100644
--- a/lib/base64.c
+++ b/lib/base64.c
@@ -52,11 +52,14 @@ static const char base64_tables[][65] = {
INIT_32(0x60, ch_62, ch_63), \
[0x80 ... 0xff] = -1 }
+__diag_push();
+__diag_ignore(clang, all, "-Wconstant-conversion", "https://github.com/llvm/llvm-project/issues/223923");
static const s8 base64_rev_maps[][256] = {
[BASE64_STD] = BASE64_REV_INIT('+', '/'),
[BASE64_URLSAFE] = BASE64_REV_INIT('-', '_'),
[BASE64_IMAP] = BASE64_REV_INIT('+', ',')
};
+__diag_pop();
#undef BASE64_REV_INIT
#undef INIT_32
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 247/507] openrisc: export __mulsi3 for modules
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (245 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 246/507] lib/base64: silence clang-24 -Wconstant-conversion with diag pragmas Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 248/507] ocfs2: find the xattr entry again after defragmenting a bucket Greg Kroah-Hartman
` (259 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andrew Morton, kernel test robot,
Bradley Morgan, Jonas Bonn, Stefan Kristiansson, Stafford Horne,
Arnd Bergmann, Karl Mehltretter, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Morton <akpm@linux-foundation.org>
[ Upstream commit 8ff981aa283a0ce516c2dc65a48a185ed336c657 ]
OpenRISC configurations without hardware multiplication fail to build
modules which contain compiler-generated calls to __mulsi3. The failure
is widespread, affecting filesystems, drivers and KUnit tests at modpost.
When CONFIG_OPENRISC_HAVE_INST_MUL is disabled, the architecture Makefile
passes -msoft-mul to GCC. The multiplication helper is supplied by the
libgcc archive linked into vmlinux, but or32_ksyms.c does not export it.
Built-in callers can therefore link while module callers cannot resolve
the symbol.
Export __mulsi3 alongside the other compiler-generated helpers.
The omission predates 7c3f4d699f34 ("resource, kunit: stop selecting
GET_FREE_REGION"), which the robot identified when reporting an additional
failing module. It was already present in the initial OpenRISC export
list.
Fixes: 616257669e1a ("OpenRISC: Miscellaneous")
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202610290106.o8Fs3NvO-lkp@intel.com/
Reviewed-by: Bradley Morgan <brads@mainlining.org>
Cc: Jonas Bonn <jonas@southpole.se>
Cc: Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
Cc: Stafford Horne <shorne@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Karl Mehltretter <kmehltretter@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/openrisc/kernel/or32_ksyms.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/openrisc/kernel/or32_ksyms.c b/arch/openrisc/kernel/or32_ksyms.c
index 84a937a64e2a7..5aabef30ca09c 100644
--- a/arch/openrisc/kernel/or32_ksyms.c
+++ b/arch/openrisc/kernel/or32_ksyms.c
@@ -35,6 +35,7 @@ DECLARE_EXPORT(__divsi3);
DECLARE_EXPORT(__umodsi3);
DECLARE_EXPORT(__modsi3);
DECLARE_EXPORT(__muldi3);
+DECLARE_EXPORT(__mulsi3);
DECLARE_EXPORT(__ashrdi3);
DECLARE_EXPORT(__ashldi3);
DECLARE_EXPORT(__lshrdi3);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 248/507] ocfs2: find the xattr entry again after defragmenting a bucket
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (246 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 247/507] openrisc: export __mulsi3 for modules Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 249/507] ocfs2: find the xattr entry again after converting a block to " Greg Kroah-Hartman
` (258 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joseph Qi, Andrew Morton,
Heming Zhao, Mark Fasheh, Joel Becker, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joseph Qi <joseph.qi@linux.alibaba.com>
[ Upstream commit 9a40c050f58344615a0604701b5d299519833163 ]
ocfs2_xattr_set_entry_bucket() hands loc.xl_entry to ocfs2_xa_set() twice:
once for the bucket as it stands, and, if that reports -ENOSPC, once more
after ocfs2_defrag_xattr_bucket() has packed the name/value pairs down.
Defragmenting ends by sorting the entry array on xe_name_hash. Buckets
are kept sorted, so the sort only permutes entries that share a hash, but
lib/sort.c is an unstable heapsort and it does permute them. loc.xl_entry
is an address inside xh_entries[], so afterwards it denotes whichever
entry landed in that slot rather than the one the search found.
The second ocfs2_xa_set() then works on the wrong entry. Nothing on that
path compares the entry's name with xi->xi_name, so what happens depends
on how the two entries compare in size: ocfs2_xa_reuse_entry() trips its
BUG_ON() when the padded name sizes differ, and otherwise the new value is
written into the neighbouring attribute's value slot while the attribute
being set is left untouched. setxattr() reports success either way.
Remember the entry's hash before defragmenting and look the entry up
again afterwards, the way ocfs2_xattr_bucket_find() does. An entry that
cannot be found again means the bucket no longer holds what the search
found, so fail with -EFSCORRUPTED rather than writing through the stale
pointer.
Link: https://lore.kernel.org/20261024151012.1059683-3-joseph.qi@linux.alibaba.com
Fixes: 012255961c9e ("ocfs2: Enable xattr set in index btree")
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/xattr.c | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 18ebe3cc64ec1..4b9f742cef554 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -5873,13 +5873,18 @@ static int ocfs2_xattr_set_entry_bucket(struct inode *inode,
struct ocfs2_xattr_search *xs,
struct ocfs2_xattr_set_ctxt *ctxt)
{
- int ret;
+ int ret, found = 0;
+ u16 xe_index;
+ u32 name_hash;
struct ocfs2_xa_loc loc;
trace_ocfs2_xattr_set_entry_bucket(xi->xi_name);
ocfs2_init_xattr_bucket_xa_loc(&loc, xs->bucket,
xs->not_found ? NULL : xs->here);
+ /* Defragmenting below may move this entry, so remember its hash. */
+ name_hash = loc.xl_entry ? le32_to_cpu(loc.xl_entry->xe_name_hash) : 0;
+
ret = ocfs2_xa_set(&loc, xi, ctxt);
if (!ret) {
xs->here = loc.xl_entry;
@@ -5898,6 +5903,29 @@ static int ocfs2_xattr_set_entry_bucket(struct inode *inode,
goto out;
}
+ /*
+ * ocfs2_defrag_xattr_bucket() sorts the entries by name hash and
+ * lib/sort.c is not stable, so entries sharing a hash may have traded
+ * slots. Look the entry up again before writing through it.
+ */
+ if (loc.xl_entry) {
+ ret = ocfs2_find_xe_in_bucket(inode, xs->bucket,
+ xi->xi_name_index, xi->xi_name,
+ name_hash, &xe_index, &found);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+ if (!found) {
+ mlog(ML_ERROR, "xattr entry not found in bucket %llu after defrag\n",
+ (unsigned long long)bucket_blkno(xs->bucket));
+ ret = -EFSCORRUPTED;
+ goto out;
+ }
+ loc.xl_entry = &bucket_xh(xs->bucket)->xh_entries[xe_index];
+ xs->here = loc.xl_entry;
+ }
+
ret = ocfs2_xa_set(&loc, xi, ctxt);
if (!ret) {
xs->here = loc.xl_entry;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 249/507] ocfs2: find the xattr entry again after converting a block to a bucket
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (247 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 248/507] ocfs2: find the xattr entry again after defragmenting a bucket Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 250/507] ocfs2: do not read the entry array of an empty xattr bucket Greg Kroah-Hartman
` (257 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joseph Qi, Andrew Morton,
Heming Zhao, Mark Fasheh, Joel Becker, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joseph Qi <joseph.qi@linux.alibaba.com>
[ Upstream commit 9c191a7a44882487e291e09f095d2ae4d7cca146 ]
ocfs2_xattr_create_index_block() turns a non-indexed xattr block into a
tree by copying it into a bucket, and the copy sorts the entries: a
block holds them in insertion order, a bucket by name hash.
ocfs2_xattr_update_xattr_search() nevertheless relocates the caller's
search by the index the entry had in the block, so unless the two orders
agreed it points at an unrelated entry, and nothing between there and
the write compares that entry's name with the one being set.
Setting an xattr whose new value no longer fits the block arrives here
with xs->not_found clear. The block gave up because
ocfs2_xa_block_can_reuse() wants an exact namevalue size match, while
ocfs2_xa_bucket_can_reuse() only wants an entry at least as large as the
new one, so the bucket accepts a pair the block rejected and the update
lands on whichever entry the sort left at that index. Equal padded name
lengths get that other attribute's value replaced in place and its name
left alone, so setxattr returns success while the attribute asked for
keeps its old value. A longer one trips ocfs2_xa_reuse_entry()'s
BUG_ON, and a shorter one is refused by the bucket as well, so
ocfs2_xa_prepare_entry() wipes the entry and writes the new name over
it, leaving xe_name_hash describing a name that is no longer there.
Find the entry again by the name being set, matching the type as well.
The copy carries every entry and every name over unchanged, and (type,
name) pairs are unique within a block, so the match is exact. The type
matters because the handlers strip their prefix before calling
ocfs2_xattr_set(), so user.foo and trusted.foo share a stored name, a
stored length and a hash, and both can sit in the same block.
The name has to come from xi rather than from xs->here: a failed set can
remove the entry xs->here names, and only the "growing" caller sets
ctxt->set_abort, which is what stops the conversion. Scan every entry
rather than narrowing on the hash the way ocfs2_find_xe_in_bucket()
does, since an existing entry keeps the hash it was stored under, which
a kernel that sign-extended the name bytes made different from the one
computed now. An empty result means the entry did not survive the
failed set and this has become an insert; leaving xs->here alone would
keep it pointing into the block, which is rewritten as a tree root
before the caller reads it again.
Link: https://lore.kernel.org/20261024151012.1059683-4-joseph.qi@linux.alibaba.com
Fixes: 012255961c9e ("ocfs2: Enable xattr set in index btree")
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/xattr.c | 54 +++++++++++++++++++++++++++++++++++++++---------
1 file changed, 44 insertions(+), 10 deletions(-)
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 4b9f742cef554..dc0e2aea14a38 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -260,6 +260,7 @@ static int ocfs2_xattr_tree_list_index_block(struct inode *inode,
size_t buffer_size);
static int ocfs2_xattr_create_index_block(struct inode *inode,
+ struct ocfs2_xattr_info *xi,
struct ocfs2_xattr_search *xs,
struct ocfs2_xattr_set_ctxt *ctxt);
@@ -3251,7 +3252,7 @@ static int ocfs2_xattr_block_set(struct inode *inode,
else if ((ret != -ENOSPC) || ctxt->set_abort)
goto end;
else {
- ret = ocfs2_xattr_create_index_block(inode, xs, ctxt);
+ ret = ocfs2_xattr_create_index_block(inode, xi, xs, ctxt);
if (ret)
goto end;
}
@@ -4579,13 +4580,10 @@ static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode,
* real place of the xattr.
*/
static void ocfs2_xattr_update_xattr_search(struct inode *inode,
- struct ocfs2_xattr_search *xs,
- struct buffer_head *old_bh)
+ struct ocfs2_xattr_info *xi,
+ struct ocfs2_xattr_search *xs)
{
- char *buf = old_bh->b_data;
- struct ocfs2_xattr_block *old_xb = (struct ocfs2_xattr_block *)buf;
- struct ocfs2_xattr_header *old_xh = &old_xb->xb_attrs.xb_header;
- int i;
+ int i, count;
xs->header = bucket_xh(xs->bucket);
xs->base = bucket_block(xs->bucket, 0);
@@ -4594,11 +4592,47 @@ static void ocfs2_xattr_update_xattr_search(struct inode *inode,
if (xs->not_found)
return;
- i = xs->here - old_xh->xh_entries;
- xs->here = &xs->header->xh_entries[i];
+ /*
+ * A block holds its entries in insertion order while a bucket holds
+ * them by name hash, so ocfs2_cp_xattr_block_to_bucket() sorted the
+ * copies and the index this entry had in the block no longer says
+ * where it is. It copied every entry and every name unchanged, and
+ * (type, name) pairs are unique within a block, so find it again by
+ * name.
+ *
+ * Search for the name being set, not for the name xs->here carries.
+ * A failed set may have removed that entry, and ocfs2_xa_remove_entry()
+ * then memmoves its successor into the slot. Comparing every entry
+ * rather than narrowing on the hash also finds an entry stored under
+ * the legacy signed hash, which ocfs2_find_xe_in_bucket() would skip.
+ */
+ count = le16_to_cpu(xs->header->xh_count);
+ for (i = 0; i < count; i++) {
+ struct ocfs2_xattr_entry *xe = &xs->header->xh_entries[i];
+
+ if (ocfs2_xattr_get_type(xe) != xi->xi_name_index)
+ continue;
+ if (xe->xe_name_len != xi->xi_name_len)
+ continue;
+ if (!memcmp(xs->base + le16_to_cpu(xe->xe_name_offset),
+ xi->xi_name, xi->xi_name_len)) {
+ xs->here = xe;
+ return;
+ }
+ }
+
+ /*
+ * The entry did not survive the failed set, so this has become an
+ * insert. Point xs->here back inside the bucket: it still refers to
+ * the block being converted, which is about to be rewritten as a tree
+ * root.
+ */
+ xs->not_found = -ENODATA;
+ xs->here = xs->header->xh_entries;
}
static int ocfs2_xattr_create_index_block(struct inode *inode,
+ struct ocfs2_xattr_info *xi,
struct ocfs2_xattr_search *xs,
struct ocfs2_xattr_set_ctxt *ctxt)
{
@@ -4665,7 +4699,7 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
ocfs2_cp_xattr_block_to_bucket(inode, xb_bh, xs->bucket);
ocfs2_xattr_bucket_journal_dirty(handle, xs->bucket);
- ocfs2_xattr_update_xattr_search(inode, xs, xb_bh);
+ ocfs2_xattr_update_xattr_search(inode, xi, xs);
/* Change from ocfs2_xattr_header to ocfs2_xattr_tree_root */
memset(&xb->xb_attrs, 0, inode->i_sb->s_blocksize -
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 250/507] ocfs2: do not read the entry array of an empty xattr bucket
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (248 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 249/507] ocfs2: find the xattr entry again after converting a block to " Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 251/507] ocfs2: do not index before the entry array when dividing an empty bucket Greg Kroah-Hartman
` (256 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joseph Qi, Andrew Morton,
Heming Zhao, Mark Fasheh, Joel Becker, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joseph Qi <joseph.qi@linux.alibaba.com>
[ Upstream commit e8de099f2958c84aa23186c5481e69f7ffd39355 ]
ocfs2_check_xattr_bucket_collision() decides whether splitting a bucket
can make room by comparing the hash being inserted against the first and
the last entry. xh_count comes off disk and is never checked, and a
bucket is allowed to hold no entries: ocfs2_xa_remove_entry() keeps the
last slot when it removes the only one, so that an empty bucket still
carries the hash it is keyed by. xh_count then reads back as 0 while
xh_entries[0] is still meaningful, and the second comparison indexes
xh_entries[-1].
That is outside the __counted_by_le(xh_count) bounds of xh_entries[] and
lands on the header. An entry is 16 bytes and xe_name_hash is its first
field, so the value read is xh_count | xh_free_start << 16. It stays
inside the block, but the answer is arbitrary, and for an empty bucket
it says there is no collision, so a new bucket gets added on the
strength of it.
An empty bucket holds no entries to collide with. Return before reading
the array.
One way to reach the test with an empty bucket is a set that removes the
bucket's only entry during cleanup and then fails for space again, since
it is that second -ENOSPC which calls this. Growing a value past
OCFS2_XATTR_INLINE_SIZE is the easy route: the cluster allocation fails,
the "!orig_clusters" arm of ocfs2_xa_cleanup_value_truncate() removes
the entry, and although the "growing" caller does set ctxt->set_abort,
only ocfs2_xattr_block_set() and __ocfs2_xattr_set_handle() look at it,
so ocfs2_xattr_set_entry_index_block() goes straight on to the collision
check.
This sits on commit a9ea8b397864 ("ocfs2: use the stored hash when
checking xattr bucket collision"), which gave the collision check its two
argument form and is marked for 6.2 and later. The read fixed here is
present in the three argument version too, but a tree without that
commit needs the hunk adapted by hand.
Link: https://lore.kernel.org/20261024151012.1059683-5-joseph.qi@linux.alibaba.com
Fixes: 012255961c9e ("ocfs2: Enable xattr set in index btree")
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/xattr.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index dc0e2aea14a38..00f628e22d661 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -5882,11 +5882,20 @@ static int ocfs2_check_xattr_bucket_collision(struct ocfs2_xattr_bucket *bucket,
u32 name_hash)
{
struct ocfs2_xattr_header *xh = bucket_xh(bucket);
+ u16 count = le16_to_cpu(xh->xh_count);
+
+ /*
+ * An empty bucket keeps the hash of the entry that was removed in
+ * xh_entries[0] so that it can still be found, but it holds no
+ * entries to collide with.
+ */
+ if (!count)
+ return 0;
if (name_hash != le32_to_cpu(xh->xh_entries[0].xe_name_hash))
return 0;
- if (xh->xh_entries[le16_to_cpu(xh->xh_count) - 1].xe_name_hash ==
+ if (xh->xh_entries[count - 1].xe_name_hash ==
xh->xh_entries[0].xe_name_hash) {
mlog(ML_ERROR, "Too much hash collision in xattr bucket %llu, "
"hash = %u\n",
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 251/507] ocfs2: do not index before the entry array when dividing an empty bucket
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (249 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 250/507] ocfs2: do not read the entry array of an empty xattr bucket Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 252/507] ocfs2: do not read the entry array of an empty xattr block Greg Kroah-Hartman
` (255 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joseph Qi, Andrew Morton,
Heming Zhao, Mark Fasheh, Joel Becker, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joseph Qi <joseph.qi@linux.alibaba.com>
[ Upstream commit 7133a0d0954c109f1764ebf8ab32d7e757a6c587 ]
ocfs2_divide_xattr_bucket() appends an empty bucket carrying a sentinel
hash when the source bucket has no divide position, taking that hash
from xh_entries[start - 1]. ocfs2_xattr_find_divide_pos() returns count
when every entry shares one hash, and its loop does not run at all for
count < 2, so an empty bucket comes back with start == count == 0 and
the read is xh_entries[-1].
That is outside the __counted_by_le(xh_count) bounds of xh_entries[] and
lands on the header, so the value picked up is
xh_count | xh_free_start << 16. One above it is written into the new
bucket's xh_entries[0] and committed, which leaves a bucket whose first
hash does not follow the bucket before it. ocfs2_xattr_bucket_find()
binary searches on xh_entries[0], so the broken key hides the range the
sentinel was meant to cover: getxattr() answers -ENODATA for an
attribute that is stored, and an insert can go to the wrong bucket and
leave two copies of a name. The cross cluster divide hands the same
value back as a tree record's e_cpos, which then claims a hash range it
does not cover.
Read xh_entries[0] instead. The branch is only reached when every entry
shares one hash, so for a non-empty bucket it holds the same value, and
for an empty one it is the slot that carries the bucket key.
An empty bucket reaches the divide from
ocfs2_check_xattr_bucket_collision(), which reports no collision for
one, through ocfs2_add_new_xattr_bucket() and
ocfs2_extend_xattr_bucket(). It does not take a failed set to get
there: a divide that finds no position is itself what leaves an empty
sentinel bucket behind, and a later extend can pick it as the target.
Link: https://lore.kernel.org/20261024151012.1059683-6-joseph.qi@linux.alibaba.com
Fixes: 80bcaf3469b8 ("ocfs2/xattr: Proper hash collision handle in bucket division")
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/xattr.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 00f628e22d661..571c40f5dd447 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -5052,7 +5052,15 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,
start = ocfs2_xattr_find_divide_pos(xh);
if (start == count) {
- xe = &xh->xh_entries[start-1];
+ /*
+ * start == count means every entry shares one hash, so the
+ * first of them carries it too. An empty bucket has no
+ * entries[start - 1], but its entries[0] still carries the
+ * bucket key: either the hash ocfs2_xa_remove_entry()
+ * deliberately leaves behind, or the sentinel a previous
+ * divide wrote.
+ */
+ xe = &xh->xh_entries[0];
/*
* initialized a new empty bucket here.
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 252/507] ocfs2: do not read the entry array of an empty xattr block
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (250 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 251/507] ocfs2: do not index before the entry array when dividing an empty bucket Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 253/507] fat: hold truncate_lock in fat_write_failed() Greg Kroah-Hartman
` (254 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joseph Qi, Andrew Morton,
Heming Zhao, Mark Fasheh, Joel Becker, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joseph Qi <joseph.qi@linux.alibaba.com>
[ Upstream commit cd7c3563a98fe8c984463d83772e518cb7e68356 ]
ocfs2_cp_xattr_block_to_bucket() sizes the name and value area it has to
carry over from the block's last entry, so an empty block makes it read
xh_entries[-1]. That lands on the header, where xe_name_offset overlaps
xh_name_value_len, and block storage never maintains that field, so it
reads as 0 and the copy runs from the header to the end of the block.
The bucket that comes out has xh_count 0 but a name_value_len of
blocksize less the header, and a matching xh_free_start that claims
those bytes are in use -- nearly the whole bucket with the common 4K
block size -- while the last block of the bucket holds a copy of the old
block's bytes. Nothing but a trace event reads xh_name_value_len, the
copied bytes came from the same inode and were wiped before the entry
was removed, and ocfs2_defrag_xattr_bucket() recomputes xh_free_start,
so this corrupts the header rather than leaking anything.
Leave the bucket empty instead, carrying over the hash the block was
keyed by, since ocfs2_add_new_xattr_bucket() and
ocfs2_xattr_bucket_find() both read xh_entries[0] of an empty bucket.
That read is the exception ocfs2_xa_remove_entry() documents rather than
a new out of bounds access.
A block reaches the conversion empty when truncating an external value
back fails partway through: the "reusing" and "overwriting" callers of
ocfs2_xa_cleanup_value_truncate() remove the entry without setting
ctxt->set_abort, so ocfs2_xattr_block_set() sees a plain -ENOSPC and
converts. The "growing" caller does set it, and the block form makes a
single attempt with no defragment and retry in between, so that is the
only route here.
Link: https://lore.kernel.org/20261024151012.1059683-7-joseph.qi@linux.alibaba.com
Fixes: 012255961c9e ("ocfs2: Enable xattr set in index btree")
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/xattr.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 571c40f5dd447..4d00a26ece3c1 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -4534,6 +4534,21 @@ static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode,
for (i = 0; i < blks; i++)
memset(bucket_block(bucket, i), 0, blocksize);
+ /*
+ * An empty block has no names or values to carry over, and the
+ * xh_entries[count - 1] below would be xh_entries[-1]. Leave the
+ * bucket empty, but carry over the hash ocfs2_xa_remove_entry() left
+ * in the block's xh_entries[0] so that the bucket still holds the key
+ * it is looked up by.
+ */
+ if (!count) {
+ xh->xh_num_buckets = cpu_to_le16(1);
+ xh->xh_free_start = cpu_to_le16(OCFS2_XATTR_BUCKET_SIZE);
+ xh->xh_entries[0].xe_name_hash =
+ xb_xh->xh_entries[0].xe_name_hash;
+ return;
+ }
+
/*
* Since the xe_name_offset is based on ocfs2_xattr_header,
* there is a offset change corresponding to the change of
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 253/507] fat: hold truncate_lock in fat_write_failed()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (251 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 252/507] ocfs2: do not read the entry array of an empty xattr block Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 254/507] ocfs2: validate move extents against a stable EOF Greg Kroah-Hartman
` (253 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matheus Alves de Almeida,
Andrew Morton, OGAWA Hirofumi, Pedro Falcato, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matheus Alves de Almeida <matheus.aalmeida@inf.ufrgs.br>
[ Upstream commit 7b90009546f5d3f3ac9428040cd7ffbdfd60f2eb ]
The current fat_write_failed() implementation calls into
fat_truncate_blocks() without holding truncate_lock.
A failed or short extending write racing with FIBMAP can spuriously make a
FAT filesystem read-only. FIBMAP bounds its lookup by i_blocks, so it can
walk allocated clusters beyond i_size while fat_write_failed() is removing
them. If the chain is shortened during the walk, the mapper can report a
bogus "request beyond EOF" error, triggering the default read-only error
policy. Hold truncate_lock for write around the block cleanup to
serialize it with _fat_bmap().
For comparison, fat_setattr() correctly holds truncate_lock during
truncation:
down_write(&MSDOS_I(inode)->truncate_lock);
truncate_setsize(inode, attr->ia_size);
fat_truncate_blocks(inode, attr->ia_size);
up_write(&MSDOS_I(inode)->truncate_lock);
Make it so ->truncate_lock is held exclusive while truncating.
Link: https://lore.kernel.org/20261021162105.62525-1-matheus.aalmeida@inf.ufrgs.br
Fixes: 16fab2015099 ("fat: permit to return phy block number by fibmap in fallocated region")
Fixes: 459f6ed3b8c7 ("fat: convert to use the new truncate convention.")
Signed-off-by: Matheus Alves de Almeida <matheus.aalmeida@inf.ufrgs.br>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Cc: Pedro Falcato <pfalcato@suse.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/fat/inode.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index f775a004cae1e..065658642e7fd 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -216,7 +216,9 @@ static void fat_write_failed(struct address_space *mapping, loff_t to)
if (to > inode->i_size) {
truncate_pagecache(inode, inode->i_size);
+ down_write(&MSDOS_I(inode)->truncate_lock);
fat_truncate_blocks(inode, inode->i_size);
+ up_write(&MSDOS_I(inode)->truncate_lock);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 254/507] ocfs2: validate move extents against a stable EOF
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (252 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 253/507] fat: hold truncate_lock in fat_write_failed() Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 255/507] ocfs2: keep locking_state within the cluster connection lifetime Greg Kroah-Hartman
` (252 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cen Zhang, Andrew Morton, Joseph Qi,
Mark Fasheh, Joel Becker, Heming Zhao, Jia-Ju Bai, jjzuming,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang <zzzccc427@gmail.com>
[ Upstream commit 84db6619cb702c37cf848b450c21b9c9706b0775 ]
The move-extents range must be bounded by the inode size used for extent
movement. ocfs2_ioctl_move_extents() checks and clamps the request before
taking the local inode and cluster locks in ocfs2_move_extents(). It also
uses separate i_size_read() calls for the range check and subtraction.
A concurrent truncate can invalidate the first check and make the later
unsigned subtraction underflow:
Move-extents ioctl Truncate
------------------ --------
check me_start <= i_size
take inode and cluster locks
shrink EOF below me_start
release locks
compare me_start + me_len with EOF
set me_len = EOF - me_start
[unsigned underflow]
acquire inode and cluster locks
select extents using the bad range
A truncate after clamping can also leave the range extending beyond EOF.
Conversely, the cached size may be smaller than the size refreshed when
the cluster inode lock is acquired. Early validation can then reject a
valid start or permanently shorten the requested length and threshold.
The me_start + me_len comparison can also wrap for a large input length.
Validate and adjust the original request once, after inode_lock(), the
exclusive rw lock and ocfs2_inode_lock() have stabilized and refreshed the
size. Read EOF once, reject a start beyond it, and bound the length by
EOF minus start. Normalize the threshold using the same EOF snapshot.
This keeps zero as the default-threshold sentinel until validation uses
the size that will govern extent movement.
Move goal validation after range adjustment as well. Its allocation-group
capacity check uses me_len and must see the EOF-clamped length. Both
validation failures use the existing inode-lock unwind path before any
extent movement or transaction starts.
Range errors now reach the ioctl's normal copyout path, as goal errors
already did. Unlike the old early rejection, a failed copyout can
therefore override -EINVAL with -EFAULT.
Link: https://lore.kernel.org/pm-ocfs2-move-extents-isize-rrw-v6-395bdee84ea81149068e@gmail.com
Fixes: 53069d4e7695 ("Ocfs2/move_extents: move/defrag extents within a certain range.")
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Suggested-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Assisted-by: LLM
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Jia-Ju Bai <baijiaju1990@gmail.com>
Cc: <jjzuming@gmail.com>
Cc: <stable@vger.kernel.org>
A truncate after clamping can also leave the range extending beyond EOF.
Conversely, the cached size may be smaller than the size refreshed when
the cluster inode lock is acquired. Early validation can then reject a
valid start or permanently shorten the requested length and threshold.
The me_start + me_len comparison can also wrap for a large input length.
Validate and adjust the original request once, after inode_lock(), the
exclusive rw lock and ocfs2_inode_lock() have stabilized and refreshed the
size. Read EOF once, reject a start beyond it, and bound the length by
EOF minus start. Normalize the threshold using the same EOF snapshot.
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/move_extents.c | 70 +++++++++++++++++++++++------------------
1 file changed, 39 insertions(+), 31 deletions(-)
diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c
index ad1678ee7cc46..93b45531bf7d8 100644
--- a/fs/ocfs2/move_extents.c
+++ b/fs/ocfs2/move_extents.c
@@ -907,6 +907,30 @@ static int __ocfs2_move_extents_range(struct buffer_head *di_bh,
return ret;
}
+static int ocfs2_validate_and_adjust_move_range(struct inode *inode,
+ struct ocfs2_move_extents *range)
+{
+ u64 i_size = i_size_read(inode);
+
+ if (range->me_start > i_size)
+ return -EINVAL;
+
+ if (range->me_len > i_size - range->me_start)
+ range->me_len = i_size - range->me_start;
+
+ /*
+ * The default threshold for defragmentation is 1 MiB, which
+ * matches the maximum OCFS2 cluster size.
+ */
+ if (!range->me_threshold)
+ range->me_threshold = 1024 * 1024;
+
+ if (range->me_threshold > i_size)
+ range->me_threshold = i_size;
+
+ return 0;
+}
+
static int ocfs2_move_extents(struct ocfs2_move_extents_context *context)
{
int status;
@@ -936,6 +960,21 @@ static int ocfs2_move_extents(struct ocfs2_move_extents_context *context)
goto out_rw_unlock;
}
+ status = ocfs2_validate_and_adjust_move_range(inode, context->range);
+ if (status) {
+ mlog_errno(status);
+ goto out_inode_unlock;
+ }
+
+ /* The goal check depends on the adjusted range length. */
+ if (!context->auto_defrag) {
+ status = ocfs2_validate_and_adjust_move_goal(inode, context->range);
+ if (status) {
+ mlog_errno(status);
+ goto out_inode_unlock;
+ }
+ }
+
/*
* remember ip_xattr_sem also needs to be held if necessary
*/
@@ -1028,27 +1067,8 @@ int ocfs2_ioctl_move_extents(struct file *filp, void __user *argp)
goto out_free;
}
- if (range.me_start > i_size_read(inode)) {
- status = -EINVAL;
- goto out_free;
- }
-
- if (range.me_start + range.me_len > i_size_read(inode))
- range.me_len = i_size_read(inode) - range.me_start;
-
context->range = ⦥
- /*
- * ok, the default threshold for the defragmentation
- * is 1M, since our maximum clustersize was 1M also.
- * any thought?
- */
- if (!range.me_threshold)
- range.me_threshold = 1024 * 1024;
-
- if (range.me_threshold > i_size_read(inode))
- range.me_threshold = i_size_read(inode);
-
if (range.me_flags & ~(OCFS2_MOVE_EXT_FL_AUTO_DEFRAG |
OCFS2_MOVE_EXT_FL_PART_DEFRAG)) {
status = -EINVAL;
@@ -1060,23 +1080,11 @@ int ocfs2_ioctl_move_extents(struct file *filp, void __user *argp)
if (range.me_flags & OCFS2_MOVE_EXT_FL_PART_DEFRAG)
context->partial = 1;
- } else {
- /*
- * first best-effort attempt to validate and adjust the goal
- * (physical address in block), while it can't guarantee later
- * operation can succeed all the time since global_bitmap may
- * change a bit over time.
- */
-
- status = ocfs2_validate_and_adjust_move_goal(inode, &range);
- if (status)
- goto out_copy;
}
status = ocfs2_move_extents(context);
if (status)
mlog_errno(status);
-out_copy:
/*
* movement/defragmentation may end up being partially completed,
* that's the reason why we need to return userspace the finished
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 255/507] ocfs2: keep locking_state within the cluster connection lifetime
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (253 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 254/507] ocfs2: validate move extents against a stable EOF Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 256/507] panic: zero the dynamically allocated taint buffer Greg Kroah-Hartman
` (251 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cen Zhang, Andrew Morton, Joseph Qi,
Mark Fasheh, Joel Becker, Heming Zhao, Jia-Ju Bai, jjzuming,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang <zzzccc427@gmail.com>
[ Upstream commit 5bdef466851e39ba752634cbea68e5ea24ccfb24 ]
The locking_state reader calls ocfs2_dlm_lvb() through the selected
cluster stack. Its debug-object reference keeps the tracking list alive,
but does not keep that stack selected without a cluster connection.
DLM initialization publishes the file before establishing its connection,
and DLM shutdown drops the connection while the file still exists. Both
the mount error unwind in ocfs2_mount_volume() and ocfs2_dismount_volume()
remove the debugfs subtree only after ocfs2_dlm_shutdown() has returned.
Whenever the disconnect releases the last stack reference, which is the
case for a failed mount and for any unmount without a pending hangup, a
concurrent reader dereferences a NULL active_stack:
Mount error unwind Debugfs reader
------------------ --------------
ocfs2_mount_volume(): out_dlm
ocfs2_dlm_shutdown()
disconnect last cluster
clear active_stack
read locking_state
ocfs2_dlm_seq_show()
ocfs2_dlm_lvb()
dereference active_stack
fill_super(): out_debugfs
remove debugfs subtree
Publish the debug files only after the connection and the mount lock
resources are initialized, so a failed DLM initialization has no debug
reference to drop. Remove them again in the common DLM shutdown helper
before the connection is dropped: debugfs removal waits for readers that
are inside the file operations, and the parent directory is still present
at that point in every caller. This covers the mount error unwind, the
ocfs2_fill_super() failures after a successful mount that dismount with
mnt_err set, and unmounts whose disconnect releases the stack directly.
Only the relevant frames of the report are kept:
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
RIP: 0010:ocfs2_dlm_lvb+0x38/0xf0
Call Trace:
<TASK>
ocfs2_dlm_seq_show+0x36a/0xb70
seq_read_iter+0x480/0x1110
seq_read+0x362/0x5a0
full_proxy_read+0x11f/0x180
vfs_read+0x1a0/0xc20
ksys_read+0x111/0x200
</TASK>
Link: https://lore.kernel.org/pm-ocfs2-objects-candidate-0011-v7-61e3ef8b1ad44ac2e817@gmail.com
Fixes: 286eaa95c5c5 ("ocfs2: Break out stackglue into modules.")
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Assisted-by: LLM
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Jia-Ju Bai <baijiaju1990@gmail.com>
Cc: <jjzuming@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/dlmglue.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 1a83241b6d41f..a093c43336080 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -3335,6 +3335,14 @@ static void ocfs2_dlm_shutdown_debug(struct ocfs2_super *osb)
{
struct ocfs2_dlm_debug *dlm_debug = osb->osb_dlm_debug;
+ /*
+ * Drain the readers before the cluster stack goes away: the
+ * locking_state reader resolves ocfs2_dlm_lvb() through the
+ * stack. Every caller removes the parent directory later.
+ */
+ debugfs_lookup_and_remove("locking_state", osb->osb_debug_root);
+ debugfs_lookup_and_remove("locking_filter", osb->osb_debug_root);
+
if (dlm_debug)
ocfs2_put_dlm_debug(dlm_debug);
}
@@ -3349,8 +3357,6 @@ int ocfs2_dlm_init(struct ocfs2_super *osb)
goto local;
}
- ocfs2_dlm_init_debug(osb);
-
/* launch downconvert thread */
osb->dc_task = kthread_run(ocfs2_downconvert_thread, osb, "ocfs2dc-%s",
osb->uuid_str);
@@ -3390,9 +3396,10 @@ int ocfs2_dlm_init(struct ocfs2_super *osb)
ocfs2_orphan_scan_lock_res_init(&osb->osb_orphan_scan.os_lockres, osb);
osb->cconn = conn;
+ if (conn)
+ ocfs2_dlm_init_debug(osb);
bail:
if (status < 0) {
- ocfs2_dlm_shutdown_debug(osb);
if (osb->dc_task)
kthread_stop(osb->dc_task);
}
@@ -3422,10 +3429,11 @@ void ocfs2_dlm_shutdown(struct ocfs2_super *osb,
ocfs2_lock_res_free(&osb->osb_orphan_scan.os_lockres);
if (osb->cconn) {
+ /* The disconnect below may release the selected stack. */
+ ocfs2_dlm_shutdown_debug(osb);
+
ocfs2_cluster_disconnect(osb->cconn, hangup_pending);
osb->cconn = NULL;
-
- ocfs2_dlm_shutdown_debug(osb);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 256/507] panic: zero the dynamically allocated taint buffer
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (254 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 255/507] ocfs2: keep locking_state within the cluster connection lifetime Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 257/507] ocfs2/dlm: serialize migration MLE cleanup on failure Greg Kroah-Hartman
` (250 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nickolai Zeldovich, Andrew Morton,
Bradley Morgan, Petr Mladek, Rio, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nickolai Zeldovich <nickolai@csail.mit.edu>
[ Upstream commit 723982e7052e65c3b31e8e8c815ffaf2ecfeaa8f ]
A %s read of print_tainted()'s string can run past the end of the taint
buffer while another CPU rebuilds a longer string in it, reading slab
memory out of bounds into the kernel log (a KASAN slab-out-of-bounds
report at taint_buf + size). A warning or an unhandled-signal dump on
another CPU reaches print_tainted() through dump_stack_print_info().
alloc_taint_buf() sizes the buffer for the longest taint string and
allocates it with kmalloc(), so the bytes past that string are never
written and the object holds no permanent NUL terminator.
_print_tainted() rebuilds the string in place without locking and writes
the terminator last, so a reader that overtakes a writer extending the
string past the previous high-water mark finds no terminator inside the
object and walks off its end. print_tainted()'s kernel-doc promises the
string is "always NULL terminated", a guarantee the previous zero-filled
static buffer kept.
Allocate the buffer with kzalloc() so its trailing bytes stay NUL and
every reader stops inside the object.
Reproduced on QEMU riscv64 under KASAN by growing the taint set while
processes took unhandled-signal dumps on several CPUs: the unpatched
kernel reports a slab-out-of-bounds read at taint_buf + size, the patched
one is clean.
Link: https://lore.kernel.org/20261024020153.830459-1-nickolai@csail.mit.edu
Fixes: a9dff0d0d11c ("kernel/panic: allocate taint string buffer dynamically")
Signed-off-by: Nickolai Zeldovich <nickolai@csail.mit.edu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Bradley Morgan <brads@mainlining.org>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Cc: Rio <rioo.tsukatsukii@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/panic.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/panic.c b/kernel/panic.c
index cec2716019355..f08453f0d8b4d 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -893,7 +893,7 @@ static __init int alloc_taint_buf(void)
size += 1; /* For NULL terminator */
- buf = kmalloc(size, GFP_KERNEL);
+ buf = kzalloc(size, GFP_KERNEL);
if (!buf) {
panic("Failed to allocate taint string buffer");
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 257/507] ocfs2/dlm: serialize migration MLE cleanup on failure
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (255 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 256/507] panic: zero the dynamically allocated taint buffer Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 258/507] ocfs2: stop recovery before shutting down local allocators Greg Kroah-Hartman
` (249 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cen Zhang, Andrew Morton, Joseph Qi,
Mark Fasheh, Joel Becker, Heming Zhao, Jia-Ju Bai, jjzuming,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang <zzzccc427@gmail.com>
[ Upstream commit 61469249aab03799b0d3294b7a0cd25dd303017a ]
A migration MLE has a base reference for the mastering answer and an
in-use reference held by dlm_migrate_lockres(). The finishing assertion
consumes the base reference, but migration failure drops it again
without checking whether the assertion already consumed it.
The target queues its migration worker before it acknowledges the
ALL_DONE packet, so its finishing assertion can be handled while the
sender still waits for the status. If the connection fails before the
status arrives, dlm_send_one_lockres() returns an error for a migration
that the target has already completed:
Old-master sender Finishing assertion
----------------- -------------------
publish MLE; take in-use reference
send ALL_DONE; wait for status
take lookup reference
unlink MLE
put lookup and base references
send returns a connection error
put base reference again; free MLE
put in-use reference; access freed MLE
dlm_assert_master_handler() holds dlm->spinlock from the MLE lookup to
the final puts, and it takes dlm->master_lock around the unlink and the
puts. Decide under the same locks: if the MLE is already unhashed, the
assertion consumed the base reference, so drop only the sender's in-use
reference. Otherwise unlink it before consuming the base reference so a
later assertion no longer finds it.
An assertion that got there first has also made the target the owner
and cleared DLM_LOCK_RES_MIGRATING. Treating the attempt as failed at
that point would leave the lockres owned by the target while this node
still holds the other nodes' locks and refmap bits, so it could neither
be purged nor migrated again. Finish our side as a completed migration
does instead: drop those locks under res->spinlock if the target still
owns the lockres, and recalculate its usage.
Use the same cleanup for the pre-send failure, the send failure and the
target-death failure paths. The sender's in-use reference keeps the MLE
alive until its final put outside the nested locks. Successful
migration retains its existing in-use-only put.
A target that has died cannot assert after the sender has seen its
death. The o2net node-down callback runs before the DLM one; it
disconnects the node and flushes the workqueue that runs the message
handlers, so an assertion already received has been handled by the time
the DLM removes the node from the domain map. A node that leaves the
domain cleanly sends its exit message only after its assertions have
been answered.
Two windows of the hand-over itself are left as they are: the handler
switches the owner and the sender drops the other nodes' locks moments
later, and an assertion from a live target that arrives after the
sender has given up still meets the owner check in the handler. Waiting
for the target before giving up would only stretch the first window
into the time in which recovery of the target can observe it.
KASAN report, only the relevant frames are kept:
BUG: KASAN: slab-use-after-free in dlm_put_mle_inuse+0xce/0xe0
Read of size 8 at addr ffff8881190e3c20 by task umount/593
Call Trace:
<TASK>
dlm_put_mle_inuse+0xce/0xe0
dlm_migrate_lockres+0x16af/0x20d0
dlm_empty_lockres+0x60a/0xbd0
dlm_unregister_domain+0x53b/0x11d0
o2cb_cluster_disconnect+0xa5/0x110
ocfs2_cluster_disconnect+0x73/0xc0
ocfs2_dlm_shutdown+0x311/0x440
ocfs2_dismount_volume+0x696/0x940
generic_shutdown_super+0x15f/0x490
kill_block_super+0x40/0xa0
deactivate_locked_super+0xae/0x120
deactivate_super+0xa2/0xc0
cleanup_mnt+0x217/0x450
task_work_run+0x144/0x230
</TASK>
Allocated by task 593:
kmem_cache_alloc_noprof+0x20b/0x5c0
dlm_migrate_lockres+0x20e/0x20d0
dlm_empty_lockres+0x60a/0xbd0
dlm_unregister_domain+0x53b/0x11d0
o2cb_cluster_disconnect+0xa5/0x110
ocfs2_cluster_disconnect+0x73/0xc0
ocfs2_dlm_shutdown+0x311/0x440
ocfs2_dismount_volume+0x696/0x940
Freed by task 593:
kmem_cache_free+0x242/0x580
__dlm_put_mle+0x4b2/0x660
dlm_migrate_lockres+0x1690/0x20d0
dlm_empty_lockres+0x60a/0xbd0
dlm_unregister_domain+0x53b/0x11d0
o2cb_cluster_disconnect+0xa5/0x110
ocfs2_cluster_disconnect+0x73/0xc0
ocfs2_dlm_shutdown+0x311/0x440
The buggy address belongs to the object at ffff8881190e3c00
which belongs to the cache o2dlm_mle of size 480
The buggy address is located 32 bytes inside of
freed 480-byte region [ffff8881190e3c00, ffff8881190e3de0)
Link: https://lore.kernel.org/pm-ocfs2-objects-candidate-0038-v9-659f247ea980d5f3fbeb@gmail.com
Fixes: 6714d8e86bf4 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem")
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Assisted-by: LLM
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Jia-Ju Bai <baijiaju1990@gmail.com>
Cc: <jjzuming@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/dlm/dlmmaster.c | 70 ++++++++++++++++++++++++++++++++++------
1 file changed, 61 insertions(+), 9 deletions(-)
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 612969867ff92..ea48c013f7fbb 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -2525,6 +2525,52 @@ static int dlm_is_lockres_migratable(struct dlm_ctxt *dlm,
*/
+/*
+ * Drop the sender's references on a migration MLE after the attempt has
+ * failed. The finishing assert from the target may already have unlinked
+ * the MLE and consumed its base reference; decide under the locks the
+ * assert handler holds, and only drop the base reference while the MLE is
+ * still hashed. Returns true when the assert got there first: the target
+ * has become the master, so the caller must complete the migration.
+ */
+static bool dlm_put_migration_mle(struct dlm_ctxt *dlm,
+ struct dlm_master_list_entry *mle)
+{
+ bool asserted;
+
+ spin_lock(&dlm->spinlock);
+ spin_lock(&dlm->master_lock);
+ __dlm_mle_detach_hb_events(dlm, mle);
+ asserted = hlist_unhashed(&mle->master_hash_node);
+ if (!asserted) {
+ __dlm_unlink_mle(dlm, mle);
+ __dlm_put_mle(mle);
+ }
+ spin_unlock(&dlm->master_lock);
+ spin_unlock(&dlm->spinlock);
+
+ dlm_put_mle_inuse(mle);
+ return asserted;
+}
+
+/*
+ * The finishing assert got there first: it switched the owner to the
+ * target and cleared DLM_LOCK_RES_MIGRATING. Drop the other nodes' locks
+ * as a completed migration does, unless recovery has taken the lockres
+ * over since, and let the usage be recalculated.
+ */
+static void dlm_migrate_lockres_asserted(struct dlm_ctxt *dlm,
+ struct dlm_lock_resource *res,
+ u8 target)
+{
+ spin_lock(&res->spinlock);
+ if (res->owner == target)
+ dlm_remove_nonlocal_locks(dlm, res);
+ spin_unlock(&res->spinlock);
+
+ dlm_lockres_calc_usage(dlm, res);
+}
+
static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
struct dlm_lock_resource *res, u8 target)
{
@@ -2609,9 +2655,10 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
if (ret < 0) {
if (mle_added) {
- dlm_mle_detach_hb_events(dlm, mle);
- dlm_put_mle(mle);
- dlm_put_mle_inuse(mle);
+ if (dlm_put_migration_mle(dlm, mle)) {
+ dlm_migrate_lockres_asserted(dlm, res, target);
+ ret = 0;
+ }
} else if (mle) {
kmem_cache_free(dlm_mle_cache, mle);
mle = NULL;
@@ -2640,9 +2687,11 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
mlog(0, "migration to node %u failed with %d\n",
target, ret);
/* migration failed, detach and clean up mle */
- dlm_mle_detach_hb_events(dlm, mle);
- dlm_put_mle(mle);
- dlm_put_mle_inuse(mle);
+ if (dlm_put_migration_mle(dlm, mle)) {
+ dlm_migrate_lockres_asserted(dlm, res, target);
+ ret = 0;
+ goto leave;
+ }
spin_lock(&res->spinlock);
res->state &= ~DLM_LOCK_RES_MIGRATING;
wake = 1;
@@ -2686,9 +2735,12 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm,
res->lockname.name, target);
ret = -EINVAL;
/* migration failed, detach and clean up mle */
- dlm_mle_detach_hb_events(dlm, mle);
- dlm_put_mle(mle);
- dlm_put_mle_inuse(mle);
+ if (dlm_put_migration_mle(dlm, mle)) {
+ dlm_migrate_lockres_asserted(dlm, res,
+ target);
+ ret = 0;
+ goto leave;
+ }
spin_lock(&res->spinlock);
res->state &= ~DLM_LOCK_RES_MIGRATING;
wake = 1;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 258/507] ocfs2: stop recovery before shutting down local allocators
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (256 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 257/507] ocfs2/dlm: serialize migration MLE cleanup on failure Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 259/507] ocfs2/cluster: unlink socket containers before releasing resources Greg Kroah-Hartman
` (248 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cen Zhang, Andrew Morton, Joseph Qi,
Mark Fasheh, Joel Becker, Heming Zhao, Jia-Ju Bai, jjzuming,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang <zzzccc427@gmail.com>
[ Upstream commit 126429e2f503ade63502978beb0c519066442250 ]
Recovery completion needs the local allocators until it has finished
reclaiming a failed node's allocation window and truncate log. During
unmount, quota recovery is stopped first, but that leaves recovery_state
at OCFS2_REC_QUOTA_DISABLED. New non-quota recovery can still start.
ocfs2_truncate_log_shutdown() drains existing completion work and releases
osb_tl_bh before ocfs2_recovery_exit() closes that publication path:
Unmount Recovery
------- --------
stop quota recovery; disable quotas
truncate_log_shutdown()
flush existing completion work
recover another failed node
queue completion
flush local log; release buffer
complete_truncate_log_recovery()
use released osb_tl_bh
recovery_exit(): disable and drain
An extra buffer reference alone would still let completion append new
records after the final truncate-log flush.
Split stopping and draining recovery from freeing its state. Stop all
recovery producers and drain completion work before shutting down either
local allocator. Keep recovery-state release at its existing later point,
so its lifetime relative to other teardown users stays unchanged. The
second stop at recovery_exit() is harmless once recovery is disabled.
KASAN report as below:
BUG: KASAN: slab-use-after-free in ocfs2_truncate_log_needs_flush+0x23d/0x360
Read of size 8 at addr ffff8881093711e8 by task kworker/u16:3/53
CPU: 0 UID: 0 PID: 53 Comm: kworker/u16:3 Not tainted 7.3.0-rc4-next-20260921-pmb-ocfs2-functional-v1+ #1 PREEMPT(lazy)
Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Workqueue: ocfs2_wq ocfs2_complete_recovery
Call Trace:
<TASK>
dump_stack_lvl+0x93/0xd0
print_report+0xce/0x630
? ocfs2_truncate_log_needs_flush+0x23d/0x360
? srso_alias_return_thunk+0x5/0xfbef5
? __virt_addr_valid+0x20e/0x420
? ocfs2_truncate_log_needs_flush+0x23d/0x360
kasan_report+0xe0/0x110
? ocfs2_truncate_log_needs_flush+0x23d/0x360
ocfs2_truncate_log_needs_flush+0x23d/0x360
? __pfx_ocfs2_truncate_log_needs_flush+0x10/0x10
? __pfx_down_write+0x10/0x10
ocfs2_complete_truncate_log_recovery+0x315/0x780
? trace_hardirqs_on+0x18/0x160
? __pfx_ocfs2_complete_truncate_log_recovery+0x10/0x10
? ocfs2_complete_recovery+0x666/0x11b0
? srso_alias_return_thunk+0x5/0xfbef5
? kfree+0x308/0x580
ocfs2_complete_recovery+0x676/0x11b0
? __pfx_ocfs2_complete_recovery+0x10/0x10
? reacquire_held_locks+0xdd/0x200
? process_one_work+0x7c8/0x1b40
? srso_alias_return_thunk+0x5/0xfbef5
? lock_acquire+0x190/0x300
? __pfx_autoremove_wake_function+0x10/0x10
? process_one_work+0x834/0x1b40
? srso_alias_return_thunk+0x5/0xfbef5
? lock_release+0xc8/0x290
? srso_alias_return_thunk+0x5/0xfbef5
process_one_work+0x9a8/0x1b40
? __pfx_process_one_work+0x10/0x10
? lock_acquire+0x190/0x300
? lock_is_held_type+0x8f/0x100
? srso_alias_return_thunk+0x5/0xfbef5
worker_thread+0x65c/0xe40
? srso_alias_return_thunk+0x5/0xfbef5
? __kthread_parkme+0x177/0x220
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_worker_thread+0x10/0x10
kthread+0x351/0x460
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx_kthread+0x10/0x10
ret_from_fork+0x659/0x940
? __pfx_ret_from_fork+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? __switch_to+0x74f/0xf70
? __pfx_kthread+0x10/0x10
ret_from_fork_asm+0x1a/0x30
</TASK>
Allocated by task 538:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_slab_alloc+0x89/0x90
kmem_cache_alloc_noprof+0x20b/0x5c0
alloc_buffer_head+0x26/0x120
folio_alloc_buffers+0x122/0x1d0
bdev_getblk+0x299/0x4f0
ocfs2_read_blocks_sync+0x513/0xbc0
ocfs2_iget+0x9cd/0x1a00
ocfs2_get_system_file_inode+0x25e/0x7a0
ocfs2_fill_super+0x1b05/0x3930
get_tree_bdev_flags+0x35d/0x5f0
vfs_get_tree+0x93/0x320
fc_mount+0x1d/0x200
path_mount+0x592/0x1e00
__x64_sys_mount+0x24b/0x2d0
do_syscall_64+0x114/0x620
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 553:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x5f/0x80
kmem_cache_free+0x242/0x580
free_buffer_head+0x4b/0xc0
try_to_free_buffers+0x1dc/0x330
ocfs2_truncate_log_shutdown+0x789/0x1290
ocfs2_dismount_volume+0x1da/0x940
generic_shutdown_super+0x15f/0x490
kill_block_super+0x40/0xa0
deactivate_locked_super+0xae/0x120
deactivate_super+0xa2/0xc0
cleanup_mnt+0x217/0x450
task_work_run+0x144/0x230
exit_to_user_mode_loop+0x17d/0x570
do_syscall_64+0x4d1/0x620
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The buggy address belongs to the object at ffff8881093711c0
which belongs to the cache buffer_head of size 160
The buggy address is located 40 bytes inside of
freed 160-byte region [ffff8881093711c0, ffff888109371260)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x109371
flags: 0x200000000000000(node=0|zone=2)
page_type: f5(slab)
raw: 0200000000000000 ffff8881008883c0 dead000000000100 dead000000000122
raw: 0000000000000000 0000000000120012 00000000f5000000 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff888109371080: 00 00 00 00 fc fc fc fc fc fc fc fc 00 00 00 00
ffff888109371100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff888109371180: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
^
ffff888109371200: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
ffff888109371280: fc fc fc fc 00 00 00 00 00 00 00 00 00 00 00 00
==================================================================
Link: https://lore.kernel.org/pm-ocfs2-objects-candidate-0019-v8-574dd69fd3f47f56348b@gmail.com
Fixes: ccd979bdbce9 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem")
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Suggested-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Assisted-by: LLM
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Jia-Ju Bai <baijiaju1990@gmail.com>
Cc: <jjzuming@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/journal.c | 15 ++++++++++++---
fs/ocfs2/journal.h | 1 +
fs/ocfs2/super.c | 3 +++
3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index a3938a03e93bf..674e70dfbb5cb 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -227,13 +227,22 @@ void ocfs2_recovery_disable_quota(struct ocfs2_super *osb)
ocfs2_recovery_disable(osb, OCFS2_REC_QUOTA_WANT_DISABLE);
}
+/* Stop producers and drain completion work without freeing recovery state. */
+void ocfs2_recovery_stop(struct ocfs2_super *osb)
+{
+ ocfs2_recovery_disable(osb, OCFS2_REC_WANT_DISABLE);
+}
+
void ocfs2_recovery_exit(struct ocfs2_super *osb)
{
struct ocfs2_recovery_map *rm;
- /* disable any new recovery threads and wait for any currently
- * running ones to exit. Do this before setting the vol_state. */
- ocfs2_recovery_disable(osb, OCFS2_REC_WANT_DISABLE);
+ /*
+ * Disable producers and drain work before freeing recovery state.
+ * Do this before setting vol_state to VOLUME_DISMOUNTED: completion
+ * work may still be waiting in __ocfs2_wait_on_mount().
+ */
+ ocfs2_recovery_stop(osb);
/*
* Now that recovery is shut down, and the osb is about to be
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
index 19fc920d26b1c..4b52bf7b0938e 100644
--- a/fs/ocfs2/journal.h
+++ b/fs/ocfs2/journal.h
@@ -147,6 +147,7 @@ void ocfs2_complete_recovery(struct work_struct *work);
void ocfs2_wait_for_recovery(struct ocfs2_super *osb);
int ocfs2_recovery_init(struct ocfs2_super *osb);
+void ocfs2_recovery_stop(struct ocfs2_super *osb);
void ocfs2_recovery_exit(struct ocfs2_super *osb);
void ocfs2_recovery_disable_quota(struct ocfs2_super *osb);
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 169c576f06bf5..e5482c556552e 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1828,6 +1828,9 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
/* Wait for worker to be done with the work structure in osb */
cancel_work_sync(&osb->dquot_drop_work);
+ /* Stop recovery producers before releasing their local allocators. */
+ ocfs2_recovery_stop(osb);
+
ocfs2_shutdown_local_alloc(osb);
ocfs2_truncate_log_shutdown(osb);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 259/507] ocfs2/cluster: unlink socket containers before releasing resources
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (257 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 258/507] ocfs2: stop recovery before shutting down local allocators Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 260/507] ocfs2: wait for filecheck kobject release after a failed add Greg Kroah-Hartman
` (247 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cen Zhang, Andrew Morton, Joseph Qi,
Mark Fasheh, Joel Becker, Heming Zhao, Kees Cook, Jakub Kicinski,
Sunil Mushran, Jia-Ju Bai, jjzuming, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang <zzzccc427@gmail.com>
[ Upstream commit 0988f0c0c7c908f0ff77fd8b90ce9918a1f41479 ]
A socket container's node and socket must remain alive while the
container is on sock_containers. The debugfs formatter reads sc_node
and sc_sock under o2net_debug_lock without taking their references, but
sc_kref_release() releases both before taking that lock to unlink the
container.
With CONFIG_DEBUG_FS enabled, a synchronous sender can retain its last
socket-container reference after o2net_disconnect_node() has detached
the connection and flushed o2net_wq. The caller runs outside that
workqueue. After the sender removes its configfs dependency, node
removal can proceed without waiting for the sender's final sc_put():
Sender (final sc_put) Configfs rmdir Debugfs reader
-------------------- -------------- --------------
o2nm_undepend_item()
Drop node item refs
o2nm_node_put()
[node can be freed]
sc_seq_show()
Lock debug lock
Read sc_node->nd_name
Unlock debug lock
sc_node = NULL
o2net_debug_del_sc()
The earlier socket release has a similar window. The container is
still selectable while its socket has been released and sc_sock has
not yet been cleared:
Sender (final sc_put) Debugfs reader
-------------------- --------------
sock_release(sc->sc_sock)
[socket can be freed]
sc_seq_show()
Lock debug lock
Read sc_sock->sk fields
Unlock debug lock
sc_sock = NULL
...
o2net_debug_del_sc()
Move o2net_debug_del_sc() before releasing either resource. Unlinking
under the existing debug lock waits for an active formatter to finish
and prevents later readers from selecting the container. This covers
both socket fields and node fields, including nd_num in the stats
formatter.
KASAN report as below:
BUG: KASAN: slab-use-after-free in string+0x42b/0x470
Read of size 1 at addr ffff88810f56fc90 by task python3/506
CPU: 0 UID: 0 PID: 506 Comm: python3 Not tainted 7.3.0-rc4-next-20260921-pmb-ocfs2-functional-v1+ #1 PREEMPT(lazy)
Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl+0x93/0xd0
print_report+0xce/0x630
kasan_report+0xe0/0x110
string+0x42b/0x470
vsnprintf+0x330/0x1110
seq_printf+0x1a8/0x260
sc_seq_show+0x604/0x9f0
seq_read_iter+0x480/0x1110
seq_read+0x362/0x5a0
full_proxy_read+0x11f/0x180
vfs_read+0x1a0/0xc20
ksys_read+0x111/0x200
do_syscall_64+0x114/0x620
entry_SYSCALL_64_after_hwframe+0x77/0x7f
(User register dump omitted.)
</TASK>
Allocated by task 497:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_kmalloc+0xaa/0xb0
__kmalloc_cache_noprof+0x28d/0x610
o2nm_node_group_make_item+0xea/0x1a0
configfs_mkdir+0x762/0xca0
vfs_mkdir+0x399/0x7e0
filename_mkdirat+0x129/0x450
__x64_sys_mkdir+0x70/0xa0
do_syscall_64+0x114/0x620
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 505:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x5f/0x80
kfree+0x308/0x580
config_item_cleanup+0x14b/0x230
config_item_put+0x79/0x90
sc_put+0x454/0x6e0
o2net_send_message_vec+0x63d/0x1560
o2net_send_message+0xa6/0xe0
validation_send_write+0x17f/0x1d0
full_proxy_write+0x11f/0x180
vfs_write+0x25a/0x1010
ksys_write+0x111/0x200
do_syscall_64+0x114/0x620
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The buggy address belongs to the object at ffff88810f56fc00
which belongs to the cache kmalloc-512 of size 512
The buggy address is located 144 bytes inside of
freed 512-byte region [ffff88810f56fc00, ffff88810f56fe00)
(Page and shadow-memory dumps omitted.)
Link: https://lore.kernel.org/pm-ocfs2-objects-candidate-0065-v6-3090153fd7cacb810214@gmail.com
Fixes: 2309e9e040fe ("ocfs2/net: Add debug interface to o2net")
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Kees Cook <kees@kernel.org>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Sunil Mushran <sunil.mushran@oracle.com>
Cc: Jia-Ju Bai <baijiaju1990@gmail.com>
Cc: <jjzuming@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/cluster/tcp.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index 474fe1414cee8..0ba26bd2eba11 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -391,6 +391,9 @@ static void sc_kref_release(struct kref *kref)
sclog(sc, "releasing\n");
+ /* Unlink before freeing anything the debugfs readers dereference. */
+ o2net_debug_del_sc(sc);
+
if (sc->sc_sock) {
sock_release(sc->sc_sock);
sc->sc_sock = NULL;
@@ -400,8 +403,6 @@ static void sc_kref_release(struct kref *kref)
o2nm_node_put(sc->sc_node);
sc->sc_node = NULL;
- o2net_debug_del_sc(sc);
-
if (sc->sc_page)
__free_page(sc->sc_page);
kfree(sc);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 260/507] ocfs2: wait for filecheck kobject release after a failed add
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (258 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 259/507] ocfs2/cluster: unlink socket containers before releasing resources Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 261/507] ocfs2: cache the mount context for dentry lock callbacks Greg Kroah-Hartman
` (246 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cen Zhang, Andrew Morton, Joseph Qi,
Mark Fasheh, Joel Becker, Heming Zhao, Jia-Ju Bai, jjzuming,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang <zzzccc427@gmail.com>
[ Upstream commit a25c02af29c3e95128e4343fceb4bdace8e480a0 ]
The filecheck kobject and its release completion are embedded in
ocfs2_super, so the osb must outlive the kobject. On a failed
kobject_init_and_add(), creation clears fs_fcheck and calls
kobject_put(), but returns without waiting for the release callback.
With CONFIG_DEBUG_KOBJECT_RELEASE, the last put queues delayed cleanup.
Mount failure can then free the containing osb before the embedded
release timer expires:
Mount failure Delayed cleanup
------------- ---------------
ocfs2_filecheck_create_sysfs()
kobject_init_and_add() fails
fs_fcheck = NULL
kobject_put()
queue delayed release
return to mount error cleanup
ocfs2_dismount_volume()
remove_sysfs() skips the wait
kfree(osb)
expire embedded release timer
access freed osb
The normal removal path waits for fs_kobj_unregister, but it returns
early when fs_fcheck is NULL. The failed-add path therefore leaves the
delayed work and its completion in freed storage.
Wait for the existing release completion after the failed-add
kobject_put(), before returning to mount error cleanup. This keeps the
enclosing osb alive until the kobject has finished releasing, matching
the normal teardown path.
KASAN report as below:
BUG: KASAN: slab-use-after-free in __run_timers+0xa6d/0xa90
Write of size 8 at addr ffff8881178a5658 by task swapper/0/0
CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 7.3.0-rc4-next-20260921-pmb-ocfs2-functional-v1+ #1 PREEMPT(lazy)
Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
<IRQ>
dump_stack_lvl+0x93/0xd0
print_report+0xce/0x630
? __run_timers+0xa6d/0xa90
? srso_alias_return_thunk+0x5/0xfbef5
? __virt_addr_valid+0x20e/0x420
? __run_timers+0xa6d/0xa90
kasan_report+0xe0/0x110
? __run_timers+0xa6d/0xa90
__run_timers+0xa6d/0xa90
? srso_alias_return_thunk+0x5/0xfbef5
? __pfx___run_timers+0x10/0x10
? __lock_acquire+0x5a3/0x2140
? __pfx_do_raw_spin_lock+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
timer_expire_remote+0xfa/0x160
? __pfx_timer_expire_remote+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? srso_alias_return_thunk+0x5/0xfbef5
? trace_hardirqs_on+0x18/0x160
tmigr_handle_remote_up+0x4ba/0x9d0
? __pfx_tmigr_handle_remote_up+0x10/0x10
? tmigr_handle_remote+0x21a/0x340
? srso_alias_return_thunk+0x5/0xfbef5
? lock_release+0xc8/0x290
? __pfx_tmigr_handle_remote_up+0x10/0x10
__walk_groups_from+0x5a/0x160
tmigr_handle_remote+0x24f/0x340
? __pfx_tmigr_handle_remote+0x10/0x10
? lock_acquire+0x190/0x300
? srso_alias_return_thunk+0x5/0xfbef5
? lock_release+0xc8/0x290
run_timer_softirq+0x222/0x270
? __pfx_run_timer_softirq+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? srso_alias_return_thunk+0x5/0xfbef5
? lockdep_hardirqs_on_prepare+0xb8/0x1a0
? srso_alias_return_thunk+0x5/0xfbef5
handle_softirqs+0x1fa/0x8d0
? __pfx_handle_softirqs+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? _raw_spin_unlock+0x23/0x40
? srso_alias_return_thunk+0x5/0xfbef5
? __hrtimer_rearm_deferred+0x1fb/0x5d0
__irq_exit_rcu+0x113/0x1e0
irq_exit_rcu+0xe/0x20
sysvec_apic_timer_interrupt+0x6c/0x80
</IRQ>
<TASK>
asm_sysvec_apic_timer_interrupt+0x1a/0x20
RIP: 0010:pv_native_safe_halt+0xf/0x20
Code: fa 18 01 e9 ee 37 ff fa 0f 1f 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa eb 07 0f 00 2d 23 c7 14 00 fb f4 <e9> c7 37 ff fa 66 2e 0f 1f 84 00 00 00 00 00 66 90 90 90 90 90 90
RSP: 0018:ffffffff87c07cf8 EFLAGS: 00000206
RAX: 0000000000045d0f RBX: ffffffff87c2d4c0 RCX: ffffffff86111e95
RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff815b508e
RBP: fffffbfff0f85a98 R08: 0000000000000001 R09: ffffed10310c68ba
R10: ffff8881886345d3 R11: 0000000000000000 R12: 0000000000000001
R13: 0000000000000000 R14: 1ffffffff0f80fa4 R15: dffffc0000000000
? ct_kernel_exit.constprop.0+0xc5/0xf0
? do_idle+0x3ae/0x650
default_idle+0x9/0x10
default_idle_call+0x6c/0xb0
do_idle+0x3ae/0x650
? __pfx___schedule+0x10/0x10
? __pfx_do_idle+0x10/0x10
? rest_init+0x1cd/0x330
? srso_alias_return_thunk+0x5/0xfbef5
cpu_startup_entry+0x54/0x60
rest_init+0x1e1/0x330
? __pfx_acpi_read_bit_register+0x10/0x10
? __pfx_rest_init+0x10/0x10
? acpi_os_write_port+0x23/0xb0
? __pfx_kernel_init+0x10/0x10
? srso_alias_return_thunk+0x5/0xfbef5
? acpi_ut_status_exit+0xd6/0x180
? srso_alias_return_thunk+0x5/0xfbef5
? acpi_ut_status_exit+0xd6/0x180
? srso_alias_return_thunk+0x5/0xfbef5
? acpi_enable_subsystem+0x2b0/0x4e0
? __pfx_x86_late_time_init+0x10/0x10
start_kernel+0x417/0x4b0
x86_64_start_reservations+0x18/0x30
x86_64_start_kernel+0x111/0x120
common_startup_64+0x13e/0x158
</TASK>
Allocated by task 494:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_kmalloc+0xaa/0xb0
__kmalloc_cache_noprof+0x28d/0x610
ocfs2_initialize_super.isra.0+0xab/0x3070
ocfs2_fill_super+0x801/0x3920
get_tree_bdev_flags+0x35d/0x5f0
vfs_get_tree+0x93/0x320
fc_mount+0x1d/0x200
path_mount+0x592/0x1e00
__x64_sys_mount+0x24b/0x2d0
do_syscall_64+0x114/0x620
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 494:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
kasan_save_free_info+0x3b/0x60
__kasan_slab_free+0x5f/0x80
kfree+0x308/0x580
ocfs2_dismount_volume+0x43c/0x9b0
ocfs2_fill_super+0x258f/0x3920
get_tree_bdev_flags+0x35d/0x5f0
vfs_get_tree+0x93/0x320
fc_mount+0x1d/0x200
path_mount+0x592/0x1e00
__x64_sys_mount+0x24b/0x2d0
do_syscall_64+0x114/0x620
entry_SYSCALL_64_after_hwframe+0x77/0x7f
The buggy address belongs to the object at ffff8881178a4000
which belongs to the cache kmalloc-8k of size 8192
The buggy address is located 5720 bytes inside of
freed 8192-byte region [ffff8881178a4000, ffff8881178a6000)
The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x1178a0
head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0
flags: 0x200000000000040(head|node=0|zone=2)
page_type: f5(slab)
raw: 0200000000000040 ffff888100043880 dead000000000122 0000000000000000
raw: 0000000000000000 0000000000020002 00000000f5000000 0000000000000000
head: 0200000000000040 ffff888100043880 dead000000000122 0000000000000000
head: 0000000000000000 0000000000020002 00000000f5000000 0000000000000000
head: 0200000000000003 fffffffffffffe01 00000000ffffffff 00000000ffffffff
head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8881178a5500: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8881178a5580: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff8881178a5600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff8881178a5680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8881178a5700: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
Link: https://lore.kernel.org/pm-ocfs2-objects-candidate-0087-v6-78f3c3d6d70887d6e0cc@gmail.com
Fixes: b9fba67b3806 ("ocfs2: fix error path kobject memory leak")
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Assisted-by: LLM
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Jia-Ju Bai <baijiaju1990@gmail.com>
Cc: <jjzuming@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/filecheck.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/ocfs2/filecheck.c b/fs/ocfs2/filecheck.c
index 75334e4bd0823..e3b79bc749f56 100644
--- a/fs/ocfs2/filecheck.c
+++ b/fs/ocfs2/filecheck.c
@@ -189,6 +189,8 @@ int ocfs2_filecheck_create_sysfs(struct ocfs2_super *osb)
/* Mount failure still calls ocfs2_filecheck_remove_sysfs(). */
entry->fs_fcheck = NULL;
kobject_put(&entry->fs_kobj);
+ /* Keep ocfs2_super alive until the kobject is released. */
+ wait_for_completion(&entry->fs_kobj_unregister);
kfree(fcheck);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 261/507] ocfs2: cache the mount context for dentry lock callbacks
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (259 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 260/507] ocfs2: wait for filecheck kobject release after a failed add Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 262/507] x86/init: Initialize wall clock in get_rtc_noop() Greg Kroah-Hartman
` (245 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cen Zhang, Andrew Morton, Joseph Qi,
Mark Fasheh, Joel Becker, Heming Zhao, Jia-Ju Bai, jjzuming,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang <zzzccc427@gmail.com>
[ Upstream commit 5b4696e0bfc358619adaeab25ad35b4979af8331 ]
ocfs2_drop_dentry_lock() drops the inode reference before releasing the
DENTRY lock. This lets inode eviction release the local inode and open
locks before a remote unlink can proceed past the DENTRY lock.
A DLM callback can still arrive before the DENTRY lock has been dropped.
ocfs2_get_dentry_osb() obtains the mount context through dl_inode->i_sb,
which can access a freed inode when the downconvert thread drops the
last inode reference in its post-unlock callback:
Downconvert thread DLM callback thread
------------------ -------------------
ocfs2_process_blocked_lock()
ocfs2_dentry_post_unlock()
ocfs2_dentry_lock_put()
ocfs2_drop_dentry_lock()
iput(dl->dl_inode)
[inode reclaimed after RCU]
ocfs2_blocking_ast()
ocfs2_get_dentry_osb()
dl->dl_inode->i_sb
ocfs2_simple_drop_lockres()
Store the mount context in the DENTRY lock resource's l_priv field and use
the default mount-context lookup. Recover the containing dentry lock with
container_of(), as already done for refcount locks, and remove
ocfs2_get_dentry_osb(). ocfs2_dismount_volume() shuts down the DLM before
freeing the mount context, so callbacks can use it without accessing the
inode. Preserve the existing iput-before-unlock order to avoid delaying
local inode and open lock release until after the DENTRY lock is released.
Link: https://lore.kernel.org/pm-ocfs2-objects-candidate-0012-v9-eeb9084fb29577971229@gmail.com
Fixes: 8ed6b23709b3 ("ocfs2: revert iput deferring code in ocfs2_drop_dentry_lock")
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Suggested-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Assisted-by: LLM
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: Jia-Ju Bai <baijiaju1990@gmail.com>
Cc: <jjzuming@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/dcache.h | 5 ++---
fs/ocfs2/dlmglue.c | 16 ++++------------
2 files changed, 6 insertions(+), 15 deletions(-)
diff --git a/fs/ocfs2/dcache.h b/fs/ocfs2/dcache.h
index 7f246c5692d82..046ab9a807692 100644
--- a/fs/ocfs2/dcache.h
+++ b/fs/ocfs2/dcache.h
@@ -17,9 +17,8 @@ struct ocfs2_dentry_lock {
u64 dl_parent_blkno;
/*
- * The ocfs2_dentry_lock keeps an inode reference until
- * dl_lockres has been destroyed. This is usually done in
- * ->d_iput() anyway, so there should be minimal impact.
+ * The inode reference is dropped before dl_lockres is unlocked.
+ * Callbacks must not use it to find the mount context during teardown.
*/
struct inode *dl_inode;
struct ocfs2_lock_res dl_lockres;
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index a093c43336080..a2a33c34fdf98 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -57,7 +57,6 @@ struct ocfs2_mask_waiter {
#endif
};
-static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres);
static struct ocfs2_super *ocfs2_get_inode_osb(struct ocfs2_lock_res *lockres);
static struct ocfs2_super *ocfs2_get_file_osb(struct ocfs2_lock_res *lockres);
static struct ocfs2_super *ocfs2_get_qinfo_osb(struct ocfs2_lock_res *lockres);
@@ -257,7 +256,6 @@ static const struct ocfs2_lock_res_ops ocfs2_orphan_scan_lops = {
};
static const struct ocfs2_lock_res_ops ocfs2_dentry_lops = {
- .get_osb = ocfs2_get_dentry_osb,
.post_unlock = ocfs2_dentry_post_unlock,
.downconvert_worker = ocfs2_dentry_convert_worker,
.flags = 0,
@@ -308,7 +306,7 @@ static inline struct ocfs2_dentry_lock *ocfs2_lock_res_dl(struct ocfs2_lock_res
{
BUG_ON(lockres->l_type != OCFS2_LOCK_TYPE_DENTRY);
- return (struct ocfs2_dentry_lock *)lockres->l_priv;
+ return container_of(lockres, struct ocfs2_dentry_lock, dl_lockres);
}
static inline struct ocfs2_mem_dqinfo *ocfs2_lock_res_qinfo(struct ocfs2_lock_res *lockres)
@@ -609,13 +607,6 @@ static __u64 ocfs2_get_dentry_lock_ino(struct ocfs2_lock_res *lockres)
return be64_to_cpu(inode_blkno_be);
}
-static struct ocfs2_super *ocfs2_get_dentry_osb(struct ocfs2_lock_res *lockres)
-{
- struct ocfs2_dentry_lock *dl = lockres->l_priv;
-
- return OCFS2_SB(dl->dl_inode->i_sb);
-}
-
void ocfs2_dentry_lock_res_init(struct ocfs2_dentry_lock *dl,
u64 parent, struct inode *inode)
{
@@ -623,6 +614,7 @@ void ocfs2_dentry_lock_res_init(struct ocfs2_dentry_lock *dl,
u64 inode_blkno = OCFS2_I(inode)->ip_blkno;
__be64 inode_blkno_be = cpu_to_be64(inode_blkno);
struct ocfs2_lock_res *lockres = &dl->dl_lockres;
+ struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
ocfs2_lock_res_init_once(lockres);
@@ -651,9 +643,9 @@ void ocfs2_dentry_lock_res_init(struct ocfs2_dentry_lock *dl,
memcpy(&lockres->l_name[OCFS2_DENTRY_LOCK_INO_START], &inode_blkno_be,
sizeof(__be64));
- ocfs2_lock_res_init_common(OCFS2_SB(inode->i_sb), lockres,
+ ocfs2_lock_res_init_common(osb, lockres,
OCFS2_LOCK_TYPE_DENTRY, &ocfs2_dentry_lops,
- dl);
+ osb);
}
static void ocfs2_super_lock_res_init(struct ocfs2_lock_res *res,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 262/507] x86/init: Initialize wall clock in get_rtc_noop()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (260 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 261/507] ocfs2: cache the mount context for dentry lock callbacks Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 263/507] xfs: fix temporary cursor leak in btree shift corruption paths Greg Kroah-Hartman
` (244 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Naman Jain, Borislav Petkov (AMD),
Thomas Gleixner, Roman Kisel, Hardik Garg, Dexuan Cui,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naman Jain <namjain@linux.microsoft.com>
[ Upstream commit 7d5af1f256fdecff6a7986bbc9146b69cb355bb5 ]
get_rtc_noop() is used when an RTC is unavailable, but leaves its output
argument untouched. When CONFIG_INIT_STACK_ALL_ZERO is not enabled,
timekeeping_init() may therefore receive a nonzero invalid persistent
clock value and warn:
"Persistent clock returned invalid value"
Initialize the output to zero, the documented representation of an
unsupported persistent clock.
Fixes: c311ed6183f4 ("x86/init: Allow DT configured systems to disable RTC at boot time")
Signed-off-by: Naman Jain <namjain@linux.microsoft.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Roman Kisel <vdso@mailbox.org>
Reviewed-by: Hardik Garg <hargar@linux.microsoft.com>
Reviewed-by: Dexuan Cui <decui@microsoft.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260831082528.1623843-1-namjain@linux.microsoft.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kernel/x86_init.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 252c5827d0634..3b9b41820c84c 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -37,7 +37,7 @@ static void iommu_shutdown_noop(void) { }
bool __init bool_x86_init_noop(void) { return false; }
void x86_op_int_noop(int cpu) { }
int set_rtc_noop(const struct timespec64 *now) { return -EINVAL; }
-void get_rtc_noop(struct timespec64 *now) { }
+void get_rtc_noop(struct timespec64 *now) { *now = (struct timespec64){0}; }
static __initconst const struct of_device_id of_cmos_match[] = {
{ .compatible = "motorola,mc146818" },
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 263/507] xfs: fix temporary cursor leak in btree shift corruption paths
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (261 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 262/507] x86/init: Initialize wall clock in get_rtc_noop() Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 264/507] net/sched: sch_qfq: prevent aggregate self-replacement Greg Kroah-Hartman
` (243 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jianyun Gao, Carlos Maiolino,
Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianyun Gao <jianyungao89@gmail.com>
[ Upstream commit 2bbca049deeb1699cafd966cb2793fee576ee409 ]
In xfs_btree_lshift and xfs_btree_rshift, when XFS_IS_CORRUPT detects
an invalid firstrec/lastrec result after xfs_btree_dup_cursor has
successfully allocated a temporary cursor, the error path jumps to
error0 which returns without freeing tcur. This leaks the cursor
memory, the xfs_group reference, and the per-level buffer references
held by the duplicated cursor. Jump to error1 instead, which calls
xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR) to properly release all
resources.
Cc: stable@vger.kernel.org
Fixes: 9eaead51bed95 ("[XFS] implement generic xfs_btree_rshift")
Signed-off-by: Jianyun Gao <jianyungao89@gmail.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/libxfs/xfs_btree.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
index 60ef7f08b1d30..b978ddc13c15c 100644
--- a/fs/xfs/libxfs/xfs_btree.c
+++ b/fs/xfs/libxfs/xfs_btree.c
@@ -2567,7 +2567,7 @@ xfs_btree_lshift(
if (XFS_IS_CORRUPT(tcur->bc_mp, i != 1)) {
xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
- goto error0;
+ goto error1;
}
error = xfs_btree_decrement(tcur, level, &i);
@@ -2737,7 +2737,7 @@ xfs_btree_rshift(
if (XFS_IS_CORRUPT(tcur->bc_mp, i != 1)) {
xfs_btree_mark_sick(cur);
error = -EFSCORRUPTED;
- goto error0;
+ goto error1;
}
error = xfs_btree_increment(tcur, level, &i);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 264/507] net/sched: sch_qfq: prevent aggregate self-replacement
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (262 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 263/507] xfs: fix temporary cursor leak in btree shift corruption paths Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 265/507] vhost-scsi: zero misaligned I/O bounce pages Greg Kroah-Hartman
` (242 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyle Zeng, David Lee, Paolo Abeni,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kyle Zeng <kylebot@openai.com>
[ Upstream commit 2e54b3e187300893688c2c7517894f5d96732e05 ]
qfq_change_class() snapshots the current aggregate settings while
holding the qdisc tree lock, but drops the lock before selecting the
destination aggregate. During that gap, qfq_enqueue() can move the
class to an aggregate matching the requested settings.
When qfq_change_class() resumes, qfq_find_agg() then returns cl->agg.
If it is a singleton, qfq_deact_rm_from_agg() frees the aggregate
before qfq_add_to_agg() immediately accesses the same pointer, causing
a use-after-free.
While holding the tree lock, skip the replacement when the destination
is already the current aggregate. Any estimator replacement has already
completed, so the class change can finish normally.
Fixes: 462dbc9101ac ("pkt_sched: QFQ Plus: fair-queueing service at DRR cost")
Link: https://lore.kernel.org/netdev/20260731140533.566493-1-david.lee@trailofbits.com/
Cc: stable@vger.kernel.org
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Co-developed-by: David Lee <david.lee@trailofbits.com>
Signed-off-by: David Lee <david.lee@trailofbits.com>
Link: https://patch.msgid.link/20261029180957.43015-1-david.lee@trailofbits.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/sch_qfq.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c
index 6f3b7273cb160..e900890e9c544 100644
--- a/net/sched/sch_qfq.c
+++ b/net/sched/sch_qfq.c
@@ -517,11 +517,14 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
sch_tree_lock(sch);
qfq_init_agg(q, new_agg, lmax, weight);
}
+ if (existing && new_agg == cl->agg)
+ goto unlock;
if (existing)
qfq_deact_rm_from_agg(q, cl);
else
qdisc_class_hash_insert(&q->clhash, &cl->common);
qfq_add_to_agg(q, new_agg, cl);
+unlock:
sch_tree_unlock(sch);
qdisc_class_hash_grow(sch, &q->clhash);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 265/507] vhost-scsi: zero misaligned I/O bounce pages
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (263 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 264/507] net/sched: sch_qfq: prevent aggregate self-replacement Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 266/507] vhost: fix used ring index wrap in vhost_add_used_n_in_order Greg Kroah-Hartman
` (241 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shubham Antil, Mike Christie,
Michael S. Tsirkin, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shubham Antil <shubham@octane.security>
[ Upstream commit 01c3a5fa6d641c93c7cef4fb25c5f12938316e18 ]
The misaligned I/O fallback copies the full bounce scatterlist to the
request buffer during completion. If a data-in command transfers less
than requested, part of a newly allocated bounce page can remain unwritten.
Allocate bounce pages with __GFP_ZERO so all bytes copied during completion
have a defined value. This path is already the slow fallback for
misaligned I/O, so the added initialization cost is acceptable.
Found during an LLM-assisted source audit and validated with a QEMU/KVM
vhost-scsi target using misaligned data-in commands.
Fixes: 5ced58bfa132 ("vhost-scsi: Fix alignment handling with windows")
Cc: stable@vger.kernel.org
Assisted-by: LLM (OpenAI Codex, gpt-5.6-sol)
Signed-off-by: Shubham Antil <shubham@octane.security>
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261020105503.75904-1-shubham@octane.security>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vhost/scsi.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 4f8c0260bc9e7..ddc9bea190ded 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -937,7 +937,12 @@ vhost_scsi_copy_iov_to_sgl(struct vhost_scsi_cmd *cmd, struct iov_iter *iter,
}
for_each_sgtable_sg(sg_table, sg, i) {
- page = alloc_page(GFP_KERNEL);
+ /*
+ * Completion copies the full bounce buffer, including bytes the
+ * target did not write. This is already the slow fallback for
+ * misaligned I/O, so zeroing is acceptable here.
+ */
+ page = alloc_page(GFP_KERNEL | __GFP_ZERO);
if (!page) {
ret = -ENOMEM;
goto err;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 266/507] vhost: fix used ring index wrap in vhost_add_used_n_in_order
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (264 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 265/507] vhost-scsi: zero misaligned I/O bounce pages Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 267/507] iommu/virtio: Reset device before deleting virtqueues on probe failure Greg Kroah-Hartman
` (240 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Weibin Liu, Fang Xieyan,
Eugenio Pérez, Michael S. Tsirkin, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fang Xieyan <fangxy@xiaopeng.com>
[ Upstream commit e244725e86be02cd85cb878b3ed8570eba2e4be1 ]
vhost_add_used_n_in_order() advances start by nheads[i] but wraps it
with a single subtraction. If start + nheads[i] >= 2 * vq->num, start
can remain outside the ring.
With used-ring logging enabled, start > vq->num makes (vq->num - start)
underflow. log_write() then sets bits beyond the dirty-log bitmap,
potentially corrupting adjacent userspace memory. This is reachable on
the vhost-net TX path with VIRTIO_F_IN_ORDER: done_idx can reach
VHOST_NET_BATCH (64), triggering the issue with a 32-entry ring.
Wrap start with a mask to keep it within the ring. VHOST_SET_VRING_NUM
enforces a nonzero power-of-two ring size, allowing start to be wrapped
using & (vq->num - 1).
Fixes: 67a873df0c41 ("vhost: basic in order support")
Cc: stable@vger.kernel.org
Reviewed-by: Weibin Liu <liuwb@xiaopeng.com>
Signed-off-by: Fang Xieyan <fangxy@xiaopeng.com>
Acked-by: Eugenio Pérez <eperezma@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261020232956.99970-1-fangxy@xiaopeng.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vhost/vhost.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 44cac11b68d2a..0226c4c597093 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -3172,8 +3172,7 @@ static int vhost_add_used_n_in_order(struct vhost_virtqueue *vq,
}
start += nheads[i];
new += nheads[i];
- if (start >= vq->num)
- start -= vq->num;
+ start &= vq->num - 1;
}
if (unlikely(vq->log_used)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 267/507] iommu/virtio: Reset device before deleting virtqueues on probe failure
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (265 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 266/507] vhost: fix used ring index wrap in vhost_add_used_n_in_order Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 268/507] vdpa/snet: Dont discard the DPU error in snet_send_ctrl_msg() Greg Kroah-Hartman
` (239 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuho Choi, Michael S. Tsirkin,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuho Choi <oss.patchbox@gmail.com>
[ Upstream commit 1f8efac19a0870cdfdf8477e447e5a07ddce9623 ]
viommu_probe() marks the device DRIVER_OK before populating the event
virtqueue and registering the IOMMU device in sysfs. viommu_fill_evtq()
hands the device a set of device-writable buffers through
virtqueue_add_inbuf(), so from that point on the device may write into
them and into the rings.
If either step fails, the error path deletes the virtqueues without
resetting the device first. The event buffers are allocated with
devm_kmalloc_array() and are released as probe unwinds, so the device can
go on writing to memory that has been freed.
Reset the device before deleting the virtqueues, the way viommu_remove()
already does.
Fixes: edcd69ab9a32 ("iommu: Add virtio-iommu driver")
Cc: stable@vger.kernel.org
Signed-off-by: Yuho Choi <oss.patchbox@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261004182218.177343-1-oss.patchbox@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iommu/virtio-iommu.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c
index 587fc13197f12..fa72ae23b8afa 100644
--- a/drivers/iommu/virtio-iommu.c
+++ b/drivers/iommu/virtio-iommu.c
@@ -1227,12 +1227,12 @@ static int viommu_probe(struct virtio_device *vdev)
/* Populate the event queue with buffers */
ret = viommu_fill_evtq(viommu);
if (ret)
- goto err_free_vqs;
+ goto err_reset_vdev;
ret = iommu_device_sysfs_add(&viommu->iommu, dev, NULL, "%s",
virtio_bus_name(vdev));
if (ret)
- goto err_free_vqs;
+ goto err_reset_vdev;
vdev->priv = viommu;
@@ -1244,6 +1244,8 @@ static int viommu_probe(struct virtio_device *vdev)
return 0;
+err_reset_vdev:
+ virtio_reset_device(vdev);
err_free_vqs:
vdev->config->del_vqs(vdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 268/507] vdpa/snet: Dont discard the DPU error in snet_send_ctrl_msg()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (266 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 267/507] iommu/virtio: Reset device before deleting virtqueues on probe failure Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 269/507] drm/bridge: nwl-dsi: Cleanup endpoint mux control selection Greg Kroah-Hartman
` (238 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuho Choi, Michael S. Tsirkin,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuho Choi <oss.patchbox@gmail.com>
[ Upstream commit f41f153d49b4c18172ec61b69ba934c36e1be745 ]
snet_send_ctrl_msg() reads the error code the DPU reports when it ACKs
a control message, but then overwrites it with the return value of
snet_wait_for_dpu_completion(). As a result, a DESTROY, SUSPEND or
RESUME that the DPU rejects is reported to the caller as a success as
long as the DPU clears the opcode register in time.
For SUSPEND this means vhost-vdpa marks the device as suspended and
lets userspace reprogram the vrings while the DPU is still running
them; for DESTROY, snet_reset_dev() never even sees that the device
failed to stop.
Return the error from the saved ACK value once the completion wait
itself has succeeded.
Fixes: 3f3a1675b731 ("vdpa/snet: support getting and setting VQ state")
Cc: stable@vger.kernel.org
Signed-off-by: Yuho Choi <oss.patchbox@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261005044915.264532-1-oss.patchbox@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vdpa/solidrun/snet_ctrl.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/vdpa/solidrun/snet_ctrl.c b/drivers/vdpa/solidrun/snet_ctrl.c
index e284c3a06717c..09afa0487fd6a 100644
--- a/drivers/vdpa/solidrun/snet_ctrl.c
+++ b/drivers/vdpa/solidrun/snet_ctrl.c
@@ -291,7 +291,6 @@ static int snet_send_ctrl_msg(struct snet *snet, u16 opcode, u16 vq_idx)
/* Check for errors */
val = snet_read_ctrl(regs);
- ret = SNET_VAL_TO_ERR(val);
/* Clear the chunk ready bit */
val &= ~SNET_CTRL_CHUNK_RDY_MASK;
@@ -301,6 +300,8 @@ static int snet_send_ctrl_msg(struct snet *snet, u16 opcode, u16 vq_idx)
if (ret)
SNET_WARN(pdev, "Timeout waiting for DPU to complete a control command, err %d\n",
ret);
+ else
+ ret = SNET_VAL_TO_ERR(val);
exit:
mutex_unlock(&snet->ctrl_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 269/507] drm/bridge: nwl-dsi: Cleanup endpoint mux control selection
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (267 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 268/507] vdpa/snet: Dont discard the DPU error in snet_send_ctrl_msg() Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 270/507] drm/bridge: nwl-dsi: Limit LCDIF specific sync override Greg Kroah-Hartman
` (237 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Luca Ceresoli, Esben Haabendal,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Esben Haabendal <esben@geanix.com>
[ Upstream commit 8dad0ebd822f54102aadc6ca4f0f8777112d175d ]
Using the endpoint define values makes it more clear that the argument to
mux_control_try_select() must be valid state integers, and not something
that looks like a boolean.
The endpoint value is kept, as it will be used in a following patch that
changes behavior slightly based on which endpoint is selected.
Cc: stable@vger.kernel.org
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Esben Haabendal <esben@geanix.com>
Link: https://patch.msgid.link/20261027-nwl-dsi-fixes-v5-1-b6d1d3d2d356@geanix.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/bridge/nwl-dsi.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index 09992529f3d85..80e26a947ae69 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -110,6 +110,8 @@ struct nwl_dsi {
int error;
struct nwl_dsi_transfer *xfer;
+
+ unsigned int endpoint;
};
static const struct regmap_config nwl_dsi_regmap_config = {
@@ -1088,13 +1090,12 @@ static int nwl_dsi_parse_dt(struct nwl_dsi *dsi)
static int nwl_dsi_select_input(struct nwl_dsi *dsi)
{
struct device_node *remote;
- u32 use_dcss = 1;
int ret;
remote = of_graph_get_remote_node(dsi->dev->of_node, 0,
NWL_DSI_ENDPOINT_LCDIF);
if (remote) {
- use_dcss = 0;
+ dsi->endpoint = NWL_DSI_ENDPOINT_LCDIF;
} else {
remote = of_graph_get_remote_node(dsi->dev->of_node, 0,
NWL_DSI_ENDPOINT_DCSS);
@@ -1103,11 +1104,12 @@ static int nwl_dsi_select_input(struct nwl_dsi *dsi)
"No valid input endpoint found\n");
return -EINVAL;
}
+ dsi->endpoint = NWL_DSI_ENDPOINT_DCSS;
}
DRM_DEV_INFO(dsi->dev, "Using %s as input source\n",
- (use_dcss) ? "DCSS" : "LCDIF");
- ret = mux_control_try_select(dsi->mux, use_dcss);
+ (dsi->endpoint == NWL_DSI_ENDPOINT_DCSS) ? "DCSS" : "LCDIF");
+ ret = mux_control_try_select(dsi->mux, dsi->endpoint);
if (ret < 0)
DRM_DEV_ERROR(dsi->dev, "Failed to select input: %d\n", ret);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 270/507] drm/bridge: nwl-dsi: Limit LCDIF specific sync override
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (268 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 269/507] drm/bridge: nwl-dsi: Cleanup endpoint mux control selection Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 271/507] hwrng: virtio - prevent use-after-free after a failed restore Greg Kroah-Hartman
` (236 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Luca Ceresoli, Esben Haabendal,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Esben Haabendal <esben@geanix.com>
[ Upstream commit 54a88d9afcca66221d14f438d0960472984968ec ]
When using DCSS with NWL, overriding the mode flags to enforce active high
sync is preventing the use of active low with downstream bridges, such as
ti-sn65dsi83, which will not see such mode flags set by the panel.
Fixes: 44cfc6233447 ("drm/bridge: Add NWL MIPI DSI host controller support")
Cc: stable@vger.kernel.org
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Esben Haabendal <esben@geanix.com>
Link: https://patch.msgid.link/20261027-nwl-dsi-fixes-v5-2-b6d1d3d2d356@geanix.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/bridge/nwl-dsi.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/nwl-dsi.c b/drivers/gpu/drm/bridge/nwl-dsi.c
index 80e26a947ae69..1aab46e1a1687 100644
--- a/drivers/gpu/drm/bridge/nwl-dsi.c
+++ b/drivers/gpu/drm/bridge/nwl-dsi.c
@@ -823,10 +823,13 @@ static int nwl_dsi_bridge_atomic_check(struct drm_bridge *bridge,
struct drm_connector_state *conn_state)
{
struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
+ struct nwl_dsi *dsi = bridge_to_dsi(bridge);
/* At least LCDIF + NWL needs active high sync */
- adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
- adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
+ if (dsi->endpoint == NWL_DSI_ENDPOINT_LCDIF) {
+ adjusted_mode->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
+ adjusted_mode->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
+ }
/*
* Do a full modeset if crtc_state->active is changed to be true.
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 271/507] hwrng: virtio - prevent use-after-free after a failed restore
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (269 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 270/507] drm/bridge: nwl-dsi: Limit LCDIF specific sync override Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 272/507] vduse: fix VA/PA confusion in the coherent page fault path Greg Kroah-Hartman
` (235 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thorsten Blum, Michael S. Tsirkin,
Sasha Levin, PrasannaKumar Muralidharan
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <blum@kernel.org>
[ Upstream commit 0f7bf47f5a0cc26320aa4b14f4504d03a07f4b74 ]
remove_common() frees the driver data during freeze, but does not clear
vdev->priv, which points to freed memory. If probe_common() then fails
during restore, a later remove or freeze can dereference the dangling
pointer.
Clear vdev->priv on the probe_common() error cleanup path and before
freeing the driver data in remove_common(). Also reset the device and
return early from remove_common() if vdev->priv is already NULL for a
safe teardown after a failed restore.
Fixes: 08e53fbdb85c ("virtio-rng: support multiple virtio-rng devices")
Cc: stable@vger.kernel.org
Signed-off-by: Thorsten Blum <blum@kernel.org>
Reviewed-by: PrasannaKumar Muralidharan <prasannatsmkumar@gmail.com>.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20261016103640.4989-2-blum@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/char/hw_random/virtio-rng.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index 5e83ffa105e41..a9ff520975a7c 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -190,6 +190,7 @@ static int probe_common(struct virtio_device *vdev)
err_find:
ida_free(&rng_index_ida, index);
err_ida:
+ vdev->priv = NULL;
kfree(vi);
return err;
}
@@ -198,6 +199,11 @@ static void remove_common(struct virtio_device *vdev)
{
struct virtrng_info *vi = vdev->priv;
+ if (!vi) {
+ virtio_reset_device(vdev);
+ return;
+ }
+
vi->hwrng_removed = true;
vi->data_avail = 0;
vi->data_idx = 0;
@@ -207,6 +213,7 @@ static void remove_common(struct virtio_device *vdev)
virtio_reset_device(vdev);
vdev->config->del_vqs(vdev);
ida_free(&rng_index_ida, vi->index);
+ vdev->priv = NULL;
kfree(vi);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 272/507] vduse: fix VA/PA confusion in the coherent page fault path
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (270 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 271/507] hwrng: virtio - prevent use-after-free after a failed restore Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 273/507] inotify: do not coalesce rename events Greg Kroah-Hartman
` (234 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xie Yongji, chenglong.ma,
Michael S. Tsirkin, Sasha Levin, Claude Code
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: chenglong.ma <longpareto@gmail.com>
[ Upstream commit bb2e6f166547838fd7c320b01c90918b736f76e2 ]
vduse_domain_get_coherent_page() assumes that iotlb entries above
bounce_size were installed by vduse_domain_alloc_coherent(), so it
treats map->addr as a physical address. But vduse registers with
use_va = true, and when the device is bound to vhost_vdpa,
vhost_vdpa_va_map() stores a userspace virtual address in map->addr,
which vduse_domain_set_map() then copies into the same iotlb. A
process holding the domain file descriptor across a rebind can
therefore fault in an arbitrary physical page with read/write
access, ignoring the entry permissions.
Additionally, since the domain file mmap lacks VM_IO, the domain
file itself can be mapped and passed to vhost_vdpa_va_map(),
producing self-referential entries that bypass the coherent path
check.
To fix, only translate entries whose backing file is the domain
file itself in vduse_domain_get_coherent_page(), reject such
entries in vduse_domain_set_map() since only external mappings
should be imported, and set VM_IO on the domain file mmap so
vhost_vdpa_va_map() refuses to map it in the first place.
Fixes: 8c773d53fb7b ("vduse: Implement an MMU-based software IOTLB")
Cc: Xie Yongji <xieyongji@bytedance.com>
Cc: stable@vger.kernel.org
Reported-by: chenglong.ma <longpareto@gmail.com>
Signed-off-by: chenglong.ma <longpareto@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vdpa/vdpa_user/iova_domain.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/vdpa/vdpa_user/iova_domain.c b/drivers/vdpa/vdpa_user/iova_domain.c
index b6c958224b7ce..28a977248a0d3 100644
--- a/drivers/vdpa/vdpa_user/iova_domain.c
+++ b/drivers/vdpa/vdpa_user/iova_domain.c
@@ -76,6 +76,10 @@ int vduse_domain_set_map(struct vduse_iova_domain *domain,
for (map = vhost_iotlb_itree_first(iotlb, start, last); map;
map = vhost_iotlb_itree_next(map, start, last)) {
map_file = (struct vdpa_map_file *)map->opaque;
+ if (!map_file || map_file->file == domain->file) {
+ ret = -EINVAL;
+ goto err;
+ }
ret = vduse_iotlb_add_range(domain, map->start, map->last,
map->addr, map->perm,
map_file->file,
@@ -226,6 +230,7 @@ vduse_domain_get_coherent_page(struct vduse_iova_domain *domain, u64 iova)
{
u64 start = iova & PAGE_MASK;
u64 last = start + PAGE_SIZE - 1;
+ struct vdpa_map_file *map_file;
struct vhost_iotlb_map *map;
struct page *page = NULL;
@@ -234,6 +239,10 @@ vduse_domain_get_coherent_page(struct vduse_iova_domain *domain, u64 iova)
if (!map)
goto out;
+ map_file = (struct vdpa_map_file *)map->opaque;
+ if (!map_file || map_file->file != domain->file)
+ goto out;
+
page = pfn_to_page((map->addr + iova - map->start) >> PAGE_SHIFT);
get_page(page);
out:
@@ -579,7 +588,7 @@ static int vduse_domain_mmap(struct file *file, struct vm_area_struct *vma)
{
struct vduse_iova_domain *domain = file->private_data;
- vm_flags_set(vma, VM_DONTDUMP | VM_DONTEXPAND);
+ vm_flags_set(vma, VM_IO | VM_DONTDUMP | VM_DONTEXPAND);
vma->vm_private_data = domain;
vma->vm_ops = &vduse_domain_mmap_ops;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 273/507] inotify: do not coalesce rename events
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (271 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 272/507] vduse: fix VA/PA confusion in the coherent page fault path Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 274/507] blk-mq: end the request if getting a keyslot fails Greg Kroah-Hartman
` (233 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Amir Goldstein, Hungyu Lin, Jan Kara,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hungyu Lin <dennylin0707@gmail.com>
[ Upstream commit 581230d2ec3c0380917d1255792508851e7c4627 ]
inotify compares the mask, watch descriptor and name when coalescing
adjacent unread events, but ignores their rename cookies. Distinct
IN_MOVED_FROM events can therefore be coalesced, losing the cookie needed
to match a later IN_MOVED_TO event.
For example, watch two directories with IN_MOVE. Move an entry from the
first directory into an unwatched directory, recreate it under the same
name, then move it from the first directory into the second watched
directory before reading the events. The second IN_MOVED_FROM is merged
with the first, while the IN_MOVED_TO retains the second rename's cookie.
Userspace can no longer pair the second rename's events.
The original inotify implementation compared cookies before coalescing.
The fsnotify conversion lost this comparison. Do not coalesce
IN_MOVED_FROM or IN_MOVED_TO events, which carry the identity of their
respective renames. Leave coalescing of other event types unchanged.
Fixes: 63c882a05416 ("inotify: reimplement inotify using fsnotify")
Cc: stable@vger.kernel.org
Suggested-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Link: https://patch.msgid.link/20261027192027.8617-1-dennylin0707@gmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/notify/inotify/inotify_fsnotify.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c
index 7c326ec2e8a8c..6e3af6452dccb 100644
--- a/fs/notify/inotify/inotify_fsnotify.c
+++ b/fs/notify/inotify/inotify_fsnotify.c
@@ -36,7 +36,7 @@ static bool event_compare(struct fsnotify_event *old_fsn,
old = INOTIFY_E(old_fsn);
new = INOTIFY_E(new_fsn);
- if (old->mask & FS_IN_IGNORED)
+ if (old->mask & (FS_IN_IGNORED | FS_MOVE))
return false;
if ((old->mask == new->mask) &&
(old->wd == new->wd) &&
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 274/507] blk-mq: end the request if getting a keyslot fails
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (272 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 273/507] inotify: do not coalesce rename events Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 275/507] virtio_blk: use synchronous quiesce in virtblk_freeze_priv() Greg Kroah-Hartman
` (232 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Eric Biggers,
Christoph Hellwig, Jens Axboe, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit e67cb6ed40e7f45912b63d7d575f18dfd2ebc98a ]
When blk_crypto_rq_get_keyslot() fails, blk_mq_submit_bio() ends the bio
by hand and frees the request. By then blk_mq_bio_to_request() has done
the IO accounting, which blk_mq_free_request() doesn't undo, so the
in_flight counter never drops and iostat shows a device that is 100%
busy. If the bio went through zone write plugging the zone stays plugged
as well, and every later write to it waits forever.
Use blk_mq_end_request() like the dispatch path does for a request the
driver rejected, after marking it for zone write plugging.
Move the call to blk_zone_write_plug_init_request() before
blk_crypto_rq_get_keyslot() so that it doesn't need to be duplicated.
It doesn't depend on the keyslot.
Fixes: 99dc422335d8 ("block: support to account io_ticks precisely")
Fixes: dd291d77cc90 ("block: Introduce zone write plugging")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20261029200110.1328103-1-ebiggers@kernel.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
block/blk-mq.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 5a5dc66fc3b15..6d111c6f0ecd1 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -3193,16 +3193,15 @@ void blk_mq_submit_bio(struct bio *bio)
blk_mq_bio_to_request(rq, bio, nr_segs);
+ if (bio_zone_write_plugging(bio))
+ blk_zone_write_plug_init_request(rq);
+
ret = blk_crypto_rq_get_keyslot(rq);
if (ret != BLK_STS_OK) {
- bio_endio_status(bio, ret);
- blk_mq_free_request(rq);
+ blk_mq_end_request(rq, ret);
return;
}
- if (bio_zone_write_plugging(bio))
- blk_zone_write_plug_init_request(rq);
-
if (op_is_flush(bio->bi_opf) && blk_insert_flush(rq))
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 275/507] virtio_blk: use synchronous quiesce in virtblk_freeze_priv()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (273 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 274/507] blk-mq: end the request if getting a keyslot fails Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 276/507] block: Return the soft block size for compat BLKBSZGET Greg Kroah-Hartman
` (231 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jason Wang, Stefan Hajnoczi,
Cong Zhang, Jens Axboe, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Zhang <cong.zhang@oss.qualcomm.com>
[ Upstream commit 6c6dec7883f8eb10b326bc9d109a4990c885d949 ]
blk_mq_run_work_fn() can call blk_mq_sched_dispatch_requests() through
blk_mq_run_dispatch_ops(). The dispatcher checks QUEUE_FLAG_QUIESCED
while the flag is clear. It can then be preempted before it gets a
request. At that time, it has no queue usage reference, so
blk_mq_freeze_queue() does not wait for it.
virtblk_freeze_priv() then calls blk_mq_quiesce_queue_nowait() and
blk_mq_unfreeze_queue(). A new request can enter the queue. The old
dispatcher can run again, use its old flag check, get the new request,
and call virtio_queue_rq(). At the same time, virtblk_freeze_priv() can
reset the device, delete the virtqueues, and free vblk->vqs. The old
dispatcher can then use a deleted virtqueue or a NULL vblk->vqs, and the
kernel can crash.
Fix this by using blk_mq_quiesce_queue(), which waits for dispatch code
that was already running. Keep the existing freeze and unfreeze order.
The queue remains quiesced until virtblk_restore_priv() calls
blk_mq_unquiesce_queue().
Fixes: 7678abee0867 ("virtio-blk: don't keep queue frozen during system suspend")
Cc: stable@vger.kernel.org
Acked-by: Jason Wang <jasowangio@gmail.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Cong Zhang <cong.zhang@oss.qualcomm.com>
Link: https://lore.kernel.org/20260911-virtblk_sync_quiesce-v1-1-a883f8f31258@oss.qualcomm.com
Link: https://patch.msgid.link/20261103-virtblk_sync_quiesce-v3-1-f40233f9bdd9@oss.qualcomm.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/block/virtio_blk.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index c8bfbf8435ac7..10ba8b0b863b8 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -1596,7 +1596,7 @@ static int virtblk_freeze_priv(struct virtio_device *vdev)
/* Ensure no requests in virtqueues before deleting vqs. */
memflags = blk_mq_freeze_queue(q);
- blk_mq_quiesce_queue_nowait(q);
+ blk_mq_quiesce_queue(q);
blk_mq_unfreeze_queue(q, memflags);
/* Ensure we don't receive any more interrupts */
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 276/507] block: Return the soft block size for compat BLKBSZGET
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (274 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 275/507] virtio_blk: use synchronous quiesce in virtblk_freeze_priv() Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 277/507] xfs: fix wrong compat fields in xfs_ioctl32_bstat_copyin() Greg Kroah-Hartman
` (230 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hungyu Lin, Christoph Hellwig,
Arnd Bergmann, Jens Axboe, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hungyu Lin <dennylin0707@gmail.com>
[ Upstream commit 57cd1a08717690e5ea01d7ac7a96bb33a2dca117 ]
BLKBSZGET returns the block device's soft block size, while BLKSSZGET
returns its logical sector size. The compat BLKBSZGET_32 handler uses
bdev_logical_block_size(), so it returns the wrong value when these
sizes differ.
For example, on an x86_64 kernel a native query of a RAM or loop device
with 512-byte logical sectors returns the initial soft block size of
4096 bytes, but an i386 process gets 512 bytes. This makes 32-bit
blockdev --getbsz and the BSZ column of --report disagree with native
queries, even without a preceding BLKBSZSET.
Use block_size() as the native handler and the pre-regression compat
handler do, and correct the case comment to describe the soft size.
Fixes: 9b81648cb5e3 ("compat_ioctl: simplify up block/ioctl.c")
Cc: stable@vger.kernel.org
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Link: https://patch.msgid.link/20261023153645.37546-1-dennylin0707@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
block/ioctl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/block/ioctl.c b/block/ioctl.c
index 64b4e6c0f6965..fb2f4b4d2505e 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -835,8 +835,8 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
return compat_put_ulong(argp, bdev_nr_sectors(bdev));
/* The data is compatible, but the command number is different */
- case BLKBSZGET_32: /* get the logical block size (cf. BLKSSZGET) */
- return put_int(argp, bdev_logical_block_size(bdev));
+ case BLKBSZGET_32: /* get the soft block size (cf. BLKSSZGET) */
+ return put_int(argp, block_size(bdev));
case BLKBSZSET_32:
return blkdev_bszset(file, mode, argp);
case BLKGETSIZE64_32:
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 277/507] xfs: fix wrong compat fields in xfs_ioctl32_bstat_copyin()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (275 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 276/507] block: Return the soft block size for compat BLKBSZGET Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 278/507] block: only serialize elevator switches of the same queue Greg Kroah-Hartman
` (229 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Reid Downing, Carlos Maiolino,
Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Reid Downing <skibletz@gmail.com>
[ Upstream commit b7eb276a39b14e685c2fe578f8ac22fc48ff9e6c ]
bs_blocks and bs_xflags were both read from bstat32->bs_size.
Read each one from its own field instead.
Fixes: e94fc4a43e5c39 ("[XFS] Add compat handlers for swapext ioctl")
Cc: stable@vger.kernel.org # v2.6.29
Signed-off-by: Reid Downing <skibletz@gmail.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_ioctl32.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index c66e192448a89..e411f9453bfba 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -123,8 +123,8 @@ xfs_ioctl32_bstat_copyin(
xfs_ioctl32_bstime_copyin(&bstat->bs_atime, &bstat32->bs_atime) ||
xfs_ioctl32_bstime_copyin(&bstat->bs_mtime, &bstat32->bs_mtime) ||
xfs_ioctl32_bstime_copyin(&bstat->bs_ctime, &bstat32->bs_ctime) ||
- get_user(bstat->bs_blocks, &bstat32->bs_size) ||
- get_user(bstat->bs_xflags, &bstat32->bs_size) ||
+ get_user(bstat->bs_blocks, &bstat32->bs_blocks) ||
+ get_user(bstat->bs_xflags, &bstat32->bs_xflags) ||
get_user(bstat->bs_extsize, &bstat32->bs_extsize) ||
get_user(bstat->bs_extents, &bstat32->bs_extents) ||
get_user(bstat->bs_gen, &bstat32->bs_gen) ||
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 278/507] block: only serialize elevator switches of the same queue
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (276 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 277/507] xfs: fix wrong compat fields in xfs_ioctl32_bstat_copyin() Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 279/507] blk-mq: fix out-of-bounds read in blk_mq_free_rqs Greg Kroah-Hartman
` (228 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Reindl Harald, Nilay Shroff,
Laveesh Bansal, Jens Axboe, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laveesh Bansal <laveeshb@laveeshbansal.com>
[ Upstream commit 603523fd54664f17630f742229166278568c3ce8 ]
Since commit 4ff58d6bc9dd ("block: serialize elevator changes for the
same queue using a writer lock"), a write to queue/scheduler fails with
-EBUSY whenever something else holds set->update_nr_hwq_lock. That
commit takes the lock for write, and it has to be a trylock because of
commit ce8ee8583ed8 ("block: use trylock to avoid lockdep circular
dependency in sysfs").
The lock covers the whole tag set, so it is easy to hit. A scheduler
write fails while another queue of the set is switching, or while a
sibling disk of the same SCSI host or NVMe controller is added or
removed. This matches the udev failures reported on 7.2.
Go back to taking the lock for read. The write lock was there to keep
two switches of one queue from overlapping in elevator_change_done(),
which touches the elevator sysfs and debugfs entries outside of
q->elevator_lock. Use QUEUE_FLAG_NO_ELV_SWITCH for that instead: a
write sets it before elevator_change() and clears it afterwards, and a
write that finds it set returns -EBUSY. Disk removal already sets the
flag under the write lock, so no switch can start once it has run.
Writes to the same queue, and writes that race with an nr_hw_queues
update, an nr_requests write or disk removal, can still get -EBUSY, as
with 4ff58d6bc9dd. A write to a disk that is being removed now gets
-EBUSY instead of -ENOENT.
Fixes: 4ff58d6bc9dd ("block: serialize elevator changes for the same queue using a writer lock")
Cc: stable@vger.kernel.org # v7.2+
Reported-by: Reindl Harald <h.reindl@thelounge.net>
Closes: https://lore.kernel.org/r/077dd42e-cbc9-4c23-a5ef-3d20e4fc7757@thelounge.net
Suggested-by: Nilay Shroff <nilay@linux.ibm.com>
Assisted-by: LLM
Signed-off-by: Laveesh Bansal <laveeshb@laveeshbansal.com>
Reviewed-by: Nilay Shroff <nilay@linux.ibm.com>
Link: https://patch.msgid.link/20261031044141.5569-1-laveeshb@laveeshbansal.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
block/elevator.c | 30 +++++++++++++++++-------------
include/linux/blkdev.h | 4 +---
2 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/block/elevator.c b/block/elevator.c
index 2161b6eea680c..66edf1a5768a8 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -812,25 +812,29 @@ ssize_t elv_iosched_store(struct gendisk *disk, const char *buf,
* reference during concurrent disk deletion:
* update_nr_hwq_lock -> kn->active (via del_gendisk -> kobject_del)
* kn->active -> update_nr_hwq_lock (via this sysfs write path)
- *
- * Use the writer lock instead of the reader lock of update_nr_hwq_lock
- * to serialize the two-stage elevator switch steps in
- * elevator_change(): the core switch step under the elevator lock and
- * the elevator_change_done() step outside the elevator lock.
*/
- if (!down_write_trylock(&set->update_nr_hwq_lock)) {
+ if (!down_read_trylock(&set->update_nr_hwq_lock)) {
ret = -EBUSY;
goto out;
}
- if (!blk_queue_no_elv_switch(q)) {
- ret = elevator_change(q, &ctx);
- if (!ret)
- ret = count;
- } else {
- ret = -ENOENT;
+
+ /*
+ * The reader lock is shared, so use QUEUE_FLAG_NO_ELV_SWITCH to allow
+ * only one switch of this queue at a time, and none once the disk is
+ * going away.
+ */
+ if (test_and_set_bit(QUEUE_FLAG_NO_ELV_SWITCH, &q->queue_flags)) {
+ ret = -EBUSY;
+ goto out_unlock;
}
- up_write(&set->update_nr_hwq_lock);
+ ret = elevator_change(q, &ctx);
+ if (!ret)
+ ret = count;
+
+ blk_queue_flag_clear(QUEUE_FLAG_NO_ELV_SWITCH, q);
+out_unlock:
+ up_read(&set->update_nr_hwq_lock);
out:
if (ctx.type)
elevator_put(ctx.type);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 4f7905c3412b8..3989bb0dd43be 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -675,7 +675,7 @@ enum {
QUEUE_FLAG_HCTX_ACTIVE, /* at least one blk-mq hctx is active */
QUEUE_FLAG_SQ_SCHED, /* single queue style io dispatch */
QUEUE_FLAG_DISABLE_WBT_DEF, /* for sched to disable/enable wbt */
- QUEUE_FLAG_NO_ELV_SWITCH, /* can't switch elevator any more */
+ QUEUE_FLAG_NO_ELV_SWITCH, /* a switch is running or disk is going away */
QUEUE_FLAG_QOS_ENABLED, /* qos is enabled */
QUEUE_FLAG_BIO_ISSUE_TIME, /* record bio->issue_time_ns */
QUEUE_FLAG_ZONED_QD1_WRITES, /* Limit zoned devices writes to QD=1 */
@@ -716,8 +716,6 @@ void blk_queue_flag_clear(unsigned int flag, struct request_queue *q);
((q)->limits.features & BLK_FEAT_SKIP_TAGSET_QUIESCE)
#define blk_queue_disable_wbt(q) \
test_bit(QUEUE_FLAG_DISABLE_WBT_DEF, &(q)->queue_flags)
-#define blk_queue_no_elv_switch(q) \
- test_bit(QUEUE_FLAG_NO_ELV_SWITCH, &(q)->queue_flags)
#define blk_queue_zoned_qd1_writes(q) \
test_bit(QUEUE_FLAG_ZONED_QD1_WRITES, &(q)->queue_flags)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 279/507] blk-mq: fix out-of-bounds read in blk_mq_free_rqs
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (277 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 278/507] block: only serialize elevator switches of the same queue Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 280/507] blk-iocost: account flush sequence latency only once Greg Kroah-Hartman
` (227 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+e90526cab23b9efcd03c,
Nilay Shorff, Krystian Kaniewski, syzbot, Jens Axboe, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krystian Kaniewski <krystianmkaniewski@gmail.com>
[ Upstream commit 894e4e6084924cfd590968d45fad20908e02ddae ]
A KASAN slab-out-of-bounds read can occur in blk_mq_free_rqs() when there
is a mismatch between the number of hardware queues allocated for the IO
scheduler (et->nr_hw_queues) and the number of hardware queues in the block
tag set (set->nr_hw_queues).
This mismatch can happen if blk_mq_update_nr_hw_queues() fails halfway
through (e.g., due to memory pressure during
blk_mq_prealloc_tag_set_tags()). In this error path, the elevator is
restored with a larger number of hardware queues than the block tag set
actually has.
When the elevator is later freed, blk_mq_free_sched_tags() iterates up to
the new et->nr_hw_queues and calls blk_mq_free_rqs(). In blk_mq_free_rqs(),
it attempts to access set->tags[hctx_idx] to get the driver tags. Because
set->nr_hw_queues was not updated due to the earlier failure, set->tags
still has the old (smaller) size, leading to an out-of-bounds read.
BUG: KASAN: slab-out-of-bounds in blk_mq_free_rqs+0xde/0x680
Read of size 8 at addr ffff88818d67fc28 by task syz-executor117/5839
Call Trace:
blk_mq_free_rqs+0xde/0x680
blk_mq_free_map_and_rqs+0x40/0xf0
blk_mq_free_sched_tags
blk_mq_free_sched_res+0xeb/0x280
elevator_change_done+0x1d2/0x5c0
elevator_change+0x34f/0x480
elv_iosched_store+0x504/0x630
queue_attr_store+0x207/0x2b0
To fix this, explicitly check if hctx_idx < set->nr_hw_queues before
accessing set->tags[hctx_idx]. If hctx_idx >= set->nr_hw_queues, the
hardware queue doesn't exist in the tag set, meaning there are no driver
tags to clear mappings from. In this case, safely set drv_tags to NULL. The
subsequent call to blk_mq_clear_rq_mapping() already handles a NULL
drv_tags pointer and will safely return.
Fixes: 04225d13aef1 ("block: fix potential deadlock while running nr_hw_queue update")
Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: syzbot+e90526cab23b9efcd03c@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=e90526cab23b9efcd03c
Link: https://syzkaller.appspot.com/ai_job?id=827b5760-86a0-4f44-9c69-430b572eac12
Reviewed-by: Nilay Shorff <nilay@linux.ibm.com>
Cc: stable@vger.kernel.org # 6.17+
Signed-off-by: Krystian Kaniewski <krystianmkaniewski@gmail.com>
Tested-by: syzbot@syzkaller.appspotmail.com
Link: https://patch.msgid.link/20261014170538.1089448-1-krystianmkaniewski@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
block/blk-mq.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 6d111c6f0ecd1..e21d69767fd47 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -3484,8 +3484,10 @@ void blk_mq_free_rqs(struct blk_mq_tag_set *set, struct blk_mq_tags *tags,
if (blk_mq_is_shared_tags(set->flags))
drv_tags = set->shared_tags;
- else
+ else if (hctx_idx < set->nr_hw_queues)
drv_tags = set->tags[hctx_idx];
+ else
+ drv_tags = NULL;
if (tags->static_rqs && set->ops->exit_request) {
int i;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 280/507] blk-iocost: account flush sequence latency only once
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (278 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 279/507] blk-mq: fix out-of-bounds read in blk_mq_free_rqs Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 281/507] xfs: mark the inode preallocated for pNFS write layouts past EOF Greg Kroah-Hartman
` (226 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhe Liu, Tejun Heo, Jens Axboe,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhe Liu <liuzhe1@kylinos.cn>
[ Upstream commit e9804489e27dd6e33aec5511fe3780ff3009f57f ]
A flush sequence with a DATA phase can complete its original request
twice. Both completions invoke ioc_rqos_done(), causing the request to
contribute two latency samples and adding the same queue wait time
twice. This gives such requests disproportionate weight compared to
ordinary writes, distorting the device-wide latency and queue wait
feedback used to adjust iocost's virtual time rate.
Skip requests marked RQF_FLUSH_SEQ in ioc_rqos_done(). The flag is set
when the request enters the flush machinery and is still set when the
data phase completes; blk_flush_restore_request() clears it before the
final completion, so accounting happens only once, after the whole
sequence finishes. The remaining sample covers the request's lifetime
through any postflush, and its queue wait time is accumulated only
once.
Fixes: 7caa47151ab2e ("blkcg: implement blk-iocost")
Cc: stable@vger.kernel.org
Signed-off-by: Zhe Liu <liuzhe1@kylinos.cn>
Acked-by: Tejun Heo <tj@kernel.org>
Link: https://patch.msgid.link/20261102061802.408173-1-liuzhe1@kylinos.cn
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
block/blk-iocost.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/block/blk-iocost.c b/block/blk-iocost.c
index 7b8af094ab370..23445d7014334 100644
--- a/block/blk-iocost.c
+++ b/block/blk-iocost.c
@@ -2851,6 +2851,9 @@ static void ioc_rqos_done(struct rq_qos *rqos, struct request *rq)
if (!ioc->enabled || !rq->alloc_time_ns || !rq->start_time_ns)
return;
+ if (unlikely(rq->rq_flags & RQF_FLUSH_SEQ))
+ return;
+
switch (req_op(rq)) {
case REQ_OP_READ:
pidx = QOS_RLAT;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 281/507] xfs: mark the inode preallocated for pNFS write layouts past EOF
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (279 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 280/507] blk-iocost: account flush sequence latency only once Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 282/507] xfs: add a flag to convert unwritten extents without allocating blocks Greg Kroah-Hartman
` (225 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chuck Lever, Daejun Park,
Christoph Hellwig, Pankaj Raghav, Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daejun Park <daejun7.park@samsung.com>
[ Upstream commit 8b8e265991556d99b6d721697f148975a7c68767 ]
xfs_fs_map_blocks() marks the inode XFS_DIFLAG_PREALLOC only when it
allocates blocks for a write layout. A write layout past EOF can also
hand out allocated blocks, such as speculative preallocation. blockgc
then frees them under the layout, and another file may get them.
Mark the inode whenever a write mapping ends past EOF.
Fixes: 527851124d10 ("xfs: implement pNFS export operations")
Cc: stable@vger.kernel.org
Reported-by: Chuck Lever <cel@kernel.org>
Link: https://lore.kernel.org/r/4de5356f-bc4d-4f1a-9c81-fce09b1b46fd@slotpi15m67
Signed-off-by: Daejun Park <daejun7.park@samsung.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_pnfs.c | 34 +++++++++++++++++++++++++---------
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
index ab385617003a2..a9f0b472f3076 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -110,7 +110,15 @@ xfs_fs_map_update_inode(
ip->i_diflags |= XFS_DIFLAG_PREALLOC;
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- return xfs_trans_commit(tp);
+ error = xfs_trans_commit(tp);
+ if (error)
+ return error;
+
+ /*
+ * Force the log so that the blocks handed out to the client are
+ * guaranteed to be present even after a server crash.
+ */
+ return xfs_log_force_inode(ip);
}
/*
@@ -134,6 +142,7 @@ xfs_fs_map_blocks(
uint lock_flags;
int error = 0;
u64 seq;
+ bool update_inode = false;
if (xfs_is_shutdown(mp))
return -EIO;
@@ -221,20 +230,27 @@ xfs_fs_map_blocks(
end_fsb - offset_fsb, 0, &imap, &seq);
if (error)
goto out_unlock;
+ update_inode = true;
+ } else {
+ xfs_iunlock(ip, lock_flags);
/*
- * Ensure the next transaction is committed synchronously so
- * that the blocks allocated and handed out to the client are
- * guaranteed to be present even after a server crash.
+ * Blocks past EOF that were allocated for buffered writes, such
+ * as speculative preallocation, can be freed by
+ * xfs_free_eofblocks() without breaking the layout unless the
+ * inode is marked as preallocated. Mark it before handing them
+ * out for writing, as for blocks allocated above.
*/
+ if (write && !(ip->i_diflags & XFS_DIFLAG_PREALLOC) &&
+ imap.br_startoff + imap.br_blockcount >
+ XFS_B_TO_FSB(mp, XFS_ISIZE(ip)))
+ update_inode = true;
+ }
+
+ if (update_inode) {
error = xfs_fs_map_update_inode(ip);
- if (!error)
- error = xfs_log_force_inode(ip);
if (error)
goto out_unlock;
-
- } else {
- xfs_iunlock(ip, lock_flags);
}
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 282/507] xfs: add a flag to convert unwritten extents without allocating blocks
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (280 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 281/507] xfs: mark the inode preallocated for pNFS write layouts past EOF Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 283/507] xfs: refuse a pNFS LAYOUTCOMMIT of a range without blocks Greg Kroah-Hartman
` (224 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Daejun Park,
Pankaj Raghav, Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daejun Park <daejun7.park@samsung.com>
[ Upstream commit f3ca3498dfe624f9b604c934263538a3acd55af5 ]
xfs_bmapi_write() with XFS_BMAPI_CONVERT also allocates blocks for
holes and delalloc extents in the range. Add XFS_BMAPI_CONVERT_ONLY for
callers that may only convert already allocated blocks. It stops at a
hole or delalloc extent, and returns -ENOSR if it stops before mapping
anything.
Marked for stable because "xfs: refuse a pNFS LAYOUTCOMMIT of a range
without blocks" needs it.
Suggested-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20261013120359.GB2944@lst.de
Cc: stable@vger.kernel.org
Signed-off-by: Daejun Park <daejun7.park@samsung.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/libxfs/xfs_bmap.c | 14 ++++++++++++--
fs/xfs/libxfs/xfs_bmap.h | 10 +++++++++-
2 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index d64defeda645e..fce2705c67d2e 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -4128,6 +4128,8 @@ xfs_bmapi_finish(
* Returns a negative error code on failure, including -ENOSPC when it could not
* allocate any blocks and -ENOSR when it did allocate blocks to convert a
* delalloc range, but those blocks were before the passed in range.
+ * With XFS_BMAPI_CONVERT_ONLY, it stops at a hole or a delalloc extent instead
+ * of allocating blocks, and returns -ENOSR if it stops before mapping anything.
*/
int
xfs_bmapi_write(
@@ -4187,6 +4189,8 @@ xfs_bmapi_write(
*/
ASSERT((flags & (XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO)) !=
(XFS_BMAPI_PREALLOC | XFS_BMAPI_ZERO));
+ ASSERT(!(flags & XFS_BMAPI_CONVERT_ONLY) ||
+ (flags & XFS_BMAPI_CONVERT));
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
XFS_TEST_ERROR(mp, XFS_ERRTAG_BMAPIFORMAT)) {
@@ -4235,6 +4239,9 @@ xfs_bmapi_write(
* that we found, if any.
*/
if (need_alloc || wasdelay) {
+ if (flags & XFS_BMAPI_CONVERT_ONLY)
+ break;
+
bma.eof = eof;
bma.conv = !!(flags & XFS_BMAPI_CONVERT);
bma.wasdel = wasdelay;
@@ -4330,10 +4337,13 @@ xfs_bmapi_write(
*
* To avoid a successful return with *nmap set to 0, return the magic
* -ENOSR error code for this particular case so that the caller can
- * handle it.
+ * handle it. The same goes for XFS_BMAPI_CONVERT_ONLY stopping at a
+ * hole or a delalloc extent at the start of the range, in which case
+ * nothing has been changed.
*/
if (!n) {
- ASSERT(bma.nallocs >= *nmap);
+ ASSERT((flags & XFS_BMAPI_CONVERT_ONLY) ? bma.nallocs == 0 :
+ bma.nallocs >= *nmap);
return -ENOSR;
}
*nmap = n;
diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h
index d5f2729305fad..76d25e5d5d9cb 100644
--- a/fs/xfs/libxfs/xfs_bmap.h
+++ b/fs/xfs/libxfs/xfs_bmap.h
@@ -90,6 +90,13 @@ struct xfs_bmalloca {
/* Try to align allocations to the extent size hint */
#define XFS_BMAPI_EXTSZALIGN (1u << 11)
+/*
+ * Use with XFS_BMAPI_CONVERT to convert unwritten extents without allocating
+ * blocks. Stop at a hole or a delalloc extent: return the mappings found so
+ * far, or -ENOSR if there are none.
+ */
+#define XFS_BMAPI_CONVERT_ONLY (1u << 12)
+
#define XFS_BMAPI_FLAGS \
{ XFS_BMAPI_ENTIRE, "ENTIRE" }, \
{ XFS_BMAPI_METADATA, "METADATA" }, \
@@ -102,7 +109,8 @@ struct xfs_bmalloca {
{ XFS_BMAPI_COWFORK, "COWFORK" }, \
{ XFS_BMAPI_NODISCARD, "NODISCARD" }, \
{ XFS_BMAPI_NORMAP, "NORMAP" },\
- { XFS_BMAPI_EXTSZALIGN, "EXTSZALIGN" }
+ { XFS_BMAPI_EXTSZALIGN, "EXTSZALIGN" }, \
+ { XFS_BMAPI_CONVERT_ONLY, "CONVERT_ONLY" }
static inline int xfs_bmapi_aflag(int w)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 283/507] xfs: refuse a pNFS LAYOUTCOMMIT of a range without blocks
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (281 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 282/507] xfs: add a flag to convert unwritten extents without allocating blocks Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 284/507] xfs: clamp a pNFS LAYOUTCOMMIT extent before computing its end Greg Kroah-Hartman
` (223 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daejun Park, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daejun Park <daejun7.park@samsung.com>
[ Upstream commit bcf0b7f18ad11e1d410e82ffef678705eff0a317 ]
A client can commit a hole in a LAYOUTCOMMIT, because nfsd does not
check the extents against its layouts. xfs_iomap_write_unwritten() then
allocates written blocks there. A large hole overruns the block
reservation and shuts XFS down. A small one exposes stale data.
Refuse such a range with -EIO, using XFS_BMAPI_CONVERT_ONLY.
Link: https://lore.kernel.org/r/20261014130834.GB15773@lst.de
Fixes: 527851124d10 ("xfs: implement pNFS export operations")
Cc: stable@vger.kernel.org
Signed-off-by: Daejun Park <daejun7.park@samsung.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_file.c | 2 +-
fs/xfs/xfs_ioend.c | 2 +-
fs/xfs/xfs_iomap.c | 20 +++++++++++++++++---
fs/xfs/xfs_iomap.h | 3 ++-
fs/xfs/xfs_pnfs.c | 9 ++++++++-
5 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index d8202da15aca9..59bd9a24b3eff 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -668,7 +668,7 @@ xfs_dio_write_end_io(
* they are converted.
*/
if (flags & IOMAP_DIO_UNWRITTEN) {
- error = xfs_iomap_write_unwritten(ip, offset, size, true);
+ error = xfs_iomap_write_unwritten(ip, offset, size, true, 0);
goto out;
}
diff --git a/fs/xfs/xfs_ioend.c b/fs/xfs/xfs_ioend.c
index 40695d18dac08..aced9a023db1d 100644
--- a/fs/xfs/xfs_ioend.c
+++ b/fs/xfs/xfs_ioend.c
@@ -102,7 +102,7 @@ xfs_end_ioend_write(
else if (ioend->io_flags & IOMAP_IOEND_SHARED)
error = xfs_reflink_end_cow(ip, offset, size);
else if (ioend->io_flags & IOMAP_IOEND_UNWRITTEN)
- error = xfs_iomap_write_unwritten(ip, offset, size, false);
+ error = xfs_iomap_write_unwritten(ip, offset, size, false, 0);
if (!error &&
!(ioend->io_flags & IOMAP_IOEND_DIRECT) &&
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 7c6238fed61e4..93826ca74b6be 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -614,7 +614,8 @@ xfs_iomap_write_unwritten(
xfs_inode_t *ip,
xfs_off_t offset,
xfs_off_t count,
- bool update_isize)
+ bool update_isize,
+ uint32_t bmapi_flags)
{
xfs_mount_t *mp = ip->i_mount;
xfs_fileoff_t offset_fsb;
@@ -676,8 +677,21 @@ xfs_iomap_write_unwritten(
*/
nimaps = 1;
error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb,
- XFS_BMAPI_CONVERT, resblks, &imap,
- &nimaps);
+ XFS_BMAPI_CONVERT | bmapi_flags,
+ resblks, &imap, &nimaps);
+ if (error == -ENOSR && (bmapi_flags & XFS_BMAPI_CONVERT_ONLY)) {
+ /*
+ * Nothing was mapped: the rest of the range starts
+ * with a hole or a delalloc extent. Nothing was
+ * changed either, but xfs_iext_count_extend() may
+ * have logged the inode, and cancelling a dirty
+ * transaction shuts the filesystem down. Commit it,
+ * as xfs_alloc_file_space() does on -ENOSR.
+ */
+ error = xfs_trans_commit(tp);
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ return error ? error : -EIO;
+ }
if (error)
goto error_on_bmapi_transaction;
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index f2520a9b3a13e..8fc0c6fc8bea5 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -15,7 +15,8 @@ struct xfs_zone_alloc_ctx;
int xfs_iomap_write_direct(struct xfs_inode *ip, xfs_fileoff_t offset_fsb,
xfs_fileoff_t count_fsb, unsigned int flags,
struct xfs_bmbt_irec *imap, u64 *sequence);
-int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, xfs_off_t, bool);
+int xfs_iomap_write_unwritten(struct xfs_inode *ip, xfs_off_t offset,
+ xfs_off_t count, bool update_isize, uint32_t bmapi_flags);
xfs_fileoff_t xfs_iomap_eof_align_last_fsb(struct xfs_inode *ip,
xfs_fileoff_t end_fsb);
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
index a9f0b472f3076..7ff83274a5135 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -344,7 +344,14 @@ xfs_fs_commit_blocks(
(end - 1) >> PAGE_SHIFT);
WARN_ON_ONCE(error);
- error = xfs_iomap_write_unwritten(ip, start, length, false);
+ /*
+ * A client may only write to blocks that a layout handed out,
+ * and xfs_fs_map_blocks() allocates blocks for any hole in a
+ * write layout, so refuse to allocate blocks for a hole or a
+ * delalloc extent in the committed range.
+ */
+ error = xfs_iomap_write_unwritten(ip, start, length, false,
+ XFS_BMAPI_CONVERT_ONLY);
if (error)
goto out_drop_iolock;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 284/507] xfs: clamp a pNFS LAYOUTCOMMIT extent before computing its end
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (282 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 283/507] xfs: refuse a pNFS LAYOUTCOMMIT of a range without blocks Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 285/507] xfs: cap the block count of xfs_iomap_write_direct() at one extent Greg Kroah-Hartman
` (222 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daejun Park, Christoph Hellwig,
Pankaj Raghav, Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daejun Park <daejun7.park@samsung.com>
[ Upstream commit d8c2bc88460f89e543ab3af622fc8f34c7011d71 ]
xfs_fs_commit_blocks() adds the client's length to the offset before it
clamps the end to the file size. A large length wraps the sum and
reaches xfs_iomap_write_unwritten() unclamped. With the previous two
patches the LAYOUTCOMMIT then fails with -EIO and converts nothing.
Clamp the length first.
Fixes: 527851124d10 ("xfs: implement pNFS export operations")
Cc: stable@vger.kernel.org
Signed-off-by: Daejun Park <daejun7.park@samsung.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_pnfs.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
index 7ff83274a5135..19eb18e1290cf 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -328,9 +328,7 @@ xfs_fs_commit_blocks(
if (start > size)
continue;
- end = start + maps[i].length;
- if (end > size)
- end = size;
+ end = start + min_t(u64, maps[i].length, size - start);
length = end - start;
if (!length)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 285/507] xfs: cap the block count of xfs_iomap_write_direct() at one extent
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (283 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 284/507] xfs: clamp a pNFS LAYOUTCOMMIT extent before computing its end Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 286/507] xfs: clamp the pNFS layout range to the maximum file size Greg Kroah-Hartman
` (221 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Pankaj Raghav, Daejun Park, Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daejun Park <daejun7.park@samsung.com>
[ Upstream commit 66d1ce09ebd72709f8d739630c39f440445173fd ]
xfs_iomap_write_direct() reserves blocks for the whole count in an
unsigned int. For a pNFS layout the client chooses that count, and an
RW LAYOUTGET for 16 TiB wraps the reservation and shuts XFS down.
xfs_bmapi_write() maps at most XFS_MAX_BMBT_EXTLEN blocks here, so cap
the count at that. nfsd asks again for the rest. The other callers get
the same mapping as before.
Suggested-by: Darrick J. Wong <djwong@kernel.org>
Suggested-by: Christoph Hellwig <hch@lst.de>
Suggested-by: Pankaj Raghav <p.raghav@samsung.com>
Fixes: 527851124d10 ("xfs: implement pNFS export operations")
Cc: stable@vger.kernel.org
Signed-off-by: Daejun Park <daejun7.park@samsung.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_iomap.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 93826ca74b6be..373ff0e64f145 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -285,6 +285,14 @@ xfs_iomap_write_direct(
ASSERT(count_fsb > 0);
+ /*
+ * xfs_bmapi_write() maps at most XFS_MAX_BMBT_EXTLEN blocks in one
+ * mapping, so don't reserve blocks for more. A pNFS layout range
+ * comes from a client, and its block count may not even fit the
+ * 32-bit reservation. The caller maps the rest with a later call.
+ */
+ count_fsb = min_t(xfs_filblks_t, count_fsb, XFS_MAX_BMBT_EXTLEN);
+
resaligned = xfs_aligned_fsb_count(offset_fsb, count_fsb,
xfs_get_extsz_hint(ip));
if (unlikely(XFS_IS_REALTIME_INODE(ip))) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 286/507] xfs: clamp the pNFS layout range to the maximum file size
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (284 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 285/507] xfs: cap the block count of xfs_iomap_write_direct() at one extent Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 287/507] net: restore refcount ordering for lockless socket access Greg Kroah-Hartman
` (220 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daejun Park, Darrick J. Wong,
Pankaj Raghav, Christoph Hellwig, Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daejun Park <daejun7.park@samsung.com>
[ Upstream commit 29f3c1be4e554c9dbc66e13333034e0947477cb6 ]
xfs_fs_map_blocks() lets two bad layout ranges through. An offset of
2^63 or more is negative and passes "offset > limit". A length above
the limit, such as NFS4_UINT64_MAX, wraps "offset > limit - length"
and stays unclamped. With NFS4_UINT64_MAX, a read layout is built from
an uninitialized mapping.
Reject a negative offset and one at the limit, and clamp the length.
This needs "xfs: cap the block count of xfs_iomap_write_direct() at one
extent".
Fixes: 527851124d10 ("xfs: implement pNFS export operations")
Cc: stable@vger.kernel.org
Signed-off-by: Daejun Park <daejun7.park@samsung.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/xfs_pnfs.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
index 19eb18e1290cf..7153e7a1e1de6 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -176,10 +176,9 @@ xfs_fs_map_blocks(
if (!write)
limit = max(limit, round_up(i_size_read(inode),
inode->i_sb->s_blocksize));
- if (offset > limit)
+ if (offset < 0 || offset >= limit)
goto out_unlock;
- if (offset > limit - length)
- length = limit - offset;
+ length = min_t(u64, length, limit - offset);
error = filemap_write_and_wait(inode->i_mapping);
if (error)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 287/507] net: restore refcount ordering for lockless socket access
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (285 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 286/507] xfs: clamp the pNFS layout range to the maximum file size Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 288/507] xfs: fix recovery of partial attr removals Greg Kroah-Hartman
` (219 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hyunwoo Kim, Kuniyuki Iwashima,
Paolo Abeni, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hyunwoo Kim <imv4bel@gmail.com>
[ Upstream commit 5b5d8f351dd96f56a58bb516a80e2d4d742fe4e2 ]
Before commit fb041bb7c0a9 ("locking/refcount: Consolidate implementations
of refcount_t"), default builds implemented refcount_inc_not_zero() using
atomic_add_unless(), which provided full memory ordering on success. The
commit removed that ordering on weakly ordered architectures, allowing
accesses after a successful reference acquisition to be reordered before
it.
Use refcount_inc_not_zero_acquire() in the IPv4 and IPv6 established
lookups and in inet_twsk_purge(), where the socket is validated again
after taking a reference.
bpf_sk_assign() can receive a socket pointer obtained through BTF
without a reference. Use acquire ordering when it takes its own reference
for a refcounted socket.
Use refcount_set_release() when setting refcounts in the SYN cookie,
TCP Fast Open, request migration, and TIME_WAIT paths. Keep the existing
TIME_WAIT smp_wmb(), which separately orders the refcount store before
ehash publication.
Fixes: fb041bb7c0a9 ("locking/refcount: Consolidate implementations of refcount_t")
Fixes: 27e5203bd9c5 ("bpf: Change bpf_sk_assign to accept ARG_PTR_TO_BTF_ID_SOCK_COMMON")
Cc: stable@vger.kernel.org
Signed-off-by: Hyunwoo Kim <imv4bel@gmail.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20261029214219.1035176-3-imv4bel@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/filter.c | 2 +-
net/ipv4/inet_connection_sock.c | 6 +++---
net/ipv4/inet_hashtables.c | 2 +-
net/ipv4/inet_timewait_sock.c | 4 ++--
net/ipv4/syncookies.c | 2 +-
net/ipv4/tcp_fastopen.c | 2 +-
net/ipv6/inet6_hashtables.c | 2 +-
7 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c
index fa20285b841dd..d3e5a2843d5e1 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -7996,7 +7996,7 @@ BPF_CALL_3(bpf_sk_assign, struct sk_buff *, skb, struct sock *, sk, u64, flags)
if (sk_unhashed(sk))
return -EOPNOTSUPP;
if (sk_is_refcounted(sk) &&
- unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
+ unlikely(!refcount_inc_not_zero_acquire(&sk->sk_refcnt)))
return -ENOENT;
skb_orphan(skb);
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 8e891c8141f85..a1fe2531cb590 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -1060,8 +1060,8 @@ static void reqsk_timer_handler(struct timer_list *t)
* hold another count to prevent use-after-free and
* call reqsk_put() just before return.
*/
- refcount_set(&nreq->rsk_refcnt, 2 + 1);
timer_setup(&nreq->rsk_timer, reqsk_timer_handler, TIMER_PINNED);
+ refcount_set_release(&nreq->rsk_refcnt, 2 + 1);
reqsk_queue_migrated(&inet_csk(nsk)->icsk_accept_queue, req);
req = nreq;
@@ -1445,7 +1445,7 @@ struct sock *inet_csk_complete_hashdance(struct sock *sk, struct sock *child,
goto child_put;
}
- refcount_set(&nreq->rsk_refcnt, 1);
+ refcount_set_release(&nreq->rsk_refcnt, 1);
if (inet_csk_reqsk_queue_add(sk, nreq, child)) {
__NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMIGRATEREQSUCCESS);
reqsk_migrate_reset(req);
@@ -1498,7 +1498,7 @@ void inet_csk_listen_stop(struct sock *sk)
if (nsk) {
nreq = inet_reqsk_clone(req, nsk);
if (nreq) {
- refcount_set(&nreq->rsk_refcnt, 1);
+ refcount_set_release(&nreq->rsk_refcnt, 1);
rcu_read_lock();
if (inet_csk_reqsk_queue_add(nsk, nreq, child)) {
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 58d54965036a2..7ffa9171d6de1 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -550,7 +550,7 @@ struct sock *__inet_lookup_established(const struct net *net,
if (sk->sk_hash != hash)
continue;
if (likely(inet_match(net, sk, acookie, ports, dif, sdif))) {
- if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
+ if (unlikely(!refcount_inc_not_zero_acquire(&sk->sk_refcnt)))
goto out;
if (unlikely(hlist_nulls_unhashed_lockless(&sk->sk_nulls_node) ||
!inet_match(net, sk, acookie, ports, dif,
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index d4c781a0667fe..74ff40d42e56b 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -141,7 +141,7 @@ void inet_twsk_hashdance_schedule(struct inet_timewait_sock *tw,
* Also note that after this point, we lost our implicit reference
* so we are not allowed to use tw anymore.
*/
- refcount_set(&tw->tw_refcnt, 3);
+ refcount_set_release(&tw->tw_refcnt, 3);
/* Ensure tw_refcnt has been set before tw is published.
* smp_wmb() provides the necessary memory barrier to enforce this
@@ -328,7 +328,7 @@ void inet_twsk_purge(struct inet_hashinfo *hashinfo)
if (check_net(sock_net(sk)))
continue;
- if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
+ if (unlikely(!refcount_inc_not_zero_acquire(&sk->sk_refcnt)))
continue;
if (check_net(sock_net(sk))) {
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 6440305615378..4b2d2713653b7 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -205,7 +205,7 @@ struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb,
child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst,
NULL, &own_req, NULL);
if (child) {
- refcount_set(&req->rsk_refcnt, 1);
+ refcount_set_release(&req->rsk_refcnt, 1);
sock_rps_save_rxhash(child, skb);
if (rsk_drop_req(req)) {
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index 471c78be55137..e40477b6b5549 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -364,7 +364,7 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk,
tcp_reset_xmit_timer(child, ICSK_TIME_RETRANS,
req->timeout, false);
- refcount_set(&req->rsk_refcnt, 2);
+ refcount_set_release(&req->rsk_refcnt, 2);
sk_mark_napi_id_set(child, skb);
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index aa5fa1dd062f7..1eea584d80df8 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -105,7 +105,7 @@ struct sock *__inet6_lookup_established(const struct net *net,
continue;
if (!inet6_match(net, sk, saddr, daddr, ports, dif, sdif))
continue;
- if (unlikely(!refcount_inc_not_zero(&sk->sk_refcnt)))
+ if (unlikely(!refcount_inc_not_zero_acquire(&sk->sk_refcnt)))
goto out;
if (unlikely(hlist_nulls_unhashed_lockless(&sk->sk_nulls_node) ||
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 288/507] xfs: fix recovery of partial attr removals
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (286 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 287/507] net: restore refcount ordering for lockless socket access Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 289/507] nvmet: reject keep-alive timeouts that would overflow Greg Kroah-Hartman
` (218 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Carlos Maiolino,
Carlos Maiolino, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <hch@lst.de>
[ Upstream commit 30bb61651d2da5a502cf504bcdad16c093c1bb08 ]
When running xfs/753 on parent pointer-enabled file systems with DEBUG
enabled, log recovery will eventually crash after a few dozen iterations
due to an ASSERT that XFS_ATTR_INCOMPLETE is not already set when
xfs_attr3_leaf_setflag is called:
XFS: Assertion failed: (entry->flags & XFS_ATTR_INCOMPLETE) == 0, file: fs/xfs/libxfs/xfs_attr_leaf.c, line: 3045
This is because parent pointer use logged attributes, and the attribute
intents do not track the work that has been done as the transaction
rolls, and the recovery mechanism is to run the operation from scratch.
Because of this various places check for XFS_DA_OP_RECOVERY skip work
already done. But while recovery tolerates an attribute already fully
removed, it currently trips the above assert for an attribute that
already has the INCOMPLETE bit set, but still exists. Fix this by
handling the case like all the others.
Fixes: 1d08e11d04d2 ("xfs: Implement attr logging and replay")
Cc: stable@vger.kernel.org # v5.19
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/libxfs/xfs_attr_leaf.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 02ca50442b466..5b1fd62714205 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -3042,7 +3042,14 @@ xfs_attr3_leaf_setflag(
#endif
entry = &xfs_attr3_leaf_entryp(leaf)[args->index];
- ASSERT((entry->flags & XFS_ATTR_INCOMPLETE) == 0);
+ if (entry->flags & XFS_ATTR_INCOMPLETE) {
+ if (!(args->op_flags & XFS_DA_OP_RECOVERY)) {
+ ASSERT(args->op_flags & XFS_DA_OP_RECOVERY);
+ return -EFSCORRUPTED;
+ }
+ return 0;
+ }
+
entry->flags |= XFS_ATTR_INCOMPLETE;
xfs_trans_log_buf(args->trans, bp,
XFS_DA_LOGRANGE(leaf, entry, sizeof(*entry)));
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 289/507] nvmet: reject keep-alive timeouts that would overflow
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (287 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 288/507] xfs: fix recovery of partial attr removals Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 290/507] can: dev: can_dropped_invalid_skb: drop CAN XL frames on non-CAN XL devices Greg Kroah-Hartman
` (217 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Yingjie Wang,
Keith Busch, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yingjie Wang <1075151112@qq.com>
[ Upstream commit 96ae13f40ce5930cd58c43128e385131476f2a66 ]
nvmet_set_feat_kato() and nvmet_alloc_ctrl() convert the 32-bit
millisecond KATO from the host to seconds with DIV_ROUND_UP(kato, 1000).
The addition in DIV_ROUND_UP() is done in 32 bits, so any KATO above
4294966296 ms wraps around and rounds to 0 seconds. A Set Features
command with KATO 0xffffffff then succeeds but disables the keep-alive
timer: Get Features returns 0 and Keep Alive fails with Keep Alive
Timeout Invalid. A Connect command with such a KATO creates a controller
without a keep-alive timer.
The converted value has more consumers that can overflow. Get Features
multiplies it by 1000, and the timer paths multiply it by HZ in 32 bits
and arm a delay that must not exceed MAX_JIFFY_OFFSET.
Reject a KATO whose rounded value does not fit all of these. Return Keep
Alive Timeout Invalid from both Set Features and Connect. Validate Set
Features before stopping the current timer so a failed update leaves its
timeout unchanged. Round in 64 bits. A KATO of 0 keeps its current
meaning.
Fixes: a07b4970f464 ("nvmet: add a generic NVMe target")
Cc: stable@vger.kernel.org
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Yingjie Wang <1075151112@qq.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/target/admin-cmd.c | 7 ++++++-
drivers/nvme/target/core.c | 8 +++++++-
drivers/nvme/target/nvmet.h | 8 ++++++++
3 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index 7764a3c0195c9..e76d4f7453004 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -1225,8 +1225,13 @@ u16 nvmet_set_feat_kato(struct nvmet_req *req)
{
u32 val32 = le32_to_cpu(req->cmd->common.cdw11);
+ if (val32 > NVMET_MAX_KATO * MSEC_PER_SEC) {
+ req->error_loc = offsetof(struct nvme_common_command, cdw11);
+ return NVME_SC_KA_TIMEOUT_INVALID | NVME_STATUS_DNR;
+ }
+
nvmet_stop_keep_alive_timer(req->sq->ctrl);
- req->sq->ctrl->kato = DIV_ROUND_UP(val32, 1000);
+ req->sq->ctrl->kato = DIV_ROUND_UP_ULL(val32, MSEC_PER_SEC);
nvmet_start_keep_alive_timer(req->sq->ctrl);
nvmet_set_result(req, req->sq->ctrl->kato);
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 07a74c2e1f587..0f5e94bf12bdf 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -1612,6 +1612,12 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args)
u8 dhchap_status;
int ret;
+ if (kato > NVMET_MAX_KATO * MSEC_PER_SEC) {
+ args->status = NVME_SC_KA_TIMEOUT_INVALID | NVME_STATUS_DNR;
+ args->error_loc = offsetof(struct nvmf_connect_command, kato);
+ return NULL;
+ }
+
args->status = NVME_SC_CONNECT_INVALID_PARAM | NVME_STATUS_DNR;
subsys = nvmet_find_get_subsys(args->port, args->subsysnqn);
if (!subsys) {
@@ -1678,7 +1684,7 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args)
kato = NVMET_DISC_KATO_MS;
/* keep-alive timeout in seconds */
- ctrl->kato = DIV_ROUND_UP(kato, 1000);
+ ctrl->kato = DIV_ROUND_UP_ULL(kato, MSEC_PER_SEC);
ctrl->err_counter = 0;
spin_lock_init(&ctrl->error_lock);
diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
index 2032db380f99e..215315ebe42de 100644
--- a/drivers/nvme/target/nvmet.h
+++ b/drivers/nvme/target/nvmet.h
@@ -7,6 +7,7 @@
#define _NVMET_H
#include <linux/dma-mapping.h>
+#include <linux/jiffies.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/kref.h>
@@ -702,6 +703,13 @@ void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
#define NVMET_KAS 10
#define NVMET_DISC_KATO_MS 120000
+/*
+ * Largest keep-alive timeout in seconds that can be reported back in
+ * milliseconds and converted to jiffies without overflowing.
+ */
+#define NVMET_MAX_KATO \
+ min3(U32_MAX / MSEC_PER_SEC, U32_MAX / HZ, MAX_JIFFY_OFFSET / HZ)
+
int __init nvmet_init_configfs(void);
void __exit nvmet_exit_configfs(void);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 290/507] can: dev: can_dropped_invalid_skb: drop CAN XL frames on non-CAN XL devices
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (288 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 289/507] nvmet: reject keep-alive timeouts that would overflow Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 291/507] can: isotp: check the frame type, not just the length Greg Kroah-Hartman
` (216 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Mailhol, stable,
Marc Kleine-Budde, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Mailhol <mailhol@kernel.org>
[ Upstream commit 0fce44e29fce4b07642491b098afb41bd571e4f2 ]
Sending a PF_PACKET bypasses the CAN framework logic and can directly
reach a CAN driver's xmit() function. The PF_PACKET framework only
checks that skb->len does not exceed the net_device MTU.
For a CAN device that is not CAN XL capable, anything above CANFD_MTU
(72 bytes) is therefore dropped before it reaches the driver. However,
CAN XL frames are variable length. can_is_canxl_skb() accepts lengths in
the range CANXL_HDR_SIZE + CANXL_MIN_DLEN up to CANXL_MTU, i.e. 13 to
2060 bytes.
As a result, an ETH_P_CANXL skb with a length between 13 and 72 bytes
can pass both the MTU and the can_dropped_invalid_skb() checks.
A driver that does not support CAN XL will interpret canxl_frame->flags
as a length because of the overlap with can_frame->len. And because
CANXL_XLF is set, the resulting length is between 128 and 255. For
drivers that do not check can_frame->len before copying can_frame->data,
as most drivers do, this results in a buffer overflow of up to 247
bytes.
Drop ETH_P_CANXL skbs if the device does not have the CAN_CAP_XL
capability. Keep can_is_canxl_skb() for the validation of CAN XL skbs.
Closes: https://sashiko.dev/#/patchset/20260731-master-v5-0-5b27029dee20@qq.com?part=1
Fixes: fb08cba12b52 ("can: canxl: update CAN infrastructure for CAN XL frames")
Signed-off-by: Vincent Mailhol <mailhol@kernel.org>
Link: https://patch.msgid.link/20260731-drop_canxl_frames-v1-1-7387b70353b3@kernel.org
Cc: stable@kernel.org
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/can/dev/skb.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
index 14edec5afb57e..bc0787535b524 100644
--- a/drivers/net/can/dev/skb.c
+++ b/drivers/net/can/dev/skb.c
@@ -4,6 +4,7 @@
* Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
*/
+#include <linux/can/can-ml.h>
#include <linux/can/dev.h>
#include <linux/module.h>
#include <net/can.h>
@@ -388,7 +389,7 @@ bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb)
break;
case ETH_P_CANXL:
- if (!can_is_canxl_skb(skb))
+ if (!can_cap_enabled(dev, CAN_CAP_XL) || !can_is_canxl_skb(skb))
goto inval_skb;
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 291/507] can: isotp: check the frame type, not just the length
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (289 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 290/507] can: dev: can_dropped_invalid_skb: drop CAN XL frames on non-CAN XL devices Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 292/507] can: skb: make echo skb freeing safe in any IRQ context Greg Kroah-Hartman
` (215 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kaixuan Li, Oliver Hartkopp,
Quchaosheng, Marc Kleine-Budde, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kaixuan Li <kaixuanli0131@gmail.com>
[ Upstream commit 933bf0fcb325e67b19c86c9c4da7f029878d5170 ]
isotp_rcv() separates Classic CAN from CAN FD by skb->len alone:
if (skb->len != so->ll.mtu)
return;
cf = (struct canfd_frame *)skb->data;
A CAN XL frame with cxl->len 4 is CAN_MTU bytes, so it passes, and is then
read as a canfd_frame whose len comes out of canxl_frame.flags: at least
0x80.
Of the paths that follow, only the flow control one uses that length
without bounding it first, so check_pad() walks to 255 over a 16-byte
frame and the caller reports EBADMSG on an unrelated socket.
bcm_rx_handler(), j1939_can_recv(), can_can_gw_rcv() and raw_rcv() check
the frame type here, and can_dropped_invalid_skb() switches on
skb->protocol on the transmit side. isotp_rcv() is the gap.
Fixes: fb08cba12b52 ("can: canxl: update CAN infrastructure for CAN XL frames")
Signed-off-by: Kaixuan Li <kaixuanli0131@gmail.com>
Reviewed-by: Oliver Hartkopp <socketcan@hartkopp.net>
Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
Reviewed-by: Quchaosheng <quchaosheng000406@163.com>
Link: https://patch.msgid.link/20260920035626.2581040-1-kaixuanli0131@gmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/can/isotp.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/net/can/isotp.c b/net/can/isotp.c
index f5dc9d04bd686..d3e43ab484258 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -755,6 +755,14 @@ static void isotp_rcv(struct sk_buff *skb, void *data)
if (skb->len != so->ll.mtu)
return;
+ /* check for correct CAN CC/FD frame content */
+ if (so->ll.mtu == CAN_MTU) {
+ if (!can_is_can_skb(skb))
+ return;
+ } else if (!can_is_canfd_skb(skb)) {
+ return;
+ }
+
cf = (struct canfd_frame *)skb->data;
/* if enabled: check reception of my configured extended address */
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 292/507] can: skb: make echo skb freeing safe in any IRQ context
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (290 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 291/507] can: isotp: check the frame type, not just the length Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 293/507] can: dev: can_put_echo_skb(): free skb on invalid echo index Greg Kroah-Hartman
` (214 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cunhao Lu, stable, Marc Kleine-Budde,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cunhao Lu <1579567540@qq.com>
[ Upstream commit d743071964920c92af598c87a9e6f4369263ee09 ]
can_put_echo_skb() can be called with hardware interrupts disabled. Its
direct drop paths use kfree_skb(), while can_create_echo_skb() uses
kfree_skb() when cloning fails and consume_skb() after a successful clone.
None of these helpers is safe in every IRQ context.
Use dev_kfree_skb_any() for all drop paths and dev_consume_skb_any() when
consuming a successfully cloned skb. This preserves the respective skb drop
and consumed semantics regardless of the caller IRQ context.
Signed-off-by: Cunhao Lu <1579567540@qq.com>
Link: https://patch.msgid.link/tencent_E84809CF236D0137885E7E4E4D58340B3208@qq.com
Cc: stable@kernel.org
Fixes: ae64438be192 ("can: dev: fix skb drop check")
Fixes: 0ae89beb283a ("can: add destructor for self generated skbs")
Fixes: 3ccd4c6167d3 ("can: Unify droping of invalid tx skbs and netdev stats")
Fixes: 39549eef3587 ("can: CAN Network device driver and Netlink interface")
[mkl: also convert can_dropped_invalid_skb(), can_dev_dropped_skb()]
[mkl: add stable on Cc + add Fixes tags]
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
FAQ:
Q: What about the comment in drivers/net/can/virtio_can.c
virtio_can_start_xmit()? The error handling for virtqueue_add_sgs()
mentions that can_put_echo_skb() consumes the skb via consume_skb().
A: The comment in virtio_can.c will be updated in a separate series, to
ease backporting of this patch.
[mkl: add FAQ section]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/can/dev/skb.c | 6 +++---
include/linux/can/dev.h | 2 +-
include/linux/can/skb.h | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
index bc0787535b524..46c151eece8f7 100644
--- a/drivers/net/can/dev/skb.c
+++ b/drivers/net/can/dev/skb.c
@@ -63,7 +63,7 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
(skb->protocol != htons(ETH_P_CAN) &&
skb->protocol != htons(ETH_P_CANFD) &&
skb->protocol != htons(ETH_P_CANXL))) {
- kfree_skb(skb);
+ dev_kfree_skb_any(skb);
return 0;
}
@@ -91,7 +91,7 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
} else {
/* locking problem with netif_stop_queue() ?? */
netdev_err(dev, "%s: BUG! echo_skb %d is occupied!\n", __func__, idx);
- kfree_skb(skb);
+ dev_kfree_skb_any(skb);
return -EBUSY;
}
@@ -403,7 +403,7 @@ bool can_dropped_invalid_skb(struct net_device *dev, struct sk_buff *skb)
return false;
inval_skb:
- kfree_skb(skb);
+ dev_kfree_skb_any(skb);
dev->stats.tx_dropped++;
return true;
}
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 6d0710d6f571d..346faddee02eb 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -176,7 +176,7 @@ static inline bool can_dev_dropped_skb(struct net_device *dev, struct sk_buff *s
return can_dropped_invalid_skb(dev, skb);
invalid_skb:
- kfree_skb(skb);
+ dev_kfree_skb_any(skb);
dev->stats.tx_dropped++;
return true;
}
diff --git a/include/linux/can/skb.h b/include/linux/can/skb.h
index 5d27843862fca..87ace09c0d8bd 100644
--- a/include/linux/can/skb.h
+++ b/include/linux/can/skb.h
@@ -78,12 +78,12 @@ static inline struct sk_buff *can_create_echo_skb(struct sk_buff *skb)
nskb = skb_clone(skb, GFP_ATOMIC);
if (unlikely(!nskb)) {
- kfree_skb(skb);
+ dev_kfree_skb_any(skb);
return NULL;
}
can_skb_set_owner(nskb, skb->sk);
- consume_skb(skb);
+ dev_consume_skb_any(skb);
return nskb;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 293/507] can: dev: can_put_echo_skb(): free skb on invalid echo index
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (291 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 292/507] can: skb: make echo skb freeing safe in any IRQ context Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 294/507] can: replace ARPHRD_CAN type checks with can_get_ml_priv() Greg Kroah-Hartman
` (213 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Mailhol, Cunhao Lu,
Marc Kleine-Budde, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cunhao Lu <1579567540@qq.com>
[ Upstream commit b4ebcbbf66ba6c5816dfe229effb4641c46e4b4c ]
can_put_echo_skb() consumes the skb on all paths except when the echo
index is out of bounds. This leaves ownership with the caller on -EINVAL,
unlike the other error paths, and can leak the skb if the caller expects
consistent semantics.
Free the skb before returning -EINVAL so that all return paths consume it.
Fixes: 6411959c10fe ("can: dev: can_put_echo_skb(): don't crash kernel if can_priv::echo_skb is accessed out of bounds")
Cc: stable@vger.kernel.org
Reviewed-by: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Cunhao Lu <1579567540@qq.com>
Link: https://patch.msgid.link/tencent_683AA16E643DE00211CD2FB62991264DC605@qq.com
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
FAQ:
Q: `can_skb_init_valid()` directly modifies `skb->data` without checking if
the SKB is cloned or shared. Is this violating SKB shared buffer rules and
causing data corruption?
A: The finding about can_skb_init_valid() modifying skb->data on a
potentially shared buffer is not relevant for this (correct) patch.
The FDF-flag write in can_skb_init_valid() only matters for PF_PACKET
use: PF_CAN allocators already set CANFD_FDF. The write exists to
normalize frames for PF_PACKET observers (tcpdump/Wireshark) so they can
distinguish classic CAN from CAN FD at the netdev level, and to
compensate for PF_PACKET senders that omit the bit. That normalization
is functionally required.
The shared-buffer concern only becomes realistic through a specific
chain: a PF_PACKET sender injects a CANFD-sized frame, the CAN driver's
loopback puts an echo skb back into can_rcv(), and cgw (without
modfuncs) clones it for forwarding to another interface. Only on that
second can_skb_init_valid() call is the skb cloned. By then the bit was
already set on the exclusive skb during the initial xmit path, so the
flags |= CANFD_FDF write is strictly idempotent for any parallel
consumer of the shared buffer - no memory-safety or
information-disclosure consequence. It's a formal violation of the skb
sharing rules without an observable effect, so the current code can stay
as-is.
Link: https://lore.kernel.org/all/54a3cc01-abcf-4a33-b932-39bb1f68cdd5@hartkopp.net/
[mkl: convert Oliver's mail to FAQ section]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/can/dev/skb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/can/dev/skb.c b/drivers/net/can/dev/skb.c
index 46c151eece8f7..9e274147ffe56 100644
--- a/drivers/net/can/dev/skb.c
+++ b/drivers/net/can/dev/skb.c
@@ -55,6 +55,7 @@ int can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
if (idx >= priv->echo_skb_max) {
netdev_err(dev, "%s: BUG! Trying to access can_priv::echo_skb out of bounds (%u/max %u)\n",
__func__, idx, priv->echo_skb_max);
+ dev_kfree_skb_any(skb);
return -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 294/507] can: replace ARPHRD_CAN type checks with can_get_ml_priv()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (292 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 293/507] can: dev: can_put_echo_skb(): free skb on invalid echo index Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 295/507] can: isotp: check the return values of can_rx_register() in isotp_bind() Greg Kroah-Hartman
` (212 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oleksij Rempel, Oliver Hartkopp,
Marc Kleine-Budde, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <socketcan@hartkopp.net>
[ Upstream commit 962947b69589881167054bae5accc8abfd5aa4b6 ]
Commit 4e096a18867a ("net: introduce CAN specific pointer in the struct
net_device") introduced an explicit way to assign the midlayer private
pointer (dev->ml_priv) to named users like ML_PRIV_CAN. A valid pointer
returned by can_get_ml_priv() therefore identifies a real CAN device.
The referenced commit only converted the j1939 and proc code to this
check, while the other parts of the CAN subsystem still rely on
dev->type == ARPHRD_CAN.
The TUNSETLINK ioctl allows a down TUN/TAP device to set its hardware
type to ARPHRD_CAN while dev->ml_priv remains NULL. Such a repurposed
netdevice passes the ARPHRD_CAN checks.
Commit 8aa59e355949 ("can: af_can: fix NULL pointer dereference in
can_rx_register()") already made can_rx_register() reject such devices.
But can_rx_unregister() still only checks dev->type and dereferences
the NULL ml_priv when it walks the receive lists of the device.
CAN_ISOTP reaches this path: isotp_bind() ignores the return values of
can_rx_register() and binds the socket anyway. When the socket is
released or the device is unregistered, isotp_release() and
isotp_notify() remove the filters that have never been registered and
trigger the NULL pointer dereference in can_rx_unregister(). This only
requires owning a TUN/TAP device or CAP_NET_ADMIN in an unprivileged
user namespace.
Convert the remaining ARPHRD_CAN checks in af_can, bcm, gw, isotp and
raw to can_get_ml_priv().
Fixes: 4e096a18867a ("net: introduce CAN specific pointer in the struct net_device")
Cc: stable@vger.kernel.org
Cc: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://patch.msgid.link/20261027-can-rx-lock-v12-1-eb5afc2d8b9b@hartkopp.net
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/can/af_can.c | 15 ++++++---------
net/can/bcm.c | 7 ++++---
net/can/gw.c | 7 ++++---
net/can/isotp.c | 5 +++--
net/can/raw.c | 4 ++--
5 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 34fe3b28d576f..dc27ace43719d 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -226,7 +226,7 @@ int can_send(struct sk_buff *skb, int loop)
goto inval_skb;
}
- if (unlikely(skb->dev->type != ARPHRD_CAN)) {
+ if (unlikely(!can_get_ml_priv(skb->dev))) {
err = -EPERM;
goto inval_skb;
}
@@ -452,7 +452,7 @@ int can_rx_register(struct net *net, struct net_device *dev, canid_t can_id,
/* insert new receiver (dev,canid,mask) -> (func,data) */
- if (dev && (dev->type != ARPHRD_CAN || !can_get_ml_priv(dev)))
+ if (dev && !can_get_ml_priv(dev))
return -ENODEV;
if (dev && !net_eq(net, dev_net(dev)))
@@ -519,7 +519,7 @@ void can_rx_unregister(struct net *net, struct net_device *dev, canid_t can_id,
struct can_rcv_lists_stats *rcv_lists_stats = net->can.rcv_lists_stats;
struct can_dev_rcv_lists *dev_rcv_lists;
- if (dev && dev->type != ARPHRD_CAN)
+ if (dev && !can_get_ml_priv(dev))
return;
if (dev && !net_eq(net, dev_net(dev)))
@@ -684,8 +684,7 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
{
struct can_skb_ext *csx = can_skb_ext_find(skb);
- if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) ||
- !csx || !can_is_can_skb(skb))) {
+ if (unlikely(!can_get_ml_priv(dev) || !csx || !can_is_can_skb(skb))) {
pr_warn_once("PF_CAN: dropped non conform CAN skbuff: dev type %d, len %d\n",
dev->type, skb->len);
@@ -710,8 +709,7 @@ static int canfd_rcv(struct sk_buff *skb, struct net_device *dev,
{
struct can_skb_ext *csx = can_skb_ext_find(skb);
- if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) ||
- !csx || !can_is_canfd_skb(skb))) {
+ if (unlikely(!can_get_ml_priv(dev) || !csx || !can_is_canfd_skb(skb))) {
pr_warn_once("PF_CAN: dropped non conform CAN FD skbuff: dev type %d, len %d\n",
dev->type, skb->len);
@@ -736,8 +734,7 @@ static int canxl_rcv(struct sk_buff *skb, struct net_device *dev,
{
struct can_skb_ext *csx = can_skb_ext_find(skb);
- if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) ||
- !csx || !can_is_canxl_skb(skb))) {
+ if (unlikely(!can_get_ml_priv(dev) || !csx || !can_is_canxl_skb(skb))) {
pr_warn_once("PF_CAN: dropped non conform CAN XL skbuff: dev type %d, len %d\n",
dev->type, skb->len);
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 3d637a1e0ac1a..60406439a13f7 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -54,6 +54,7 @@
#include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <linux/can.h>
+#include <linux/can/can-ml.h>
#include <linux/can/core.h>
#include <linux/can/skb.h>
#include <linux/can/bcm.h>
@@ -1719,7 +1720,7 @@ static int bcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
goto out_release;
}
- if (dev->type != ARPHRD_CAN) {
+ if (!can_get_ml_priv(dev)) {
dev_put(dev);
ret = -ENODEV;
goto out_release;
@@ -1867,7 +1868,7 @@ static int bcm_notifier(struct notifier_block *nb, unsigned long msg,
{
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
- if (dev->type != ARPHRD_CAN)
+ if (!can_get_ml_priv(dev))
return NOTIFY_DONE;
if (msg != NETDEV_UNREGISTER && msg != NETDEV_DOWN)
return NOTIFY_DONE;
@@ -2024,7 +2025,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr_unsized *uaddr, int
ret = -ENODEV;
goto fail;
}
- if (dev->type != ARPHRD_CAN) {
+ if (!can_get_ml_priv(dev)) {
dev_put(dev);
ret = -ENODEV;
goto fail;
diff --git a/net/can/gw.c b/net/can/gw.c
index 5793cb2420ed3..54bb5bd3242af 100644
--- a/net/can/gw.c
+++ b/net/can/gw.c
@@ -52,6 +52,7 @@
#include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <linux/can.h>
+#include <linux/can/can-ml.h>
#include <linux/can/core.h>
#include <linux/can/skb.h>
#include <linux/can/gw.h>
@@ -612,7 +613,7 @@ static int cgw_notifier(struct notifier_block *nb,
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
struct net *net = dev_net(dev);
- if (dev->type != ARPHRD_CAN)
+ if (!can_get_ml_priv(dev))
return NOTIFY_DONE;
if (msg == NETDEV_UNREGISTER) {
@@ -1163,7 +1164,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh,
if (!gwj->src.dev)
goto out;
- if (gwj->src.dev->type != ARPHRD_CAN)
+ if (!can_get_ml_priv(gwj->src.dev))
goto out;
gwj->dst.dev = __dev_get_by_index(net, gwj->ccgw.dst_idx);
@@ -1171,7 +1172,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh,
if (!gwj->dst.dev)
goto out;
- if (gwj->dst.dev->type != ARPHRD_CAN)
+ if (!can_get_ml_priv(gwj->dst.dev))
goto out;
/* is sending the skb back to the incoming interface intended? */
diff --git a/net/can/isotp.c b/net/can/isotp.c
index d3e43ab484258..e4957855829e6 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -65,6 +65,7 @@
#include <linux/if_arp.h>
#include <linux/skbuff.h>
#include <linux/can.h>
+#include <linux/can/can-ml.h>
#include <linux/can/core.h>
#include <linux/can/skb.h>
#include <linux/can/isotp.h>
@@ -1618,7 +1619,7 @@ static int isotp_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int l
err = -ENODEV;
goto out;
}
- if (dev->type != ARPHRD_CAN) {
+ if (!can_get_ml_priv(dev)) {
err = -ENODEV;
goto out_put_dev;
}
@@ -1905,7 +1906,7 @@ static int isotp_notifier(struct notifier_block *nb, unsigned long msg,
{
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
- if (dev->type != ARPHRD_CAN)
+ if (!can_get_ml_priv(dev))
return NOTIFY_DONE;
if (msg != NETDEV_UNREGISTER && msg != NETDEV_DOWN)
return NOTIFY_DONE;
diff --git a/net/can/raw.c b/net/can/raw.c
index 0acd4f6c6dd67..e1d741a25be3f 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -348,7 +348,7 @@ static int raw_notifier(struct notifier_block *nb, unsigned long msg,
{
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
- if (dev->type != ARPHRD_CAN)
+ if (!can_get_ml_priv(dev))
return NOTIFY_DONE;
if (msg != NETDEV_UNREGISTER && msg != NETDEV_DOWN)
return NOTIFY_DONE;
@@ -491,7 +491,7 @@ static int raw_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int len
err = -ENODEV;
goto out;
}
- if (dev->type != ARPHRD_CAN) {
+ if (!can_get_ml_priv(dev)) {
err = -ENODEV;
goto out_put_dev;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 295/507] can: isotp: check the return values of can_rx_register() in isotp_bind()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (293 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 294/507] can: replace ARPHRD_CAN type checks with can_get_ml_priv() Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 296/507] can: protect the receive lists with a per-device lock Greg Kroah-Hartman
` (211 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oliver Hartkopp, Marc Kleine-Budde,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <socketcan@hartkopp.net>
[ Upstream commit 874f5f14cf626f72477071eff381c8485554250d ]
isotp_bind() ignores the return values of can_rx_register() for the RX
and the echo receiver and binds the socket anyway. When a receiver can
not be allocated, bind() succeeds without this receiver, so the socket
does not receive frames or its transmissions time out. isotp_release()
and isotp_notify() later try to remove the missing receiver, which
triggers the "receive list entry not found" warning in
can_rx_unregister().
As the device has been checked before and RTNL prevents a namespace
change during bind(), only -ENOMEM can be returned here.
Check the return values and register the RX receiver as the last step.
The echo receiver is registered first, as it only handles the socket's
own echo frames and does nothing while no transmission is in progress.
So a failed RX registration only needs to remove the echo receiver, and
isotp_rcv() has never processed a frame for this socket.
Set so->ifindex before the registrations, so that a First Frame received
before so->bound is set can be answered with a Flow Control frame and
the RX timeout is started as usual. As the RX receiver is registered
last, this can only happen for a bind() that succeeds. Reset so->ifindex
when bind() fails.
Check IFF_UP only after the receivers have been registered, so that a
bind() that fails on a down device does not report ENETDOWN. As bind()
holds RTNL, the device state can not change in between.
Fixes: e057dd3fc20f ("can: add ISO 15765-2:2016 transport protocol")
Cc: stable@vger.kernel.org
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://patch.msgid.link/20261027-can-rx-lock-v12-2-eb5afc2d8b9b@hartkopp.net
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/can/isotp.c | 42 +++++++++++++++++++++++++++---------------
1 file changed, 27 insertions(+), 15 deletions(-)
diff --git a/net/can/isotp.c b/net/can/isotp.c
index e4957855829e6..28e9d22772fa3 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -1550,7 +1550,6 @@ static int isotp_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int l
struct sock *sk = sock->sk;
struct isotp_sock *so = isotp_sk(sk);
struct net *net = sock_net(sk);
- int ifindex;
struct net_device *dev;
canid_t tx_id = addr->can_addr.tp.tx_id;
canid_t rx_id = addr->can_addr.tp.rx_id;
@@ -1627,26 +1626,36 @@ static int isotp_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int l
err = -EINVAL;
goto out_put_dev;
}
- if (!(dev->flags & IFF_UP))
- notify_enetdown = 1;
- ifindex = dev->ifindex;
-
- if (isotp_register_rxid(so))
- can_rx_register(net, dev, rx_id, SINGLE_MASK(rx_id),
- isotp_rcv, sk, "isotp", sk);
+ /* switch to new settings */
+ so->ifindex = dev->ifindex;
+ so->rxid = rx_id;
+ so->txid = tx_id;
/* no consecutive frame echo skb in flight */
WRITE_ONCE(so->cfecho, 0);
- /* register for echo skb's */
- can_rx_register(net, dev, tx_id, SINGLE_MASK(tx_id),
- isotp_rcv_echo, sk, "isotpe", sk);
+ /* register for echo skb's first (no echo traffic at this point) */
+ err = can_rx_register(net, dev, tx_id, SINGLE_MASK(tx_id),
+ isotp_rcv_echo, sk, "isotpe", sk);
+ if (err)
+ goto out_put_dev;
+
+ if (isotp_register_rxid(so)) {
+ err = can_rx_register(net, dev, rx_id, SINGLE_MASK(rx_id),
+ isotp_rcv, sk, "isotp", sk);
+ if (err) {
+ /* unregister echo skb subscription */
+ can_rx_unregister(net, dev, tx_id, SINGLE_MASK(tx_id),
+ isotp_rcv_echo, sk);
+ goto out_put_dev;
+ }
+ }
+
+ /* report a down device only for a successful bind() */
+ if (!(dev->flags & IFF_UP))
+ notify_enetdown = 1;
- /* switch to new settings */
- so->ifindex = ifindex;
- so->rxid = rx_id;
- so->txid = tx_id;
so->bound = 1;
/* bind() ok -> hold a reference for so->dev so that isotp_release()
@@ -1657,6 +1666,9 @@ static int isotp_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int l
netdev_hold(so->dev, &so->dev_tracker, GFP_KERNEL);
out_put_dev:
+ if (err)
+ so->ifindex = 0; /* reset on failed bind() */
+
/* remove potential reference from dev_get_by_index() */
dev_put(dev);
out:
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 296/507] can: protect the receive lists with a per-device lock
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (294 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 7.3 295/507] can: isotp: check the return values of can_rx_register() in isotp_bind() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 297/507] can: raw, isotp: copy socket options outside of lock_sock() Greg Kroah-Hartman
` (210 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Oliver Hartkopp,
Marc Kleine-Budde, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <socketcan@hartkopp.net>
[ Upstream commit 0f3ad9ab40e3dad06d5c0693806e07935ceedbc3 ]
The receive lists of a CAN device are located in the device's
can_ml_priv and travel with the device when it is moved to another
network namespace. But they are protected by the per-netns
rcvlists_lock. So can_rx_unregister() needs dev_net(dev) to pick the
right lock and silently returns when the passed namespace does not
match dev_net(dev) anymore.
isotp_release() and bcm_release() leave their notifier list before they
take any lock that serializes against the netdev notifier, which runs
under RTNL. When the bound device is moved to another namespace in this
window, the notifier skips the socket and the release path has to remove
the filters itself. isotp_release() passes the socket's namespace, which
does not match dev_net(dev) anymore. bcm_rx_unreg() passes dev_net(dev),
which can_rx_unregister() reads again for its check, so a namespace
change between both reads makes the check fail as well. In both cases
can_rx_unregister() silently returns. As can_rx_register() stores
rcv->sk without a reference, the remaining receivers point to the freed
socket (isotp) or the freed op (bcm):
BUG: KASAN: use-after-free in isotp_rcv+0x1570/0x24d0
Read of size 1 at addr ffff888118130552 by task isotp_ns_uaf/578
can_rcv_filter+0x4af/0x8c0
can_receive+0x28d/0x3c0
can_rcv+0x2a9/0x310
__netif_receive_skb_one_core+0x21a/0x260
process_backlog+0x210/0x760
Besides this, the lists of a device are protected by the rcvlists_lock
of the namespace that is passed in. Callers which pass dev_net(dev) read
it at different times, so the same lists may be modified under the locks
of different namespaces while the device is moved.
Taking RTNL in these release paths is no option: raw_bind(),
raw_setsockopt() and raw_release() already hold RTNL while adding and
removing up to CAN_RAW_FILTER_MAX filters per socket, which unprivileged
users can trigger repeatedly and which makes RTNL a global bottleneck.
Instead fix the root cause and add a spinlock to struct
can_dev_rcv_lists, which protects the receive lists of a CAN device or
the 'any' CAN device lists of a namespace. It is initialized in
can_set_ml_priv(), which is used by all CAN network devices. With this,
can_rx_unregister() finds the subscription independently of the
current namespace of the device. The protocols keep the device valid
with their tracked references. The per-netns rcvlists_lock only protects
the receive list statistics anymore, and CAN_RAW, CAN_BCM and CAN_ISOTP
pass the namespace that has been used for can_rx_register().
So isotp_release() and bcm_release() now remove their filters correctly
without RTNL, and raw_release(), raw_setsockopt(), raw_bind() and
isotp_bind() do not need RTNL anymore and add and remove their filters
under lock_sock(). To serialize bind() with NETDEV_UNREGISTER, bind()
publishes the device inside the RCU section of its lookup, and
raw_notify() and isotp_notify() recheck the bound device under lock_sock().
As RTNL does not keep NETDEV_DOWN out of bind() anymore, bind() checks
IFF_UP after publishing the bound device, with a barrier pair against
raw_notify() and isotp_notify(), so a down transition during bind() is
still reported with ENETDOWN.
Fixes: 20bab8b88baa ("can: isotp: fix use-after-free race with concurrent NETDEV_UNREGISTER")
Fixes: 8e8cda6d737d ("can: initial support for network namespaces")
Reported-by: Norbert Szetei <norbert@doyensec.com>
Link: https://lore.kernel.org/linux-can/CEA6A38A-2646-4ADA-95B4-CBAE2F301A8E@doyensec.com/
Cc: stable@vger.kernel.org
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://patch.msgid.link/20261027-can-rx-lock-v12-3-eb5afc2d8b9b@hartkopp.net
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/can/can-ml.h | 3 ++
include/net/netns/can.h | 2 +-
net/can/af_can.c | 39 +++++++++++------
net/can/bcm.c | 43 +++++-------------
net/can/isotp.c | 89 +++++++++++++++++++++++---------------
net/can/raw.c | 88 +++++++++++++++++++++++++++----------
6 files changed, 160 insertions(+), 104 deletions(-)
diff --git a/include/linux/can/can-ml.h b/include/linux/can/can-ml.h
index 1e99fda2b3803..cfefa4a385be9 100644
--- a/include/linux/can/can-ml.h
+++ b/include/linux/can/can-ml.h
@@ -45,6 +45,7 @@
#include <linux/can.h>
#include <linux/list.h>
#include <linux/netdevice.h>
+#include <linux/spinlock.h>
/* exposed CAN device capabilities for network layer */
#define CAN_CAP_CC BIT(0) /* CAN CC aka Classical CAN */
@@ -59,6 +60,7 @@
enum { RX_ERR, RX_ALL, RX_FIL, RX_INV, RX_MAX };
struct can_dev_rcv_lists {
+ spinlock_t lock; /* protects the receive lists and entries */
struct hlist_head rx[RX_MAX];
struct hlist_head rx_sff[CAN_SFF_RCV_ARRAY_SZ];
struct hlist_head rx_eff[CAN_EFF_RCV_ARRAY_SZ];
@@ -81,6 +83,7 @@ static inline struct can_ml_priv *can_get_ml_priv(struct net_device *dev)
static inline void can_set_ml_priv(struct net_device *dev,
struct can_ml_priv *ml_priv)
{
+ spin_lock_init(&ml_priv->dev_rcv_lists.lock);
netdev_set_ml_priv(dev, ml_priv, ML_PRIV_CAN);
}
diff --git a/include/net/netns/can.h b/include/net/netns/can.h
index 48b79f7e6236d..54f23681e0d45 100644
--- a/include/net/netns/can.h
+++ b/include/net/netns/can.h
@@ -29,7 +29,7 @@ struct netns_can {
/* receive filters subscribed for 'all' CAN devices */
struct can_dev_rcv_lists *rx_alldev_list;
- spinlock_t rcvlists_lock;
+ spinlock_t rcvlists_lock; /* protects the rcv_entries(_max) stats */
struct timer_list stattimer; /* timer for statistics update */
struct can_pkg_stats *pkg_stats;
struct can_rcv_lists_stats *rcv_lists_stats;
diff --git a/net/can/af_can.c b/net/can/af_can.c
index dc27ace43719d..167b2dc40eebc 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -462,9 +462,10 @@ int can_rx_register(struct net *net, struct net_device *dev, canid_t can_id,
if (!rcv)
return -ENOMEM;
- spin_lock_bh(&net->can.rcvlists_lock);
-
dev_rcv_lists = can_dev_rcv_lists_find(net, dev);
+
+ spin_lock_bh(&dev_rcv_lists->lock);
+
rcv_list = can_rcv_list_find(&can_id, &mask, dev_rcv_lists);
rcv->can_id = can_id;
@@ -478,6 +479,9 @@ int can_rx_register(struct net *net, struct net_device *dev, canid_t can_id,
hlist_add_head_rcu(&rcv->list, rcv_list);
dev_rcv_lists->entries++;
+ spin_unlock_bh(&dev_rcv_lists->lock);
+
+ spin_lock_bh(&net->can.rcvlists_lock);
rcv_lists_stats->rcv_entries++;
rcv_lists_stats->rcv_entries_max = max(rcv_lists_stats->rcv_entries_max,
rcv_lists_stats->rcv_entries);
@@ -509,6 +513,14 @@ static void can_rx_delete_receiver(struct rcu_head *rp)
*
* Description:
* Removes subscription entry depending on given (subscription) values.
+ * The receive lists of a CAN device are protected by a per-device lock,
+ * so the subscription is found even when the device has been moved to
+ * another network namespace after can_rx_register(). The caller has to
+ * ensure that @dev stays valid, e.g. by holding a reference to @dev or
+ * RTNL. @net should be the namespace that has been used for
+ * can_rx_register(). It selects the 'any' CAN device lists for
+ * @dev == NULL and is otherwise only used for the receive list
+ * statistics, which become imprecise when another namespace is passed.
*/
void can_rx_unregister(struct net *net, struct net_device *dev, canid_t can_id,
canid_t mask, void (*func)(struct sk_buff *, void *),
@@ -522,12 +534,10 @@ void can_rx_unregister(struct net *net, struct net_device *dev, canid_t can_id,
if (dev && !can_get_ml_priv(dev))
return;
- if (dev && !net_eq(net, dev_net(dev)))
- return;
+ dev_rcv_lists = can_dev_rcv_lists_find(net, dev);
- spin_lock_bh(&net->can.rcvlists_lock);
+ spin_lock_bh(&dev_rcv_lists->lock);
- dev_rcv_lists = can_dev_rcv_lists_find(net, dev);
rcv_list = can_rcv_list_find(&can_id, &mask, dev_rcv_lists);
/* Search the receiver list for the item to delete. This should
@@ -547,26 +557,26 @@ void can_rx_unregister(struct net *net, struct net_device *dev, canid_t can_id,
* a warning here.
*/
if (!rcv) {
+ spin_unlock_bh(&dev_rcv_lists->lock);
pr_warn("can: receive list entry not found for dev %s, id %03X, mask %03X\n",
DNAME(dev), can_id, mask);
- goto out;
+ return;
}
hlist_del_rcu(&rcv->list);
dev_rcv_lists->entries--;
+ spin_unlock_bh(&dev_rcv_lists->lock);
+
+ spin_lock_bh(&net->can.rcvlists_lock);
if (rcv_lists_stats->rcv_entries > 0)
rcv_lists_stats->rcv_entries--;
-
- out:
spin_unlock_bh(&net->can.rcvlists_lock);
/* schedule the receiver item for deletion */
- if (rcv) {
- if (rcv->sk)
- sock_hold(rcv->sk);
- call_rcu(&rcv->rcu, can_rx_delete_receiver);
- }
+ if (rcv->sk)
+ sock_hold(rcv->sk);
+ call_rcu(&rcv->rcu, can_rx_delete_receiver);
}
EXPORT_SYMBOL(can_rx_unregister);
@@ -823,6 +833,7 @@ static int can_pernet_init(struct net *net)
net->can.rx_alldev_list = kzalloc_obj(*net->can.rx_alldev_list);
if (!net->can.rx_alldev_list)
goto out;
+ spin_lock_init(&net->can.rx_alldev_list->lock);
net->can.pkg_stats = kzalloc_obj(*net->can.pkg_stats);
if (!net->can.pkg_stats)
goto out_free_rx_alldev_list;
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 60406439a13f7..9288b96724da2 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -964,7 +964,7 @@ static void bcm_remove_op(struct bcm_op *op)
static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op)
{
if (op->rx_reg_dev == dev) {
- can_rx_unregister(dev_net(dev), dev, op->can_id,
+ can_rx_unregister(sock_net(op->sk), dev, op->can_id,
REGMASK(op->can_id), bcm_rx_handler, op);
/* mark as removed subscription */
@@ -990,21 +990,10 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,
/* disable automatic timer on frame reception */
op->flags |= RX_NO_AUTOTIMER;
- /*
- * Don't care if we're bound or not (due to netdev
- * problems) can_rx_unregister() is always a save
- * thing to do here.
- */
if (op->ifindex) {
- /*
- * Only remove subscriptions that had not
- * been removed due to NETDEV_UNREGISTER
- * in bcm_notifier()
- *
- * op->rx_reg_dev is a tracked reference taken
- * when the subscription was registered, so it
- * stays valid here even if a concurrent
- * NETDEV_UNREGISTER already unlisted the dev.
+ /* Only remove subscriptions that had not been
+ * removed in bcm_notify(). op->rx_reg_dev keeps
+ * the device's receive lists accessible.
*/
if (op->rx_reg_dev)
bcm_rx_unreg(op->rx_reg_dev, op);
@@ -1936,6 +1925,7 @@ static int bcm_release(struct socket *sock)
list_del(&bo->notifier);
spin_unlock(&bcm_notifier_lock);
+ /* bcm_notify() can not access this socket anymore */
lock_sock(sk);
#if IS_ENABLED(CONFIG_PROC_FS)
@@ -1949,29 +1939,20 @@ static int bcm_release(struct socket *sock)
bcm_remove_op(op);
}
- list_for_each_entry_safe(op, next, &bo->rx_ops, list) {
- /*
- * Don't care if we're bound or not (due to netdev problems)
- * can_rx_unregister() is always a save thing to do here.
- */
+ list_for_each_entry(op, &bo->rx_ops, list) {
if (op->ifindex) {
- /*
- * Only remove subscriptions that had not
- * been removed due to NETDEV_UNREGISTER
- * in bcm_notifier()
- *
- * op->rx_reg_dev is a tracked reference taken
- * when the subscription was registered, so it
- * stays valid here even if a concurrent
- * NETDEV_UNREGISTER already unlisted the device.
+ /* Only remove subscriptions that had not been removed
+ * in bcm_notify(). op->rx_reg_dev keeps the device's
+ * receive lists accessible.
*/
if (op->rx_reg_dev)
bcm_rx_unreg(op->rx_reg_dev, op);
- } else
+ } else {
can_rx_unregister(net, NULL, op->can_id,
REGMASK(op->can_id),
bcm_rx_handler, op);
-
+ }
+ cond_resched();
}
synchronize_rcu();
diff --git a/net/can/isotp.c b/net/can/isotp.c
index 28e9d22772fa3..1e40825b58cb7 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -1132,7 +1132,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
int off;
int err;
- if (!so->bound || READ_ONCE(so->tx.state) == ISOTP_SHUTDOWN)
+ if (!READ_ONCE(so->bound) || READ_ONCE(so->tx.state) == ISOTP_SHUTDOWN)
return -EADDRNOTAVAIL;
/* claim the socket under so->rx_lock: this serializes the claim
@@ -1177,7 +1177,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
/* so->bound is only checked once above - a wakeup may have
* unbound/rebound the socket meanwhile => recheck
*/
- if (!so->bound) {
+ if (!READ_ONCE(so->bound)) {
err = -EADDRNOTAVAIL;
goto err_out_drop;
}
@@ -1423,7 +1423,7 @@ static int isotp_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
if (flags & ~(MSG_DONTWAIT | MSG_TRUNC | MSG_PEEK | MSG_CMSG_COMPAT))
return -EINVAL;
- if (!so->bound)
+ if (!READ_ONCE(so->bound))
return -EADDRNOTAVAIL;
skb = skb_recv_datagram(sk, flags, &ret);
@@ -1497,11 +1497,11 @@ static int isotp_release(struct socket *sock)
list_del(&so->notifier);
spin_unlock(&isotp_notifier_lock);
- rtnl_lock();
lock_sock(sk);
/* remove current filters & unregister
- * tracked reference so->dev is taken at bind() time with rtnl_lock
+ * the tracked reference so->dev keeps the device's receive lists
+ * accessible, even after a namespace change
*/
if (so->bound && so->dev) {
if (isotp_register_rxid(so))
@@ -1516,11 +1516,9 @@ static int isotp_release(struct socket *sock)
}
so->ifindex = 0;
- so->bound = 0;
+ WRITE_ONCE(so->bound, 0);
so->dev = NULL;
- rtnl_unlock();
-
/* Always wait for a grace period before touching the timers below.
* A concurrent NETDEV_UNREGISTER may have already unregistered our
* filters and cleared so->bound in isotp_notify() without waiting
@@ -1587,7 +1585,7 @@ static int isotp_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int l
if (!addr->can_ifindex)
return -ENODEV;
- rtnl_lock();
+ /* lock_sock() serializes the binding with isotp_notify() */
lock_sock(sk);
if (so->bound) {
@@ -1613,19 +1611,24 @@ static int isotp_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int l
goto out;
}
- dev = dev_get_by_index(net, addr->can_ifindex);
- if (!dev) {
- err = -ENODEV;
- goto out;
- }
- if (!can_get_ml_priv(dev)) {
+ /* Publish the device inside the RCU section of the lookup: When it
+ * is unlisted concurrently, either isotp_notify() sees so->dev after
+ * synchronize_net() or the lookup fails. Check the device before
+ * publishing it.
+ */
+ rcu_read_lock();
+ dev = dev_get_by_index_rcu(net, addr->can_ifindex);
+ if (!dev || !can_get_ml_priv(dev))
err = -ENODEV;
- goto out_put_dev;
- }
- if (READ_ONCE(dev->mtu) < so->ll.mtu) {
+ else if (READ_ONCE(dev->mtu) < so->ll.mtu)
err = -EINVAL;
- goto out_put_dev;
+ if (!err) {
+ dev_hold(dev);
+ WRITE_ONCE(so->dev, dev);
}
+ rcu_read_unlock();
+ if (err)
+ goto out;
/* switch to new settings */
so->ifindex = dev->ifindex;
@@ -1652,35 +1655,39 @@ static int isotp_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int l
}
}
- /* report a down device only for a successful bind() */
- if (!(dev->flags & IFF_UP))
- notify_enetdown = 1;
-
- so->bound = 1;
+ WRITE_ONCE(so->bound, 1);
/* bind() ok -> hold a reference for so->dev so that isotp_release()
* can safely reach the device later, even if a concurrent
* NETDEV_UNREGISTER has already unlisted it by ifindex.
*/
- so->dev = dev;
netdev_hold(so->dev, &so->dev_tracker, GFP_KERNEL);
+ /* Either isotp_notify() sees so->dev on NETDEV_DOWN or we see the
+ * cleared IFF_UP, pairs with isotp_notify()
+ */
+ smp_mb();
+ if (!(READ_ONCE(dev->flags) & IFF_UP))
+ notify_enetdown = 1;
+
out_put_dev:
- if (err)
- so->ifindex = 0; /* reset on failed bind() */
+ /* revert so->ifindex and so->dev on failed bind() */
+ if (err) {
+ so->ifindex = 0;
+ WRITE_ONCE(so->dev, NULL);
+ }
- /* remove potential reference from dev_get_by_index() */
+ /* remove reference from the device lookup */
dev_put(dev);
out:
- release_sock(sk);
- rtnl_unlock();
-
if (notify_enetdown) {
sk->sk_err = ENETDOWN;
if (!sock_flag(sk, SOCK_DEAD))
sk_error_report(sk);
}
+ release_sock(sk);
+
return err;
}
@@ -1876,12 +1883,21 @@ static void isotp_notify(struct isotp_sock *so, unsigned long msg,
if (!net_eq(dev_net(dev), sock_net(sk)))
return;
- if (so->dev != dev)
+ if (msg == NETDEV_DOWN)
+ smp_mb(); /* pairs with isotp_bind(), see raw_notify() */
+
+ /* lockless fast path, see raw_notify() */
+ if (READ_ONCE(so->dev) != dev)
return;
switch (msg) {
case NETDEV_UNREGISTER:
lock_sock(sk);
+ if (so->dev != dev) {
+ release_sock(sk);
+ break;
+ }
+
/* remove current filters & unregister */
if (so->bound) {
if (isotp_register_rxid(so))
@@ -1896,16 +1912,19 @@ static void isotp_notify(struct isotp_sock *so, unsigned long msg,
}
so->ifindex = 0;
- so->bound = 0;
- so->dev = NULL;
- release_sock(sk);
+ WRITE_ONCE(so->bound, 0);
+ WRITE_ONCE(so->dev, NULL);
sk->sk_err = ENODEV;
if (!sock_flag(sk, SOCK_DEAD))
sk_error_report(sk);
+ release_sock(sk);
break;
case NETDEV_DOWN:
+ if (!READ_ONCE(so->bound))
+ break;
+
sk->sk_err = ENETDOWN;
if (!sock_flag(sk, SOCK_DEAD))
sk_error_report(sk);
diff --git a/net/can/raw.c b/net/can/raw.c
index e1d741a25be3f..d6517f71cadeb 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -85,6 +85,7 @@ struct raw_sock {
struct sock sk;
struct net_device *dev;
netdevice_tracker dev_tracker;
+ struct net_device *bind_dev; /* hint for raw_notify(), no reference */
struct list_head notifier;
int ifindex;
unsigned int bound:1;
@@ -224,6 +225,7 @@ static int raw_enable_filters(struct net *net, struct net_device *dev,
int i;
for (i = 0; i < count; i++) {
+ cond_resched();
err = can_rx_register(net, dev, filter[i].can_id,
filter[i].can_mask,
raw_rcv, sk, "raw", sk);
@@ -258,9 +260,11 @@ static void raw_disable_filters(struct net *net, struct net_device *dev,
{
int i;
- for (i = 0; i < count; i++)
+ for (i = 0; i < count; i++) {
can_rx_unregister(net, dev, filter[i].can_id,
filter[i].can_mask, raw_rcv, sk);
+ cond_resched();
+ }
}
static inline void raw_disable_errfilter(struct net *net,
@@ -305,16 +309,31 @@ static void raw_notify(struct raw_sock *ro, unsigned long msg,
struct net_device *dev)
{
struct sock *sk = &ro->sk;
+ struct net_device *bind_dev;
if (!net_eq(dev_net(dev), sock_net(sk)))
return;
- if (ro->dev != dev)
+ if (msg == NETDEV_DOWN)
+ smp_mb(); /* IFF_UP is cleared before, pairs with raw_bind() */
+
+ /* Lockless fast path, ro->bind_dev covers a concurrent bind().
+ * Read it before ro->dev, pairs with smp_store_release() in
+ * raw_bind(). A stale ro->bind_dev only costs a lock_sock().
+ */
+ bind_dev = smp_load_acquire(&ro->bind_dev);
+ if (READ_ONCE(ro->dev) != dev &&
+ (msg != NETDEV_UNREGISTER || bind_dev != dev))
return;
switch (msg) {
case NETDEV_UNREGISTER:
lock_sock(sk);
+ if (ro->dev != dev) {
+ release_sock(sk);
+ break;
+ }
+
/* remove current filters & unregister */
if (ro->bound) {
raw_disable_allfilters(dev_net(dev), dev, sk);
@@ -326,13 +345,13 @@ static void raw_notify(struct raw_sock *ro, unsigned long msg,
ro->ifindex = 0;
ro->bound = 0;
- ro->dev = NULL;
+ WRITE_ONCE(ro->dev, NULL);
ro->count = 0;
- release_sock(sk);
sk->sk_err = ENODEV;
if (!sock_flag(sk, SOCK_DEAD))
sk_error_report(sk);
+ release_sock(sk);
break;
case NETDEV_DOWN:
@@ -381,6 +400,7 @@ static int raw_init(struct sock *sk)
ro->bound = 0;
ro->ifindex = 0;
ro->dev = NULL;
+ ro->bind_dev = NULL;
/* set default filter to single entry dfilter */
ro->dfilter.can_id = 0;
@@ -431,13 +451,15 @@ static int raw_release(struct socket *sock)
list_del(&ro->notifier);
spin_unlock(&raw_notifier_lock);
- rtnl_lock();
lock_sock(sk);
- /* remove current filters & unregister */
+ /* remove current filters & unregister
+ * the tracked reference ro->dev keeps the device's receive lists
+ * accessible, even after a namespace change
+ */
if (ro->bound) {
if (ro->dev) {
- raw_disable_allfilters(dev_net(ro->dev), ro->dev, sk);
+ raw_disable_allfilters(net, ro->dev, sk);
netdev_put(ro->dev, &ro->dev_tracker);
} else {
raw_disable_allfilters(net, NULL, sk);
@@ -456,7 +478,6 @@ static int raw_release(struct socket *sock)
sock->sk = NULL;
release_sock(sk);
- rtnl_unlock();
sock_prot_inuse_add(net, sk->sk_prot, -1);
sock_put(sk);
@@ -479,14 +500,25 @@ static int raw_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int len
if (addr->can_family != AF_CAN)
return -EINVAL;
- rtnl_lock();
+ /* lock_sock() serializes the binding with raw_notify() */
lock_sock(sk);
if (ro->bound && addr->can_ifindex == ro->ifindex)
goto out;
if (addr->can_ifindex) {
- dev = dev_get_by_index(sock_net(sk), addr->can_ifindex);
+ /* Publish the device inside the RCU section of the lookup:
+ * When it is unlisted concurrently, either raw_notify() sees
+ * ro->bind_dev after synchronize_net() or the lookup fails.
+ */
+ rcu_read_lock();
+ dev = dev_get_by_index_rcu(sock_net(sk), addr->can_ifindex);
+ if (dev) {
+ dev_hold(dev);
+ /* pairs with smp_load_acquire() in raw_notify() */
+ smp_store_release(&ro->bind_dev, dev);
+ }
+ rcu_read_unlock();
if (!dev) {
err = -ENODEV;
goto out;
@@ -496,9 +528,6 @@ static int raw_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int len
goto out_put_dev;
}
- if (!(dev->flags & IFF_UP))
- notify_enetdown = 1;
-
ifindex = dev->ifindex;
/* filters set by default/setsockopt */
@@ -517,7 +546,7 @@ static int raw_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int len
if (ro->bound) {
/* unregister old filters */
if (ro->dev) {
- raw_disable_allfilters(dev_net(ro->dev),
+ raw_disable_allfilters(sock_net(sk),
ro->dev, sk);
/* drop reference to old ro->dev */
netdev_put(ro->dev, &ro->dev_tracker);
@@ -528,24 +557,32 @@ static int raw_bind(struct socket *sock, struct sockaddr_unsized *uaddr, int len
ro->ifindex = ifindex;
ro->bound = 1;
/* bind() ok -> hold a reference for new ro->dev */
- ro->dev = dev;
+ WRITE_ONCE(ro->dev, dev);
if (ro->dev)
netdev_hold(ro->dev, &ro->dev_tracker, GFP_KERNEL);
+
+ if (dev) {
+ /* Either raw_notify() sees ro->dev on NETDEV_DOWN or
+ * we see the cleared IFF_UP, pairs with raw_notify()
+ */
+ smp_mb();
+ if (!(READ_ONCE(dev->flags) & IFF_UP))
+ notify_enetdown = 1;
+ }
}
out_put_dev:
- /* remove potential reference from dev_get_by_index() */
+ /* remove reference from the device lookup */
dev_put(dev);
out:
- release_sock(sk);
- rtnl_unlock();
-
if (notify_enetdown) {
sk->sk_err = ENETDOWN;
if (!sock_flag(sk, SOCK_DEAD))
sk_error_report(sk);
}
+ release_sock(sk);
+
return err;
}
@@ -599,8 +636,13 @@ static int raw_setsockopt_locked(struct socket *sock, int optname,
return -EFAULT;
}
+ /* The reg_state check is only a shortcut: On a concurrent
+ * unregistration or namespace change raw_notify() waits for
+ * lock_sock() and removes the filters set here.
+ */
dev = ro->dev;
- if (ro->bound && dev && dev->reg_state != NETREG_REGISTERED) {
+ if (ro->bound && dev &&
+ READ_ONCE(dev->reg_state) != NETREG_REGISTERED) {
if (count > 1)
kfree(filter);
return -ENODEV;
@@ -648,8 +690,10 @@ static int raw_setsockopt_locked(struct socket *sock, int optname,
err_mask &= CAN_ERR_MASK;
+ /* lockless shortcut, see CAN_RAW_FILTER */
dev = ro->dev;
- if (ro->bound && dev && dev->reg_state != NETREG_REGISTERED)
+ if (ro->bound && dev &&
+ READ_ONCE(dev->reg_state) != NETREG_REGISTERED)
return -ENODEV;
/* remove current error mask */
@@ -756,13 +800,11 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
if (level != SOL_CAN_RAW)
return -EINVAL;
- rtnl_lock();
lock_sock(sk);
err = raw_setsockopt_locked(sock, optname, optval, optlen);
release_sock(sk);
- rtnl_unlock();
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 297/507] can: raw, isotp: copy socket options outside of lock_sock()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (295 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 296/507] can: protect the receive lists with a per-device lock Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 298/507] can: proc: reset pkg_stats atomics individually Greg Kroah-Hartman
` (209 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oliver Hartkopp, Marc Kleine-Budde,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <socketcan@hartkopp.net>
[ Upstream commit 43c973a0887d3d7b2ee0a446603c97bf0f38c58e ]
The CAN_RAW and CAN_ISOTP specific socket options are copied from and
to user space while holding lock_sock(). A copy that faults or stalls,
e.g. on a userfaultfd or FUSE backed mapping, holds lock_sock() for its
whole duration.
raw_notify() and isotp_notify() take lock_sock() of a socket that is
bound to the vanishing device while holding RTNL. As the CAN_RAW
options can also be changed on a bound socket, a stalled copy can block
RTNL on an unregistration or namespace change of the bound device.
Before "can: protect the receive lists with a per-device lock",
raw_setsockopt() even held RTNL itself during the copy. CAN_ISOTP only
copies its options for unbound sockets, which isotp_notify() skips
without taking lock_sock().
Keep the user space copies out of the locked sections: Check the option
name and length and copy the option values, including the CAN_RAW_FILTER
filters, to kernel memory before lock_sock(). raw_setsockopt_locked()
and isotp_setsockopt_locked() get the copied values directly and drop
their now redundant length checks and copies. As a side effect, a
failing copy can not leave partially overwritten options behind
anymore. In raw_getsockopt() duplicate the filters under lock_sock() and
copy them to user space after release_sock().
As the option name and length are now checked before lock_sock(), the
order of the checks in isotp_setsockopt() and accordingly the order of
the returned error values changes. This is in line with POSIX, which
does not define an order in which multiple error conditions are
detected and reported.
The generic SOL_SOCKET options in sk_setsockopt() are not affected by
this patch.
Fixes: c18ce101f2e4 ("[CAN]: Add raw protocol")
Fixes: 1e5185c09058 ("can: raw: add locking for raw flags bitfield")
Cc: stable@vger.kernel.org # depends on "can: protect the receive lists with a per-device lock"
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://patch.msgid.link/20261027-can-rx-lock-v12-4-eb5afc2d8b9b@hartkopp.net
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/can/isotp.c | 100 +++++++++++++++-----------
net/can/raw.c | 186 +++++++++++++++++++++++++-----------------------
2 files changed, 155 insertions(+), 131 deletions(-)
diff --git a/net/can/isotp.c b/net/can/isotp.c
index 1e40825b58cb7..5e2de051fc5ec 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -1709,8 +1709,8 @@ static int isotp_getname(struct socket *sock, struct sockaddr *uaddr, int peer)
return ISOTP_MIN_NAMELEN;
}
-static int isotp_setsockopt_locked(struct socket *sock, int level, int optname,
- sockptr_t optval, unsigned int optlen)
+static int isotp_setsockopt_locked(struct socket *sock, int optname,
+ const void *val)
{
struct sock *sk = sock->sk;
struct isotp_sock *so = isotp_sk(sk);
@@ -1721,11 +1721,7 @@ static int isotp_setsockopt_locked(struct socket *sock, int level, int optname,
switch (optname) {
case CAN_ISOTP_OPTS:
- if (optlen != sizeof(struct can_isotp_options))
- return -EINVAL;
-
- if (copy_from_sockptr(&so->opt, optval, optlen))
- return -EFAULT;
+ memcpy(&so->opt, val, sizeof(so->opt));
/* no separate rx_ext_address is given => use ext_address */
if (!(so->opt.flags & CAN_ISOTP_RX_EXT_ADDR))
@@ -1750,55 +1746,37 @@ static int isotp_setsockopt_locked(struct socket *sock, int level, int optname,
break;
case CAN_ISOTP_RECV_FC:
- if (optlen != sizeof(struct can_isotp_fc_options))
- return -EINVAL;
-
- if (copy_from_sockptr(&so->rxfc, optval, optlen))
- return -EFAULT;
+ memcpy(&so->rxfc, val, sizeof(so->rxfc));
break;
case CAN_ISOTP_TX_STMIN:
- if (optlen != sizeof(u32))
- return -EINVAL;
-
- if (copy_from_sockptr(&so->force_tx_stmin, optval, optlen))
- return -EFAULT;
+ so->force_tx_stmin = *(const u32 *)val;
break;
case CAN_ISOTP_RX_STMIN:
- if (optlen != sizeof(u32))
- return -EINVAL;
-
- if (copy_from_sockptr(&so->force_rx_stmin, optval, optlen))
- return -EFAULT;
+ so->force_rx_stmin = *(const u32 *)val;
break;
- case CAN_ISOTP_LL_OPTS:
- if (optlen == sizeof(struct can_isotp_ll_options)) {
- struct can_isotp_ll_options ll;
-
- if (copy_from_sockptr(&ll, optval, optlen))
- return -EFAULT;
+ case CAN_ISOTP_LL_OPTS: {
+ const struct can_isotp_ll_options *ll = val;
- /* check for correct ISO 11898-1 DLC data length */
- if (ll.tx_dl != padlen(ll.tx_dl))
- return -EINVAL;
+ /* check for correct ISO 11898-1 DLC data length */
+ if (ll->tx_dl != padlen(ll->tx_dl))
+ return -EINVAL;
- if (ll.mtu != CAN_MTU && ll.mtu != CANFD_MTU)
- return -EINVAL;
+ if (ll->mtu != CAN_MTU && ll->mtu != CANFD_MTU)
+ return -EINVAL;
- if (ll.mtu == CAN_MTU &&
- (ll.tx_dl > CAN_MAX_DLEN || ll.tx_flags != 0))
- return -EINVAL;
+ if (ll->mtu == CAN_MTU &&
+ (ll->tx_dl > CAN_MAX_DLEN || ll->tx_flags != 0))
+ return -EINVAL;
- memcpy(&so->ll, &ll, sizeof(ll));
+ memcpy(&so->ll, ll, sizeof(*ll));
- /* set ll_dl for tx path to similar place as for rx */
- so->tx.ll_dl = ll.tx_dl;
- } else {
- return -EINVAL;
- }
+ /* set ll_dl for tx path to similar place as for rx */
+ so->tx.ll_dl = ll->tx_dl;
break;
+ }
default:
ret = -ENOPROTOOPT;
@@ -1812,13 +1790,49 @@ static int isotp_setsockopt(struct socket *sock, int level, int optname,
{
struct sock *sk = sock->sk;
+ union {
+ struct can_isotp_options opt;
+ struct can_isotp_fc_options rxfc;
+ struct can_isotp_ll_options ll;
+ u32 stmin;
+ } val;
+ unsigned int size;
int ret;
if (level != SOL_CAN_ISOTP)
return -EINVAL;
+ /* copy the option values from user space before lock_sock() */
+ switch (optname) {
+ case CAN_ISOTP_OPTS:
+ size = sizeof(val.opt);
+ break;
+
+ case CAN_ISOTP_RECV_FC:
+ size = sizeof(val.rxfc);
+ break;
+
+ case CAN_ISOTP_TX_STMIN:
+ case CAN_ISOTP_RX_STMIN:
+ size = sizeof(val.stmin);
+ break;
+
+ case CAN_ISOTP_LL_OPTS:
+ size = sizeof(val.ll);
+ break;
+
+ default:
+ return -ENOPROTOOPT;
+ }
+
+ if (optlen != size)
+ return -EINVAL;
+
+ if (copy_from_sockptr(&val, optval, size))
+ return -EFAULT;
+
lock_sock(sk);
- ret = isotp_setsockopt_locked(sock, level, optname, optval, optlen);
+ ret = isotp_setsockopt_locked(sock, optname, &val);
release_sock(sk);
return ret;
}
diff --git a/net/can/raw.c b/net/can/raw.c
index d6517f71cadeb..0926d5686e419 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -604,63 +604,36 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
}
static int raw_setsockopt_locked(struct socket *sock, int optname,
- sockptr_t optval, unsigned int optlen)
+ const void *val, struct can_filter *filter,
+ int count)
{
struct sock *sk = sock->sk;
struct raw_sock *ro = raw_sk(sk);
- struct can_filter *filter = NULL; /* dyn. alloc'ed filters */
- struct can_filter sfilter; /* single filter */
struct net_device *dev = NULL;
- can_err_mask_t err_mask = 0;
- int count = 0;
+ can_err_mask_t err_mask;
int flag;
int err = 0;
switch (optname) {
case CAN_RAW_FILTER:
- if (optlen % sizeof(struct can_filter) != 0)
- return -EINVAL;
-
- if (optlen > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
- return -EINVAL;
-
- count = optlen / sizeof(struct can_filter);
-
- if (count > 1) {
- /* filter does not fit into dfilter => alloc space */
- filter = memdup_sockptr(optval, optlen);
- if (IS_ERR(filter))
- return PTR_ERR(filter);
- } else if (count == 1) {
- if (copy_from_sockptr(&sfilter, optval, sizeof(sfilter)))
- return -EFAULT;
- }
-
- /* The reg_state check is only a shortcut: On a concurrent
+ /* @filter has been copied by raw_setsockopt(). It is linked
+ * to the socket on success and freed by the caller on error.
+ *
+ * The reg_state check is only a shortcut: On a concurrent
* unregistration or namespace change raw_notify() waits for
* lock_sock() and removes the filters set here.
*/
dev = ro->dev;
if (ro->bound && dev &&
- READ_ONCE(dev->reg_state) != NETREG_REGISTERED) {
- if (count > 1)
- kfree(filter);
+ READ_ONCE(dev->reg_state) != NETREG_REGISTERED)
return -ENODEV;
- }
if (ro->bound) {
/* (try to) register the new filters */
- if (count == 1)
- err = raw_enable_filters(sock_net(sk), dev, sk,
- &sfilter, 1);
- else
- err = raw_enable_filters(sock_net(sk), dev, sk,
- filter, count);
- if (err) {
- if (count > 1)
- kfree(filter);
+ err = raw_enable_filters(sock_net(sk), dev, sk, filter,
+ count);
+ if (err)
return err;
- }
/* remove old filter registrations */
raw_disable_filters(sock_net(sk), dev, sk, ro->filter,
@@ -674,7 +647,7 @@ static int raw_setsockopt_locked(struct socket *sock, int optname,
/* link new filters to the socket */
if (count == 1) {
/* copy filter data for single filter */
- ro->dfilter = sfilter;
+ ro->dfilter = *filter;
filter = &ro->dfilter;
}
ro->filter = filter;
@@ -682,13 +655,7 @@ static int raw_setsockopt_locked(struct socket *sock, int optname,
break;
case CAN_RAW_ERR_FILTER:
- if (optlen != sizeof(err_mask))
- return -EINVAL;
-
- if (copy_from_sockptr(&err_mask, optval, optlen))
- return -EFAULT;
-
- err_mask &= CAN_ERR_MASK;
+ err_mask = *(const can_err_mask_t *)val & CAN_ERR_MASK;
/* lockless shortcut, see CAN_RAW_FILTER */
dev = ro->dev;
@@ -715,31 +682,15 @@ static int raw_setsockopt_locked(struct socket *sock, int optname,
break;
case CAN_RAW_LOOPBACK:
- if (optlen != sizeof(flag))
- return -EINVAL;
-
- if (copy_from_sockptr(&flag, optval, optlen))
- return -EFAULT;
-
- ro->loopback = !!flag;
+ ro->loopback = !!*(const int *)val;
break;
case CAN_RAW_RECV_OWN_MSGS:
- if (optlen != sizeof(flag))
- return -EINVAL;
-
- if (copy_from_sockptr(&flag, optval, optlen))
- return -EFAULT;
-
- ro->recv_own_msgs = !!flag;
+ ro->recv_own_msgs = !!*(const int *)val;
break;
case CAN_RAW_FD_FRAMES:
- if (optlen != sizeof(flag))
- return -EINVAL;
-
- if (copy_from_sockptr(&flag, optval, optlen))
- return -EFAULT;
+ flag = *(const int *)val;
/* Enabling CAN XL includes CAN FD */
if (ro->xl_frames && !flag)
@@ -749,13 +700,7 @@ static int raw_setsockopt_locked(struct socket *sock, int optname,
break;
case CAN_RAW_XL_FRAMES:
- if (optlen != sizeof(flag))
- return -EINVAL;
-
- if (copy_from_sockptr(&flag, optval, optlen))
- return -EFAULT;
-
- ro->xl_frames = !!flag;
+ ro->xl_frames = !!*(const int *)val;
/* Enabling CAN XL includes CAN FD */
if (ro->xl_frames)
@@ -763,11 +708,7 @@ static int raw_setsockopt_locked(struct socket *sock, int optname,
break;
case CAN_RAW_XL_VCID_OPTS:
- if (optlen != sizeof(ro->raw_vcid_opts))
- return -EINVAL;
-
- if (copy_from_sockptr(&ro->raw_vcid_opts, optval, optlen))
- return -EFAULT;
+ memcpy(&ro->raw_vcid_opts, val, sizeof(ro->raw_vcid_opts));
/* prepare 32 bit values for handling in hot path */
ro->tx_vcid_shifted = ro->raw_vcid_opts.tx_vcid << CANXL_VCID_OFFSET;
@@ -776,13 +717,7 @@ static int raw_setsockopt_locked(struct socket *sock, int optname,
break;
case CAN_RAW_JOIN_FILTERS:
- if (optlen != sizeof(flag))
- return -EINVAL;
-
- if (copy_from_sockptr(&flag, optval, optlen))
- return -EFAULT;
-
- ro->join_filters = !!flag;
+ ro->join_filters = !!*(const int *)val;
break;
default:
@@ -795,17 +730,84 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
sockptr_t optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
+ struct can_filter *filter = NULL; /* dyn. alloc'ed filters */
+ struct can_filter sfilter; /* single filter */
+ union {
+ can_err_mask_t err_mask;
+ int flag;
+ struct can_raw_vcid_options vcid_opts;
+ } val;
+ unsigned int size = 0;
+ int count = 0;
int err;
if (level != SOL_CAN_RAW)
return -EINVAL;
+ /* Copy the option values from user space before lock_sock(), so a
+ * stalled copy can not block raw_notify() waiting for lock_sock()
+ * under RTNL.
+ */
+ switch (optname) {
+ case CAN_RAW_FILTER:
+ if (optlen % sizeof(struct can_filter) != 0)
+ return -EINVAL;
+
+ if (optlen > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
+ return -EINVAL;
+
+ count = optlen / sizeof(struct can_filter);
+
+ if (count > 1) {
+ /* filter does not fit into dfilter => alloc space */
+ filter = memdup_sockptr(optval, optlen);
+ if (IS_ERR(filter))
+ return PTR_ERR(filter);
+ } else if (count == 1) {
+ if (copy_from_sockptr(&sfilter, optval, sizeof(sfilter)))
+ return -EFAULT;
+ filter = &sfilter;
+ }
+ break;
+
+ case CAN_RAW_ERR_FILTER:
+ size = sizeof(val.err_mask);
+ break;
+
+ case CAN_RAW_XL_VCID_OPTS:
+ size = sizeof(val.vcid_opts);
+ break;
+
+ case CAN_RAW_LOOPBACK:
+ case CAN_RAW_RECV_OWN_MSGS:
+ case CAN_RAW_FD_FRAMES:
+ case CAN_RAW_XL_FRAMES:
+ case CAN_RAW_JOIN_FILTERS:
+ size = sizeof(val.flag);
+ break;
+
+ default:
+ return -ENOPROTOOPT;
+ }
+
+ if (size) {
+ if (optlen != size)
+ return -EINVAL;
+
+ if (copy_from_sockptr(&val, optval, size))
+ return -EFAULT;
+ }
+
lock_sock(sk);
- err = raw_setsockopt_locked(sock, optname, optval, optlen);
+ err = raw_setsockopt_locked(sock, optname, &val, filter, count);
release_sock(sk);
+ /* on error free the filters allocated for CAN_RAW_FILTER above */
+ if (err && count > 1)
+ kfree(filter);
+
return err;
}
@@ -826,6 +828,7 @@ static int raw_getsockopt(struct socket *sock, int level, int optname,
switch (optname) {
case CAN_RAW_FILTER: {
+ struct can_filter *filter = NULL;
int err = 0;
lock_sock(sk);
@@ -840,15 +843,22 @@ static int raw_getsockopt(struct socket *sock, int level, int optname,
} else {
if (len > fsize)
len = fsize;
- if (copy_to_iter(ro->filter, len,
- &opt->iter_out) != len)
- err = -EFAULT;
+ /* copy to user space after release_sock() */
+ filter = kmemdup(ro->filter, len, GFP_KERNEL);
+ if (!filter)
+ err = -ENOMEM;
}
} else {
len = 0;
}
release_sock(sk);
+ if (filter) {
+ if (copy_to_iter(filter, len, &opt->iter_out) != len)
+ err = -EFAULT;
+ kfree(filter);
+ }
+
if (!err)
opt->optlen = len;
return err;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 298/507] can: proc: reset pkg_stats atomics individually
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (296 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 297/507] can: raw, isotp: copy socket options outside of lock_sock() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 299/507] can: proc: skip stats calculation after reset in can_stat_update() Greg Kroah-Hartman
` (208 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Oliver Hartkopp,
Marc Kleine-Budde, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
[ Upstream commit 12297f855bbd943847cb8893a3614caef5a9c2a8 ]
Commit 80b5f90158d1 ("can: statistics: use atomic access in hot path")
converted several members of struct can_pkg_stats to atomic_long_t and
updated the hot TX/RX and procfs read paths to use atomic_long_*()
helpers. However, can_init_stats() still clears the whole struct with
memset().
can_init_stats() is reached from can_stat_update() in timer context and
also from the procfs reset path. Those paths can run while the TX/RX hot
paths are concurrently updating rx_frames, tx_frames, matches and their
*_delta counters. Hitting the whole-struct memset() in that window
performs plain writes to fields that otherwise follow an atomic_long_t
access contract, which can lose or mix live statistics updates.
This issue was found by source-level API-misuse analysis looking for
whole-object resets left behind after atomic_long_t conversions, then
manually audited on Linux v6.18.21.
Replace the whole-struct memset() with a helper that resets the
atomic_long_t counters via atomic_long_set() and clears the derived
scalar statistics explicitly. This preserves the existing reset
semantics for scalar fields while restoring atomic access discipline for
the live counters.
Build-tested by compiling net/can/proc.o on x86_64 netdev/main.
Runtime-tested with a QEMU + vcan setup on Linux v6.18.21 by driving
concurrent traffic and reset_stats reads, which reproduced inconsistent
exported statistics before the fix.
[Hartkopp] can_stat_update() also read the *_delta counters at the
beginning and cleared them with atomic_long_set() at the end. Increments
from the hot path in between were lost for both the current and the next
interval. Use atomic_long_xchg() to fetch and clear the *_delta counters
in one atomic step instead.
On x86_64 atomic_long_set() is a plain store like memset(), so the
memset() is an actual problem only on architectures with lock-based
atomics (e.g. parisc). The inconsistencies seen on x86_64 come from the
*_delta handling and from the stale snapshots, which are fixed in "can:
proc: skip stats calculation after reset in can_stat_update()". As
before, the counters are reset one at a time and the derived scalar
statistics use plain stores.
Fixes: 80b5f90158d1 ("can: statistics: use atomic access in hot path")
Cc: stable@vger.kernel.org
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://patch.msgid.link/20261027-can-rx-lock-v12-5-eb5afc2d8b9b@hartkopp.net
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/can/proc.c | 39 +++++++++++++++++++++++++++++----------
1 file changed, 29 insertions(+), 10 deletions(-)
diff --git a/net/can/proc.c b/net/can/proc.c
index de4d05ae34597..70104f13077e0 100644
--- a/net/can/proc.c
+++ b/net/can/proc.c
@@ -76,16 +76,39 @@ static const char rx_list_name[][8] = {
* af_can statistics stuff
*/
+static void can_reset_pkg_stats(struct can_pkg_stats *pkg_stats)
+{
+ atomic_long_set(&pkg_stats->rx_frames, 0);
+ atomic_long_set(&pkg_stats->tx_frames, 0);
+ atomic_long_set(&pkg_stats->matches, 0);
+
+ pkg_stats->total_rx_rate = 0;
+ pkg_stats->total_tx_rate = 0;
+ pkg_stats->total_rx_match_ratio = 0;
+
+ pkg_stats->current_rx_rate = 0;
+ pkg_stats->current_tx_rate = 0;
+ pkg_stats->current_rx_match_ratio = 0;
+
+ pkg_stats->max_rx_rate = 0;
+ pkg_stats->max_tx_rate = 0;
+ pkg_stats->max_rx_match_ratio = 0;
+
+ atomic_long_set(&pkg_stats->rx_frames_delta, 0);
+ atomic_long_set(&pkg_stats->tx_frames_delta, 0);
+ atomic_long_set(&pkg_stats->matches_delta, 0);
+}
+
static void can_init_stats(struct net *net)
{
struct can_pkg_stats *pkg_stats = net->can.pkg_stats;
struct can_rcv_lists_stats *rcv_lists_stats = net->can.rcv_lists_stats;
/*
- * This memset function is called from a timer context (when
+ * This stats reset is called from a timer context (when
* can_stattimer is active which is the default) OR in a process
* context (reading the proc_fs when can_stattimer is disabled).
*/
- memset(pkg_stats, 0, sizeof(struct can_pkg_stats));
+ can_reset_pkg_stats(pkg_stats);
pkg_stats->jiffies_init = jiffies;
rcv_lists_stats->stats_reset++;
@@ -121,9 +144,10 @@ void can_stat_update(struct timer_list *t)
long rx_frames = atomic_long_read(&pkg_stats->rx_frames);
long tx_frames = atomic_long_read(&pkg_stats->tx_frames);
long matches = atomic_long_read(&pkg_stats->matches);
- long rx_frames_delta = atomic_long_read(&pkg_stats->rx_frames_delta);
- long tx_frames_delta = atomic_long_read(&pkg_stats->tx_frames_delta);
- long matches_delta = atomic_long_read(&pkg_stats->matches_delta);
+ /* fetch and clear values for 'current rate' calculation */
+ long rx_frames_delta = atomic_long_xchg(&pkg_stats->rx_frames_delta, 0);
+ long tx_frames_delta = atomic_long_xchg(&pkg_stats->tx_frames_delta, 0);
+ long matches_delta = atomic_long_xchg(&pkg_stats->matches_delta, 0);
/* restart counting in timer context on user request */
if (user_reset)
@@ -172,11 +196,6 @@ void can_stat_update(struct timer_list *t)
if (pkg_stats->max_rx_match_ratio < pkg_stats->current_rx_match_ratio)
pkg_stats->max_rx_match_ratio = pkg_stats->current_rx_match_ratio;
- /* clear values for 'current rate' calculation */
- atomic_long_set(&pkg_stats->tx_frames_delta, 0);
- atomic_long_set(&pkg_stats->rx_frames_delta, 0);
- atomic_long_set(&pkg_stats->matches_delta, 0);
-
/* restart timer (one second) */
mod_timer(&net->can.stattimer, round_jiffies(jiffies + HZ));
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 299/507] can: proc: skip stats calculation after reset in can_stat_update()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (297 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 298/507] can: proc: reset pkg_stats atomics individually Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 300/507] can: dev: can_fill_info(): dont wake up controller if interface is down Greg Kroah-Hartman
` (207 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oliver Hartkopp, Marc Kleine-Budde,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <socketcan@hartkopp.net>
[ Upstream commit 01b19ed9fa031a649f3dd103ebe6e0102602e542 ]
Commit 80b5f90158d1 ("can: statistics: use atomic access in hot path")
introduced local snapshots of the statistics counters at the beginning
of can_stat_update(). When can_init_stats() resets the statistics, these
stale pre-reset snapshots are still used for the following total/current
/max calculations and overwrite the freshly reset values. Additionally a
jiffies tick between the snapshot and the reset could trigger a second
can_init_stats() call.
Merge the reset conditions into a single check and skip the calculation
for the current interval when the statistics have been reset.
Fixes: 80b5f90158d1 ("can: statistics: use atomic access in hot path")
Cc: stable@vger.kernel.org
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://patch.msgid.link/20261027-can-rx-lock-v12-6-eb5afc2d8b9b@hartkopp.net
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/can/proc.c | 30 ++++++++++++------------------
1 file changed, 12 insertions(+), 18 deletions(-)
diff --git a/net/can/proc.c b/net/can/proc.c
index 70104f13077e0..fb144d2adc35d 100644
--- a/net/can/proc.c
+++ b/net/can/proc.c
@@ -149,25 +149,18 @@ void can_stat_update(struct timer_list *t)
long tx_frames_delta = atomic_long_xchg(&pkg_stats->tx_frames_delta, 0);
long matches_delta = atomic_long_xchg(&pkg_stats->matches_delta, 0);
- /* restart counting in timer context on user request */
- if (user_reset)
- can_init_stats(net);
-
- /* restart counting on jiffies overflow */
- if (j < pkg_stats->jiffies_init)
- can_init_stats(net);
-
- /* prevent overflow in calc_rate() */
- if (rx_frames > (LONG_MAX / HZ))
- can_init_stats(net);
-
- /* prevent overflow in calc_rate() */
- if (tx_frames > (LONG_MAX / HZ))
- can_init_stats(net);
-
- /* matches overflow - very improbable */
- if (matches > (LONG_MAX / 100))
+ /*
+ * Restart counting in timer context on user request, on jiffies
+ * overflow or to prevent overflows in calc_rate() and in the
+ * match ratio calculation. The local snapshots are stale after
+ * the reset, so skip the calculation for this interval.
+ */
+ if (user_reset || j < pkg_stats->jiffies_init ||
+ rx_frames > (LONG_MAX / HZ) || tx_frames > (LONG_MAX / HZ) ||
+ matches > (LONG_MAX / 100)) {
can_init_stats(net);
+ goto out;
+ }
/* calc total values */
if (rx_frames)
@@ -196,6 +189,7 @@ void can_stat_update(struct timer_list *t)
if (pkg_stats->max_rx_match_ratio < pkg_stats->current_rx_match_ratio)
pkg_stats->max_rx_match_ratio = pkg_stats->current_rx_match_ratio;
+out:
/* restart timer (one second) */
mod_timer(&net->can.stattimer, round_jiffies(jiffies + HZ));
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 300/507] can: dev: can_fill_info(): dont wake up controller if interface is down
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (298 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 299/507] can: proc: skip stats calculation after reset in can_stat_update() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 301/507] can: peak_usb: pcan_usb_fd_decode_buf(): accept short uCAN end-of-list records Greg Kroah-Hartman
` (206 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, ChunYuZhiQiang, Vincent Mailhol,
Marc Kleine-Budde, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChunYuZhiQiang <chunyuzhiqiang@yinhe.ht>
[ Upstream commit 75332c410c8190d61499001c5516af977ca426c3 ]
If the interface is down, the CAN controller might be powered down and
its clocks gated. Don't call do_get_berr_counter() to read the bus error
counters if the interface is down, and adjust can_get_size() to match.
This removes one trigger for a synchronous external abort seen on
i.MX8QXP when "ip link show" is run on a flexcan interface that was
never brought up. The underlying cause is platform-specific: on i.MX8QXP
the CAN clocks are gated through the SCU LPCG and the subsystem shares
the IMX_SC_R_CAN_0 power domain, and there is a window after
pm_runtime_resume_and_get() returns where the clock has not reached the
module yet. This patch avoids the netlink query path while the interface
is down, but does not root-cause the LPCG window itself.
As a result, IFLA_CAN_BERR_COUNTER is no longer reported for down
interfaces. Userspace must treat the attribute as optional.
The issue was triggered on an i.MX8QXP board by running "ip link show"
without ever bringing the interface up:
Internal error: synchronous external abort: 0000000096000210
pc : flexcan_read_le+0x0/0x18
lr : flexcan_get_berr_counter+0x4c/0x8c
Call trace:
flexcan_read_le+0x0/0x18
flexcan_get_berr_counter+0x4c/0x8c
can_fill_info+0x1f8/0x434
rtnl_fill_ifinfo+0x8fc/0xbb4
rtnl_dump_ifinfo+0x364/0x448
This is the same class of problem fixed for m_can in
commit 91a55c72a821 ("can: m_can: m_can_get_berr_counter(): don't
wake up controller if interface is down").
Fixes: ec56acfef2af1 ("can: flexcan: flexcan_get_berr_counter(): switch on clocks before accessing ecr register")
Cc: stable@vger.kernel.org
Signed-off-by: ChunYuZhiQiang <chunyuzhiqiang@yinhe.ht>
Reviewed-by: Vincent Mailhol <mailhol@kernel.org>
Link: https://patch.msgid.link/20261027065012.191348-1-chunyuzhiqiang@yinhe.ht
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/can/dev/netlink.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
index 766d455950f55..b958c04d53db6 100644
--- a/drivers/net/can/dev/netlink.c
+++ b/drivers/net/can/dev/netlink.c
@@ -812,7 +812,7 @@ static size_t can_get_size(const struct net_device *dev)
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_STATE */
size += nla_total_size(sizeof(struct can_ctrlmode)); /* IFLA_CAN_CTRLMODE */
size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */
- if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */
+ if (priv->do_get_berr_counter && netif_running(dev)) /* IFLA_CAN_BERR_COUNTER */
size += nla_total_size(sizeof(struct can_berr_counter));
if (priv->termination_const) {
size += nla_total_size(sizeof(priv->termination)); /* IFLA_CAN_TERMINATION */
@@ -1006,7 +1006,7 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
nla_put(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm) ||
nla_put_u32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms) ||
- (priv->do_get_berr_counter &&
+ (priv->do_get_berr_counter && netif_running(dev) &&
!priv->do_get_berr_counter(dev, &bec) &&
nla_put(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec)) ||
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 301/507] can: peak_usb: pcan_usb_fd_decode_buf(): accept short uCAN end-of-list records
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (299 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 300/507] can: dev: can_fill_info(): dont wake up controller if interface is down Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 302/507] mm/huge_memory: fix truncate racing with PMD zapping Greg Kroah-Hartman
` (205 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Liu Changjie, Stéphane Grosjean,
Marc Kleine-Budde, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liu Changjie <liucj1228@outlook.com>
[ Upstream commit 2d4c272e816a5b784f1fc7899256f8826df34edb ]
A PCAN-USB FD v2 running firmware 3.2.0 sends a 16-byte status record
followed by a four-byte zero-size end marker.
Since commit 93fcab2c6968 ("can: peak_usb: validate uCAN receive record
lengths") these transfers cause repeated receive-buffer dumps while the
interface is up.
This has been observed on Linux 7.2.11-arch1-1 with matching kernel
headers:
- Classic CAN, 500 kbit/s: 25 decoder errors in 5 s before the fix; none in
15 s after.
- CAN FD, 500 kbit/s nominal and 2 Mbit/s data: 26 decoder errors in 5 s
before the fix; none in 60 s after.
- Three additional down/up cycles: no decoder errors.
pcan_usb_fd_decode_buf() requires a complete 12-byte struct pucan_msg
before checking the size field, so it rejects the end marker with -EBADMSG.
Check that the size field is present before testing for an end marker.
Require the full header for nonzero-size records and keep the remaining
record and payload length checks.
This patch was created with LLM assistance.
Fixes: 93fcab2c6968 ("can: peak_usb: validate uCAN receive record lengths")
Signed-off-by: Liu Changjie <liucj1228@outlook.com>
Reviewed-by: Stéphane Grosjean <s.grosjean@peak-system.fr>
Link: https://patch.msgid.link/CH5PR19MB997156AB3BE253C3BE445223B0AC992@CH5PR19MB997156.namprd19.prod.outlook.com
Cc: stable@vger.kernel.org
[mkl: copy additional info to commit message]
[mkl: convert Assisted-by: tag to prose]
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
Built and tested the original and patched peak_usb modules on Arch
Linux 7.2.11-arch1-1 with matching kernel headers.
- Classic CAN, 500 kbit/s: 25 decoder errors in 5 s before the fix;
none in 15 s after.
- CAN FD, 500 kbit/s nominal and 2 Mbit/s data: 26 decoder errors
in 5 s before the fix; none in 60 s after.
- Three additional down/up cycles: no decoder errors.
USB captures during the patched tests contained 406 packets with
short end markers. Neither receive-buffer dump recurred.
The CAN bus was disconnected; external TX/RX was not tested.
One startup "can_change_state: oops, state did not change" message and
an RX dropped count reaching 2 were observed during the patched tests.
Their causes remain undetermined.
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 0d46f4ce5dca7..39f0740421c36 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -755,7 +755,7 @@ static int pcan_usb_fd_decode_buf(struct peak_usb_device *dev, struct urb *urb)
u16 rx_msg_type, rx_msg_size;
size_t rx_msg_min_size;
- if (msg_end - msg_ptr < sizeof(*rx_msg)) {
+ if (msg_end - msg_ptr < sizeof(rx_msg->size)) {
err = -EBADMSG;
break;
}
@@ -766,6 +766,11 @@ static int pcan_usb_fd_decode_buf(struct peak_usb_device *dev, struct urb *urb)
break;
}
+ if (msg_end - msg_ptr < sizeof(*rx_msg)) {
+ err = -EBADMSG;
+ break;
+ }
+
rx_msg_size = le16_to_cpu(rx_msg->size);
rx_msg_type = le16_to_cpu(rx_msg->type);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 302/507] mm/huge_memory: fix truncate racing with PMD zapping
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (300 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 301/507] can: peak_usb: pcan_usb_fd_decode_buf(): accept short uCAN end-of-list records Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 303/507] mm/huge_memory: fix zapping migration entries for device-private THPs Greg Kroah-Hartman
` (204 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Gregory Price (Meta),
Muhammad Usama Anjum, Zi Yan, Baolin Wang,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit e6a07d29b0a60f3a4cfe77fe34eeb4b3fb38d6c4 ]
zap_huge_pmd_folio() removes the rmap before calling folio_mark_dirty().
If this was the last mapping, truncation can skip unmapping the folio
and proceed without waiting for the PMD lock, racing with dirtying.
ifs_set_range_dirty() can oops if MADV_DONTNEED races with
ftruncate() on XFS, when we get the folio set dirty after it was found
to not be mapped anymore.
Move folio_mark_dirty() and folio_mark_accessed() before rmap removal,
matching the PTE zap path. This keeps the folio mapped while updating
its state, so truncation must wait for the page table lock.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: fe6cf984939d ("mm/huge_memory: transfer the pmd dirty bit to the folio on zap")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
[ david: simplify comment and description ]
Reviewed-by: Gregory Price (Meta) <gourry@gourry.net>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-13-d6437171ecc3@kernel.org
Reviewed-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/huge_memory.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index f5e871059ba6b..da96959998692 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2496,10 +2496,6 @@ static void zap_huge_pmd_folio(struct mm_struct *mm, struct vm_area_struct *vma,
{
const bool is_device_private = folio_is_device_private(folio);
- /* Present and device private folios are rmappable. */
- if (is_present || is_device_private)
- folio_remove_rmap_pmd(folio, &folio->page, vma);
-
if (folio_test_anon(folio)) {
add_mm_counter(mm, MM_ANONPAGES, -HPAGE_PMD_NR);
} else {
@@ -2513,6 +2509,13 @@ static void zap_huge_pmd_folio(struct mm_struct *mm, struct vm_area_struct *vma,
folio_mark_accessed(folio);
}
+ /*
+ * Present and device private folios are rmappable. Remove the
+ * rmap after transferring young+dirty to the folio.
+ */
+ if (is_present || is_device_private)
+ folio_remove_rmap_pmd(folio, &folio->page, vma);
+
/* Device private folios are pinned. */
if (is_device_private)
folio_put(folio);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 303/507] mm/huge_memory: fix zapping migration entries for device-private THPs
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (301 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 302/507] mm/huge_memory: fix truncate racing with PMD zapping Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 304/507] mm/khugepaged: always recheck the pmd in try_collapse_pte_mapped_thp() Greg Kroah-Hartman
` (203 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Gregory Price (Meta),
Zi Yan, Lance Yang, David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit 63a940541358d09cc9f02d40b71eb8d3917a21c0 ]
A PMD migration entry can refer to a device-private folio.
zap_huge_pmd_folio() checks the folio type instead of the entry type,
so it treats such a migration entry as a device-private entry.
Installing the migration entry already removed the reverse mapping and
dropped the mapping reference. Zapping it must not repeat those
operations. Concurrent MADV_DONTNEED during migration back to system
memory can trigger this.
Check the PMD entry type using pmd_is_device_private_entry().
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: 368076f52ebe ("mm/huge_memory: add device-private THP support to PMD operations")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
[ david: simplify description ]
Reviewed-by: Gregory Price (Meta) <gourry@gourry.net>
Link: https://patch.msgid.link/20261031-fixes_core-v3-14-d6437171ecc3@kernel.org
Reviewed-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/huge_memory.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index da96959998692..c1130d3d28261 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2494,7 +2494,7 @@ static inline void zap_deposited_table(struct mm_struct *mm, pmd_t *pmd)
static void zap_huge_pmd_folio(struct mm_struct *mm, struct vm_area_struct *vma,
pmd_t pmdval, struct folio *folio, bool is_present)
{
- const bool is_device_private = folio_is_device_private(folio);
+ const bool is_device_private = pmd_is_device_private_entry(pmdval);
if (folio_test_anon(folio)) {
add_mm_counter(mm, MM_ANONPAGES, -HPAGE_PMD_NR);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 304/507] mm/khugepaged: always recheck the pmd in try_collapse_pte_mapped_thp()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (302 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 303/507] mm/huge_memory: fix zapping migration entries for device-private THPs Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 305/507] mm/khugepaged: fix PMD table lock leak " Greg Kroah-Hartman
` (202 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Gregory Price (Meta),
Muhammad Usama Anjum, Lance Yang, Baolin Wang,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit aa72cf34d90da7019591ab67533a8ece8b41da2d ]
try_collapse_pte_mapped_thp() drops the PTE lock after it has cleared the
page table, and takes the PMD lock and the PTE lock to remove it.
In between, MADV_DONTNEED with CONFIG_PT_RECLAIM can reclaim the
page table. The pmd_same() check is supposed to handle this, but it is
only done with CONFIG_SPLIT_PTE_PTLOCKS.
Fix it by performing the check unconditionally.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: 6375e95f381e ("mm: pgtable: reclaim empty PTE page in madvise(MADV_DONTNEED)")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
[ david: adjust description ]
Reviewed-by: Gregory Price (Meta) <gourry@gourry.net>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-15-d6437171ecc3@kernel.org
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/khugepaged.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 16444bd7f1c0a..9cd468307841f 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -2037,12 +2037,11 @@ static enum scan_result try_collapse_pte_mapped_thp(struct mm_struct *mm, unsign
/* step 4: remove empty page table */
if (!pml) {
pml = pmd_lock(mm, pmd);
- if (ptl != pml) {
+ if (ptl != pml)
spin_lock_nested(ptl, SINGLE_DEPTH_NESTING);
- if (unlikely(!pmd_same(pgt_pmd, pmdp_get_lockless(pmd)))) {
- flush_tlb_mm(mm);
- goto unlock;
- }
+ if (unlikely(!pmd_same(pgt_pmd, pmdp_get_lockless(pmd)))) {
+ flush_tlb_mm(mm);
+ goto unlock;
}
}
pgt_pmd = pmdp_collapse_flush(vma, haddr, pmd);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 305/507] mm/khugepaged: fix PMD table lock leak in try_collapse_pte_mapped_thp()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (303 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 304/507] mm/khugepaged: always recheck the pmd in try_collapse_pte_mapped_thp() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 306/507] mm/khugepaged: preserve dirty bits when collapsing PTE-mapped THPs Greg Kroah-Hartman
` (201 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Gregory Price (Meta),
Muhammad Usama Anjum, Lance Yang, Baolin Wang,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit db38b902307e687219ec765ef51a6ef459746c87 ]
For a private mapping with userfaultfd, try_collapse_pte_mapped_thp()
takes the PMD table lock before it maps the page table for the second time.
If that (pte_offset_map_rw_nolock) fails, because the page table vanished
in the meantime due to concurrent page table reclaim, it leaves through
the abort label, where the PMD table lock is unlocked if it differs from
PTE table lock.
In case the PMD table lock and the PTE table lock match, which is the
case without CONFIG_SPLIT_PTE_PTLOCKS after pte_offset_map_rw_nolock()
failed, we miss to unlock the PMD table.
To fix it, forget the PTE table lock when we unmap+unlock the PTE table.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: 6375e95f381e ("mm: pgtable: reclaim empty PTE page in madvise(MADV_DONTNEED)")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
[ david: move the ptl = NULL handling; rewrite description, drop wrong comments ]
Reviewed-by: Gregory Price (Meta) <gourry@gourry.net>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-16-d6437171ecc3@kernel.org
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/khugepaged.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 9cd468307841f..065030fb3e327 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -1928,7 +1928,7 @@ static enum scan_result try_collapse_pte_mapped_thp(struct mm_struct *mm, unsign
result = SCAN_FAIL;
start_pte = pte_offset_map_lock(mm, pmd, haddr, &ptl);
- if (!start_pte) /* mmap_lock + page lock should prevent this */
+ if (!start_pte)
goto drop_folio;
/* step 1: check all mapped PTEs are to the right huge page */
@@ -1959,6 +1959,7 @@ static enum scan_result try_collapse_pte_mapped_thp(struct mm_struct *mm, unsign
}
pte_unmap_unlock(start_pte, ptl);
+ ptl = NULL;
mmu_notifier_range_init(&range, MMU_NOTIFY_CLEAR, 0, mm,
haddr, haddr + HPAGE_PMD_SIZE);
mmu_notifier_invalidate_range_start(&range);
@@ -1976,7 +1977,7 @@ static enum scan_result try_collapse_pte_mapped_thp(struct mm_struct *mm, unsign
pml = pmd_lock(mm, pmd);
start_pte = pte_offset_map_rw_nolock(mm, pmd, haddr, &pgt_pmd, &ptl);
- if (!start_pte) /* mmap_lock + page lock should prevent this */
+ if (!start_pte)
goto abort;
if (!pml)
spin_lock(ptl);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 306/507] mm/khugepaged: preserve dirty bits when collapsing PTE-mapped THPs
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (304 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 305/507] mm/khugepaged: fix PMD table lock leak " Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 307/507] mm/gup: recheck the PUD under PTL in follow_pud_mask() Greg Kroah-Hartman
` (200 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Pedro Falcato,
Gregory Price (Meta), Muhammad Usama Anjum, Lance Yang,
Baolin Wang, David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit fe2817e3d5ea347214342c9a5cd8bcbff20c0574 ]
try_collapse_pte_mapped_thp() clears PTEs without transferring their dirty
bits to the folio. A shmem read fault can map a clean folio writable, so
a later store only dirties the PTE. Losing that dirty bit allows reclaim
to discard modified data.
The assumption that regular files are read-only is also obsolete since
commit 1b6444331bebb ("mm/khugepaged: enable clean pagecache folio collapse
for writable files"). In any case, transferring PTE dirty bits to the folio
when removing mappings (and while the folio is still mapped) is the right
thing to do.
Use get_and_clear_ptes() to collect the dirty bits and mark the folio
dirty before unmapping it. Update the comment.
This was reproduced with shmem using MADV_COLLAPSE followed by
MADV_PAGEOUT.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: 27e1f8273113 ("khugepaged: enable collapse pmd for pte-mapped THP")
Fixes: 1b6444331bebb ("mm/khugepaged: enable clean pagecache folio collapse for writable files")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
[ david: adjust comment; simplify description; cover file-thp as well ]
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Reviewed-by: Gregory Price (Meta) <gourry@gourry.net>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-17-d6437171ecc3@kernel.org
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/khugepaged.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 065030fb3e327..8fc8f79641ea5 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -2019,9 +2019,10 @@ static enum scan_result try_collapse_pte_mapped_thp(struct mm_struct *mm, unsign
/*
* Must clear entry, or a racing truncate may re-remove it.
* TLB flush can be left until pmdp_collapse_flush() does it.
- * PTE dirty? Shmem page is already dirty; file is read-only.
*/
- clear_ptes(mm, addr, pte, nr_batch_ptes);
+ ptent = get_and_clear_ptes(mm, addr, pte, nr_batch_ptes);
+ if (pte_dirty(ptent))
+ folio_mark_dirty(folio);
folio_remove_rmap_ptes(folio, page, nr_batch_ptes, vma);
nr_mapped_ptes += nr_batch_ptes;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 307/507] mm/gup: recheck the PUD under PTL in follow_pud_mask()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (305 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 306/507] mm/khugepaged: preserve dirty bits when collapsing PTE-mapped THPs Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 308/507] mm/gup: fix clearing folios in memfd_pin_folios() Greg Kroah-Hartman
` (199 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Muhammad Usama Anjum,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 79cb51d538abc459f74e046d27797d36b133ce0e ]
follow_pud_mask() reads the PUD without a lock. If it is a leaf, it takes
the lock and calls follow_huge_pud(), which reads the entry again, but
only tests whether it is present.
A leaf can be zapped concurrently and a page fault can fill the empty
entry with a page table.
This currently only applies when device-dax makes use of PUD entries,
and the fault after e.g., MADV_DONTNEED would find THPs to be disabled.
That requires a sequence like
1) Fault in the PUD
2) Disable THP
3) Have GUP race against concurrent MADV_DONTNEED + refault
Which is rather unlikely to happen in practice, which is why we never
received a report about such a problem.
Before commit 1b1676180246 ("mm/gup: handle huge pud for
follow_pud_mask()"), we performed that check in follow_devmap_pud() by
testing for pud_devmap().
Let's fix it by just structuring follow_pud_mask() similar to
follow_pmd_mask(), minus protnone stuff that does not apply and minus
FOLL_SPLIT_PMD handling. That makes it much easier to spot any such
inconsistencies.
Perform the pud_bad() check early in follow_pmd_mask() and just forward
the PUD value. We can drop the pud_present() check in follow_huge_pud(),
just like we have in follow_huge_pmd().
Even though we are performing more changes than strictly necessary, the
fix should be easy to backport.
Fixes: 1b1676180246 ("mm/gup: handle huge pud for follow_pud_mask()")
Cc: stable@vger.kernel.org
Reported-by: Josef Bacik <josef@toxicpanda.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-19-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/gup.c | 32 ++++++++++++++++++--------------
1 file changed, 18 insertions(+), 14 deletions(-)
diff --git a/mm/gup.c b/mm/gup.c
index eb898ea1ee22e..6a101ff74a29f 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -658,9 +658,6 @@ static struct page *follow_huge_pud(struct vm_area_struct *vma,
assert_spin_locked(pud_lockptr(mm, pudp));
- if (!pud_present(pud))
- return NULL;
-
if ((flags & FOLL_WRITE) &&
!can_follow_write_pud(pud, pfn_to_page(pfn), vma, flags))
return NULL;
@@ -896,15 +893,17 @@ static struct page *follow_page_pte(struct vm_area_struct *vma,
}
static struct page *follow_pmd_mask(struct vm_area_struct *vma,
- unsigned long address, pud_t *pudp,
- unsigned int flags,
- unsigned long *page_mask)
+ unsigned long address, pud_t *pudp, pud_t pud,
+ unsigned int flags, unsigned long *page_mask)
{
pmd_t *pmd, pmdval;
spinlock_t *ptl;
struct page *page;
struct mm_struct *mm = vma->vm_mm;
+ if (unlikely(pud_bad(pud)))
+ return no_page_table(vma, flags, address);
+
pmd = pmd_offset(pudp, address);
pmdval = pmdp_get_lockless(pmd);
if (pmd_none(pmdval))
@@ -953,18 +952,23 @@ static struct page *follow_pud_mask(struct vm_area_struct *vma,
pud = pudp_get(pudp);
if (!pud_present(pud))
return no_page_table(vma, flags, address);
- if (pud_leaf(pud)) {
- ptl = pud_lock(mm, pudp);
- page = follow_huge_pud(vma, address, pudp, flags, page_mask);
+ if (!pud_leaf(pud))
+ return follow_pmd_mask(vma, address, pudp, pud, flags, page_mask);
+
+ ptl = pud_lock(mm, pudp);
+ pud = *pudp;
+ if (unlikely(!pud_present(pud))) {
spin_unlock(ptl);
- if (page)
- return page;
return no_page_table(vma, flags, address);
}
- if (unlikely(pud_bad(pud)))
- return no_page_table(vma, flags, address);
+ if (unlikely(!pud_leaf(pud))) {
+ spin_unlock(ptl);
+ return follow_pmd_mask(vma, address, pudp, pud, flags, page_mask);
+ }
- return follow_pmd_mask(vma, address, pudp, flags, page_mask);
+ page = follow_huge_pud(vma, address, pudp, flags, page_mask);
+ spin_unlock(ptl);
+ return page;
}
static struct page *follow_p4d_mask(struct vm_area_struct *vma,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 308/507] mm/gup: fix clearing folios in memfd_pin_folios()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (306 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 307/507] mm/gup: recheck the PUD under PTL in follow_pud_mask() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 309/507] mm/gup: fix out-of-bounds write for nr_pages == 0 in GUP-fast Greg Kroah-Hartman
` (198 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Pratyush Yadav (Google),
Samiullah Khawaja, Muhammad Usama Anjum, Lance Yang,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit c83ee2fa5a94edb2e04102b9dd4f1ee0eeb2b932 ]
memfd_pin_folios() pins folios obtained directly from the page cache
without checking whether they are uptodate. However, shmem fallocate()
can leave newly allocated folios uncleared and not uptodate. Callers
such as udmabuf can then expose uninitialized memory to userspace.
Clear non-uptodate folios and mark them uptodate under the folio lock
before returning them to the caller.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: 89c1905d9c14 ("mm/gup: introduce memfd_pin_folios() for pinning memfd folios")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
[ david: simplify description and comment ]
Reviewed-by: Pratyush Yadav (Google) <pratyush@kernel.org>
Reviewed-by: Samiullah Khawaja <skhawaja@google.com>
Tested-by: Samiullah Khawaja <skhawaja@google.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-20-d6437171ecc3@kernel.org
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/gup.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/mm/gup.c b/mm/gup.c
index 6a101ff74a29f..cc63c6a0e5f37 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -3502,6 +3502,20 @@ long memfd_pin_folios(struct file *memfd, loff_t start, loff_t end,
goto err;
}
+ /*
+ * fallocate() can leave folios in the
+ * page cache that were never cleared.
+ */
+ if (!folio_test_uptodate(folio)) {
+ folio_lock(folio);
+ if (!folio_test_uptodate(folio)) {
+ folio_zero_range(folio, 0, folio_size(folio));
+ flush_dcache_folio(folio);
+ folio_mark_uptodate(folio);
+ }
+ folio_unlock(folio);
+ }
+
if (nr_folios == 0)
*offset = offset_in_folio(folio, start);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 309/507] mm/gup: fix out-of-bounds write for nr_pages == 0 in GUP-fast
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (307 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 308/507] mm/gup: fix clearing folios in memfd_pin_folios() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 310/507] mm/gup: check for overflow when converting nr_pages to bytes " Greg Kroah-Hartman
` (197 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Lorenzo Stoakes (ARM),
Muchun Song, Muhammad Usama Anjum, David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit 1dfe4b276c23189394afb42d114ee8a54cc3aff2 ]
With nr_pages == 0, GUP-fast still enters its page table walk and can
write past the caller's page array. The old end <= start check caught
empty ranges, but was replaced with an overflow check.
Users such as OrangeFS can pass a zero page count derived from a
userspace-supplied length. So let's return zero for nr_pages == 0 before
starting the walk, just like GUP-slow.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: c28b1fc70390 ("mm/gup: reorganize internal_get_user_pages_fast()")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
[ david: simplify description ]
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Acked-by: Muchun Song <muchun.song@linux.dev>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-21-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/gup.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/mm/gup.c b/mm/gup.c
index cc63c6a0e5f37..17f4150a6d7c6 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -3190,6 +3190,9 @@ static int gup_fast_fallback(unsigned long start, unsigned long nr_pages,
FOLL_PCI_P2PDMA | FOLL_HONOR_NUMA_FAULT)))
return -EINVAL;
+ if (unlikely(!nr_pages))
+ return 0;
+
if (gup_flags & FOLL_PIN)
mm_set_has_pinned_flag(current->mm);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 310/507] mm/gup: check for overflow when converting nr_pages to bytes in GUP-fast
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (308 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 309/507] mm/gup: fix out-of-bounds write for nr_pages == 0 in GUP-fast Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 311/507] mm/userfaultfd: write-lock the VMA before waking waiters when unregistering Greg Kroah-Hartman
` (196 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM), Muchun Song,
Barry Song, Muhammad Usama Anjum, David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 21a3888d3d2f87b7f15ccea1f0befd57346fe899 ]
The overflow check in gup_fast_fallback() only covers the addition to
start. The preceding nr_pages << PAGE_SHIFT can already have truncated
the length on 32bit.
Users such as RapidIO's rio_dma_transfer() can derive such page counts
from a 64-bit userspace length.
Let's just check_shl_overflow() to reject any such overflow with
-EOVERFLOW early.
Fixes: c28b1fc70390 ("mm/gup: reorganize internal_get_user_pages_fast()")
Cc: stable@vger.kernel.org
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Acked-by: Muchun Song <muchun.song@linux.dev>
Reviewed-by: Barry Song <baohua@kernel.org>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-22-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/gup.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mm/gup.c b/mm/gup.c
index 17f4150a6d7c6..b3937aff3ad44 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -3200,8 +3200,8 @@ static int gup_fast_fallback(unsigned long start, unsigned long nr_pages,
might_lock_read(¤t->mm->mmap_lock);
start = untagged_addr(start) & PAGE_MASK;
- len = nr_pages << PAGE_SHIFT;
- if (check_add_overflow(start, len, &end))
+ if (check_shl_overflow(nr_pages, PAGE_SHIFT, &len) ||
+ check_add_overflow(start, len, &end))
return -EOVERFLOW;
if (end > TASK_SIZE_MAX)
return -EFAULT;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 311/507] mm/userfaultfd: write-lock the VMA before waking waiters when unregistering
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (309 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 310/507] mm/gup: check for overflow when converting nr_pages to bytes " Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 312/507] mm/userfaultfd: wake all waiters on unregister Greg Kroah-Hartman
` (195 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik,
Mike Rapoport (Microsoft), Lorenzo Stoakes (ARM),
Suren Baghdasaryan, Muhammad Usama Anjum, David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 35f7ecd55ce7e51cb6d5ef49e6dd51f3c80f61e4 ]
userfaultfd_unregister() wakes pending missing faults before clearing the
VMA's userfaultfd registration. With per-VMA fault locking, holding
mmap_lock for write does not prevent another fault from queuing after
the wakeup but before userfaultfd_clear_vma() write-locks the VMA. That
waiter can then remain asleep indefinitely.
Call vma_start_write() before waking waiters. Existing fault handlers
queue themselves before dropping the VMA read lock, and new readers are
excluded until mmap_write_unlock().
Fixes: 29a22b9e08d7 ("mm: handle userfaults under VMA lock")
Cc: stable@vger.kernel.org
Reported-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Suren Baghdasaryan <surenb@google.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-23-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/userfaultfd.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 500962be11624..ddce409db0ad7 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -4035,6 +4035,9 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
start = vma->vm_start;
vma_end = min(end, vma->vm_end);
+ /* Prevent new userfaults from being queued after the wakeup. */
+ vma_start_write(vma);
+
if (userfaultfd_missing(vma)) {
/*
* Wake any concurrent pending userfault while
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 312/507] mm/userfaultfd: wake all waiters on unregister
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (310 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 311/507] mm/userfaultfd: write-lock the VMA before waking waiters when unregistering Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 313/507] mm/mmu_gather: fix flushing ranges with 4 GiB or larger Greg Kroah-Hartman
` (194 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik,
Mike Rapoport (Microsoft), Lorenzo Stoakes (ARM),
Muhammad Usama Anjum, David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit 3afb19d68cc5e7851fdb1069c8094af97bd80417 ]
UFFDIO_UNREGISTER only wakes pending faults if VM_UFFD_MISSING is set.
Threads waiting on write-protect, minor or RWP faults can therefore remain
asleep after unregistering a range that does not track missing faults.
Wake pending faults regardless of the registration mode so they can retry
without an explicit UFFDIO_WAKE or closing the userfaultfd. This matches
the existing behavior for missing faults, including removing unread fault
messages for the woken waiters.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
[ david: rebase; simplify description ]
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-24-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/userfaultfd.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index ddce409db0ad7..5689df692401e 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -4021,6 +4021,8 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
ret = 0;
for_each_vma_range(vmi, vma, end) {
+ struct userfaultfd_wake_range range;
+
cond_resched();
/* VMA not registered with userfaultfd. */
@@ -4038,18 +4040,14 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
/* Prevent new userfaults from being queued after the wakeup. */
vma_start_write(vma);
- if (userfaultfd_missing(vma)) {
- /*
- * Wake any concurrent pending userfault while
- * we unregister, so they will not hang
- * permanently and it avoids userland to call
- * UFFDIO_WAKE explicitly.
- */
- struct userfaultfd_wake_range range;
- range.start = start;
- range.len = vma_end - start;
- wake_userfault(vma->vm_userfaultfd_ctx.ctx, &range);
- }
+ /*
+ * Wake any concurrent pending userfault while we unregister,
+ * so they will not hang permanently and it avoids userland to
+ * call UFFDIO_WAKE explicitly.
+ */
+ range.start = start;
+ range.len = vma_end - start;
+ wake_userfault(ctx, &range);
vma = userfaultfd_clear_vma(&vmi, prev, vma,
start, vma_end);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 313/507] mm/mmu_gather: fix flushing ranges with 4 GiB or larger
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (311 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 312/507] mm/userfaultfd: wake all waiters on unregister Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 314/507] mm/mmu_notifier: finish non-blocking interval invalidation on error Greg Kroah-Hartman
` (193 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Lorenzo Stoakes (ARM),
Qi Zheng, Gregory Price (Meta), Dev Jain, Muchun Song,
Pedro Falcato, SJ Park, Muhammad Usama Anjum,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit 64ae7959a1df8af8eec504e31df2ec9670424a4e ]
__tlb_adjust_range() takes the size of the range which has to be flushed
as an unsigned int. Its callers, tlb_flush_{pte,pmd,pud,p4d}_range(), get
and pass an unsigned long. Consequently, a range that is 4 GiB or larger
gets truncated, possibly to 0.
On arm64 with hugetlb, a 64k kernel can have 16 GiB hugetlb folios
mapped contiguously at the PMD level and flush them when unmapping, and a
16k kernel can flush 64 GiB PUDs through tlb_unshare_pmd_ptdesc(). So
at least these two scenarios are affected.
Fix it by flushing the proper range instead of the truncated one by
properly using "unsigned long" for range_size.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: b528e4b6405b ("mm/hugetlb: add tlb_remove_hugetlb_entry for handling hugetlb pages")
Fixes: 8ce720d5bd91 ("mm/hugetlb: fix excessive IPI broadcasts when unsharing PMD tables using mmu_gather")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
[ david: use two-tab indent, simplify description ]
Reviewed-by: Qi Zheng <qi.zheng@linux.dev>
Reviewed-by: Gregory Price (Meta) <gourry@gourry.net>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Reviewed-by: Dev Jain <dev.jain@arm.com>
Reviewed-by: Muchun Song <muchun.song@linux.dev>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Reviewed-by: SJ Park <sj@kernel.org>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-27-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/asm-generic/tlb.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index bdcc2778ac64f..32ffffd9d7b98 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -398,8 +398,7 @@ struct mmu_gather {
void tlb_flush_mmu(struct mmu_gather *tlb);
static inline void __tlb_adjust_range(struct mmu_gather *tlb,
- unsigned long address,
- unsigned int range_size)
+ unsigned long address, unsigned long range_size)
{
tlb->start = min(tlb->start, address);
tlb->end = max(tlb->end, address + range_size);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 314/507] mm/mmu_notifier: finish non-blocking interval invalidation on error
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (312 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 313/507] mm/mmu_gather: fix flushing ranges with 4 GiB or larger Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 315/507] mm/mmu_notifier: set ->mm only after mmgrab() Greg Kroah-Hartman
` (192 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Lorenzo Stoakes (ARM),
Muhammad Usama Anjum, David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit 6d65925777ecae9d7a571a327e41c63f3940a0c7 ]
When an ordinary MMU notifier rejects a non-blocking invalidation, the
interval invalidation started beforehand is left unfinished: the caller
skips mmu_notifier_invalidate_range_end(). Subsequent interval notifier
operations can then wait forever.
The only in-tree trigger is nouveau SVM, which uses both notifier types
and rejects non-blocking invalidations. Reaping via the OOM reaper or
process_mrelease() can therefore leave the GPU fault worker stuck,
holding a reference that prevents the dying process's address space
and memory from being freed.
End the interval invalidation when an ordinary notifier fails a
non-blocking invalidation, like mn_itree_invalidate() already does when
an interval notifier fails. Make that handling clearer in the
documentation of mmu_notifier_invalidate_range_start_nonblock().
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: 99cb252f5e68 ("mm/mmu_notifier: add an interval tree notifier")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
[ david: simplify description, update function doc ]
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-28-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/mmu_notifier.h | 3 ++-
mm/mmu_notifier.c | 17 +++++++++++++----
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h
index a11a44eef521e..5db78e5761c5c 100644
--- a/include/linux/mmu_notifier.h
+++ b/include/linux/mmu_notifier.h
@@ -483,7 +483,8 @@ mmu_notifier_invalidate_range_start(struct mmu_notifier_range *range)
/*
* This version of mmu_notifier_invalidate_range_start() avoids blocking, but it
* can return an error if a notifier can't proceed without blocking, in which
- * case you're not allowed to modify PTEs in the specified range.
+ * case you're not allowed to modify PTEs in the specified range or call
+ * mmu_notifier_invalidate_range_end().
*
* This is mainly intended for OOM handling.
*/
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c
index df69ba6e797f7..2e20f88e162d7 100644
--- a/mm/mmu_notifier.c
+++ b/mm/mmu_notifier.c
@@ -569,16 +569,25 @@ int __mmu_notifier_invalidate_range_start(struct mmu_notifier_range *range)
{
struct mmu_notifier_subscriptions *subscriptions =
range->mm->notifier_subscriptions;
- int ret;
+ const bool has_itree = subscriptions->has_itree;
+ int ret = 0;
- if (subscriptions->has_itree) {
+ if (has_itree) {
ret = mn_itree_invalidate(subscriptions, range);
if (ret)
return ret;
}
if (!hlist_empty(&subscriptions->list))
- return mn_hlist_invalidate_range_start(subscriptions, range);
- return 0;
+ ret = mn_hlist_invalidate_range_start(subscriptions, range);
+
+ /*
+ * On error, the non-blocking caller is not allowed to call
+ * invalidate_range_end(), as in mn_itree_invalidate().
+ */
+ if (ret && has_itree && !mmu_notifier_range_blockable(range))
+ mn_itree_inv_end(subscriptions);
+
+ return ret;
}
static void
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 315/507] mm/mmu_notifier: set ->mm only after mmgrab()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (313 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 314/507] mm/mmu_notifier: finish non-blocking interval invalidation on error Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 316/507] mm/mremap: use pudp_huge_get_and_clear() when moving huge PUDs Greg Kroah-Hartman
` (191 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Gregory Price (Meta),
Lorenzo Stoakes (ARM), Muhammad Usama Anjum,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit 5ad9e4b0f1104f5dbfb41125c34bb30ea6dc7a94 ]
Radeon uses a non-NULL notifier->mm to decide whether to call
mmu_interval_notifier_remove() when freeing a buffer object.
__mmu_interval_notifier_insert() sets ->mm before validating the range,
so a wrapping userptr range can leave ->mm set after insertion fails.
Cleanup then tries to remove an unregistered notifier for which no mm
reference was acquired.
Set ->mm only after mmgrab(), once insertion can no longer fail. While
we could fix radeon's code instead, setting ->mm on success only makes
the code more robust.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: 3506ff69c3ec ("drm/radeon: use mmu_interval_notifier_insert")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
[ david: simplify description ]
Reviewed-by: Gregory Price (Meta) <gourry@gourry.net>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-29-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/mmu_notifier.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c
index 2e20f88e162d7..a7bae5de5fedc 100644
--- a/mm/mmu_notifier.c
+++ b/mm/mmu_notifier.c
@@ -947,7 +947,6 @@ static int __mmu_interval_notifier_insert(
struct mmu_notifier_subscriptions *subscriptions, unsigned long start,
unsigned long length, const struct mmu_interval_notifier_ops *ops)
{
- interval_sub->mm = mm;
interval_sub->ops = ops;
RB_CLEAR_NODE(&interval_sub->interval_tree.rb);
interval_sub->interval_tree.start = start;
@@ -964,8 +963,12 @@ static int __mmu_interval_notifier_insert(
if (WARN_ON(atomic_read(&mm->mm_users) <= 0))
return -EINVAL;
- /* pairs with mmdrop in mmu_interval_notifier_remove() */
+ /*
+ * Pairs with mmdrop in mmu_interval_notifier_remove(). Drivers take a
+ * non-NULL ->mm for "registered", so set it only with the reference.
+ */
mmgrab(mm);
+ interval_sub->mm = mm;
/*
* If some invalidate_range_start/end region is going on in parallel
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 316/507] mm/mremap: use pudp_huge_get_and_clear() when moving huge PUDs
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (314 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 315/507] mm/mmu_notifier: set ->mm only after mmgrab() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 317/507] mm/mremap: recheck PUDs under the page table lock Greg Kroah-Hartman
` (190 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM), Pedro Falcato,
Dev Jain, Muhammad Usama Anjum, Lance Yang,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit b4417d08034a7b4a3083e0e2d95429d4542524f2 ]
move_huge_pud() reads the old PUD and clears it in separate operations.
Hardware accessed or dirty updates between those operations can be lost
when the saved entry is installed at the new address.
The raw pud_clear() also bypasses page_table_check_pud_clear(), while
set_pud_at() accounts for the destination mapping. This leaves the
checker counts unbalanced for mappings tracked by page table checking.
To fix it, simply use pudp_huge_get_and_clear().
Fixes: 7d846db7d0e2 ("mm/mremap: convert huge PUD move to separate helper")
Cc: stable@vger.kernel.org
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Reviewed-by: Dev Jain <dev.jain@arm.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-30-d6437171ecc3@kernel.org
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/mremap.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/mm/mremap.c b/mm/mremap.c
index d404e4b1b6cbd..961569eaa8d7c 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -509,8 +509,7 @@ static bool move_huge_pud(struct pagetable_move_control *pmc,
spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
/* Clear the pud */
- pud = *old_pud;
- pud_clear(old_pud);
+ pud = pudp_huge_get_and_clear(mm, pmc->old_addr, old_pud);
VM_BUG_ON(!pud_none(*new_pud));
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 317/507] mm/mremap: recheck PUDs under the page table lock
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (315 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 316/507] mm/mremap: use pudp_huge_get_and_clear() when moving huge PUDs Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 318/507] mm/mremap: fix moving PUD leaves Greg Kroah-Hartman
` (189 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM), Pedro Falcato,
Muhammad Usama Anjum, Lance Yang, David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 402882943dfa8bab5c2bcc66189f9fb2828f248e ]
Once get_old_pud() is fixed to accept PUD leaves, unmap_mapping_range() can
clear a leaf between the lookup and the move. Holding mmap_lock in write
mode does not prevent this.
If the zap happens before move_page_tables() tests the entry, an empty
PUD can reach move_normal_pud(), where pud_populate() turns it into a
present page table entry. If it happens after the test, move_huge_pud()
can instead try to move an empty entry, triggering CONFIG_DEBUG_VM
warnings on powerpc.
Recheck the source under the page table lock in both helpers. Treat an
empty source in move_normal_pud() as a completed move, and use
__pud_trans_huge_lock() in move_huge_pud().
In the future we should likely have the code lookup a PUD/PMD lockless
once, instead of multiple times, because one of the problematic bits
here is the:
pud_trans_huge(*old_pud)
Fixes: 0881ace292b6 ("mm/mremap: use pmd/pud_poplulate to update page table entries")
Cc: stable@vger.kernel.org
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-31-d6437171ecc3@kernel.org
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/mremap.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/mm/mremap.c b/mm/mremap.c
index 961569eaa8d7c..fd4da262ea13c 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -461,14 +461,18 @@ static bool move_normal_pud(struct pagetable_move_control *pmc,
if (new_ptl != old_ptl)
spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
- /* Clear the pud */
pud = *old_pud;
+ if (unlikely(pud_none(pud)))
+ goto out_unlock;
+
+ /* Clear the pud */
pud_clear(old_pud);
VM_BUG_ON(!pud_none(*new_pud));
pud_populate(mm, new_pud, pud_pgtable(pud));
flush_tlb_range(vma, pmc->old_addr, pmc->old_addr + PUD_SIZE);
+out_unlock:
if (new_ptl != old_ptl)
spin_unlock(new_ptl);
spin_unlock(old_ptl);
@@ -503,7 +507,9 @@ static bool move_huge_pud(struct pagetable_move_control *pmc,
* We don't have to worry about the ordering of src and dst
* ptlocks because exclusive mmap_lock prevents deadlock.
*/
- old_ptl = pud_lock(mm, old_pud);
+ old_ptl = __pud_trans_huge_lock(old_pud, vma);
+ if (unlikely(!old_ptl))
+ return false;
new_ptl = pud_lockptr(mm, new_pud);
if (new_ptl != old_ptl)
spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 318/507] mm/mremap: fix moving PUD leaves
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (316 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 317/507] mm/mremap: recheck PUDs under the page table lock Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 319/507] mm/madvise: fix data loss from MADV_FREE on a KSM page Greg Kroah-Hartman
` (188 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Lorenzo Stoakes (ARM),
Pedro Falcato, Muhammad Usama Anjum, Lance Yang,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit 440c8779757f09f290770b1d361dc1516a9d0b3e ]
pud_none_or_clear_bad() only really works on page tables. PUD leaves
confuse the check and make us clear the page table entry and print a
warning.
Since commit aed877c2b4257 ("device/dax: properly refcount device dax pages
when mapping"), this also leaks device-DAX folio references, mapcounts
and RSS accounting, resulting in "Bad rss-counter state" warnings on exit.
Allow PUD leaves in get_old_pud(). If a PUD leaf cannot be moved as a
whole or the move fails, split it. This unmaps it with proper accounting
instead of treating the leaf entry as a PMD table.
Keep using pud_trans_huge() for now, in the future this code should be
cleaned up to just check for PUD leaves.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: a00cc7d9dd93 ("mm, x86: add support for PUD-sized transparent hugepages")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
[ david: fallthrough after splitting ]
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-32-d6437171ecc3@kernel.org
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/mremap.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/mm/mremap.c b/mm/mremap.c
index fd4da262ea13c..b6e0a4206016b 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -87,7 +87,7 @@ static pud_t *get_old_pud(struct mm_struct *mm, unsigned long addr)
return NULL;
pud = pud_offset(p4d, addr);
- if (pud_none_or_clear_bad(pud))
+ if (!pud_trans_huge(*pud) && pud_none_or_clear_bad(pud))
return NULL;
return pud;
@@ -847,11 +847,10 @@ unsigned long move_page_tables(struct pagetable_move_control *pmc)
if (!new_pud)
break;
if (pud_trans_huge(*old_pud)) {
- if (extent == HPAGE_PUD_SIZE) {
- move_pgt_entry(pmc, HPAGE_PUD, old_pud, new_pud);
- /* We ignore and continue on error? */
+ if (extent == HPAGE_PUD_SIZE &&
+ move_pgt_entry(pmc, HPAGE_PUD, old_pud, new_pud))
continue;
- }
+ split_huge_pud(pmc->old, old_pud, pmc->old_addr);
} else if (IS_ENABLED(CONFIG_HAVE_MOVE_PUD) && extent == PUD_SIZE) {
if (move_pgt_entry(pmc, NORMAL_PUD, old_pud, new_pud))
continue;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 319/507] mm/madvise: fix data loss from MADV_FREE on a KSM page
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (317 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 318/507] mm/mremap: fix moving PUD leaves Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 320/507] mm/memory: reject remote COW faults on PFN mappings Greg Kroah-Hartman
` (187 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Lorenzo Stoakes (ARM),
Xu Xin, Muhammad Usama Anjum, David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 22d043c1da48d6c7274f9dd900714b6d58b7b9c6 ]
MADV_FREE can clear the dirty flag of a singly mapped KSM folio. The
folio remains in the stable tree and can gain new mappings without being
dirtied again. Once marked lazyfree, reclaim can discard data that those
mappings still need.
KSM always marks a folio dirty when converting it to a KSM folio in
try_to_merge_one_page(). Marking a folio lazyfree clears PG_swapbacked
but leaves PG_dirty unchanged. Preserving PG_dirty makes reclaim restore
PG_swapbacked instead of discarding the folio. This also protects folios
that were already lazyfree when KSM converted them.
Skip KSM folios before clearing their dirty flag, checking under the
folio lock to serialize with KSM conversion.
Fixes: 854e9ed09ded ("mm: support madvise(MADV_FREE)")
Cc: stable@vger.kernel.org
Reported-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Xu Xin <xu.xin@linux.dev>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-34-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/madvise.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/mm/madvise.c b/mm/madvise.c
index 54d8397059ba6..222c10eb61eb4 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -755,6 +755,15 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
if (folio_test_swapcache(folio) || folio_test_dirty(folio)) {
if (!folio_trylock(folio))
continue;
+ /*
+ * KSM folios can gain new mappings at any time, so we must
+ * not clear their dirty flag.
+ */
+ if (folio_test_ksm(folio)) {
+ folio_unlock(folio);
+ continue;
+ }
+
/*
* If we have a large folio at this point, we know it is
* fully mapped so if its mapcount is the same as its
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 320/507] mm/memory: reject remote COW faults on PFN mappings
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (318 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 319/507] mm/madvise: fix data loss from MADV_FREE on a KSM page Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 321/507] mm: fix unmap_mapping_range() beyond 4 GiB on 32-bit Greg Kroah-Hartman
` (186 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Lorenzo Stoakes (ARM),
Pedro Falcato, Muhammad Usama Anjum, David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit 8db6921cc07b74197a3866d62ed262b68aeadcf3 ]
When handling a COW fault without a normal source page (PFN mappings),
__wp_page_copy_user() copies from the faulting user address. For remote
faults, this accesses the wrong address space, resulting in wrong data
getting copied.
For example, user_events updates an enable bit in the registering
process's memory. If that memory needs to be faulted in,
user_event_enabler_fault_fixup() calls fixup_user_fault() from a work
item. Placing the enable bit in a private PFN mapping can trigger this
remote COW path.
Reject these faults with VM_FAULT_SIGBUS when the target mm differs from
current->mm: remote faults. Ordinary (non-PFN) mappings are not affected.
The user-address copy dates back to commit 6aab341e0a28 ("mm: re-architect
the VM_UNPAGED logic"); likely, actual ways to get remote faults in
there on COW PFN mappings appeared afterwards. But the fix is simple and
straight forward.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: 6aab341e0a28 ("mm: re-architect the VM_UNPAGED logic")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
[ david: simplify comment and description ]
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-35-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/memory.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/mm/memory.c b/mm/memory.c
index 88f7953afbabc..c2d3d8d94346d 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3703,6 +3703,13 @@ static inline int __wp_page_copy_user(struct page *dst, struct page *src,
return 0;
}
+ /*
+ * __copy_from_user_inatomic() only works as expected for local faults.
+ * Reject remote faults.
+ */
+ if (unlikely(mm != current->mm))
+ return -EFAULT;
+
/*
* If the source page was a PFN mapping, we don't have
* a "struct page" for it. We do a best-effort copy by
@@ -4028,6 +4035,8 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf)
folio_put(old_folio);
delayacct_wpcopy_end();
+ if (err == -EFAULT)
+ return VM_FAULT_SIGBUS;
return err == -EHWPOISON ? VM_FAULT_HWPOISON : 0;
}
kmsan_copy_page_meta(&new_folio->page, vmf->page);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 321/507] mm: fix unmap_mapping_range() beyond 4 GiB on 32-bit
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (319 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 320/507] mm/memory: reject remote COW faults on PFN mappings Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 322/507] mm: fix unkillable fault loop on MAP_DROPPABLE memory Greg Kroah-Hartman
` (185 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Lorenzo Stoakes (ARM),
Pedro Falcato, Muhammad Usama Anjum, David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit 7a81bc23dade8082187be6d9cc36e4be4b7207e2 ]
Commit 9eab0421fa94 ("mm: fix unmap_mapping_range high bits shift bug")
made holebegin and holelen unsigned before they are shifted, by casting
them to pgoff_t. That is an unsigned long: on a 32-bit kernel the cast
cuts off the upper half of the two loff_t values, so a hole which begins
at 4 GiB or beyond is taken for one in the first 4 GiB of the file.
truncate_pagecache() passes the new size of the file and asks for private
COWed pages to be unmapped as well. If a file of 6 GiB is truncated to
5 GiB, everything from 1 GiB on is unmapped, and what a process has
written to a private mapping of the range between 1 GiB and 5 GiB is
lost: it reads the contents of the file again.
Where the range has an end, the wrong range is unmapped instead of the
right one. The page cache copes with that, as it unmaps every folio that
it removes. The callers which only have unmap_mapping_range() to get
rid of user mappings do not, for example drm_vma_node_unmap(), whose fake
offsets reach beyond 4 GiB on 32-bit, and revoke_iomem() with physical
addresses of more than 32 bits.
Cast to u64 instead. Nothing changes for 64-bit kernels.
Fix generated by an LLM and sent by Josef Bacik in private.
Fixes: 9eab0421fa94 ("mm: fix unmap_mapping_range high bits shift bug")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-36-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/memory.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mm/memory.c b/mm/memory.c
index c2d3d8d94346d..e773d51f0d6fc 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4594,8 +4594,8 @@ EXPORT_SYMBOL_GPL(unmap_mapping_pages);
void unmap_mapping_range(struct address_space *mapping,
loff_t const holebegin, loff_t const holelen, int even_cows)
{
- pgoff_t hba = (pgoff_t)(holebegin) >> PAGE_SHIFT;
- pgoff_t hlen = ((pgoff_t)(holelen) + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ pgoff_t hba = (u64)holebegin >> PAGE_SHIFT;
+ pgoff_t hlen = ((u64)holelen + PAGE_SIZE - 1) >> PAGE_SHIFT;
/* Check for overflow. */
if (sizeof(holelen) > sizeof(hlen)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 322/507] mm: fix unkillable fault loop on MAP_DROPPABLE memory
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (320 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 321/507] mm: fix unmap_mapping_range() beyond 4 GiB on 32-bit Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 323/507] mm: fix deadlock of mremap() against UFFDIO_MOVE Greg Kroah-Hartman
` (184 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Lorenzo Stoakes (ARM),
Muhammad Usama Anjum, David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit 9f02ca8c15a74bc9e4e8e05ec089f63cb87cbf75 ]
handle_mm_fault() suppresses VM_FAULT_OOM for VM_DROPPABLE mappings.
For user-mode faults, pending signals are processed before retrying the
access. Kernel-mode faults on user buffers instead return directly to
the faulting instruction.
With persistent allocation failures (esp. memcg limits), a syscall,
such as write(), can therefore loop while not dropping locks.
Only suppress VM_FAULT_OOM when FAULT_FLAG_USER is set, allowing
kernel-mode faults and GUP to fail and signal allocation errors.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: 9651fcedf7b9 ("mm: add MAP_DROPPABLE for designating always lazily freeable mappings")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
[ david: simplify description ]
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-37-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/memory.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/mm/memory.c b/mm/memory.c
index e773d51f0d6fc..f6f704d693f4f 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -6923,8 +6923,12 @@ vm_fault_t handle_mm_fault(struct vm_area_struct *vma, unsigned long address,
lru_gen_exit_fault();
- /* If the mapping is droppable, then errors due to OOM aren't fatal. */
- if (is_droppable)
+ /*
+ * If the mapping is droppable, then errors due to OOM aren't fatal: the
+ * task returns to user mode, handles its signals and tries again. A
+ * fault from kernel mode has no such return, so it must see the error.
+ */
+ if (is_droppable && (flags & FAULT_FLAG_USER))
ret &= ~VM_FAULT_OOM;
if (flags & FAULT_FLAG_USER) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 323/507] mm: fix deadlock of mremap() against UFFDIO_MOVE
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (321 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 322/507] mm: fix unkillable fault loop on MAP_DROPPABLE memory Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 324/507] mm/ksm: reset the unstable trees of all nodes Greg Kroah-Hartman
` (183 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Lorenzo Stoakes (ARM),
Muchun Song, Muhammad Usama Anjum, Lance Yang,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit d03df42ddae196f20e9cfb775704e60269eb6b44 ]
With per-VMA locks, UFFDIO_MOVE can run concurrently with mremap()
on different VMAs in the same mm. Those VMAs can share page tables, so
both operations can acquire the same pair of page-table locks.
UFFDIO_MOVE orders the locks by address, while mremap() takes the source
lock first. These conflicting orders can deadlock; mremap() holding
mmap_lock for writing no longer helps.
Move double_pt_lock() and double_pt_unlock() to mm/internal.h and use
them for all page-table moves in mremap(). Preserve the source entry
checks after acquiring both locks. Remove the comments claiming that
exclusive mmap_lock makes lock ordering irrelevant.
In move_ptes(), make sure to just recheck source and destination PMD
after taking the locks and drop the overly-long comment.
Fix generated by an LLM and sent by Chris Mason in private.
[ david: use new helpers consistently; simplify description and comments;
move_ptes() fixup ]
Fixes: 867a43a34ff8 ("userfaultfd: use per-vma locks in userfaultfd operations")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Acked-by: Muchun Song <muchun.song@linux.dev>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-38-d6437171ecc3@kernel.org
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/userfaultfd_k.h | 2 -
mm/huge_memory.c | 19 +++-----
mm/hugetlb.c | 14 ++----
mm/internal.h | 28 +++++++++++
mm/mremap.c | 87 ++++++++++++++---------------------
mm/userfaultfd.c | 27 -----------
6 files changed, 72 insertions(+), 105 deletions(-)
diff --git a/include/linux/userfaultfd_k.h b/include/linux/userfaultfd_k.h
index a4351cffc60ce..4c0924c73166d 100644
--- a/include/linux/userfaultfd_k.h
+++ b/include/linux/userfaultfd_k.h
@@ -154,8 +154,6 @@ extern int mrwprotect_range(struct userfaultfd_ctx *ctx, unsigned long start,
unsigned long len, bool enable_rwp);
/* move_pages */
-void double_pt_lock(spinlock_t *ptl1, spinlock_t *ptl2);
-void double_pt_unlock(spinlock_t *ptl1, spinlock_t *ptl2);
int move_pages_huge_pmd(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd, pmd_t dst_pmdval,
struct vm_area_struct *dst_vma,
struct vm_area_struct *src_vma,
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index c1130d3d28261..c0d500bfb9fbc 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2659,15 +2659,11 @@ bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr,
return false;
}
- /*
- * We don't have to worry about the ordering of src and dst
- * ptlocks because exclusive mmap_lock prevents deadlock.
- */
- old_ptl = __pmd_trans_huge_lock(old_pmd, vma);
- if (old_ptl) {
- new_ptl = pmd_lockptr(mm, new_pmd);
- if (new_ptl != old_ptl)
- spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
+ old_ptl = pmd_lockptr(mm, old_pmd);
+ new_ptl = pmd_lockptr(mm, new_pmd);
+
+ double_pt_lock(old_ptl, new_ptl);
+ if (likely(pmd_is_huge(*old_pmd))) {
pmd = pmdp_huge_get_and_clear(mm, old_addr, old_pmd);
if (pmd_present(pmd))
force_flush = true;
@@ -2695,11 +2691,10 @@ bool move_huge_pmd(struct vm_area_struct *vma, unsigned long old_addr,
set_pmd_at(mm, new_addr, new_pmd, pmd);
if (force_flush)
flush_pmd_tlb_range(vma, old_addr, old_addr + PMD_SIZE);
- if (new_ptl != old_ptl)
- spin_unlock(new_ptl);
- spin_unlock(old_ptl);
+ double_pt_unlock(old_ptl, new_ptl);
return true;
}
+ double_pt_unlock(old_ptl, new_ptl);
return false;
}
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 532cc42662a69..09665fd220752 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5119,15 +5119,9 @@ static void move_huge_pte(struct vm_area_struct *vma, unsigned long old_addr,
spinlock_t *src_ptl, *dst_ptl;
pte_t pte;
- dst_ptl = huge_pte_lock(h, mm, dst_pte);
+ dst_ptl = huge_pte_lockptr(h, mm, dst_pte);
src_ptl = huge_pte_lockptr(h, mm, src_pte);
-
- /*
- * We don't have to worry about the ordering of src and dst ptlocks
- * because exclusive mmap_lock (or the i_mmap_lock) prevents deadlock.
- */
- if (src_ptl != dst_ptl)
- spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
+ double_pt_lock(dst_ptl, src_ptl);
pte = huge_ptep_get_and_clear(mm, old_addr, src_pte, sz);
@@ -5156,9 +5150,7 @@ static void move_huge_pte(struct vm_area_struct *vma, unsigned long old_addr,
set_huge_pte_at(mm, new_addr, dst_pte, pte, sz);
}
- if (src_ptl != dst_ptl)
- spin_unlock(src_ptl);
- spin_unlock(dst_ptl);
+ double_pt_unlock(dst_ptl, src_ptl);
}
unsigned long move_hugetlb_page_tables(struct vm_area_struct *vma,
diff --git a/mm/internal.h b/mm/internal.h
index a533b56e2f2b9..526ad50e3c1d8 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -621,6 +621,34 @@ static inline void force_page_cache_readahead(struct address_space *mapping,
force_page_cache_ra(&ractl, nr_to_read);
}
+/*
+ * Take two page table locks at the same level in address order such that
+ * we cannot deadlock.
+ */
+static inline void double_pt_lock(spinlock_t *ptl1, spinlock_t *ptl2)
+ __acquires(ptl1)
+ __acquires(ptl2)
+{
+ if (ptl1 > ptl2)
+ swap(ptl1, ptl2);
+ spin_lock(ptl1);
+ if (ptl1 != ptl2)
+ spin_lock_nested(ptl2, SINGLE_DEPTH_NESTING);
+ else
+ __acquire(ptl2);
+}
+
+static inline void double_pt_unlock(spinlock_t *ptl1, spinlock_t *ptl2)
+ __releases(ptl1)
+ __releases(ptl2)
+{
+ spin_unlock(ptl1);
+ if (ptl1 != ptl2)
+ spin_unlock(ptl2);
+ else
+ __release(ptl2);
+}
+
unsigned find_lock_entries(struct address_space *mapping, pgoff_t *start,
pgoff_t end, struct folio_batch *fbatch, pgoff_t *indices);
unsigned find_get_entries(struct address_space *mapping, pgoff_t *start,
diff --git a/mm/mremap.c b/mm/mremap.c
index b6e0a4206016b..23498d0783c43 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -202,7 +202,7 @@ static int move_ptes(struct pagetable_move_control *pmc,
struct mm_struct *mm = vma->vm_mm;
pte_t *old_ptep, *new_ptep;
pte_t old_pte, pte;
- pmd_t dummy_pmdval;
+ pmd_t old_pmdval, new_pmdval;
spinlock_t *old_ptl, *new_ptl;
bool force_flush = false;
unsigned long old_addr = pmc->old_addr;
@@ -234,31 +234,30 @@ static int move_ptes(struct pagetable_move_control *pmc,
if (pmc->need_rmap_locks)
take_rmap_locks(vma);
- /*
- * We don't have to worry about the ordering of src and dst
- * pte locks because exclusive mmap_lock prevents deadlock.
- */
- old_ptep = pte_offset_map_lock(mm, old_pmd, old_addr, &old_ptl);
+ old_ptep = pte_offset_map_rw_nolock(mm, old_pmd, old_addr, &old_pmdval,
+ &old_ptl);
if (!old_ptep) {
err = -EAGAIN;
goto out;
}
- /*
- * Now new_pte is none, so collapse_scan_file() path can not find
- * this by traversing file->f_mapping, so there is no concurrency with
- * retract_page_tables(). In addition, we already hold the exclusive
- * mmap_lock, so this new_pte page is stable, so there is no need to get
- * pmdval and do pmd_same() check.
- */
- new_ptep = pte_offset_map_rw_nolock(mm, new_pmd, new_addr, &dummy_pmdval,
- &new_ptl);
+ new_ptep = pte_offset_map_rw_nolock(mm, new_pmd, new_addr, &new_pmdval,
+ &new_ptl);
if (!new_ptep) {
- pte_unmap_unlock(old_ptep, old_ptl);
+ pte_unmap(old_ptep);
+ err = -EAGAIN;
+ goto out;
+ }
+
+ double_pt_lock(old_ptl, new_ptl);
+ if (unlikely(!pmd_same(old_pmdval, pmdp_get_lockless(old_pmd)) ||
+ !pmd_same(new_pmdval, pmdp_get_lockless(new_pmd)))) {
+ double_pt_unlock(old_ptl, new_ptl);
+ pte_unmap(new_ptep);
+ pte_unmap(old_ptep);
err = -EAGAIN;
goto out;
}
- if (new_ptl != old_ptl)
- spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
+
flush_tlb_batched_pending(vma->vm_mm);
lazy_mmu_mode_enable();
@@ -317,10 +316,9 @@ static int move_ptes(struct pagetable_move_control *pmc,
lazy_mmu_mode_disable();
if (force_flush)
flush_tlb_range(vma, old_end - len, old_end);
- if (new_ptl != old_ptl)
- spin_unlock(new_ptl);
+ double_pt_unlock(old_ptl, new_ptl);
pte_unmap(new_ptep - 1);
- pte_unmap_unlock(old_ptep - 1, old_ptl);
+ pte_unmap(old_ptep - 1);
out:
if (pmc->need_rmap_locks)
drop_rmap_locks(vma);
@@ -395,14 +393,9 @@ static bool move_normal_pmd(struct pagetable_move_control *pmc,
if (WARN_ON_ONCE(!pmd_none(*new_pmd)))
return false;
- /*
- * We don't have to worry about the ordering of src and dst
- * ptlocks because exclusive mmap_lock prevents deadlock.
- */
- old_ptl = pmd_lock(mm, old_pmd);
+ old_ptl = pmd_lockptr(mm, old_pmd);
new_ptl = pmd_lockptr(mm, new_pmd);
- if (new_ptl != old_ptl)
- spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
+ double_pt_lock(old_ptl, new_ptl);
pmd = *old_pmd;
@@ -418,9 +411,7 @@ static bool move_normal_pmd(struct pagetable_move_control *pmc,
pmd_populate(mm, new_pmd, pmd_pgtable(pmd));
flush_tlb_range(vma, pmc->old_addr, pmc->old_addr + PMD_SIZE);
out_unlock:
- if (new_ptl != old_ptl)
- spin_unlock(new_ptl);
- spin_unlock(old_ptl);
+ double_pt_unlock(old_ptl, new_ptl);
return res;
}
@@ -452,14 +443,10 @@ static bool move_normal_pud(struct pagetable_move_control *pmc,
if (WARN_ON_ONCE(!pud_none(*new_pud)))
return false;
- /*
- * We don't have to worry about the ordering of src and dst
- * ptlocks because exclusive mmap_lock prevents deadlock.
- */
- old_ptl = pud_lock(mm, old_pud);
+ old_ptl = pud_lockptr(mm, old_pud);
new_ptl = pud_lockptr(mm, new_pud);
- if (new_ptl != old_ptl)
- spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
+
+ double_pt_lock(old_ptl, new_ptl);
pud = *old_pud;
if (unlikely(pud_none(pud)))
@@ -473,9 +460,7 @@ static bool move_normal_pud(struct pagetable_move_control *pmc,
pud_populate(mm, new_pud, pud_pgtable(pud));
flush_tlb_range(vma, pmc->old_addr, pmc->old_addr + PUD_SIZE);
out_unlock:
- if (new_ptl != old_ptl)
- spin_unlock(new_ptl);
- spin_unlock(old_ptl);
+ double_pt_unlock(old_ptl, new_ptl);
return true;
}
@@ -503,16 +488,14 @@ static bool move_huge_pud(struct pagetable_move_control *pmc,
if (WARN_ON_ONCE(!pud_none(*new_pud)))
return false;
- /*
- * We don't have to worry about the ordering of src and dst
- * ptlocks because exclusive mmap_lock prevents deadlock.
- */
- old_ptl = __pud_trans_huge_lock(old_pud, vma);
- if (unlikely(!old_ptl))
- return false;
+ old_ptl = pud_lockptr(mm, old_pud);
new_ptl = pud_lockptr(mm, new_pud);
- if (new_ptl != old_ptl)
- spin_lock_nested(new_ptl, SINGLE_DEPTH_NESTING);
+
+ double_pt_lock(old_ptl, new_ptl);
+ if (unlikely(!pud_trans_huge(*old_pud))) {
+ double_pt_unlock(old_ptl, new_ptl);
+ return false;
+ }
/* Clear the pud */
pud = pudp_huge_get_and_clear(mm, pmc->old_addr, old_pud);
@@ -523,9 +506,7 @@ static bool move_huge_pud(struct pagetable_move_control *pmc,
/* mark soft_ditry when we add pud level soft dirty support */
set_pud_at(mm, pmc->new_addr, new_pud, pud);
flush_pud_tlb_range(vma, pmc->old_addr, pmc->old_addr + HPAGE_PUD_SIZE);
- if (new_ptl != old_ptl)
- spin_unlock(new_ptl);
- spin_unlock(old_ptl);
+ double_pt_unlock(old_ptl, new_ptl);
return true;
}
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 5689df692401e..cc37b60fc3e81 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -1234,33 +1234,6 @@ int mrwprotect_range(struct userfaultfd_ctx *ctx, unsigned long start,
return 0;
}
-void double_pt_lock(spinlock_t *ptl1,
- spinlock_t *ptl2)
- __acquires(ptl1)
- __acquires(ptl2)
-{
- if (ptl1 > ptl2)
- swap(ptl1, ptl2);
- /* lock in virtual address order to avoid lock inversion */
- spin_lock(ptl1);
- if (ptl1 != ptl2)
- spin_lock_nested(ptl2, SINGLE_DEPTH_NESTING);
- else
- __acquire(ptl2);
-}
-
-void double_pt_unlock(spinlock_t *ptl1,
- spinlock_t *ptl2)
- __releases(ptl1)
- __releases(ptl2)
-{
- spin_unlock(ptl1);
- if (ptl1 != ptl2)
- spin_unlock(ptl2);
- else
- __release(ptl2);
-}
-
static inline bool is_pte_pages_stable(pte_t *dst_pte, pte_t *src_pte,
pte_t orig_dst_pte, pte_t orig_src_pte,
pmd_t *dst_pmd, pmd_t dst_pmdval)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 324/507] mm/ksm: reset the unstable trees of all nodes
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (322 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 323/507] mm: fix deadlock of mremap() against UFFDIO_MOVE Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 325/507] mm/ksm: fix use of a freed anon_vma at swap-in Greg Kroah-Hartman
` (182 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Lorenzo Stoakes (ARM),
Pasha Tatashin, Muhammad Usama Anjum, Xu Xin,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 890e118e95bfc2aae4432ec2a95192d6f9193211 ]
Each full scan resets ksm_nr_node_ids unstable tree roots. Enabling
merge_across_nodes resets this count to 1, even if per-node roots were
previously allocated.
So when toggling "merge_across_nodes" 0 -> 1 -> 0, a scan that starts
while the setting is 1 and continues after switching back to 0 can
encounter stale unstable tree roots, resulting in UAF.
Only root is allowed to change "merge_across_nodes", and the documented
sequence is: "merge_across_nodes setting can be changed only when there
are no ksm shared pages in the system: set run 2 to unmerge pages first,
then to 1 after changing merge_across_nodes, to remerge according to the
new setting."
Let's fix it by tracking in ksm_nr_node_ids the actual number of
allocated tree roots.
remove_all_stable_nodes() and ksm_check_stable_tree() will now scan
more tree roots (skipping the empty ones), which is harmless.
Fixes: ef53d16cded7 ("ksm: allocate roots when needed")
Cc: stable@vger.kernel.org
Reported-by: Josef Bacik <josef@toxicpanda.com>
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-39-d6437171ecc3@kernel.org
Reviewed-by: Xu Xin <xu.xin@linux.dev>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/ksm.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/mm/ksm.c b/mm/ksm.c
index 5b3559bf4c8f8..6f6077b044e43 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -476,6 +476,7 @@ static void advisor_stop_scan(void)
#ifdef CONFIG_NUMA
/* Zeroed when merging across nodes is not allowed */
static unsigned int ksm_merge_across_nodes = 1;
+/* Number of allocated stable and unstable tree roots. */
static int ksm_nr_node_ids = 1;
#else
#define ksm_merge_across_nodes 1U
@@ -3645,14 +3646,13 @@ static ssize_t merge_across_nodes_store(struct kobject *kobj,
else {
root_stable_tree = buf;
root_unstable_tree = buf + nr_node_ids;
+ ksm_nr_node_ids = nr_node_ids;
/* Stable tree is empty but not the unstable */
root_unstable_tree[0] = one_unstable_tree[0];
}
}
- if (!err) {
+ if (!err)
ksm_merge_across_nodes = knob;
- ksm_nr_node_ids = knob ? 1 : nr_node_ids;
- }
}
mutex_unlock(&ksm_thread_mutex);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 325/507] mm/ksm: fix use of a freed anon_vma at swap-in
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (323 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 324/507] mm/ksm: reset the unstable trees of all nodes Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 326/507] mm/ksm: check large swap-cache folios before mapping them Greg Kroah-Hartman
` (181 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Lorenzo Stoakes (ARM),
Xu Xin, Muhammad Usama Anjum, David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 4c2dec1dce368ad9e9b1814307cb5ef3832fa07e ]
A folio read from a swap slot previously shared by KSM can remain in the
swap cache after the process that first mapped it exits. Its anon_vma
can then be freed, so ksm_might_need_to_copy() must not dereference it
to compare roots.
Doing so can result in some false-positives, resulting in the reverse
mapping missing the new folio mapping, preventing migration and reclaim.
SLAB_TYPESAFE_BY_RCU allows individual anon_vma objects to be reused
immediately after freeing. A stale pointer can then refer to another
anon_vma whose root matches, even though the target VMA is not linked
to that anon_vma.
Move the anonymous rmap compatibility checks into
folio_anon_rmap_compatible(). Keep the page-index check and compare the
folio's anon_vma pointer against the VMA's own anon_vma and root first.
If neither matches, bite the bullet and walk the VMA's anon_vma_chain.
The VMA keeps these anon_vmas alive, and finding a match guarantees that
reverse mapping can find the new mapping.
Lorenzo Stoakes says in a private discussion:
"This isn't quite equivalent to the existing check.
Every anon_vma in an anon_vma_chain shares the same root, but if you
split a VMA then fork both of them like this:
VMA A
/ \ <split>
VMA B VMA C
\ /
root <- anon_vma 1
----^ ^---- <fork>
/ parent \
anon_vma 2 anon_vma 3
| |
VMA D VMA E
VMA's D and E both get their own new
anon_vma's such that:
VMA D: anon_vma 2 -> anon_vma 1 -> root
VMA E: anon_vma 3 -> anon_vma 1 -> root
And if you found a folio referencing anon_vma 2, the existing check:
anon_vma->root == vma->anon-vma->root
Would be true for VMA's B, C, D & E.
However after your change it'd be true for VMA D only, as it's the only
one with anon_vma 2 in its anon_vma_chain.
Whether or not that could actually happen in practice... 🙂 I don't
know.
[...] after your change it'd be true for VMA D only, as it's the only
one with anon_vma 2 in its anon_vma_chain. [...] I would [...] say that
you are making the test stricter but more correct.
"
If this affects performance when KSM was never even involved, we could
just track whether KSM ever merged anything and just skip these checks.
There isn't really a lot we can do otherwise: for mapped folios we might
be able to use folio_get_anon_vma(), but for unmapped folios there really
is no easy way to see if the anon_vma is still valid.
Document the (confusing) lifetime requirements of folio_anon_vma().
Fixes: ba6f0ff3981e ("ksm: fix ksm swapin time optimization")
Cc: stable@vger.kernel.org
Reported-by: Chris Mason <mason@kernel.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Acked-by: Xu Xin <xu.xin@linux.dev>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-40-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/ksm.c | 36 +++++++++++++++++++++++++++++++-----
mm/util.c | 13 +++++++++++++
2 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/mm/ksm.c b/mm/ksm.c
index 6f6077b044e43..c600efa5396db 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -3146,11 +3146,40 @@ void __ksm_exit(struct mm_struct *mm)
trace_ksm_exit(mm);
}
+static bool folio_anon_rmap_compatible(const struct folio *folio,
+ struct vm_area_struct *vma, unsigned long addr)
+{
+ const struct anon_vma *anon_vma = folio_anon_vma(folio);
+ struct anon_vma_chain *avc;
+
+ VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio);
+ VM_WARN_ON_ONCE_FOLIO(folio_test_large(folio), folio);
+ VM_WARN_ON_ONCE_FOLIO(folio_test_ksm(folio), folio);
+ vma_assert_stabilised(vma);
+
+ if (!anon_vma)
+ return true;
+ if (folio->index != linear_anon_page_index(vma, addr))
+ return false;
+
+ /*
+ * Careful: anon_vma might have been freed, so we cannot safely
+ * dereference it. Add a fast path before we walk the anon_vma chain.
+ */
+ if (anon_vma == vma->anon_vma || anon_vma == vma->anon_vma->root)
+ return true;
+
+ list_for_each_entry(avc, &vma->anon_vma_chain, same_vma) {
+ if (avc->anon_vma == anon_vma)
+ return true;
+ }
+ return false;
+}
+
struct folio *ksm_might_need_to_copy(struct folio *folio,
struct vm_area_struct *vma, unsigned long addr)
{
struct page *page = folio_page(folio, 0);
- struct anon_vma *anon_vma = folio_anon_vma(folio);
struct folio *new_folio;
if (folio_test_large(folio))
@@ -3160,10 +3189,7 @@ struct folio *ksm_might_need_to_copy(struct folio *folio,
if (folio_stable_node(folio) &&
!(ksm_run & KSM_RUN_UNMERGE))
return folio; /* no need to copy it */
- } else if (!anon_vma) {
- return folio; /* no need to copy it */
- } else if (folio->index == linear_anon_page_index(vma, addr) &&
- anon_vma->root == vma->anon_vma->root) {
+ } else if (folio_anon_rmap_compatible(folio, vma, addr)) {
return folio; /* still no need to copy it */
}
if (PageHWPoison(page))
diff --git a/mm/util.c b/mm/util.c
index bf0513d1d3d08..e31eb565445cb 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -697,6 +697,19 @@ void *vcalloc_noprof(size_t n, size_t size)
}
EXPORT_SYMBOL(vcalloc_noprof);
+/**
+ * folio_anon_vma - Get a folio's raw anon_vma pointer.
+ * @folio: The folio.
+ *
+ * The returned pointer may be stale for an unmapped folio. The caller
+ * must ensure the anon_vma stays alive before dereferencing it. A folio
+ * reference or lock alone is insufficient; use folio_get_anon_vma() when
+ * the anon_vma's lifetime is not otherwise protected. Note that
+ * folio_get_anon_vma() is only useful for folios that are still mapped.
+ *
+ * Return: The raw anon_vma pointer for an anonymous, non-KSM folio, or
+ * %NULL otherwise.
+ */
struct anon_vma *folio_anon_vma(const struct folio *folio)
{
unsigned long mapping = (unsigned long)folio->mapping;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 326/507] mm/ksm: check large swap-cache folios before mapping them
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (324 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 325/507] mm/ksm: fix use of a freed anon_vma at swap-in Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 327/507] mm/vma: call ->may_split() before a partial merge Greg Kroah-Hartman
` (180 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Lorenzo Stoakes (ARM),
Muhammad Usama Anjum, Lance Yang, David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit 7f2c000ffb1047b476cbf267f741272c389d3e31 ]
KSM folios are always small, but their shared swap slots can be read
back as part of a large folio in the swap cache. ksm_might_need_to_copy()
skips large folios, so another process can map a page with an incompatible
anon_vma or page index. Reverse mapping then cannot find the new
mapping, preventing migration or reclaim.
Apply the same compatibility checks to large folios as to small ones.
Pass the page corresponding to the swap entry and copy only that page
when necessary. In do_swap_page()'s copy path, decrement only that slot's
swap count, because the source swap-cache folio can now be large.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: f1879e8a0c60 ("mm, swap: never bypass the swap cache even for SWP_SYNCHRONOUS_IO")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-41-d6437171ecc3@kernel.org
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/ksm.h | 6 +++---
mm/ksm.c | 22 ++++++++++++----------
mm/memory.c | 5 +++--
mm/swapfile.c | 3 ++-
4 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/include/linux/ksm.h b/include/linux/ksm.h
index d39d0d5483a23..a0d358a1feb63 100644
--- a/include/linux/ksm.h
+++ b/include/linux/ksm.h
@@ -91,8 +91,8 @@ static inline void ksm_exit(struct mm_struct *mm)
* We'd like to make this conditional on vma->vm_flags & VM_MERGEABLE,
* but what if the vma was unmerged while the page was swapped out?
*/
-struct folio *ksm_might_need_to_copy(struct folio *folio,
- struct vm_area_struct *vma, unsigned long addr);
+struct folio *ksm_might_need_to_copy(struct folio *folio, struct page *page,
+ struct vm_area_struct *vma, unsigned long addr);
void rmap_walk_ksm(struct folio *folio, struct rmap_walk_control *rwc);
void folio_migrate_ksm(struct folio *newfolio, struct folio *folio);
@@ -145,7 +145,7 @@ static inline int ksm_madvise(struct vm_area_struct *vma, unsigned long start,
}
static inline struct folio *ksm_might_need_to_copy(struct folio *folio,
- struct vm_area_struct *vma, unsigned long addr)
+ struct page *page, struct vm_area_struct *vma, unsigned long addr)
{
return folio;
}
diff --git a/mm/ksm.c b/mm/ksm.c
index c600efa5396db..a554e5c0ed07a 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -3147,19 +3147,20 @@ void __ksm_exit(struct mm_struct *mm)
}
static bool folio_anon_rmap_compatible(const struct folio *folio,
- struct vm_area_struct *vma, unsigned long addr)
+ const struct page *page, struct vm_area_struct *vma,
+ unsigned long addr)
{
const struct anon_vma *anon_vma = folio_anon_vma(folio);
struct anon_vma_chain *avc;
VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio);
- VM_WARN_ON_ONCE_FOLIO(folio_test_large(folio), folio);
+ VM_WARN_ON_ONCE_FOLIO(page_folio(page) != folio, folio);
VM_WARN_ON_ONCE_FOLIO(folio_test_ksm(folio), folio);
vma_assert_stabilised(vma);
if (!anon_vma)
return true;
- if (folio->index != linear_anon_page_index(vma, addr))
+ if (page_pgoff(folio, page) != linear_anon_page_index(vma, addr))
return false;
/*
@@ -3176,20 +3177,21 @@ static bool folio_anon_rmap_compatible(const struct folio *folio,
return false;
}
-struct folio *ksm_might_need_to_copy(struct folio *folio,
- struct vm_area_struct *vma, unsigned long addr)
+struct folio *ksm_might_need_to_copy(struct folio *folio, struct page *page,
+ struct vm_area_struct *vma, unsigned long addr)
{
- struct page *page = folio_page(folio, 0);
struct folio *new_folio;
- if (folio_test_large(folio))
- return folio;
-
+ /*
+ * A KSM folio is small, but the slot that it left behind can be swapped
+ * in as a part of a large folio by one of the processes that shared it.
+ * So test, and copy, the page of the slot.
+ */
if (folio_test_ksm(folio)) {
if (folio_stable_node(folio) &&
!(ksm_run & KSM_RUN_UNMERGE))
return folio; /* no need to copy it */
- } else if (folio_anon_rmap_compatible(folio, vma, addr)) {
+ } else if (folio_anon_rmap_compatible(folio, page, vma, addr)) {
return folio; /* still no need to copy it */
}
if (PageHWPoison(page))
diff --git a/mm/memory.c b/mm/memory.c
index f6f704d693f4f..77e0a9bf63211 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -5063,7 +5063,7 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
* folio->index of non-ksm folios would be nonlinear inside the
* anon VMA -- the ksm flag is lost on actual swapout.
*/
- folio = ksm_might_need_to_copy(folio, vma, vmf->address);
+ folio = ksm_might_need_to_copy(folio, page, vma, vmf->address);
if (unlikely(!folio)) {
ret = VM_FAULT_OOM;
folio = swapcache;
@@ -5244,7 +5244,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
if (unlikely(folio != swapcache)) {
folio_add_new_anon_rmap(folio, vma, address, RMAP_EXCLUSIVE);
folio_add_lru_vma(folio, vma);
- folio_put_swap(swapcache, NULL);
+ folio_put_swap(swapcache,
+ folio_file_page(swapcache, swp_offset(entry)));
} else if (!folio_test_anon(folio)) {
/*
* We currently only expect !anon folios that are fully
diff --git a/mm/swapfile.c b/mm/swapfile.c
index fbb4b3dcf9562..278060e241130 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -2434,7 +2434,8 @@ static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
return 0;
swapcache = folio;
- folio = ksm_might_need_to_copy(folio, vma, addr);
+ folio = ksm_might_need_to_copy(folio,
+ folio_file_page(folio, swp_offset(entry)), vma, addr);
if (unlikely(!folio))
return -ENOMEM;
else if (unlikely(folio == ERR_PTR(-EHWPOISON))) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 327/507] mm/vma: call ->may_split() before a partial merge
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (325 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 326/507] mm/ksm: check large swap-cache folios before mapping them Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 328/507] mm/huge_memory: split huge PUDs when adjusting VMA boundaries Greg Kroah-Hartman
` (179 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Lorenzo Stoakes (ARM),
Gregory Price (Meta), Muhammad Usama Anjum, Lance Yang,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit 0193e83368022a308d19ee0293f55a4f5d548e40 ]
A driver can use the ->may_split() hook to forbid a VMA boundary at
certain addresses.
A device-dax device is a character device that gives raw access to a
range of memory through mmap(). device-dax refuses any address that is not
a multiple of the device's alignment through vm_ops->may_split.
vma_merge_existing_range() can move boundaries, but does not call
vm_ops->may_split.
If a range at the edge of a VMA gets the attributes of the adjacent VMA,
the function moves only that range over to the neighbour: one VMA shrinks
and the other grows. This is a partial merge, and vma_modify() tries it
before any split.
Take a device-dax VMA that lies next to another VMA of the same file.
The user calls mprotect() on the one page of the first VMA that touches
the second VMA, and asks for the protection that the second VMA already
has. The result is a partial merge. It puts the boundary inside a 1 GiB
mapping, which is a single leaf entry at the PUD level.
As part of the merge, the kernel looks for a huge PMD to split at the
new boundary. That code does not expect a PUD leaf:
vma_merge_existing_range()
commit_merge()
vma_adjust_trans_huge()
split_huge_pmd_address()
mm_find_pmd()
treats the PUD leaf as a pointer to a PMD table,
so the "table" is the device memory that the leaf maps
__split_huge_pmd()
reads a PMD that the user wrote to the device memory
folio_put() on the folio that this PMD names
Bad. While the code must at some point be taught to split PUD entries as
well, the issue here is that we move VMA boundaries such that they are
incompatible with the driver.
Fix this by calling ->may_split() on the address that a partial merge
would move the boundary to, and by abandoning the merge if the driver
refuses. vma_modify() then tries the split, which fails with -EINVAL.
Factor out existing split handling into check_split() and reuse it.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: 38607c62b34b ("fs/dax: properly refcount fs dax pages")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
[ david: improve description; cleanup the code ]
Reviewed-by: Gregory Price (Meta) <gourry@gourry.net>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
Signed-off-by: Gregory Price (Meta) <gourry@gourry.net>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-42-d6437171ecc3@kernel.org
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/vma.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/mm/vma.c b/mm/vma.c
index 2962670f27b5e..b257365f6e3c4 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -535,6 +535,15 @@ void unmap_region(struct unmap_desc *unmap)
tlb_finish_mmu(&tlb);
}
+static int check_split(struct vm_area_struct *vma, unsigned long addr)
+{
+ if (!vma->vm_ops)
+ return 0;
+ if (!vma->vm_ops->may_split)
+ return 0;
+ return vma->vm_ops->may_split(vma, addr);
+}
+
/*
* __split_vma() bypasses sysctl_max_map_count checking. We use this where it
* has already been checked or doesn't make sense to fail.
@@ -551,11 +560,9 @@ __split_vma(struct vma_iterator *vmi, struct vm_area_struct *vma,
WARN_ON(vma->vm_start >= addr);
WARN_ON(vma->vm_end <= addr);
- if (vma->vm_ops && vma->vm_ops->may_split) {
- err = vma->vm_ops->may_split(vma, addr);
- if (err)
- return err;
- }
+ err = check_split(vma, addr);
+ if (err)
+ return err;
vma_start_write(vma);
new = vm_area_dup(vma);
@@ -964,6 +971,10 @@ static __must_check struct vm_area_struct *vma_merge_existing_range(
if (vmg->__remove_middle && !can_merge_remove_vma(middle))
return NULL;
+ /* If middle isn't removed then it's resized, i.e. splits. */
+ if (!vmg->__remove_middle && check_split(middle, left_side ? end : start))
+ return NULL;
+
/*
* If we merge both VMAs, then next is also deleted. This implies
* merge_will_delete_vma also.
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 328/507] mm/huge_memory: split huge PUDs when adjusting VMA boundaries
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (326 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 327/507] mm/vma: call ->may_split() before a partial merge Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 329/507] mm/vma: dont leak the charge for stack growth Greg Kroah-Hartman
` (178 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Muhammad Usama Anjum,
Kiryl Shutsemau (Meta), David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 23e570927421d569fdc510d5f3f29542a43eeda5 ]
PFN mappings such as VFIO PCI BAR mappings can use PUD leaves while
allowing VMA splits at page granularity. However, vma_adjust_trans_huge()
only handles PMDs.
After faulting a writable PUD-sized VFIO BAR mapping, changing its first
page to read-only with mprotect() makes the PMD walk treat the PUD leaf
as a PMD table. Applying MADV_DONTFORK to the first PMD-sized chunk leaves
the PUD spanning two VMAs: the PMD-aligned boundary skips splitting.
Walk the page tables once at each adjusted boundary and split a huge
PUD or PMD leaf as needed. Handle PUD leaves even when the boundary is
PMD-aligned.
Fixes: f9e54c3a2f5b7 ("vfio/pci: implement huge_fault support")
Cc: stable@vger.kernel.org
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Link: https://patch.msgid.link/20261031-fixes_core-v3-43-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/huge_memory.c | 70 +++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 60 insertions(+), 10 deletions(-)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index c0d500bfb9fbc..fde9ea15fef9e 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -3516,16 +3516,66 @@ void split_huge_pmd_address(struct vm_area_struct *vma, unsigned long address,
__split_huge_pmd(vma, pmd, address, freeze);
}
-static inline void split_huge_pmd_if_needed(struct vm_area_struct *vma, unsigned long address)
+static bool pud_split_required(const struct vm_area_struct *vma,
+ unsigned long address)
{
+ if (!IS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD))
+ return false;
+ if (IS_ALIGNED(address, HPAGE_PUD_SIZE))
+ return false;
/*
- * If the new address isn't hpage aligned and it could previously
- * contain an hugepage: check if we need to split an huge pmd.
+ * Only selected VMAs support mapping PUDs for now. Lift the
+ * restriction once this changes.
*/
- if (!IS_ALIGNED(address, HPAGE_PMD_SIZE) &&
- range_in_vma(vma, ALIGN_DOWN(address, HPAGE_PMD_SIZE),
- ALIGN(address, HPAGE_PMD_SIZE)))
- split_huge_pmd_address(vma, address, false);
+ if (!vma_is_dax(vma) && !vma_test_any(vma, VMA_PFNMAP_BIT, VMA_MIXEDMAP_BIT))
+ return false;
+ return range_in_vma(vma, ALIGN_DOWN(address, HPAGE_PUD_SIZE),
+ ALIGN(address, HPAGE_PUD_SIZE));
+}
+
+static bool pmd_split_required(const struct vm_area_struct *vma,
+ unsigned long address)
+{
+ if (IS_ALIGNED(address, HPAGE_PMD_SIZE))
+ return false;
+
+ return range_in_vma(vma, ALIGN_DOWN(address, HPAGE_PMD_SIZE),
+ ALIGN(address, HPAGE_PMD_SIZE));
+}
+
+static void split_huge_leaf(struct vm_area_struct *vma,
+ unsigned long address)
+{
+ const bool split_pud = pud_split_required(vma, address);
+ const bool split_pmd = pmd_split_required(vma, address);
+ pgd_t *pgd;
+ p4d_t *p4d;
+ pud_t *pud;
+ pmd_t *pmd;
+
+ /*
+ * mmap, VMA and rmap write locks protect the walk; the split helpers
+ * take the page table locks.
+ */
+ if (!split_pud && !split_pmd)
+ return;
+
+ pgd = pgd_offset(vma->vm_mm, address);
+ if (!pgd_present(*pgd))
+ return;
+
+ p4d = p4d_offset(pgd, address);
+ if (!p4d_present(*p4d))
+ return;
+
+ pud = pud_offset(p4d, address);
+ if (pud_leaf(*pud))
+ __split_huge_pud(vma, pud, address);
+ if (!split_pmd || !pud_present(*pud))
+ return;
+
+ pmd = pmd_offset(pud, address);
+ __split_huge_pmd(vma, pmd, address, false);
}
void vma_adjust_trans_huge(struct vm_area_struct *vma,
@@ -3534,14 +3584,14 @@ void vma_adjust_trans_huge(struct vm_area_struct *vma,
struct vm_area_struct *next)
{
/* Check if we need to split start first. */
- split_huge_pmd_if_needed(vma, start);
+ split_huge_leaf(vma, start);
/* Check if we need to split end next. */
- split_huge_pmd_if_needed(vma, end);
+ split_huge_leaf(vma, end);
/* If we're incrementing next->vm_start, we might need to split it. */
if (next)
- split_huge_pmd_if_needed(next, end);
+ split_huge_leaf(next, end);
}
static void unmap_folio(struct folio *folio)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 329/507] mm/vma: dont leak the charge for stack growth
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (327 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 328/507] mm/huge_memory: split huge PUDs when adjusting VMA boundaries Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 330/507] mm/cma: dont release CMA pages still in use Greg Kroah-Hartman
` (177 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Lorenzo Stoakes (ARM),
Pedro Falcato, Harry Yoo (Meta), Muhammad Usama Anjum,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit b1ee87802111156e27557e82acc31fa7dfc76e2a ]
acct_stack_growth() charges stack expansion even without VM_ACCOUNT.
This can happen for read-only or MAP_NORESERVE mappings created with
MAP_GROWSDOWN. Unmapping these VMAs does not release the charge, leaking
Committed_AS.
Only check and charge growth for VM_ACCOUNT VMAs, matching mremap().
Unaccounted growth skips the overcommit check while remaining subject
to the other stack-growth limits.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Reviewed-by: Harry Yoo (Meta) <harry@kernel.org>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-44-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/vma.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mm/vma.c b/mm/vma.c
index b257365f6e3c4..e382fd32f0fff 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -3260,7 +3260,8 @@ static int acct_stack_growth(struct vm_area_struct *vma,
* Overcommit.. This must be the final test, as it will
* update security statistics.
*/
- if (security_vm_enough_memory_mm(mm, grow))
+ if (vma_test(vma, VMA_ACCOUNT_BIT) &&
+ security_vm_enough_memory_mm(mm, grow))
return -ENOMEM;
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 330/507] mm/cma: dont release CMA pages still in use
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (328 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 329/507] mm/vma: dont leak the charge for stack growth Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 331/507] mm/memory-tiers: unregister empty tiers outside memory_tier_lock Greg Kroah-Hartman
` (176 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rik van Riel, Lorenzo Stoakes (ARM),
Muchun Song, Muhammad Usama Anjum, David Hildenbrand (Arm),
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rik van Riel <riel@surriel.com>
[ Upstream commit e8abc61d8a549a91c8fa639f68be2ef13d5fa63b ]
When a driver calls dma_free_contiguous() before quiescing DMA, the
page might still have a reference from the device.
put_page_testzero() there returns false, WARN fires, but the code proceeds
to free_contig_frozen_range() putting a live page onto buddy and clearing
the bitmap. A subsequent allocation can hand the same PFN to a new
owner while the original holder still references it.
A concurrent put_page() that drops the last reference between the
testzero loop and free_contig_frozen_range() can double-queue the page
via page->lru, corrupting buddy lists.
Avoid the corruption by not freeing a CMA region if any of the
pages inside are still in use.
Make it explicit in the warning that the driver allowed a leak.
While at it, use page_ref_freeze() to make the semantics clearer and
switch to pr_warn_ratelimited().
Fixes: 9bda131c6093 ("mm: cma: add cma_alloc_frozen{_compound}()")
Cc: stable@vger.kernel.org
Signed-off-by: Rik van Riel <riel@surriel.com>
Link: https://patch.msgid.link/20260811132045.5f114772@fangorn
[ david: use page_ref_freeze() + pr_warn_ratelimited() ]
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Acked-by: Muchun Song <muchun.song@linux.dev>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-45-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/cma.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/mm/cma.c b/mm/cma.c
index f61d52796f4ef..9ec1d1fd5dff5 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -1024,7 +1024,7 @@ bool cma_release(struct cma *cma, const struct page *pages,
unsigned long count)
{
struct cma_memrange *cmr;
- unsigned long ret = 0;
+ unsigned long leaked = 0;
unsigned long i, pfn;
cmr = find_cma_memrange(cma, pages, count);
@@ -1033,9 +1033,13 @@ bool cma_release(struct cma *cma, const struct page *pages,
pfn = page_to_pfn(pages);
for (i = 0; i < count; i++, pfn++)
- ret += !put_page_testzero(pfn_to_page(pfn));
+ leaked += !page_ref_freeze(pfn_to_page(pfn), 1);
- WARN(ret, "%lu pages are still in use!\n", ret);
+ if (leaked) {
+ pr_warn_ratelimited("%lu pages are still in use, not freeing CMA region!\n",
+ leaked);
+ return true;
+ }
__cma_release_frozen(cma, cmr, pages, count);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 331/507] mm/memory-tiers: unregister empty tiers outside memory_tier_lock
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (329 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 330/507] mm/cma: dont release CMA pages still in use Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 332/507] mm/huge_memory: set the mmu_gather page size in zap_huge_pud() Greg Kroah-Hartman
` (175 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Gregory Price (Meta),
Muhammad Usama Anjum, David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 500624f28eca441e35f978979ccfb373202fefd3 ]
When offlining a node's last memory empties its tier,
clear_node_memory_tier() calls device_unregister() while holding
memory_tier_lock. A concurrent sysfs read can hold a kernfs active
reference and block in nodelist_show() on that mutex. device_unregister()
then waits in kernfs_drain() for the read to finish and release its active
reference, while the reader waits for the offlining task to release the
mutex.
Return the node's former tier from clear_node_memory_tier(), making the
helper more similar to set_node_memory_tier(), which also returns a
memory_tier pointer. Let the caller unlink an empty tier under
memory_tier_lock before rebuilding demotion targets, then unregister its
device after dropping the lock.
Fixes: 9832fb87834e ("mm/demotion: expose memory tier details via sysfs")
Cc: stable@vger.kernel.org
Reported-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Gregory Price (Meta) <gourry@gourry.net>
Tested-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Link: https://patch.msgid.link/20261031-fixes_core-v3-46-d6437171ecc3@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/memory-tiers.c | 29 +++++++++++++----------------
1 file changed, 13 insertions(+), 16 deletions(-)
diff --git a/mm/memory-tiers.c b/mm/memory-tiers.c
index 54851d8a195b0..ddc135f55eb8b 100644
--- a/mm/memory-tiers.c
+++ b/mm/memory-tiers.c
@@ -571,21 +571,14 @@ static struct memory_tier *set_node_memory_tier(int node)
return memtier;
}
-static void destroy_memory_tier(struct memory_tier *memtier)
+static struct memory_tier *clear_node_memory_tier(int node)
{
- list_del(&memtier->list);
- device_unregister(&memtier->dev);
-}
-
-static bool clear_node_memory_tier(int node)
-{
- bool cleared = false;
pg_data_t *pgdat;
struct memory_tier *memtier;
pgdat = NODE_DATA(node);
if (!pgdat)
- return false;
+ return NULL;
/*
* Make sure that anybody looking at NODE_DATA who finds
@@ -603,14 +596,10 @@ static bool clear_node_memory_tier(int node)
synchronize_rcu();
memtype = node_memory_types[node].memtype;
node_clear(node, memtype->nodes);
- if (nodes_empty(memtype->nodes)) {
+ if (nodes_empty(memtype->nodes))
list_del_init(&memtype->tier_sibling);
- if (list_empty(&memtier->memory_types))
- destroy_memory_tier(memtier);
- }
- cleared = true;
}
- return cleared;
+ return memtier;
}
static void release_memtype(struct kref *kref)
@@ -883,13 +872,21 @@ static int __meminit memtier_hotplug_callback(struct notifier_block *self,
{
struct memory_tier *memtier;
struct node_notify *nn = _arg;
+ bool empty = false;
switch (action) {
case NODE_REMOVED_LAST_MEMORY:
mutex_lock(&memory_tier_lock);
- if (clear_node_memory_tier(nn->nid))
+ memtier = clear_node_memory_tier(nn->nid);
+ if (memtier) {
+ empty = list_empty(&memtier->memory_types);
+ if (empty)
+ list_del(&memtier->list);
establish_demotion_targets();
+ }
mutex_unlock(&memory_tier_lock);
+ if (empty)
+ device_unregister(&memtier->dev);
break;
case NODE_ADDED_FIRST_MEMORY:
mutex_lock(&memory_tier_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 332/507] mm/huge_memory: set the mmu_gather page size in zap_huge_pud()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (330 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 331/507] mm/memory-tiers: unregister empty tiers outside memory_tier_lock Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 333/507] khugepaged: fix readahead lock inversion in collapse_file() Greg Kroah-Hartman
` (174 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pavithra, Ritesh Harjani (IBM),
Zi Yan, Muchun Song, David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
[ Upstream commit 466d6844c8f19fba16b668b49861bdb8d7ded282 ]
Unmapping a device-dax mapping with 1G alignment on powerpc radix kernel
built with CONFIG_DEBUG_VM triggers this warning on every munmap:
WARNING: mm/mmu_gather.c:176 at __tlb_remove_folio_pages_size+0x38/0x230
NIP [c00000000063d508] __tlb_remove_folio_pages_size+0x38/0x230
LR [c0000000006fb688] zap_huge_pud+0x1b8/0x2d0
Call Trace:
zap_huge_pud+0x170/0x2d0 (unreliable)
__zap_vma_range+0x1604/0x1e20
unmap_vmas+0xa0/0x1f0
unmap_region+0xb0/0x130
vms_complete_munmap_vmas+0x120/0x310
do_vmi_align_munmap+0x1ec/0x240
__vm_munmap+0x148/0x220
sys_munmap+0x28/0x40
To trigger this - it is enough to mmap() /dev/dax0.0, touch the first
byte so that the whole 1G is mapped by a single PUD and then munmap()
it.
PowerPC needs MMU_GATHER_PAGE_SIZE in which mmu_gather needs to record
the page size for which tlb flush is needed. zap_huge_pmd(),
zap_pte_range(), change_huge_pud() etc all do this already. However,
since commit:
dbe54153296d ("mm/huge_memory: add vmf_insert_folio_pud()")
a device-dax PUD maps a real folio and zap_huge_pud() now hands it to
tlb_remove_page_size(tlb, page, HPAGE_PUD_SIZE). At that point
tlb->page_size is still whatever the previous user left behind, which is
0 for the fresh gather set up by munmap() and so the check fires.
Fix this in the same way like how other similar paths do.
Fixes: dbe54153296d0 ("mm/huge_memory: add vmf_insert_folio_pud()")
Cc: stable@vger.kernel.org
Reported-by: Pavithra <pavrampu@linux.ibm.com>
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Acked-by: Zi Yan <ziy@nvidia.com>
Acked-by: Muchun Song <muchun.song@linux.dev>
Tested-by: Pavithra Prakash <pavrampu@linux.ibm.com>
Link: https://patch.msgid.link/8b853e5f9f16145859407b28af654b0f79e12642.1793318297.git.ritesh.list@gmail.com
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/huge_memory.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index fde9ea15fef9e..5f7e3320d4d06 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -3061,6 +3061,8 @@ int zap_huge_pud(struct mmu_gather *tlb, struct vm_area_struct *vma,
spinlock_t *ptl;
pud_t orig_pud;
+ tlb_change_page_size(tlb, HPAGE_PUD_SIZE);
+
ptl = __pud_trans_huge_lock(pud, vma);
if (!ptl)
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 333/507] khugepaged: fix readahead lock inversion in collapse_file()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (331 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 332/507] mm/huge_memory: set the mmu_gather page size in zap_huge_pud() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 334/507] mm/gup: check folio->mapping under folio lock in memfd_pin_folios() Greg Kroah-Hartman
` (173 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+16bf7cd0ebeb1de93aa5,
Lance Yang, Pedro Falcato, David Hildenbrand (Arm), Zi Yan,
Baolin Wang, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lance Yang <lance.yang@linux.dev>
[ Upstream commit eadce52a9ef657d561b3e76c9b5f178bd99735f5 ]
collapse_file() can call page_cache_sync_readahead() while still holding
source folios locked. If truncate holds mapping->invalidate_lock
exclusively and waits for one of those folios, readahead waits for
invalidate_lock and neither side can make progress.
We need to release those folio locks before starting readahead. On a page
cache miss, roll back first, populate the collapse range, and retry once.
Doing readahead after rollback avoids an extra pass when all folios are
already present. If another miss occurs on retry, give up rather than keep
retrying while truncate or reclaim removes folios.
Keep page_cache_sync_readahead() and wait for read I/O with
filemap_lock_folio(), releasing each folio before moving to the next. The
existing uptodate check during collapse still handles read errors.
Shmem uses shmem_get_folio() for swapin and fallocated folios without
taking mapping->invalidate_lock, so it is unaffected.
Reported-by: syzbot+16bf7cd0ebeb1de93aa5@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=16bf7cd0ebeb1de93aa5
Fixes: 730633f0b7f9 ("mm: Protect operations adding pages to page cache with invalidate_lock")
Cc: stable@vger.kernel.org
Signed-off-by: Lance Yang <lance.yang@linux.dev>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Acked-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Link: https://patch.msgid.link/20261026152013.10511-1-lance.yang@linux.dev
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/khugepaged.c | 44 +++++++++++++++++++++++++++++++++-----------
1 file changed, 33 insertions(+), 11 deletions(-)
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index 8fc8f79641ea5..47ed64f51748f 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -2261,6 +2261,8 @@ static enum scan_result collapse_file(struct mm_struct *mm, unsigned long addr,
XA_STATE_ORDER(xas, &mapping->i_pages, start, HPAGE_PMD_ORDER);
enum scan_result result = SCAN_SUCCEED;
int nr_none = 0;
+ bool do_readahead = false;
+ bool readahead_done = false;
/*
* MADV_COLLAPSE ignores shmem huge config, so do not check shmem
@@ -2278,6 +2280,10 @@ static enum scan_result collapse_file(struct mm_struct *mm, unsigned long addr,
mapping_set_update(&xas, mapping);
+retry:
+ result = SCAN_SUCCEED;
+ do_readahead = false;
+ xas_set_order(&xas, start, HPAGE_PMD_ORDER);
__folio_set_locked(new_folio);
if (is_shmem)
__folio_set_swapbacked(new_folio);
@@ -2342,17 +2348,9 @@ static enum scan_result collapse_file(struct mm_struct *mm, unsigned long addr,
}
} else { /* !is_shmem */
if (!folio || xa_is_value(folio)) {
- xas_unlock_irq(&xas);
- page_cache_sync_readahead(mapping, &file->f_ra,
- file, index,
- end - index);
- /* drain lru cache to help folio_isolate_lru() */
- lru_add_drain();
- folio = filemap_lock_folio(mapping, index);
- if (IS_ERR(folio)) {
- result = SCAN_FAIL;
- goto xa_unlocked;
- }
+ do_readahead = !readahead_done;
+ result = SCAN_FAIL;
+ goto xa_locked;
} else if (folio_test_dirty(folio)) {
/*
* This page is dirty because it hasn't
@@ -2679,6 +2677,30 @@ static enum scan_result collapse_file(struct mm_struct *mm, unsigned long addr,
new_folio->mapping = NULL;
folio_unlock(new_folio);
+
+ /* Readahead may take invalidate_lock; source folios are unlocked. */
+ if (do_readahead) {
+ for (index = start; index < end;) {
+ folio = filemap_lock_folio(mapping, index);
+ if (IS_ERR(folio)) {
+ page_cache_sync_readahead(mapping, &file->f_ra,
+ file, index, end - index);
+ folio = filemap_lock_folio(mapping, index);
+ if (IS_ERR(folio)) {
+ result = SCAN_FAIL;
+ goto out_put;
+ }
+ }
+ index = folio_next_index(folio);
+ folio_unlock(folio);
+ folio_put(folio);
+ }
+ /* Drain the local LRU batch before retrying isolation. */
+ lru_add_drain();
+ readahead_done = true;
+ goto retry;
+ }
+out_put:
folio_put(new_folio);
out:
VM_BUG_ON(!list_empty(&pagelist));
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 334/507] mm/gup: check folio->mapping under folio lock in memfd_pin_folios()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (332 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 333/507] khugepaged: fix readahead lock inversion in collapse_file() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 335/507] x86/entry: Fix ptrace regression Greg Kroah-Hartman
` (172 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andy Lutomirski, Samiullah Khawaja,
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Samiullah Khawaja <skhawaja@google.com>
[ Upstream commit 71555ae8c7572fd99158013ca2e29187c5d2508d ]
memfd_pin_folios() pins folios from the page cache without taking the
folio lock. khugepaged or MADV_COLLAPSE can therefore replace a folio
after checking its refcount while memfd_pin_folios() still pins the old
folio. The caller then receives a folio which is no longer part of the
memfd.
For udmabuf and iommufd, this can cause data corruption: DMA accesses
the detached folio rather than the live memfd contents. DMA reads can
return stale data, while DMA writes update the detached copy and are
lost from the live memfd. The detached folio remains pinned, so these
accesses do not constitute a use-after-free or target another
application's memory. For memfd live update, the stale contents can
reappear in the memfd after handover.
Lock the folio and recheck folio->mapping before pinning it, like other
page cache users do. If the folio was removed, retry the folio lookup
from the index that was removed.
Fixes: 89c1905d9c14 ("mm/gup: introduce memfd_pin_folios() for pinning memfd folios")
Reported-by: Andy Lutomirski <luto@amacapital.net>
Closes: https://lore.kernel.org/all/CALCETrV5eqg6d9=+BQhCpRwBNe3aCQiut8vxPBs8b7PToqjaHg@mail.gmail.com/
Cc: stable@vger.kernel.org
Signed-off-by: Samiullah Khawaja <skhawaja@google.com>
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
Link: https://patch.msgid.link/20261031203540.2282507-1-skhawaja@google.com
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/gup.c | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/mm/gup.c b/mm/gup.c
index b3937aff3ad44..4f58ad22a756b 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -3446,7 +3446,7 @@ long memfd_pin_folios(struct file *memfd, loff_t start, loff_t end,
{
unsigned int flags, nr_folios, nr_found;
unsigned int i, pgshift = PAGE_SHIFT;
- pgoff_t start_idx, end_idx;
+ pgoff_t start_idx, end_idx, retry_idx;
struct folio *folio = NULL;
struct folio_batch fbatch;
struct hstate *h;
@@ -3487,6 +3487,7 @@ long memfd_pin_folios(struct file *memfd, loff_t start, loff_t end,
* reason, we try to allocate them and add them to the
* page cache.
*/
+ retry_idx = start_idx;
nr_found = filemap_get_folios_contig(memfd->f_mapping,
&start_idx,
end_idx,
@@ -3499,7 +3500,21 @@ long memfd_pin_folios(struct file *memfd, loff_t start, loff_t end,
for (i = 0; i < nr_found; i++) {
folio = fbatch.folios[i];
+ /*
+ * The folio might have been removed from the
+ * page cache (e.g., truncated or collapsed)
+ * after the lookup. Recheck under the folio
+ * lock.
+ */
+ folio_lock(folio);
+ if (unlikely(folio->mapping != memfd->f_mapping)) {
+ folio_unlock(folio);
+ start_idx = retry_idx;
+ break;
+ }
+
if (try_grab_folio(folio, 1, FOLL_PIN)) {
+ folio_unlock(folio);
folio_batch_release(&fbatch);
ret = -EINVAL;
goto err;
@@ -3510,14 +3525,12 @@ long memfd_pin_folios(struct file *memfd, loff_t start, loff_t end,
* page cache that were never cleared.
*/
if (!folio_test_uptodate(folio)) {
- folio_lock(folio);
- if (!folio_test_uptodate(folio)) {
- folio_zero_range(folio, 0, folio_size(folio));
- flush_dcache_folio(folio);
- folio_mark_uptodate(folio);
- }
- folio_unlock(folio);
+ folio_zero_range(folio, 0, folio_size(folio));
+ flush_dcache_folio(folio);
+ folio_mark_uptodate(folio);
}
+ retry_idx = folio_next_index(folio);
+ folio_unlock(folio);
if (nr_folios == 0)
*offset = offset_in_folio(folio, start);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 335/507] x86/entry: Fix ptrace regression
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (333 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 334/507] mm/gup: check folio->mapping under folio lock in memfd_pin_folios() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 336/507] ipv6: fix device binding after failed datagram connect Greg Kroah-Hartman
` (171 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sebastian Andrzej Siewior,
Thomas Gleixner, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <tglx@kernel.org>
[ Upstream commit b697faab2c92653ee13bd950c8de13551a78971d ]
The recent rework of the syscall entry code missed the historical detail of
the abuse of syscall number -1L to abort a syscall and keep modifications
by tracers to the return value, while a rewrite of the syscall number to an
invalid value undoes eventual tracer modification to the return value and
overwrite it with -ENOSYS.
Restore the original behaviour.
Fixes: 1b1f3b3e1b39 ("x86/entry: Get rid of the sys_ni_syscall() indirection")
Reported-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Tested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/87ecd4xwlr.ffs@fw13
Closes: https://lore.kernel.org/all/20261022142425.3Wx-RrU5@linutronix.de
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/entry/syscall_32.c | 4 ++++
arch/x86/entry/syscall_64.c | 26 ++++++++++++++++++++++----
2 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/arch/x86/entry/syscall_32.c b/arch/x86/entry/syscall_32.c
index 91123a90710c4..4c36e8db0e341 100644
--- a/arch/x86/entry/syscall_32.c
+++ b/arch/x86/entry/syscall_32.c
@@ -77,6 +77,10 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs, unsigned
if (likely(nr < IA32_NR_syscalls)) {
nr = array_index_nospec(nr, IA32_NR_syscalls);
regs->ax = ia32_sys_call(regs, (unsigned int)nr);
+ } else {
+ /* See comment in do_syscall_64() */
+ if (nr != -1UL)
+ regs->ax = -ENOSYS;
}
}
diff --git a/arch/x86/entry/syscall_64.c b/arch/x86/entry/syscall_64.c
index 966d3d1b75868..bb95ad0ab7862 100644
--- a/arch/x86/entry/syscall_64.c
+++ b/arch/x86/entry/syscall_64.c
@@ -64,15 +64,20 @@ static __always_inline bool do_syscall_x64(struct pt_regs *regs, unsigned long n
return false;
}
-static __always_inline void do_syscall_x32(struct pt_regs *regs, unsigned long nr)
+static __always_inline bool do_syscall_x32(struct pt_regs *regs, unsigned long nr)
{
+ if (!IS_ENABLED(CONFIG_X86_X32_ABI))
+ return false;
+
/* Adjust the starting offset of the table */
nr -= __X32_SYSCALL_BIT;
- if (IS_ENABLED(CONFIG_X86_X32_ABI) && likely(nr < X32_NR_syscalls)) {
+ if (likely(nr < X32_NR_syscalls)) {
nr = array_index_nospec(nr, X32_NR_syscalls);
regs->ax = x32_sys_call(regs, (unsigned int)nr);
+ return true;
}
+ return false;
}
/* Returns true to return using SYSRET, or false to use IRET */
@@ -81,8 +86,21 @@ __visible noinstr bool do_syscall_64(struct pt_regs *regs, long nr)
if (likely(syscall_enter_from_user_mode_randomize_stack(regs, &nr))) {
instrumentation_begin();
- if (!do_syscall_x64(regs, nr))
- do_syscall_x32(regs, nr);
+ if (unlikely(!do_syscall_x64(regs, nr))) {
+ /*
+ * The special treatment of syscall number -1 is a
+ * historical bogosity as the original code used -1 to
+ * indicate syscall abort, which is not distinguishable
+ * from a syscall which is invoked with syscall number
+ * -1. The historic behavior is to keep the return value
+ * in regs->ax unmodified in that case, which means it's
+ * either the preset value -ENOSYS or a value which was
+ * written by a tracer. If the syscall number is invalid
+ * but not -1 then overwrite any tracer modification.
+ */
+ if (!do_syscall_x32(regs, nr) && nr != -1L)
+ regs->ax = -ENOSYS;
+ }
instrumentation_end();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 336/507] ipv6: fix device binding after failed datagram connect
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (334 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 335/507] x86/entry: Fix ptrace regression Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 337/507] ovl: fail the mount if the casefold flag has changed Greg Kroah-Hartman
` (170 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xia Yan, Paolo Abeni, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xia Yan <yanxia@cmss.chinamobile.com>
[ Upstream commit bc53aab4881adc134f495092034e9e7c0791d84c ]
__ip6_datagram_connect() can change sk_bound_dev_if when connecting to
an address that needs a scope ID. If ip6_datagram_dst_update() fails,
the old peer address and port are restored, but the new device binding
is left behind.
A UDP socket can then keep reporting its original peer while sends and
attempts to reconnect to that peer fail with ENETUNREACH. Replies to the
socket are also dropped by the device match. The same problem occurs
when a scoped multicast destination picks up np->mcast_oif.
Save the original binding before processing the scope and restore it
along with the peer information on failure. This completes the rollback
in commit 2f987a76a977 ("net: ipv6: keep sk status consistent after
datagram connect failure") and preserves the new binding on success.
Found while reviewing scope-ID handling in __ip6_datagram_connect().
Confirmed by exchanging UDP traffic over ::1, then attempting a link-local
connect with a nonexistent scope ifindex or a down interface. After that
connect fails, the original peer is still reported but communication and
reconnecting to it fail.
Tested before and after the fix in UML for three rounds, covering explicit
scopes, multicast interface fallback, initially unconnected sockets and
existing bindings. With the fix, the old binding and peer are retained,
and traffic and reconnection to the original peer work. Also built on
x86_64 with W=1 using adjusted allmodconfig and allyesconfig
configurations, with no new warnings.
Fixes: 2f987a76a977 ("net: ipv6: keep sk status consistent after datagram connect failure")
Cc: stable@vger.kernel.org
Signed-off-by: Xia Yan <yanxia@cmss.chinamobile.com>
Link: https://patch.msgid.link/20261029135822.448299-1-yanxia@cmss.chinamobile.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/datagram.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 38d7b48452817..9672ac979f476 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -149,6 +149,7 @@ int __ip6_datagram_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
__be32 fl6_flowlabel = 0;
__be32 old_fl6_flowlabel;
__be16 old_dport;
+ int old_bound_dev_if;
int addr_type;
int err;
@@ -219,6 +220,8 @@ int __ip6_datagram_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
goto out;
}
+ old_bound_dev_if = sk->sk_bound_dev_if;
+
if (__ipv6_addr_needs_scope_id(addr_type)) {
if (addr_len >= sizeof(struct sockaddr_in6) &&
usin->sin6_scope_id) {
@@ -261,6 +264,7 @@ int __ip6_datagram_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
sk->sk_v6_daddr = old_daddr;
np->flow_label = old_fl6_flowlabel;
inet->inet_dport = old_dport;
+ WRITE_ONCE(sk->sk_bound_dev_if, old_bound_dev_if);
goto out;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 337/507] ovl: fail the mount if the casefold flag has changed
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (335 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 336/507] ipv6: fix device binding after failed datagram connect Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 338/507] ovl: do not let chattr change the casefold flag Greg Kroah-Hartman
` (169 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Hungyu Lin,
Amir Goldstein, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit c782fc8ada811569811c0fdea5c3412511be95d0 ]
An unprivileged user in a user namespace can repeatedly trigger a kernel
warning with their own overlay mounts. They do so by changing the
casefold flag of the topmost layer's empty root, the top directory of
that layer, after the layers are set and before the mount is created.
The casefold flag of a directory makes name lookups in that directory
case-insensitive. All layers of an overlay must agree on casefolding.
ovl_mount_dir_check() reads the casefold flag of a layer root when
fsconfig() sets that layer, and saves the result in ofs->casefold. The
mount is created later, by another fsconfig() call with
FSCONFIG_CMD_CREATE.
The casefold flag of an empty directory can be changed.
The casefold flag of the overlay root must match ofs->casefold.
ovl_get_root() copies the flag from the topmost layer root, as it is
when the mount is created. On a mismatch, ovl_get_root() only does a
WARN_ON(), and the mount continues. The check is not a WARN_ON_ONCE(),
so each such mount warns again.
An unprivileged user needs CONFIG_UNICODE, and a tmpfs mounted with the
casefold option in their namespace.
Reproduced by changing the casefold flag of the empty upper directory
after the layers were set and before FSCONFIG_CMD_CREATE, with tmpfs and
ext4 layers, and as uid 1000 in a user namespace.
Fix this by replacing the WARN_ON() with a check that fails the mount
with -EINVAL.
Fixes: f9377faaeae0 ("ovl: Add S_CASEFOLD as part of the inode flag to be copied")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
Tested-by: Hungyu Lin <dennylin0707@gmail.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/overlayfs/super.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 861b0775f9ddb..c06bfe9765e25 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -1366,7 +1366,6 @@ static struct dentry *ovl_get_root(struct super_block *sb,
ovl_dentry_set_flag(OVL_E_CONNECTED, root);
ovl_set_upperdata(d_inode(root));
ovl_inode_init(d_inode(root), &oip, ino, fsid);
- WARN_ON(!!IS_CASEFOLDED(d_inode(root)) != ofs->casefold);
ovl_dentry_init_flags(root, upperdentry, oe, DCACHE_OP_WEAK_REVALIDATE);
/* root keeps a reference of upperdentry */
dget(upperdentry);
@@ -1550,6 +1549,17 @@ static int ovl_fill_super_creds(struct fs_context *fc, struct super_block *sb)
if (!sb->s_root)
goto out_free_oe;
+ /*
+ * The casefold flag of an empty layer root may have changed since the
+ * mount options were parsed. The root inode owns oe by now.
+ */
+ if (!!IS_CASEFOLDED(d_inode(sb->s_root)) != ofs->casefold) {
+ pr_err("casefold flag of the root directory has changed\n");
+ dput(sb->s_root);
+ sb->s_root = NULL;
+ return -EINVAL;
+ }
+
return 0;
out_free_oe:
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 338/507] ovl: do not let chattr change the casefold flag
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (336 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 337/507] ovl: fail the mount if the casefold flag has changed Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 339/507] ovl: fix whiteout creation in casefolded directories Greg Kroah-Hartman
` (168 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Hungyu Lin,
Amir Goldstein, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit 83b351c3ade542bbfa1073e8c2d919826628252a ]
chattr +F or -F on an overlay directory can make the directory, or the
whole mount, unusable. Lookups of the directory, and lookups in it, then
fail. From code inspection, the caller only needs to own the directory.
The upper filesystem must support casefolding: ext4 or f2fs with the
casefold feature, or tmpfs with the casefold option.
chattr +F and -F set and clear FS_CASEFOLD_FL, the casefold flag of a
directory. The flag enables casefolding (case-insensitive name lookup)
for the directory. All directories of an overlay must match the casefold
state that was recorded at mount time, and ovl_lookup_single() enforces
this:
- A lookup in a directory that does not match fails with -ESTALE.
- A lookup of the directory itself fails with -EREMOTE.
ovl_fileattr_set() copies the directory up, which creates it in the
upper layer if it only existed in a lower layer. It then passes
FS_CASEFOLD_FL on to the upper filesystem. The upper filesystem accepts
the change if the upper directory is empty, regardless of what the
merged directory contains. The merged directory is the one that the user
sees, with the names from the upper and the lower directories.
After the change the upper directory no longer matches the mount. If the
directory is the root of the overlay, the whole mount is affected.
The flag can also change without chattr +F or -F. chattr reads all flags
of a directory, changes one and writes all of them back. For a directory
that only exists in a lower layer, overlayfs reads the flags from the
lower filesystem. xfs with the ascii-ci feature reports FS_CASEFOLD_FL
on every inode, but never sets S_CASEFOLD, the inode flag that overlayfs
compares with the mount. So its directories count as not casefolded.
With a lower layer on such an xfs and an upper layer on ext4 with the
casefold feature, chattr +A on a lower-only directory therefore sets
FS_CASEFOLD_FL on the new, empty upper directory.
Reproduced as root on tmpfs and on ext4 with chattr +F or -F on an
overlay directory whose upper directory was empty. Afterwards lookups
below it failed with ESTALE, and lookups of the directory itself failed
with EREMOTE. The chattr +A case was seen once, on a kernel with an
earlier form of this patch that still passed the caller's flag on:
lookups of the directory failed with EREMOTE.
Fix this by returning -EOPNOTSUPP if FS_IOC_SETFLAGS, the only call that
can change the flag, asks for a casefold flag on a directory that does
not agree with the casefold state of the mount. This also refuses the
chattr +A case above.
Fixes: 083957f9614a ("ovl: support layers on case-folding capable filesystems")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
[amir: check the flag against the casefold state of the mount instead of
reading back the flags]
Tested-by: Hungyu Lin <dennylin0707@gmail.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/overlayfs/inode.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 7e1ac70c5d97b..e3aa0931bea9f 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -658,6 +658,14 @@ int ovl_fileattr_set(struct mnt_idmap *idmap,
unsigned int flags;
int err;
+ /*
+ * Lookup refuses a directory that does not agree with the casefold
+ * state of the mount. Only FS_IOC_SETFLAGS can ask for a change.
+ */
+ if (S_ISDIR(inode->i_mode) && fa->flags_valid &&
+ !!(fa->flags & FS_CASEFOLD_FL) != OVL_FS(inode->i_sb)->casefold)
+ return -EOPNOTSUPP;
+
err = ovl_copy_up(dentry);
if (!err) {
ovl_path_real(dentry, &upperpath);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 339/507] ovl: fix whiteout creation in casefolded directories
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (337 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 338/507] ovl: do not let chattr change the casefold flag Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 340/507] net/sched: clamp skb->queue_mapping before indexing the tx queue Greg Kroah-Hartman
` (167 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Hungyu Lin,
Amir Goldstein, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit e803c82dcdd15e87b48fca1ea8d2cfe6a7ed83d4 ]
unlink and rmdir fail with EINVAL on an overlay with casefolded
(case-insensitive) layers, if the name exists in a lower layer.
Casefolded layers need CONFIG_UNICODE. Root can mount such an overlay,
and so can an unprivileged user in a user namespace, with tmpfs layers.
Overlayfs does not change a lower layer. To remove a name that exists
there, it hides the name with a marker file, a whiteout. It creates the
whiteout in the work directory, a scratch directory on the upper
filesystem, and renames it over the name in the upper directory:
- ovl_whiteout() creates the whiteout with mknod, or as a hard link to
an earlier whiteout.
- ovl_cleanup_and_whiteout() then prepares the rename with
start_renaming_two_dentries(), which returns -EINVAL if the source or
the target dentry is unhashed, that is, not in the dentry hash table.
With casefolded directories, both dentries can be unhashed:
- The target. Lookup in a casefolded directory leaves a negative dentry
unhashed, so the rename target is unhashed if the name does not exist
in the upper directory.
- The source, which is the new whiteout. tmpfs hashes a dentry when
mknod or link makes it positive, but ext4 does not, so on ext4 the
source is unhashed as well.
The cleanup after the failure also refuses an unhashed dentry, so on
ext4 the whiteout is left behind in the work directory.
Reproduced with rm and rmdir on casefolded tmpfs and ext4 layers, also
as uid 1000 in a user namespace.
Fix this by creating the whiteout with ovl_create_temp(), which repeats
the lookup if the new dentry is unhashed. Prepare the rename with
start_renaming_dentry(), which looks up the target name with the
directories locked. The caller looked the name up without a lock, so
return -ESTALE if the name now refers to a different inode.
Fixes: 833d2b3a072f ("Add start_renaming_two_dentries()")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
[amir: pass the name used for lookup instead of taking a name snapshot]
Tested-by: Hungyu Lin <dennylin0707@gmail.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/overlayfs/dir.c | 46 ++++++++++++++++++++++------------------
fs/overlayfs/overlayfs.h | 10 +--------
fs/overlayfs/readdir.c | 3 ++-
fs/overlayfs/util.c | 2 +-
4 files changed, 29 insertions(+), 32 deletions(-)
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index f716ac13badf3..c77af9a79d883 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -74,39 +74,34 @@ static struct dentry *ovl_start_creating_temp(struct ovl_fs *ofs,
&QSTR(name));
}
+/*
+ * The whiteout is the source of a rename, so it has to be hashed.
+ * ovl_create_temp() takes care of that for a casefolded workdir.
+ */
static struct dentry *ovl_whiteout(struct ovl_fs *ofs)
{
int err;
struct dentry *whiteout, *link;
struct dentry *workdir = ofs->workdir;
- struct inode *wdir = workdir->d_inode;
- char name[OVL_TEMPNAME_SIZE];
guard(mutex)(&ofs->whiteout_lock);
if (!ofs->whiteout) {
- whiteout = ovl_start_creating_temp(ofs, workdir, name);
+ whiteout = ovl_create_temp(ofs, workdir, &(struct ovl_cattr) {
+ .mode = S_IFCHR | WHITEOUT_MODE,
+ .rdev = WHITEOUT_DEV });
if (IS_ERR(whiteout))
return whiteout;
- err = ovl_do_whiteout(ofs, wdir, whiteout);
- if (!err)
- ofs->whiteout = dget(whiteout);
- end_creating(whiteout);
- if (err)
- return ERR_PTR(err);
+ ofs->whiteout = whiteout;
}
if (!ofs->no_shared_whiteout) {
- link = ovl_start_creating_temp(ofs, workdir, name);
- if (IS_ERR(link))
+ link = ovl_create_temp(ofs, workdir, &(struct ovl_cattr) {
+ .hardlink = ofs->whiteout });
+ if (!IS_ERR(link))
return link;
- err = ovl_do_link(ofs, ofs->whiteout, wdir, link);
- if (!err)
- whiteout = dget(link);
- end_creating(link);
- if (!err)
- return whiteout;
+ err = PTR_ERR(link);
if (err != -EMLINK) {
pr_warn("Failed to link whiteout - disabling whiteout inode sharing(nlink=%u, err=%u)\n",
ofs->whiteout->d_inode->i_nlink,
@@ -120,9 +115,10 @@ static struct dentry *ovl_whiteout(struct ovl_fs *ofs)
}
int ovl_cleanup_and_whiteout(struct ovl_fs *ofs, struct dentry *dir,
- struct dentry *dentry)
+ struct dentry *dentry, const struct qstr *name)
{
struct dentry *whiteout;
+ struct qstr last = QSTR_LEN(name->name, name->len);
struct renamedata rd = {};
int err;
int flags = 0;
@@ -139,9 +135,17 @@ int ovl_cleanup_and_whiteout(struct ovl_fs *ofs, struct dentry *dir,
rd.old_parent = ofs->workdir;
rd.new_parent = dir;
rd.flags = flags;
- err = start_renaming_two_dentries(&rd, whiteout, dentry);
+ /*
+ * The caller looked up @dentry by @name without a lock on @dir, and a
+ * casefolded directory leaves a negative dentry unhashed. Nothing tells
+ * if such a dentry is still valid, so look up @name again with @dir locked.
+ */
+ err = start_renaming_dentry(&rd, 0, whiteout, &last);
if (!err) {
- err = ovl_do_rename_rd(&rd);
+ if (d_inode(rd.new_dentry) != d_inode(dentry))
+ err = -ESTALE;
+ else
+ err = ovl_do_rename_rd(&rd);
end_renaming(&rd);
}
if (err)
@@ -847,7 +851,7 @@ static int ovl_remove_and_whiteout(struct dentry *dentry,
goto out_dput_upper;
}
- err = ovl_cleanup_and_whiteout(ofs, upperdir, upper);
+ err = ovl_cleanup_and_whiteout(ofs, upperdir, upper, &dentry->d_name);
if (!err)
ovl_dir_modified(dentry->d_parent, true);
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 91cdd7e15696c..4faebb4c6825b 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -394,14 +394,6 @@ static inline int ovl_do_rename(struct ovl_fs *ofs, struct dentry *olddir,
return ovl_do_rename_rd(&rd);
}
-static inline int ovl_do_whiteout(struct ovl_fs *ofs,
- struct inode *dir, struct dentry *dentry)
-{
- int err = vfs_whiteout(ovl_upper_mnt_idmap(ofs), dir, dentry);
- pr_debug("whiteout(%pd2) = %i\n", dentry, err);
- return err;
-}
-
static inline struct file *ovl_do_tmpfile(struct ovl_fs *ofs,
struct dentry *dentry, umode_t mode)
{
@@ -897,7 +889,7 @@ static inline void ovl_copyflags(struct inode *from, struct inode *to)
/* dir.c */
extern const struct inode_operations ovl_dir_inode_operations;
int ovl_cleanup_and_whiteout(struct ovl_fs *ofs, struct dentry *dir,
- struct dentry *dentry);
+ struct dentry *dentry, const struct qstr *name);
struct ovl_cattr {
dev_t rdev;
umode_t mode;
diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
index 80366424b3dc1..aefa41b163cd8 100644
--- a/fs/overlayfs/readdir.c
+++ b/fs/overlayfs/readdir.c
@@ -1322,7 +1322,8 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs)
* Whiteout orphan index to block future open by
* handle after overlay nlink dropped to zero.
*/
- err = ovl_cleanup_and_whiteout(ofs, indexdir, index);
+ err = ovl_cleanup_and_whiteout(ofs, indexdir, index,
+ &QSTR_LEN(p->name, p->len));
} else {
/* Cleanup orphan index entries */
err = ovl_cleanup(ofs, indexdir, index);
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index b41f4788e4f06..47734eeb97b75 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -1118,7 +1118,7 @@ static void ovl_cleanup_index(struct dentry *dentry)
} else if (ovl_index_all(dentry->d_sb)) {
/* Whiteout orphan index to block future open by handle */
err = ovl_cleanup_and_whiteout(OVL_FS(dentry->d_sb),
- indexdir, index);
+ indexdir, index, &name);
} else {
/* Cleanup orphan index entries */
err = ovl_cleanup(ofs, indexdir, index);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 340/507] net/sched: clamp skb->queue_mapping before indexing the tx queue
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (338 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 339/507] ovl: fix whiteout creation in casefolded directories Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 341/507] ovl: inherit FMODE_NONOTIFY when opening directory realfiles Greg Kroah-Hartman
` (166 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko (nipa), Jamal Hadi Salim,
Simon Horman, Paolo Abeni, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit f19f2b308beb158d0e6f6eb806ced636e4ebf6ce ]
This issue was caught by Sashiko (nipa). A producer-side path cap is
already merged (ea4d4b5dddb5); this patch adds the matching consumer-side
caps.
The issue:
The tx queue is picked and capped in netdev_core_pick_tx() before the
__dev_xmit_skb() qdisc enqueue path. A tc BPF program running inside an
egress qdisc (not clsact) can then change __sk_buff->queue_mapping; that
store is never re-checked. bpf_convert_ctx_access() bounds it only by
NO_QUEUE_MAPPING, not by the device's queue count.
Two consumers read the stale value:
- On dequeue, qdisc_restart() calls netdev_get_tx_queue(), which
indexes dev->_tx[]. netdev_get_tx_queue() guards it with just a
DEBUG_NET_WARN_ON_ONCE, so sch_direct_xmit() takes the out-of-bounds
txq->_xmit_lock and writes txq->xmit_lock_owner past the end of the
allocation on non-lltx devices such as ifb. Drivers that index their
rings from skb_get_queue_mapping() (ex: ifb) go out of range the same
way.
- On enqueue, taprio_enqueue() indexes q->qdiscs[] with the same value;
the array is sized dev->num_tx_queues. A duplicating netem on a child
qdisc clones the skb and re-enqueues the clone at the taprio root
(qdisc_root_bh()) through a direct rootq->enqueue() call, so the value
reaches taprio_enqueue() before any dequeue cap runs.
The Fix:
Cap the mapping at the consumers and write the capped value back, so the
qdisc's _tx[] lookup, the taprio q->qdiscs[] lookup and any later driver
read stay in range.
On the dequeue side the cap folds into the dequeue path instead of a
separate walk over the returned list: dequeue_skb() caps the head, and
each bulk helper caps the element it appends. For a qdisc that is not
TCQ_F_ONETXQUEUE, netdev_cap_txqueue() logs a ratelimited notice and
selects queue 0.
A TCQ_F_ONETXQUEUE qdisc is bound to a single tx queue: dequeue_skb() uses
q->dev_queue for the frozen check, the BQL limit and the trace point, while
qdisc_restart() transmits on the skb's queue. Capping an out-of-range
mapping to queue 0 would therefore send a per-queue child's skb through a
different queue than the one it was dequeued for. On mq, mqprio, taprio and
htb offload children, a stopped queue 0 could then park the list in
q->gso_skb, and the later wake would schedule queue 0's own child instead
of this qdisc. Pin a TCQ_F_ONETXQUEUE mapping to the qdisc's own queue to
keep the documented invariant.
The pin covers every mapping, not only an out-of-range one: an in-range
mapping that a filter sets on one of those per-queue children is rewritten
to the child's own queue, and this path does not call netdev_cap_txqueue(),
so it logs no notice. On a single-queue device qdisc_create() sets
TCQ_F_ONETXQUEUE, so the one-queue trigger described below also takes this
branch and is corrected without a notice.
That also keeps a bulk list on one queue by construction: every element of
a TCQ_F_ONETXQUEUE qdisc, including a follower changed by a filter, is
pinned to q->dev_queue before it is appended. The fast bulk helper
therefore needs no head comparison and no skb_bad_txq requeue; the slow
helper, used only by non-ONETXQUEUE qdiscs, still compares and requeues a
mismatched follower, where a wake on any queue reschedules q.
On the enqueue side taprio_enqueue() caps the mapping against
real_num_tx_queues and writes it back before selecting q->qdiscs[queue], so
a duplicating child cannot steer the clone out of the array.
Conditions to recreate the bug:
The dequeue path: load a SCHED_CLS or SCHED_ACT program that stores
__sk_buff->queue_mapping (a tc BPF action is enough), attach it to a
transmit qdisc (for example a matchall filter on a prio root), and send a
packet. With a 1-queue device a store of 1 indexes one past dev->_tx[].
Under KASAN with panic_on_warn=1 the unfixed kernel faults with "BUG:
KASAN: slab-out-of-bounds in sch_direct_xmit". Loading the program needs
CAP_BPF/CAP_SYS_ADMIN, so the trigger is root.
The enqueue path: on a multi-queue device, install a software taprio root,
graft a prio child with a duplicating netem on every class, and store an
out-of-range queue_mapping from a matchall+bpf filter on the prio. The
duplicate is re-enqueued at the taprio root and indexes q->qdiscs[] past
dev->num_tx_queues; the unfixed kernel faults in taprio_enqueue_one().
Same CAP_BPF/CAP_SYS_ADMIN requirement.
Fixes: 74e31ca850c1 ("bpf: add skb->queue_mapping write access from tc clsact")
Reported-by: Sashiko (nipa) <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/netdev/179033713973.2160803.4914570693994398206@kernel.org/
Link: https://lore.kernel.org/netdev/179329777513.3134.12135506558709584471@kernel.org/
Link: https://lore.kernel.org/netdev/179293123940.3134.1149128679923234677@kernel.org/
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/QDISC-MD1X.v4.r0.20261021042722-1%40mojatatu.com
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/QDISC-MD1X.v3.r0.20261015165943-1%40mojatatu.com
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/QDISC-MD1X.v1.20261005193231%40mojatatu.com
Link: https://lore.kernel.org/netdev/20261015125822.GH83879@horms.kernel.org/
Cc: stable@vger.kernel.org
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/QDISC-MD1X.v6.r0.20261029162633-1@mojatatu.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/sch_generic.c | 41 ++++++++++++++++++++++++++++++++++++-----
net/sched/sch_taprio.c | 5 +++++
2 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 3e8ee4a691c34..d2e0d20f3ba1c 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -96,9 +96,34 @@ static void qdisc_maybe_clear_missed(struct Qdisc *q,
#define SKB_XOFF_MAGIC ((struct sk_buff *)1UL)
+/* Re-cap a stale queue_mapping; an ONETXQUEUE qdisc pins q->dev_queue. */
+static u16 qdisc_cap_skb_tx_queue(struct Qdisc *q, struct sk_buff *skb)
+{
+ u16 queue = skb_get_queue_mapping(skb);
+ struct net_device *dev = qdisc_dev(q);
+ u16 capped;
+
+ if (q->flags & TCQ_F_ONETXQUEUE)
+ capped = q->dev_queue - netdev_get_tx_queue(dev, 0);
+ else
+ capped = netdev_cap_txqueue(dev, queue);
+
+ if (unlikely(capped != queue))
+ skb_set_queue_mapping(skb, capped);
+
+ return capped;
+}
+
+static struct netdev_queue *skb_cap_tx_queue(struct Qdisc *q,
+ struct sk_buff *skb)
+{
+ return netdev_get_tx_queue(qdisc_dev(q),
+ qdisc_cap_skb_tx_queue(q, skb));
+}
+
static inline struct sk_buff *__skb_dequeue_bad_txq(struct Qdisc *q)
{
- const struct netdev_queue *txq = q->dev_queue;
+ const struct netdev_queue *txq;
spinlock_t *lock = NULL;
struct sk_buff *skb;
@@ -110,7 +135,8 @@ static inline struct sk_buff *__skb_dequeue_bad_txq(struct Qdisc *q)
skb = skb_peek(&q->skb_bad_txq);
if (skb) {
/* check the reason of requeuing without tx lock first */
- txq = skb_get_tx_queue(txq->dev, skb);
+ /* re-cap: real_num_tx_queues may have shrunk */
+ txq = skb_cap_tx_queue(q, skb);
if (!netif_xmit_frozen_or_stopped(txq)) {
skb = __skb_dequeue(&q->skb_bad_txq);
if (qdisc_is_percpu_stats(q)) {
@@ -224,6 +250,8 @@ static void try_bulk_dequeue_skb(struct Qdisc *q,
if (!nskb)
break;
+ /* Every element of an ONETXQUEUE qdisc is pinned to q->dev_queue. */
+ qdisc_cap_skb_tx_queue(q, nskb);
bytelimit -= nskb->len; /* covers GSO len */
skb->next = nskb;
skb = nskb;
@@ -241,7 +269,6 @@ static void try_bulk_dequeue_skb_slow(struct Qdisc *q,
struct sk_buff *skb,
int *packets)
{
- int mapping = skb_get_queue_mapping(skb);
struct sk_buff *nskb;
int cnt = 0;
@@ -249,7 +276,9 @@ static void try_bulk_dequeue_skb_slow(struct Qdisc *q,
nskb = q->dequeue(q);
if (!nskb)
break;
- if (unlikely(skb_get_queue_mapping(nskb) != mapping)) {
+ /* A tc BPF store may have changed the mapping; cap it. */
+ if (unlikely(qdisc_cap_skb_tx_queue(q, nskb) !=
+ skb_get_queue_mapping(skb))) {
qdisc_enqueue_skb_bad_txq(q, nskb);
break;
}
@@ -294,7 +323,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
if (xfrm_offload(skb))
*validate = true;
/* check the reason of requeuing without tx lock first */
- txq = skb_get_tx_queue(txq->dev, skb);
+ txq = skb_cap_tx_queue(q, skb);
if (!netif_xmit_frozen_or_stopped(txq)) {
skb = __skb_dequeue(&q->gso_skb);
if (qdisc_is_percpu_stats(q)) {
@@ -330,6 +359,8 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
skb = q->dequeue(q);
if (skb) {
bulk:
+ /* cap the head; the bulk helpers cap every appended element */
+ qdisc_cap_skb_tx_queue(q, skb);
if (qdisc_may_bulk(q))
try_bulk_dequeue_skb(q, skb, txq, packets, budget);
else
diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
index 39ac5b97aa3af..0eb0803047a1e 100644
--- a/net/sched/sch_taprio.c
+++ b/net/sched/sch_taprio.c
@@ -632,6 +632,11 @@ static int taprio_enqueue(struct sk_buff *skb, struct Qdisc *sch,
int queue;
queue = skb_get_queue_mapping(skb);
+ if (unlikely(queue >= qdisc_dev(sch)->real_num_tx_queues)) {
+ /* A tc BPF program may have stored an out-of-range mapping. */
+ queue = netdev_cap_txqueue(qdisc_dev(sch), queue);
+ skb_set_queue_mapping(skb, queue);
+ }
child = q->qdiscs[queue];
if (unlikely(child == &noop_qdisc))
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 341/507] ovl: inherit FMODE_NONOTIFY when opening directory realfiles
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (339 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 340/507] net/sched: clamp skb->queue_mapping before indexing the tx queue Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 342/507] net: reject a negative TCP header offset in qdisc_pkt_len_segs_init() Greg Kroah-Hartman
` (165 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Brauner (Amutable),
Edvard Conrad, Amir Goldstein, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <amir73il@gmail.com>
[ Upstream commit 323899b4ed233d5b6e2fc160c16fbf39cf0317da ]
When fanotify hands a listener an fd for a permission event on an
overlay directory, ovl_dir_open_realfile() opens the real directory via
dentry_open(), not backing_file_open(), so the lower open could still
raise FS_OPEN_PERM and deadlock a listener that also marks the backing
filesystem.
Export dentry_open_nonotify() and call it from ovl_path_open_realfile()
when the overlay user file must not generate events. Ordinary
ovl_path_open() callers are unchanged.
Reported-by: Christian Brauner (Amutable) <brauner@kernel.org>
Closes: https://lore.kernel.org/all/20261030-welpen-anbinden-nullen-b2432cee1d10@brauner/
Fixes: 130fdbc3d1f99 ("ovl: pass correct flags for opening real directory")
Cc: stable@vger.kernel.org
Tested-by: Edvard Conrad <edvard@tuta.io>
Link: https://lore.kernel.org/ltp/P5Iny41--F-9@tuta.io/
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/open.c | 1 +
fs/overlayfs/overlayfs.h | 9 ++++++++-
fs/overlayfs/readdir.c | 3 ++-
fs/overlayfs/util.c | 11 ++++++++++-
4 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/fs/open.c b/fs/open.c
index 6b1c14e684a93..d7d9fcc666ab5 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -1147,6 +1147,7 @@ struct file *dentry_open_nonotify(const struct path *path, int flags,
}
return f;
}
+EXPORT_SYMBOL_GPL(dentry_open_nonotify);
/**
* kernel_file_open - open a file for kernel internal use
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 4faebb4c6825b..b32089a104291 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -529,7 +529,14 @@ void ovl_dir_modified(struct dentry *dentry, bool impurity);
u64 ovl_inode_version_get(struct inode *inode);
bool ovl_is_whiteout(struct dentry *dentry);
bool ovl_path_is_whiteout(struct ovl_fs *ofs, const struct path *path);
-struct file *ovl_path_open(const struct path *path, int flags);
+struct file *ovl_path_open_realfile(const struct file *user_file,
+ const struct path *path, int flags);
+
+static inline struct file *ovl_path_open(const struct path *path, int flags)
+{
+ return ovl_path_open_realfile(NULL, path, flags);
+}
+
int ovl_copy_up_start(struct dentry *dentry, int flags);
void ovl_copy_up_end(struct dentry *dentry);
bool ovl_already_copied_up(struct dentry *dentry, int flags);
diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c
index aefa41b163cd8..e23331212a29b 100644
--- a/fs/overlayfs/readdir.c
+++ b/fs/overlayfs/readdir.c
@@ -973,7 +973,8 @@ static struct file *ovl_dir_open_realfile(const struct file *file,
const struct path *realpath)
{
with_ovl_creds(file_inode(file)->i_sb)
- return ovl_path_open(realpath, O_RDONLY | (file->f_flags & O_LARGEFILE));
+ return ovl_path_open_realfile(file, realpath,
+ O_RDONLY | (file->f_flags & O_LARGEFILE));
}
/*
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 47734eeb97b75..04103a6741ba0 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -654,7 +654,8 @@ bool ovl_path_is_whiteout(struct ovl_fs *ofs, const struct path *path)
ovl_path_check_xwhiteout_xattr(ofs, path);
}
-struct file *ovl_path_open(const struct path *path, int flags)
+struct file *ovl_path_open_realfile(const struct file *user_file,
+ const struct path *path, int flags)
{
struct inode *inode = d_inode(path->dentry);
struct mnt_idmap *real_idmap = mnt_idmap(path->mnt);
@@ -682,6 +683,14 @@ struct file *ovl_path_open(const struct path *path, int flags)
if (inode_owner_or_capable(real_idmap, inode))
flags |= O_NOATIME;
+ /*
+ * Directory opens use dentry_open() here, not backing_file_open().
+ * Inherit FMODE_NONOTIFY from a fanotify permission fd so a listener
+ * that also watches the real filesystem does not deadlock.
+ */
+ if (user_file && FMODE_FSNOTIFY_NONE(user_file->f_mode))
+ return dentry_open_nonotify(path, flags, current_cred());
+
return dentry_open(path, flags, current_cred());
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 342/507] net: reject a negative TCP header offset in qdisc_pkt_len_segs_init()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (340 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 341/507] ovl: inherit FMODE_NONOTIFY when opening directory realfiles Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 343/507] vhost/vsock: size receive SKBs from declared payload Greg Kroah-Hartman
` (164 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexei Starovoitov, Eric Dumazet,
Michael S. Tsirkin, Paolo Abeni, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexei Starovoitov <ast@kernel.org>
[ Upstream commit 35d2d6e5ac0d22428b2a0216061f3330c095393c ]
qdisc_pkt_len_segs_init() stores skb_transport_offset(), or the inner
offset, in the unsigned hdr_len. A header in front of skb->data gives a
negative offset. For an offset a little below zero, pskb_may_pull() gets a
small length and succeeds. Then a 64-bit kernel reads the TCP header far
after the skb and can crash. Further below zero pskb_may_pull() fails.
Commit 28a57fb2c5df ("net: iptunnel: fix stale transport header during
tunnel decapsulation") fixed one source of such offsets. Other code that
removes bytes from the front of a packet can leave the same stale header.
Return SKB_DROP_REASON_SKB_BAD_GSO for a negative offset in the TCP branch.
SKB_GSO_UDP_L4 and the other GSO types read no header and still get a wrong
qdisc_pkt_len(). On a 64-bit kernel only packets that cause the read after
the skb today get a new result. Then __dev_queue_xmit() drops them and
returns -EINVAL, but sch_handle_ingress() ignores the result. Their content
can be valid. Thus the code that leaves the header stale needs its own fix.
Fixes: 7fb4c1967011 ("net: pull headers in qdisc_pkt_len_segs_init()")
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
CC: stable@vger.kernel.org
Link: https://patch.msgid.link/20261101194433.2637113-1-alexei.starovoitov@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/dev.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index cc7b32ab56085..f803d8ba866ff 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4204,7 +4204,9 @@ static enum skb_drop_reason qdisc_pkt_len_segs_init(struct sk_buff *skb)
if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) {
const struct tcphdr *th;
- if (!pskb_may_pull(skb, hdr_len + sizeof(struct tcphdr)))
+ /* A header in front of skb->data gives a negative offset. */
+ if ((int)hdr_len < 0 ||
+ !pskb_may_pull(skb, hdr_len + sizeof(struct tcphdr)))
return SKB_DROP_REASON_SKB_BAD_GSO;
th = (const struct tcphdr *)(skb->data + hdr_len);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 343/507] vhost/vsock: size receive SKBs from declared payload
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (341 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 342/507] net: reject a negative TCP header offset in qdisc_pkt_len_segs_init() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 344/507] mptcp: do not use Fast Open on MP_JOIN subflows Greg Kroah-Hartman
` (163 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daehyeon Ko, Stefano Garzarella,
Michael S. Tsirkin, Paolo Abeni, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
[ Upstream commit d5e912448cd98b261eba8e35ab838f2dc69a79f5 ]
vhost_vsock_alloc_skb() sizes the skb from iov_length(), the total guest
descriptor length. virtio_transport_inc_rx_pkt() instead adds hdr->len to
rx_bytes and buf_used, and budgets each queued skb as SKB_TRUESIZE(0). The
guest controls the descriptor length and hdr->len independently.
A guest can therefore provide a 64 KiB descriptor while declaring a zero
payload. The descriptor-sized skb remains queued, rx_bytes and buf_used
remain unchanged, and only the fixed queue-entry budget limits retention.
This is not a lifetime leak: the skb is freed when dequeued or at socket
teardown. Repeating this across connections can nevertheless exhaust host
memory. On Linux v7.2, 455 such descriptors retained 30,255,680 bytes for
a 262,144-byte receive buffer; a full-payload control retained 265,984
bytes.
Vhost previously read hdr->len and allocated pkt->buf from that value. The
conversion from virtio_vsock_pkt to sk_buff instead allocated receive skbs
from the descriptor length, introducing the allocation-accounting mismatch.
Copy the header into a stack object and validate hdr->len before allocating
the skb. Size the allocation as sizeof(hdr) + payload_len so descriptor
capacity no longer determines queued memory. Check payload_len against
len - sizeof(hdr) to avoid addition overflow on 32-bit hosts.
Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")
Cc: stable@vger.kernel.org
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Link: https://patch.msgid.link/20261004235101.1464007-1-4ncienth@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vhost/vsock.c | 34 ++++++++++++++++------------------
1 file changed, 16 insertions(+), 18 deletions(-)
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index abed1fbcf66cc..35f75e23c7497 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -364,7 +364,7 @@ static struct sk_buff *
vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
unsigned int out, unsigned int in)
{
- struct virtio_vsock_hdr *hdr;
+ struct virtio_vsock_hdr hdr;
struct iov_iter iov_iter;
struct sk_buff *skb;
size_t payload_len;
@@ -382,34 +382,32 @@ vhost_vsock_alloc_skb(struct vhost_virtqueue *vq,
len > VIRTIO_VSOCK_MAX_PKT_BUF_SIZE + VIRTIO_VSOCK_SKB_HEADROOM)
return NULL;
- /* len contains both payload and hdr */
- skb = virtio_vsock_alloc_skb(len, GFP_KERNEL);
- if (!skb)
- return NULL;
-
iov_iter_init(&iov_iter, ITER_SOURCE, vq->iov, out, len);
- hdr = virtio_vsock_hdr(skb);
- nbytes = copy_from_iter(hdr, sizeof(*hdr), &iov_iter);
- if (nbytes != sizeof(*hdr)) {
+ nbytes = copy_from_iter(&hdr, sizeof(hdr), &iov_iter);
+ if (nbytes != sizeof(hdr)) {
vq_err(vq, "Expected %zu bytes for pkt->hdr, got %zu bytes\n",
- sizeof(*hdr), nbytes);
- kfree_skb(skb);
+ sizeof(hdr), nbytes);
return NULL;
}
- payload_len = le32_to_cpu(hdr->len);
+ payload_len = le32_to_cpu(hdr.len);
+
+ /* The pkt is too big or the length in the header is invalid */
+ if (payload_len > len - sizeof(hdr))
+ return NULL;
+
+ /* Allocate only for the payload declared in the header. */
+ skb = virtio_vsock_alloc_skb(payload_len + sizeof(hdr), GFP_KERNEL);
+ if (!skb)
+ return NULL;
+
+ memcpy(virtio_vsock_hdr(skb), &hdr, sizeof(hdr));
/* No payload */
if (!payload_len)
return skb;
- /* The pkt is too big or the length in the header is invalid */
- if (payload_len + sizeof(*hdr) > len) {
- kfree_skb(skb);
- return NULL;
- }
-
virtio_vsock_skb_put(skb, payload_len);
if (skb_copy_datagram_from_iter(skb, 0, &iov_iter, payload_len)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 344/507] mptcp: do not use Fast Open on MP_JOIN subflows
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (342 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 343/507] vhost/vsock: size receive SKBs from declared payload Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 345/507] ublk: add missing DEL_DEV_ASYNC to unprivileged permission check Greg Kroah-Hartman
` (162 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kimi Security Team, Jiayuan Chen,
Paolo Abeni, Yilin Zhang, Matthieu Baerts (NGI0), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yilin Zhang <yilinzhang@moonshot.ai>
[ Upstream commit 6d2cf411aba2aa0bd641b49be5b1964ac5097a50 ]
tcp_fastopen_create_child() hands the SYN packet itself to
subflow_syn_recv_sock(). For an MP_JOIN request this takes the
fatal fallback: the cloned child is destroyed and handed back with
drop_req flagged, but tcp_fastopen_create_child() does not check
the flag and queues it, so accept() can expose the freed child.
MP_JOIN cannot use Fast Open: data on a subflow requires the
completed HMAC exchange (RFC 8684, sec. 3.2). Refuse it (only the
TFO path passes a SYN skb here) and let tcp_conn_request() fall
back to the regular MP_JOIN handshake; also strip the Fast Open
cookie from MP_JOIN SYN/ACKs.
Fixes: 90bf45134d55 ("mptcp: add new sock flag to deal with join subflows")
Cc: stable@vger.kernel.org
Reported-by: Kimi Security Team <bug-report@moonshot.ai>
Suggested-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Yilin Zhang <yilinzhang@moonshot.ai>
[ Moving code to avoid clearing TS and consolidating checks. ]
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20261030-mptcp-tfo-mpj-v4-1-e6eff2027342@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mptcp/subflow.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index 2c72cb50fbf36..0b67b46ef872e 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -379,6 +379,10 @@ static void subflow_prep_synack(const struct sock *sk, struct request_sock *req,
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
struct inet_request_sock *ireq = inet_rsk(req);
+ /* MP_JOIN cannot use TFO, do not send a cookie in the SYN/ACK */
+ if (foc && mptcp_subflow_rsk(req)->mp_join)
+ foc->len = -1;
+
/* clear tstamp_ok, as needed depending on cookie */
if (foc && foc->len > -1)
ireq->tstamp_ok = 0;
@@ -887,6 +891,13 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
fallback = true;
} else if (subflow_req->mp_join) {
+ /* a SYN skb here comes from TFO, which MP_JOIN cannot use: just
+ * fall back to the regular path.
+ */
+ if ((TCP_SKB_CB(skb)->tcp_flags & (TCPHDR_SYN | TCPHDR_ACK)) ==
+ TCPHDR_SYN)
+ return NULL;
+
mptcp_get_options(skb, &mp_opt);
if (!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK))
fallback = true;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 345/507] ublk: add missing DEL_DEV_ASYNC to unprivileged permission check
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (343 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 344/507] mptcp: do not use Fast Open on MP_JOIN subflows Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 346/507] nvme-keyring: Add a missing key_put() call to nvme_tls_key_lookup() Greg Kroah-Hartman
` (161 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yitang Yang, Ming Lei, Jens Axboe,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yitang Yang <yi1tang.yang@gmail.com>
[ Upstream commit e6ac1da6a53c5f670bf09e60a2500d15be68d2fc ]
ublk_ctrl_uring_cmd_permission() is missing the UBLK_CMD_DEL_DEV_ASYNC
case, causing the command to always return -EINVAL for unprivileged
ublk devices. Fix it by adding the missing case.
Fixes: 13fe8e6825e4 ("ublk: add UBLK_CMD_DEL_DEV_ASYNC")
Cc: stable@vger.kernel.org
Signed-off-by: Yitang Yang <yi1tang.yang@gmail.com>
Reviewed-by: Ming Lei <tom.leiming@gmail.com>
Link: https://patch.msgid.link/20260901142438.237586-1-yi1tang.yang@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/block/ublk_drv.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 1ef01ce18f4f0..959e6594013a8 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -5833,6 +5833,7 @@ static int ublk_ctrl_uring_cmd_permission(struct ublk_device *ub,
case UBLK_CMD_STOP_DEV:
case UBLK_CMD_ADD_DEV:
case UBLK_CMD_DEL_DEV:
+ case UBLK_CMD_DEL_DEV_ASYNC:
case UBLK_CMD_SET_PARAMS:
case UBLK_CMD_START_USER_RECOVERY:
case UBLK_CMD_END_USER_RECOVERY:
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 346/507] nvme-keyring: Add a missing key_put() call to nvme_tls_key_lookup()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (344 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 345/507] ublk: add missing DEL_DEV_ASYNC to unprivileged permission check Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 347/507] drm/amdgpu: Check cs flags Greg Kroah-Hartman
` (160 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hannes Reinecke, Jarkko Sakkinen,
Keith Busch, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jarkko Sakkinen <jarkko@kernel.org>
[ Upstream commit 404a8f6caa63822c1d2a45adbf07fd9c0567a7ef ]
Call key_put() before returning -EKEYREVOKED, as the reference count gets
incremented by key_lookup().
Cc: stable@vger.kernel.org # v6.12+
Fixes: 5bc46b49c828 ("nvme-tcp: check for invalidated or revoked key")
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/common/keyring.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/nvme/common/keyring.c b/drivers/nvme/common/keyring.c
index 32d16c53133be..87cb51e1f5a7f 100644
--- a/drivers/nvme/common/keyring.c
+++ b/drivers/nvme/common/keyring.c
@@ -35,6 +35,7 @@ struct key *nvme_tls_key_lookup(key_serial_t key_id)
}
if (nvme_tls_psk_revoked(key)) {
pr_err("key id %08x revoked\n", key_id);
+ key_put(key);
return ERR_PTR(-EKEYREVOKED);
}
return key;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 347/507] drm/amdgpu: Check cs flags.
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (345 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 346/507] nvme-keyring: Add a missing key_put() call to nvme_tls_key_lookup() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 348/507] drm/amdgpu: skip RAS error count reset in debug mode Greg Kroah-Hartman
` (159 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bas Nieuwenhuizen, Faith Ekstrand,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
[ Upstream commit f5ea64f9fcd921bc4e2307a262e19450b8a58524 ]
Had no validation before. libdrm_amdgpu memsets this, even
for the raw/raw2 functions.
We have a lot of functions touching the ioctl struct, no
strong opinion on where this is placed, but I thought
early would be good.
Signed-off-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 4d01e15e76358f60ef6734462d2b6d9972b9dfbc)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 86a3dc3655b3c..40c71332d9746 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -188,6 +188,9 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
int ret;
int i;
+ if (cs->in.flags)
+ return -EINVAL;
+
chunk_array = memdup_array_user(u64_to_user_ptr(cs->in.chunks),
cs->in.num_chunks,
sizeof(uint64_t));
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 348/507] drm/amdgpu: skip RAS error count reset in debug mode
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (346 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 347/507] drm/amdgpu: Check cs flags Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 349/507] drm/amdgpu: sign extend the addresses GEM_OP(GET_MAPPING_INFO) returns Greg Kroah-Hartman
` (158 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ce Sun, Hawking Zhang, Alex Deucher,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ce Sun <cesun102@amd.com>
[ Upstream commit 9b115ca0e5ceba08da9b9ca09e6ba65d1a2544c0 ]
After legacy ACA support was retired, some ASICs systems may trigger
security violations during driver load when
amdgpu_ras_reset_error_count() is invoked in debug mode.
The function only checks whether RAS is supported for the target
block before proceeding. In debug mode, ACA/RAS handling is not
available and attempting to access the reset path can lead to
unexpected HW accesses, resulting in security violation reports
during driver initialization.
Prevent this by treating debug mode as unsupported for RAS error
count reset and return -EOPNOTSUPP early.
Fixes: af1ae7d0beaf ("drm/amdgpu: retire legacy ACA support")
Signed-off-by: Ce Sun <cesun102@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit af6b6f1a14dca860468b0fe2a55b7194702d5fa0)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 35eb87591740a..37cf1b8089502 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -1485,7 +1485,8 @@ int amdgpu_ras_reset_error_count(struct amdgpu_device *adev,
return -EOPNOTSUPP;
}
- if (!amdgpu_ras_is_supported(adev, block))
+ if (!amdgpu_ras_is_supported(adev, block) ||
+ !amdgpu_ras_mgr_get_debug_mode(adev))
return -EOPNOTSUPP;
if (amdgpu_sriov_vf(adev))
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 349/507] drm/amdgpu: sign extend the addresses GEM_OP(GET_MAPPING_INFO) returns
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (347 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 348/507] drm/amdgpu: skip RAS error count reset in debug mode Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 350/507] drm/amdgpu: parse CS IBs at the BO offset their VA mapping starts at Greg Kroah-Hartman
` (157 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Jesse Zhang,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <Jesse.Zhang@amd.com>
[ Upstream commit 37cfaaa6b5e9448ef786342d470d0e0b8eb89fa6 ]
GEM_VA takes the GPU virtual addresses above the VA hole sign extended,
like the rest of the UAPI, but GET_MAPPING_INFO reports them without the
upper bits, so they land in the hole. Mappings in the upper half of the
address space can't be recreated or removed with what it returns. On
navi31:
MAP at 0xffff800100000000 -> 0
GET_MAPPING_INFO -> addr 0x800100000000
UNMAP at 0x800100000000 -> -EINVAL
Sign extend the addresses before handing them out.
Fixes: 4d82724f7f2b ("drm/amdgpu: Add mapping info option for GEM_OP ioctl")
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 9d5524a339390da9145b19bfb40da45640332fb3)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
index afd8502a2bc49..cd05921aede54 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
@@ -1033,6 +1033,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data,
int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{
+ struct amdgpu_device *adev = drm_to_adev(dev);
struct drm_amdgpu_gem_op *args = data;
struct drm_gem_object *gobj;
struct amdgpu_vm_bo_base *base;
@@ -1139,7 +1140,8 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
amdgpu_vm_bo_va_for_each_valid_mapping(bo_va, mapping) {
if (num_mappings < args->num_entries) {
- vm_entries[num_mappings].addr = mapping->start * AMDGPU_GPU_PAGE_SIZE;
+ vm_entries[num_mappings].addr =
+ amdgpu_gmc_sign_extend(mapping->start * AMDGPU_GPU_PAGE_SIZE);
vm_entries[num_mappings].size = (mapping->last - mapping->start + 1) * AMDGPU_GPU_PAGE_SIZE;
vm_entries[num_mappings].offset = mapping->offset;
vm_entries[num_mappings].flags = mapping->flags;
@@ -1149,7 +1151,8 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
amdgpu_vm_bo_va_for_each_invalid_mapping(bo_va, mapping) {
if (num_mappings < args->num_entries) {
- vm_entries[num_mappings].addr = mapping->start * AMDGPU_GPU_PAGE_SIZE;
+ vm_entries[num_mappings].addr =
+ amdgpu_gmc_sign_extend(mapping->start * AMDGPU_GPU_PAGE_SIZE);
vm_entries[num_mappings].size = (mapping->last - mapping->start + 1) * AMDGPU_GPU_PAGE_SIZE;
vm_entries[num_mappings].offset = mapping->offset;
vm_entries[num_mappings].flags = mapping->flags;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 350/507] drm/amdgpu: parse CS IBs at the BO offset their VA mapping starts at
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (348 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 349/507] drm/amdgpu: sign extend the addresses GEM_OP(GET_MAPPING_INFO) returns Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 351/507] drm/amdgpu: keep the CS user fence BO in GTT Greg Kroah-Hartman
` (156 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Alex Deucher, Jesse Zhang,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <Jesse.Zhang@amd.com>
[ Upstream commit 63a59637517682a920f86da1a189a3e639dd4fb3 ]
For rings which parse or patch the IBs on the CPU, like JPEG and VCN,
the CS looks the IB up through its VA mapping and maps the BO, but
ignores the offset in the BO the mapping starts at. It then parses
other data than the GPU executes. On navi31, an IB of JPEG NOPs in the
second page of a BO, mapped with offset_in_bo 4096, is parsed from the
zeros in the first page and rejected:
amdgpu 0000:03:00.0: Invalid packet [0x00000000]!
while the same IB submitted through a mapping of the whole BO works.
Add the mapping offset when locating the IB in the BO.
Fixes: 4802ce117786 ("drm/amdgpu: fix UVD/VCE VM emulation")
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 74ba1d87d67d0a38d8248928241c3e1c73d0d53b)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 40c71332d9746..bb039ed938939 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1074,7 +1074,7 @@ static int amdgpu_cs_patch_ibs(struct amdgpu_cs_parser *p,
if (r)
return r;
- kptr += va_start - (m->start * AMDGPU_GPU_PAGE_SIZE);
+ kptr += va_start - (m->start * AMDGPU_GPU_PAGE_SIZE) + m->offset;
if (ring->funcs->parse_cs) {
memcpy(ib->ptr, kptr, ib->length_dw * 4);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 351/507] drm/amdgpu: keep the CS user fence BO in GTT
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (349 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 350/507] drm/amdgpu: parse CS IBs at the BO offset their VA mapping starts at Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 352/507] drm/amdkfd: use the queues process info for the WPTR BO eviction fence Greg Kroah-Hartman
` (155 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Jesse Zhang,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <Jesse.Zhang@amd.com>
[ Upstream commit 7a56d929dc2304edaa6231e1eb5eb82b7e8b74a9 ]
The CS ioctl hands the GPU the GART address of the user fence BO, but
since the BO keeps its own preferred and allowed domains, it no longer
makes sure the BO is in GTT. A user fence in a VRAM BO, which only needs
to be a page in size, gets its address from amdgpu_bo_gpu_offset(), which
warns about non-contiguous VRAM. On navi31, a CS with a user fence in a
4K VRAM BO, or in one created with AMDGPU_GEM_CREATE_VM_ALWAYS_VALID:
WARNING: amdgpu_object.c:1531 at amdgpu_bo_gpu_offset+0x86/0xb0 [amdgpu], CPU#11: cs_gem_checks/18393
RIP: 0010:amdgpu_bo_gpu_offset+0x86/0xb0 [amdgpu]
Call Trace:
<TASK>
amdgpu_cs_parser_bos.isra.0+0x4eb/0x850 [amdgpu]
amdgpu_cs_ioctl+0x97e/0x2510 [amdgpu]
drm_ioctl_kernel+0xac/0x110 [drm]
drm_ioctl+0x2c6/0x5b0 [drm]
__x64_sys_ioctl+0xa0/0xf0
do_syscall_64+0xa3/0x4d0
entry_SYSCALL_64_after_hwframe+0x76/0x7e
and BOs which can't be in GTT at all, like GWS or OA ones of a page in
size, pass the checks as well.
Only take BOs which can't be anywhere else than in GTT as user fence,
which the CS then validates there along with its other BOs. While at it,
detect userptrs with amdgpu_ttm_tt_is_userptr(); amdgpu_ttm_tt_get_usermm()
returns NULL once the task which created the userptr is gone.
v2: only take BOs which can only be in GTT instead of special casing the
user fence BO in the validation, use amdgpu_ttm_tt_is_userptr()
(Christian)
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit f16989def9561d04d0f2e77216f5319112d29bf1)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index bb039ed938939..ba9c7dc084384 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -149,7 +149,12 @@ static int amdgpu_cs_p1_user_fence(struct amdgpu_cs_parser *p,
if (size != PAGE_SIZE || data->offset > (size - 8))
return -EINVAL;
- if (amdgpu_ttm_tt_get_usermm(p->uf_bo->tbo.ttm))
+ if (amdgpu_ttm_tt_is_userptr(p->uf_bo->tbo.ttm))
+ return -EINVAL;
+
+ /* The GPU writes the user fence through the GART */
+ if (p->uf_bo->preferred_domains != AMDGPU_GEM_DOMAIN_GTT &&
+ p->uf_bo->allowed_domains != AMDGPU_GEM_DOMAIN_GTT)
return -EINVAL;
*offset = data->offset;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 352/507] drm/amdkfd: use the queues process info for the WPTR BO eviction fence
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (350 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 351/507] drm/amdgpu: keep the CS user fence BO in GTT Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 353/507] drm/amdgpu/userq: wait for GPU reset before mapping or unmapping queues Greg Kroah-Hartman
` (154 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Felix Kuehling, Jesse Zhang,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <Jesse.Zhang@amd.com>
[ Upstream commit da2897ee8b811945fd40ecc4aaf03291c14ce61c ]
amdgpu_amdkfd_map_gtt_bo_to_gart() removes the eviction fence of
bo->vm_bo->vm->process_info from the WPTR BO of a new queue. bo->vm_bo
is the VM which opened the BO last, not necessarily the KFD process' VM,
and a render node VM has no process info.
On navi31, an unprivileged process which exports its WPTR BO with
AMDKFD_IOC_EXPORT_DMABUF and imports it on a second render node fd
oopses in AMDKFD_IOC_CREATE_QUEUE:
BUG: kernel NULL pointer dereference, address: 0000000000000060
RIP: 0010:amdgpu_amdkfd_map_gtt_bo_to_gart+0x86/0x1a0 [amdgpu]
init_user_queue.part.0+0x180/0x250 [amdgpu]
pqm_create_queue+0x32d/0x730 [amdgpu]
kfd_ioctl_create_queue+0x583/0x9f0 [amdgpu]
Pass the process info of the queue instead. With the fix, the queue is
created and destroyed normally.
Fixes: 7f347e3f8217 ("drm/amdkfd: Fix NULL pointer error for GC 11.0.1 on mGPU")
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 6b4157498a176bd1c6083f6bb5aaf8a257a2027e)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h | 3 ++-
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 8 +++++---
drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c | 3 ++-
3 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
index f462b40220eb2..8e0b3db5c15eb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -345,7 +345,8 @@ int amdgpu_amdkfd_gpuvm_map_bo_to_kernel(struct kgd_mem *mem, void **kptr,
u64 *size, u32 domain);
void amdgpu_amdkfd_gpuvm_unmap_bo_from_kernel(struct kgd_mem *mem);
-int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_bo *bo, struct amdgpu_bo **bo_gart);
+int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_bo *bo, struct amdgpu_bo **bo_gart,
+ struct amdkfd_process_info *process_info);
int amdgpu_amdkfd_gpuvm_restore_process_bos(void *process_info,
struct dma_fence __rcu **ef);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index c5c2a73ddd94b..b59329c42597e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -2261,11 +2261,13 @@ int amdgpu_amdkfd_gpuvm_sync_memory(
* amdgpu_amdkfd_map_gtt_bo_to_gart - Map BO to GART and increment reference count
* @bo: Buffer object to be mapped
* @bo_gart: Return bo reference
+ * @process_info: KFD process info of the queue the BO is for
*
* Before return, bo reference count is incremented. To release the reference and unpin/
* unmap the BO, call amdgpu_amdkfd_free_kernel_mem.
*/
-int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_bo *bo, struct amdgpu_bo **bo_gart)
+int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_bo *bo, struct amdgpu_bo **bo_gart,
+ struct amdkfd_process_info *process_info)
{
int ret;
@@ -2287,8 +2289,8 @@ int amdgpu_amdkfd_map_gtt_bo_to_gart(struct amdgpu_bo *bo, struct amdgpu_bo **bo
goto err_map_bo_gart_failed;
}
- amdgpu_amdkfd_remove_eviction_fence(
- bo, bo->vm_bo->vm->process_info->eviction_fence);
+ /* bo->vm_bo can be the VM of any file which opened the BO */
+ amdgpu_amdkfd_remove_eviction_fence(bo, process_info->eviction_fence);
amdgpu_bo_unreserve(bo);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index 87fb42d3c7139..64673007ccdef 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -303,7 +303,8 @@ static int init_user_queue(struct process_queue_manager *pqm,
}
retval = amdgpu_amdkfd_map_gtt_bo_to_gart(q_properties->wptr_bo,
- &(*q)->wptr_bo_gart);
+ &(*q)->wptr_bo_gart,
+ pqm->process->kgd_process_info);
if (retval) {
pr_err("Failed to map wptr bo to GART\n");
goto free_gang_ctx_bo;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 353/507] drm/amdgpu/userq: wait for GPU reset before mapping or unmapping queues
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (351 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 352/507] drm/amdkfd: use the queues process info for the WPTR BO eviction fence Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 354/507] drm/amdgpu: check amdgpu_vm_ready() in dma-buf move notify Greg Kroah-Hartman
` (153 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Prike Liang, Vitaly Prosyak,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prike Liang <Prike.Liang@amd.com>
[ Upstream commit 623507b8f4fe24851b2f1cb2c177f8ae3c8584b8 ]
The user queue map and unmap helpers talk to the MES, but only the
create path holds reset_domain->sem around them. The eviction, restore,
destroy and suspend paths can submit to the MES while a GPU reset is in
progress:
WARNING: amdgpu_device.c:928 at amdgpu_device_skip_hw_access+0x73/0x90 [amdgpu]
Workqueue: events amdgpu_eviction_fence_suspend_worker [amdgpu]
Call Trace:
amdgpu_mm_wdoorbell64+0x20/0x70 [amdgpu]
mes_v11_0_ring_set_wptr+0x71/0x80 [amdgpu]
amdgpu_ring_commit+0x5b/0xa0 [amdgpu]
mes_v11_0_submit_pkt_and_poll_completion.constprop.0+0x207/0x520 [amdgpu]
mes_v11_0_remove_hw_queue+0xd9/0x100 [amdgpu]
mes_userq_unmap+0xc3/0x140 [amdgpu]
amdgpu_userq_unmap_helper+0x67/0x280 [amdgpu]
amdgpu_userq_evict+0x52/0xf0 [amdgpu]
amdgpu_eviction_fence_suspend_worker+0x55/0xe0 [amdgpu]
Take the semaphore for read in the helpers instead, around both the MES
call and the queue state check and update. The reset changes the queue
state from amdgpu_userq_pre_reset()/post_reset(), so every caller now
waits for a running reset and acts on the state it left behind.
Signed-off-by: Prike Liang <Prike.Liang@amd.com>
Reviewed-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit e6a8b8588f43bd4d7054ac47cccc35f56ad2df90)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index b3dc5dd49a647..dcccf6a9682c1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -365,6 +365,8 @@ static int amdgpu_userq_unmap_helper(struct amdgpu_usermode_queue *queue)
adev->userq_funcs[queue->queue_type];
int r;
+ /* The reset changes the queue state and the MES is unusable meanwhile */
+ guard(rwsem_read)(&adev->reset_domain->sem);
if ((queue->state == AMDGPU_USERQ_STATE_MAPPED) ||
(queue->state == AMDGPU_USERQ_STATE_PREEMPTED)) {
trace_amdgpu_userq_state_start(queue);
@@ -391,6 +393,8 @@ static int amdgpu_userq_map_helper(struct amdgpu_usermode_queue *queue)
adev->userq_funcs[queue->queue_type];
int r;
+ /* The reset changes the queue state and the MES is unusable meanwhile */
+ guard(rwsem_read)(&adev->reset_domain->sem);
if (queue->state == AMDGPU_USERQ_STATE_UNMAPPED) {
trace_amdgpu_userq_state_start(queue);
@@ -751,12 +755,7 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
if (!adev->userq_halt_for_enforce_isolation ||
((queue->queue_type != AMDGPU_HW_IP_GFX) &&
(queue->queue_type != AMDGPU_HW_IP_COMPUTE))) {
- /* Serialize the map against an in-progress GPU reset (MES is
- * unresponsive during recovery), matching amdgpu_userq_detach_doorbell().
- */
- down_read(&adev->reset_domain->sem);
r = amdgpu_userq_map_helper(queue);
- up_read(&adev->reset_domain->sem);
if (r) {
drm_file_err(uq_mgr->file, "Failed to map Queue\n");
trace_amdgpu_userq_create_end(queue, r);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 354/507] drm/amdgpu: check amdgpu_vm_ready() in dma-buf move notify
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (352 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 353/507] drm/amdgpu/userq: wait for GPU reset before mapping or unmapping queues Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 355/507] drm/amdgpu/userq: validate the moved individual BOs on restore Greg Kroah-Hartman
` (152 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Deucher, Dariusz Marcinkiewicz,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dariusz Marcinkiewicz <darekm@google.com>
[ Upstream commit 920ca822f527e45ce084b36f3c420b625eb7c62a ]
amdgpu_dma_buf_move_notify() touches the page tables without first
calling amdgpu_vm_ready(). When a process is SIGKILLed, its VM entities
are stopped. Teardown of an imported dma-buf then tries to clear PTEs by
submitting to one of those stopped entities. That eventually hangs the
task.
Commit aa5fc4362fac ("drm/amdgpu: fix task hang from failed job
submission during process kill") added the stopped entity check in
amdgpu_vm_ready() and used it in amdgpu_cs_vm_handling(). That did not
cover a call in amdgpu_dma_buf_move_notify(), what was already mentioned
in:
https://lists.freedesktop.org/archives/amd-gfx/2025-October/133076.html
Tested by SIGKILLing a GPU workload holding imported dma-bufs. Without
the patch "Trying to push to a killed entity" errors are logged, then a
task hangs. With the patch there are no hung tasks. This was tested on a
6.18 kernel.
Fixes: aa5fc4362fac ("drm/amdgpu: fix task hang from failed job submission during process kill")
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dariusz Marcinkiewicz <darekm@google.com>
Assisted-by: LLM
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit bee5c9d7a34cb1b510ad3b4c18c30f9d38b0ab7d)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 9adf3eed8822c..ccadbcf38d3fb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -547,6 +547,11 @@ amdgpu_dma_buf_move_notify(struct dma_buf_attachment *attach)
continue;
}
+ if (!amdgpu_vm_ready(vm)) {
+ dma_resv_unlock(resv);
+ continue;
+ }
+
/* Reserve fences for two SDMA page table updates */
r = dma_resv_reserve_fences(resv, 2);
if (!r)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 355/507] drm/amdgpu/userq: validate the moved individual BOs on restore
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (353 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 354/507] drm/amdgpu: check amdgpu_vm_ready() in dma-buf move notify Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 356/507] drm/amd/display: add missing CRC engine 1 registers Greg Kroah-Hartman
` (151 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Jesse Zhang,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <Jesse.Zhang@amd.com>
[ Upstream commit ce5f2a25bdf6b2bccfc4ffb5e4c5f12e97eeace1 ]
An individual BO of a user queue VM, i.e. one which doesn't share the
root reservation, goes to the individual needs_update list when it is
evicted. The user queue restore looked at vm->invalidated for them, which
the VM state machine rework turned into the always_valid evicted list and
commit 18decfc9e8cc ("drm/amdgpu/userq: actually validate userq BOs")
into the individual evicted one. That list only holds imported DMA-bufs of
compute VMs though, so for a user queue VM nothing is validated.
The restore then neither locks such a BO nor moves it back. Its PTEs are
updated to wherever it is now, cleared if it went to system memory, and
it doesn't get the new eviction fence, so it can move again under the
running queue.
On navi48, once the BOs of an SDMA user queue are evicted from GTT
(debugfs amdgpu_evict_gtt) the queue faults on its ring and rptr:
amdgpu 0000:03:00.0: in page starting at address 0x0000000100000000 from client 10
amdgpu 0000:03:00.0: Faulty UTCL2 client ID: SDMA0 (0xd)
amdgpu 0000:03:00.0: in page starting at address 0x0000000100101000 from client 10
Validate the BOs on the individual needs_update list like before.
Fixes: 4cdbba5a16aa ("drm/amdgpu: restructure VM state machine v4")
Fixes: 18decfc9e8cc ("drm/amdgpu/userq: actually validate userq BOs")
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit eb0d94765d4be18d41e93ad09947dd9cc06ed31a)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index dcccf6a9682c1..053ead0d690f1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -972,7 +972,11 @@ static int amdgpu_userq_validate_vm(void *param, struct amdgpu_bo *bo)
return ttm_bo_validate(&bo->tbo, &bo->placement, &ctx);
}
-/* Handle all BOs on the invalidated list, validate them and update the PTs */
+/*
+ * Handle all individual BOs which were moved, lock and validate them and
+ * update the PTs. An evicted individual BO lands on the needs_update list,
+ * the evicted one only holds imported DMA-bufs of compute VMs.
+ */
static int
amdgpu_userq_bo_validate(struct amdgpu_device *adev, struct drm_exec *exec,
struct amdgpu_vm *vm)
@@ -983,8 +987,8 @@ amdgpu_userq_bo_validate(struct amdgpu_device *adev, struct drm_exec *exec,
int ret;
spin_lock(&vm->individual_lock);
- while (!list_empty(&vm->individual.evicted)) {
- bo_va = list_first_entry(&vm->individual.evicted,
+ while (!list_empty(&vm->individual.needs_update)) {
+ bo_va = list_first_entry(&vm->individual.needs_update,
struct amdgpu_bo_va,
base.vm_status);
bo = bo_va->base.bo;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 356/507] drm/amd/display: add missing CRC engine 1 registers
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (354 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 7.3 355/507] drm/amdgpu/userq: validate the moved individual BOs on restore Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 357/507] drm/amdgpu: finish GPU recovery callbacks before restarting schedulers Greg Kroah-Hartman
` (150 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mikhail Gavrilov, Wayne Lin,
Tom Chung, Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wayne Lin <Wayne.Lin@amd.com>
[ Upstream commit f18c112edb600398b3dbd28a455e17cf945d6d91 ]
[why]
Opening the CRTC CRC debugfs file programs every CRC engine. On
several generations the engine 1 window and data entries were missing,
so configure hits a zero field mask and WARNs. DCN4.2, DCN4.2B, and
DCN6.0 already had those entries, but configure still writes
OTG_CRC1_SELECT with no mask check. DCN6.0 also lacks OTG_CRC1_EN, so
optc1_configure_crc() writes OTG_CRC_EN instead. The ASIC headers
already define the addresses and fields. The driver tables did not
list them.
[how]
How the missing entries are filled in:
1. DCN3.0 through DCN3.0.3 use OPTC_COMMON_*_DCN3_BASE. Add the six
engine 1 addresses and the window, data, and OTG_CRC1_SELECT masks.
These headers have no OTG_CRC1_EN bit, so that field is not added.
2. DCN3.1 uses OPTC_COMMON_*_DCN3_1. Add the same addresses and masks,
including OTG_CRC1_EN. dcn_3_1_2 defines that bit. DCN3.1.5
and DCN3.1.6 expand DCN3_1 through DCN31X. DCN3.1.4 has its own
list. OTG_CRC1_EN was already on it, so only addresses, SELECT,
window, and data are added.
3. DCN3.2 and DCN3.2.1 already had OTG_CRC1_EN and OTG_CRC1_SELECT.
Add the window and data masks in the OPTC header and the addresses
in the resource header. DCN3.2 fills addresses at init from
ctx->dcn_reg_offsets[].
4. DCN4.0.1 also uses optc1_configure_crc() and was missing SELECT,
window, and data. Add those masks and the six addresses.
OTG_CRC1_EN was already present.
5. DCN3.5, DCN3.5.1, and DCN3.6 already have the addresses and program
engine 1 through optc35_configure_crc(). Their mask list included
DCN3.2 and then repeated the CRC1 window and data fields. Drop the
duplicates.
6. DCN2.0, DCN2.0.1, and DCN2.1 are left unchanged. They inherit the
DCN1.0 lists, which already name engine 1 window, data, and
OTG_CRC1_SELECT. Their headers have no OTG_CRC1_EN bit.
7. DCN4.2 and DCN4.2B use optc35_configure_crc(). Window, data, and
OTG_CRC1_EN were already present. Add OTG_CRC1_SELECT. DCN6.0 uses
optc1_configure_crc(). Window and data were already present. Add
OTG_CRC1_SELECT and OTG_CRC1_EN.
Fixes: ef45aaf73717 ("drm/amd/display: Configure all CRC engines in pipe CRC source path")
Reported-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Closes: https://lore.kernel.org/all/20260829085941.106318-1-mikhail.v.gavrilov@gmail.com/
Signed-off-by: Wayne Lin <Wayne.Lin@amd.com>
Assisted-by: Cursor:Grok 4.7
Tested-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com> # Navi 31 (DCN3.2)
Reviewed-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Reviewed-by: Tom Chung <chiahsuan.chung@amd.com>
Cc: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit f42edf63ba4456fa7a02e81a3aa7f2d410a28921)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../amd/display/dc/optc/dcn30/dcn30_optc.h | 18 +++++++++++++++
.../amd/display/dc/optc/dcn31/dcn31_optc.h | 22 +++++++++++++++++--
.../amd/display/dc/optc/dcn314/dcn314_optc.h | 18 +++++++++++++++
.../amd/display/dc/optc/dcn32/dcn32_optc.h | 11 ++++++++++
.../amd/display/dc/optc/dcn35/dcn35_optc.h | 11 ----------
.../amd/display/dc/optc/dcn401/dcn401_optc.h | 12 ++++++++++
.../amd/display/dc/optc/dcn42/dcn42_optc.h | 2 ++
.../amd/display/dc/optc/dcn60/dcn60_optc.h | 2 ++
.../dc/resource/dcn32/dcn32_resource.h | 6 +++++
.../dc/resource/dcn401/dcn401_resource.h | 6 +++++
10 files changed, 95 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn30/dcn30_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn30/dcn30_optc.h
index 16c5610b49acc..b801989f10cfc 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn30/dcn30_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn30/dcn30_optc.h
@@ -91,6 +91,12 @@
SRI(OTG_CRC0_WINDOWA_Y_CONTROL, OTG, inst),\
SRI(OTG_CRC0_WINDOWB_X_CONTROL, OTG, inst),\
SRI(OTG_CRC0_WINDOWB_Y_CONTROL, OTG, inst),\
+ SRI(OTG_CRC1_DATA_RG, OTG, inst),\
+ SRI(OTG_CRC1_DATA_B, OTG, inst),\
+ SRI(OTG_CRC1_WINDOWA_X_CONTROL, OTG, inst),\
+ SRI(OTG_CRC1_WINDOWA_Y_CONTROL, OTG, inst),\
+ SRI(OTG_CRC1_WINDOWB_X_CONTROL, OTG, inst),\
+ SRI(OTG_CRC1_WINDOWB_Y_CONTROL, OTG, inst),\
SR(GSL_SOURCE_SELECT),\
SRI(OTG_TRIGA_MANUAL_TRIG, OTG, inst),\
SRI(OTG_DRR_CONTROL, OTG, inst)
@@ -229,6 +235,7 @@
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_CHECK_ALL_FIELDS, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_CONT_EN, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC0_SELECT, mask_sh),\
+ SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_SELECT, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_EN, mask_sh),\
SF(OTG0_OTG_CRC_CNTL2, OTG_CRC_DSC_MODE, mask_sh),\
SF(OTG0_OTG_CRC_CNTL2, OTG_CRC_DATA_STREAM_COMBINE_MODE, mask_sh),\
@@ -245,6 +252,17 @@
SF(OTG0_OTG_CRC0_WINDOWB_X_CONTROL, OTG_CRC0_WINDOWB_X_END, mask_sh),\
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_START, mask_sh),\
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_RG, CRC1_R_CR, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_RG, CRC1_G_Y, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_B, CRC1_B_CB, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_X_CONTROL, OTG_CRC1_WINDOWA_X_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_X_CONTROL, OTG_CRC1_WINDOWA_X_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_Y_CONTROL, OTG_CRC1_WINDOWA_Y_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_Y_CONTROL, OTG_CRC1_WINDOWA_Y_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_X_CONTROL, OTG_CRC1_WINDOWB_X_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_X_CONTROL, OTG_CRC1_WINDOWB_X_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL, OTG_CRC1_WINDOWB_Y_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL, OTG_CRC1_WINDOWB_Y_END, mask_sh),\
SF(OTG0_OTG_TRIGA_MANUAL_TRIG, OTG_TRIGA_MANUAL_TRIG, mask_sh),\
SF(GSL_SOURCE_SELECT, GSL0_READY_SOURCE_SEL, mask_sh),\
SF(GSL_SOURCE_SELECT, GSL1_READY_SOURCE_SEL, mask_sh),\
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h
index 119a954fe3e52..85223414c9092 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn31/dcn31_optc.h
@@ -83,6 +83,12 @@
SRI(OTG_CRC0_WINDOWA_Y_CONTROL, OTG, inst),\
SRI(OTG_CRC0_WINDOWB_X_CONTROL, OTG, inst),\
SRI(OTG_CRC0_WINDOWB_Y_CONTROL, OTG, inst),\
+ SRI(OTG_CRC1_DATA_RG, OTG, inst),\
+ SRI(OTG_CRC1_DATA_B, OTG, inst),\
+ SRI(OTG_CRC1_WINDOWA_X_CONTROL, OTG, inst),\
+ SRI(OTG_CRC1_WINDOWA_Y_CONTROL, OTG, inst),\
+ SRI(OTG_CRC1_WINDOWB_X_CONTROL, OTG, inst),\
+ SRI(OTG_CRC1_WINDOWB_Y_CONTROL, OTG, inst),\
SR(GSL_SOURCE_SELECT),\
SRI(OTG_TRIGA_MANUAL_TRIG, OTG, inst),\
SRI(OTG_GLOBAL_CONTROL1, OTG, inst),\
@@ -205,7 +211,9 @@
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_CHECK_ALL_FIELDS, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_CONT_EN, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC0_SELECT, mask_sh),\
+ SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_SELECT, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_EN, mask_sh),\
+ SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_EN, mask_sh),\
SF(OTG0_OTG_CRC0_DATA_RG, CRC0_R_CR, mask_sh),\
SF(OTG0_OTG_CRC0_DATA_RG, CRC0_G_Y, mask_sh),\
SF(OTG0_OTG_CRC0_DATA_B, CRC0_B_CB, mask_sh),\
@@ -217,6 +225,17 @@
SF(OTG0_OTG_CRC0_WINDOWB_X_CONTROL, OTG_CRC0_WINDOWB_X_END, mask_sh),\
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_START, mask_sh),\
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_RG, CRC1_R_CR, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_RG, CRC1_G_Y, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_B, CRC1_B_CB, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_X_CONTROL, OTG_CRC1_WINDOWA_X_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_X_CONTROL, OTG_CRC1_WINDOWA_X_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_Y_CONTROL, OTG_CRC1_WINDOWA_Y_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_Y_CONTROL, OTG_CRC1_WINDOWA_Y_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_X_CONTROL, OTG_CRC1_WINDOWB_X_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_X_CONTROL, OTG_CRC1_WINDOWB_X_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL, OTG_CRC1_WINDOWB_Y_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL, OTG_CRC1_WINDOWB_Y_END, mask_sh),\
SF(OTG0_OTG_TRIGA_MANUAL_TRIG, OTG_TRIGA_MANUAL_TRIG, mask_sh),\
SF(GSL_SOURCE_SELECT, GSL0_READY_SOURCE_SEL, mask_sh),\
SF(GSL_SOURCE_SELECT, GSL1_READY_SOURCE_SEL, mask_sh),\
@@ -264,8 +283,7 @@
SF(OTG0_INTERRUPT_DEST, OTG0_IHC_OTG_VERTICAL_INTERRUPT2_DEST, mask_sh)
#define OPTC_COMMON_MASK_SH_LIST_DCN31X(mask_sh)\
- OPTC_COMMON_MASK_SH_LIST_DCN3_1(mask_sh),\
- SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_EN, mask_sh)
+ OPTC_COMMON_MASK_SH_LIST_DCN3_1(mask_sh)
void dcn31_timing_generator_init(struct optc *optc1);
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.h
index 7b43c3ecd46b6..956eecf0a43a9 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn314/dcn314_optc.h
@@ -84,6 +84,12 @@
SRI(OTG_CRC0_WINDOWA_Y_CONTROL, OTG, inst),\
SRI(OTG_CRC0_WINDOWB_X_CONTROL, OTG, inst),\
SRI(OTG_CRC0_WINDOWB_Y_CONTROL, OTG, inst),\
+ SRI(OTG_CRC1_DATA_RG, OTG, inst),\
+ SRI(OTG_CRC1_DATA_B, OTG, inst),\
+ SRI(OTG_CRC1_WINDOWA_X_CONTROL, OTG, inst),\
+ SRI(OTG_CRC1_WINDOWA_Y_CONTROL, OTG, inst),\
+ SRI(OTG_CRC1_WINDOWB_X_CONTROL, OTG, inst),\
+ SRI(OTG_CRC1_WINDOWB_Y_CONTROL, OTG, inst),\
SR(GSL_SOURCE_SELECT),\
SRI(OTG_TRIGA_MANUAL_TRIG, OTG, inst),\
SRI(OTG_GLOBAL_CONTROL1, OTG, inst),\
@@ -204,6 +210,7 @@
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_CHECK_ALL_FIELDS, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_CONT_EN, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC0_SELECT, mask_sh),\
+ SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_SELECT, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_EN, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_EN, mask_sh),\
SF(OTG0_OTG_CRC0_DATA_RG, CRC0_R_CR, mask_sh),\
@@ -217,6 +224,17 @@
SF(OTG0_OTG_CRC0_WINDOWB_X_CONTROL, OTG_CRC0_WINDOWB_X_END, mask_sh),\
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_START, mask_sh),\
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_RG, CRC1_R_CR, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_RG, CRC1_G_Y, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_B, CRC1_B_CB, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_X_CONTROL, OTG_CRC1_WINDOWA_X_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_X_CONTROL, OTG_CRC1_WINDOWA_X_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_Y_CONTROL, OTG_CRC1_WINDOWA_Y_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_Y_CONTROL, OTG_CRC1_WINDOWA_Y_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_X_CONTROL, OTG_CRC1_WINDOWB_X_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_X_CONTROL, OTG_CRC1_WINDOWB_X_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL, OTG_CRC1_WINDOWB_Y_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL, OTG_CRC1_WINDOWB_Y_END, mask_sh),\
SF(OTG0_OTG_TRIGA_MANUAL_TRIG, OTG_TRIGA_MANUAL_TRIG, mask_sh),\
SF(GSL_SOURCE_SELECT, GSL0_READY_SOURCE_SEL, mask_sh),\
SF(GSL_SOURCE_SELECT, GSL1_READY_SOURCE_SEL, mask_sh),\
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h
index 60c01ec28b653..492760779226c 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn32/dcn32_optc.h
@@ -146,6 +146,17 @@
SF(OTG0_OTG_CRC0_WINDOWB_X_CONTROL, OTG_CRC0_WINDOWB_X_END, mask_sh),\
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_START, mask_sh),\
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_RG, CRC1_R_CR, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_RG, CRC1_G_Y, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_B, CRC1_B_CB, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_X_CONTROL, OTG_CRC1_WINDOWA_X_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_X_CONTROL, OTG_CRC1_WINDOWA_X_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_Y_CONTROL, OTG_CRC1_WINDOWA_Y_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_Y_CONTROL, OTG_CRC1_WINDOWA_Y_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_X_CONTROL, OTG_CRC1_WINDOWB_X_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_X_CONTROL, OTG_CRC1_WINDOWB_X_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL, OTG_CRC1_WINDOWB_Y_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL, OTG_CRC1_WINDOWB_Y_END, mask_sh),\
SF(OTG0_OTG_TRIGA_MANUAL_TRIG, OTG_TRIGA_MANUAL_TRIG, mask_sh),\
SF(GSL_SOURCE_SELECT, GSL0_READY_SOURCE_SEL, mask_sh),\
SF(GSL_SOURCE_SELECT, GSL1_READY_SOURCE_SEL, mask_sh),\
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h
index 82e0818c8f9f4..196596cc9fb6c 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h
@@ -32,23 +32,12 @@
#define OPTC_COMMON_MASK_SH_LIST_DCN3_5(mask_sh)\
OPTC_COMMON_MASK_SH_LIST_DCN3_2(mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_WINDOW_DB_EN, mask_sh),\
- SF(OTG0_OTG_CRC1_DATA_RG, CRC1_R_CR, mask_sh),\
- SF(OTG0_OTG_CRC1_DATA_RG, CRC1_G_Y, mask_sh),\
- SF(OTG0_OTG_CRC1_DATA_B, CRC1_B_CB, mask_sh),\
SF(OTG0_OTG_CRC2_DATA_RG, CRC2_R_CR, mask_sh),\
SF(OTG0_OTG_CRC2_DATA_RG, CRC2_G_Y, mask_sh),\
SF(OTG0_OTG_CRC2_DATA_B, CRC2_B_CB, mask_sh),\
SF(OTG0_OTG_CRC3_DATA_RG, CRC3_R_CR, mask_sh),\
SF(OTG0_OTG_CRC3_DATA_RG, CRC3_G_Y, mask_sh),\
SF(OTG0_OTG_CRC3_DATA_B, CRC3_B_CB, mask_sh),\
- SF(OTG0_OTG_CRC1_WINDOWA_X_CONTROL, OTG_CRC1_WINDOWA_X_START, mask_sh),\
- SF(OTG0_OTG_CRC1_WINDOWA_X_CONTROL, OTG_CRC1_WINDOWA_X_END, mask_sh),\
- SF(OTG0_OTG_CRC1_WINDOWA_Y_CONTROL, OTG_CRC1_WINDOWA_Y_START, mask_sh),\
- SF(OTG0_OTG_CRC1_WINDOWA_Y_CONTROL, OTG_CRC1_WINDOWA_Y_END, mask_sh),\
- SF(OTG0_OTG_CRC1_WINDOWB_X_CONTROL, OTG_CRC1_WINDOWB_X_START, mask_sh),\
- SF(OTG0_OTG_CRC1_WINDOWB_X_CONTROL, OTG_CRC1_WINDOWB_X_END, mask_sh),\
- SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL, OTG_CRC1_WINDOWB_Y_START, mask_sh),\
- SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL, OTG_CRC1_WINDOWB_Y_END, mask_sh),\
SF(OTG0_OTG_CRC0_WINDOWA_X_CONTROL_READBACK, OTG_CRC0_WINDOWA_X_START_READBACK, mask_sh),\
SF(OTG0_OTG_CRC0_WINDOWA_X_CONTROL_READBACK, OTG_CRC0_WINDOWA_X_END_READBACK, mask_sh),\
SF(OTG0_OTG_CRC0_WINDOWA_Y_CONTROL_READBACK, OTG_CRC0_WINDOWA_Y_START_READBACK, mask_sh),\
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.h
index 3add972ca2ff1..9e4e9d75400ae 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn401/dcn401_optc.h
@@ -110,6 +110,7 @@
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_CHECK_ALL_FIELDS, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_CONT_EN, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC0_SELECT, mask_sh),\
+ SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_SELECT, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_EN, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_EN, mask_sh),\
SF(OTG0_OTG_CRC0_DATA_RG, CRC0_R_CR, mask_sh),\
@@ -123,6 +124,17 @@
SF(OTG0_OTG_CRC0_WINDOWB_X_CONTROL, OTG_CRC0_WINDOWB_X_END, mask_sh),\
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_START, mask_sh),\
SF(OTG0_OTG_CRC0_WINDOWB_Y_CONTROL, OTG_CRC0_WINDOWB_Y_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_RG, CRC1_R_CR, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_RG, CRC1_G_Y, mask_sh),\
+ SF(OTG0_OTG_CRC1_DATA_B, CRC1_B_CB, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_X_CONTROL, OTG_CRC1_WINDOWA_X_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_X_CONTROL, OTG_CRC1_WINDOWA_X_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_Y_CONTROL, OTG_CRC1_WINDOWA_Y_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWA_Y_CONTROL, OTG_CRC1_WINDOWA_Y_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_X_CONTROL, OTG_CRC1_WINDOWB_X_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_X_CONTROL, OTG_CRC1_WINDOWB_X_END, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL, OTG_CRC1_WINDOWB_Y_START, mask_sh),\
+ SF(OTG0_OTG_CRC1_WINDOWB_Y_CONTROL, OTG_CRC1_WINDOWB_Y_END, mask_sh),\
SF(OTG0_OTG_TRIGA_MANUAL_TRIG, OTG_TRIGA_MANUAL_TRIG, mask_sh),\
SF(GSL_SOURCE_SELECT, GSL0_READY_SOURCE_SEL, mask_sh),\
SF(GSL_SOURCE_SELECT, GSL1_READY_SOURCE_SEL, mask_sh),\
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.h
index bc641f6ecd7e7..bdda94489a23a 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn42/dcn42_optc.h
@@ -137,6 +137,7 @@
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_CHECK_ALL_FIELDS, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_CONT_EN, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC0_SELECT, mask_sh),\
+ SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_SELECT, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_EN, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_EN, mask_sh),\
SF(OTG0_OTG_CRC0_DATA_R, CRC0_R_CR, mask_sh),\
@@ -316,6 +317,7 @@
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_CHECK_ALL_FIELDS, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_CONT_EN, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC0_SELECT, mask_sh),\
+ SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_SELECT, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_EN, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_EN, mask_sh),\
SF(OTG0_OTG_CRC0_DATA_R, CRC0_R_CR, mask_sh),\
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn60/dcn60_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn60/dcn60_optc.h
index ba207c0e498e9..ec40c91800309 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn60/dcn60_optc.h
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn60/dcn60_optc.h
@@ -109,7 +109,9 @@
SF(OTG0_OTG_GSL_CONTROL, OTG_GSL_FORCE_DELAY, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_CONT_EN, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC0_SELECT, mask_sh),\
+ SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_SELECT, mask_sh),\
SF(OTG0_OTG_CRC_CNTL, OTG_CRC_EN, mask_sh),\
+ SF(OTG0_OTG_CRC_CNTL, OTG_CRC1_EN, mask_sh),\
SF(OTG0_OTG_CRC0_DATA_R, CRC0_R_CR, mask_sh),\
SF(OTG0_OTG_CRC0_DATA_G, CRC0_G_Y, mask_sh),\
SF(OTG0_OTG_CRC0_DATA_B, CRC0_B_CB, mask_sh),\
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
index 68e7140f1505d..fa8cc89cb3f75 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.h
@@ -1054,6 +1054,12 @@ unsigned int dcn32_get_max_hw_cursor_size(const struct dc *dc,
SRI_ARR(OTG_CRC0_WINDOWA_Y_CONTROL, OTG, inst), \
SRI_ARR(OTG_CRC0_WINDOWB_X_CONTROL, OTG, inst), \
SRI_ARR(OTG_CRC0_WINDOWB_Y_CONTROL, OTG, inst), \
+ SRI_ARR(OTG_CRC1_DATA_RG, OTG, inst), \
+ SRI_ARR(OTG_CRC1_DATA_B, OTG, inst), \
+ SRI_ARR(OTG_CRC1_WINDOWA_X_CONTROL, OTG, inst), \
+ SRI_ARR(OTG_CRC1_WINDOWA_Y_CONTROL, OTG, inst), \
+ SRI_ARR(OTG_CRC1_WINDOWB_X_CONTROL, OTG, inst), \
+ SRI_ARR(OTG_CRC1_WINDOWB_Y_CONTROL, OTG, inst), \
SR_ARR(GSL_SOURCE_SELECT, inst), \
SRI_ARR(OTG_TRIGA_MANUAL_TRIG, OTG, inst), \
SRI_ARR(OTG_GLOBAL_CONTROL1, OTG, inst), \
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h
index 8e3473f864901..3cfc1a39a103c 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.h
@@ -535,6 +535,12 @@ int dcn401_get_power_profile(const struct dc_state *context);
SRI_ARR(OTG_CRC0_WINDOWA_Y_CONTROL, OTG, inst), \
SRI_ARR(OTG_CRC0_WINDOWB_X_CONTROL, OTG, inst), \
SRI_ARR(OTG_CRC0_WINDOWB_Y_CONTROL, OTG, inst), \
+ SRI_ARR(OTG_CRC1_DATA_RG, OTG, inst), \
+ SRI_ARR(OTG_CRC1_DATA_B, OTG, inst), \
+ SRI_ARR(OTG_CRC1_WINDOWA_X_CONTROL, OTG, inst), \
+ SRI_ARR(OTG_CRC1_WINDOWA_Y_CONTROL, OTG, inst), \
+ SRI_ARR(OTG_CRC1_WINDOWB_X_CONTROL, OTG, inst), \
+ SRI_ARR(OTG_CRC1_WINDOWB_Y_CONTROL, OTG, inst), \
SR_ARR(GSL_SOURCE_SELECT, inst), \
SRI_ARR(OTG_TRIGA_MANUAL_TRIG, OTG, inst), \
SRI_ARR(OTG_GLOBAL_CONTROL1, OTG, inst), \
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 357/507] drm/amdgpu: finish GPU recovery callbacks before restarting schedulers
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (355 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 356/507] drm/amd/display: add missing CRC engine 1 registers Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 358/507] drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts for navi10_ih Greg Kroah-Hartman
` (149 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Prike Liang, Lijo Lazar,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prike Liang <Prike.Liang@amd.com>
[ Upstream commit 733389cb31e2c55e355410759fdc68afe74a4582 ]
Run GPU post-reset callbacks, including KFD and display-audio resume,
before restarting DRM scheduler workqueues. IP hardware initialization
already happens inside ASIC recovery; this change orders the remaining
callbacks before new scheduler submissions. Preserve the emergency-stop
and guity job completition path's callbacks without starting schedulers,
Signed-off-by: Prike Liang <Prike.Liang@amd.com>
Acked-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 1f6433e2b264e75c56ae95f187788806201bdbc3)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 5b72e4afb650f..10fc1981fb640 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -5797,8 +5797,10 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
amdgpu_device_halt_activities(adev, job, reset_context, &device_list,
hive, need_emergency_restart);
- if (need_emergency_restart)
- goto skip_sched_resume;
+ if (need_emergency_restart) {
+ amdgpu_device_gpu_resume(adev, &device_list, need_emergency_restart);
+ goto reset_unlock;
+ }
/*
* Must check guilty signal here since after this point all old
* HW fences are force signaled.
@@ -5808,18 +5810,17 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
if (job && (dma_fence_get_status(&job->hw_fence->base) > 0)) {
job_signaled = true;
dev_info(adev->dev, "Guilty job already signaled, skipping HW reset");
- goto skip_hw_reset;
+ goto post_resume;
}
r = amdgpu_device_asic_reset(adev, &device_list, reset_context);
if (r)
goto reset_unlock;
-skip_hw_reset:
+post_resume:
+ amdgpu_device_gpu_resume(adev, &device_list, need_emergency_restart);
r = amdgpu_device_sched_resume(&device_list, reset_context, job_signaled);
if (r)
goto reset_unlock;
-skip_sched_resume:
- amdgpu_device_gpu_resume(adev, &device_list, need_emergency_restart);
reset_unlock:
amdgpu_device_recovery_put_reset_lock(adev, &device_list);
amdgpu_ras_post_reset(adev, &device_list);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 358/507] drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts for navi10_ih
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (356 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 357/507] drm/amdgpu: finish GPU recovery callbacks before restarting schedulers Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 359/507] drm/amdgpu: stop the schedulers before preparing the GPU reset Greg Kroah-Hartman
` (148 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Danijel Slivka, Alex Deucher,
Milan Milicevic, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Milan Milicevic <Milan.Milicevic@amd.com>
[ Upstream commit 146b96974b33b8cca52755ffed3cd24a82836013 ]
Port this change to navi10_ih.c:
commit afbf7955ff01 ("drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts")
Setting IH_RB_WPTR to 0 does not clear RB_OVERFLOW if RB_ENABLE is not
set. Pulse WPTR_OVERFLOW_CLEAR after RB_ENABLE (and with
WPTR_OVERFLOW_ENABLE) so overflow is cleared when interrupts are
enabled.
Signed-off-by: Danijel Slivka <Danijel.Slivka@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Milan Milicevic <Milan.Milicevic@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 713fb4ab04f4d2af6120f8eb607c5673b2759b38)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/navi10_ih.c | 28 ++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/navi10_ih.c b/drivers/gpu/drm/amd/amdgpu/navi10_ih.c
index 4cd325149b63e..1e23d123e7f77 100644
--- a/drivers/gpu/drm/amd/amdgpu/navi10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/navi10_ih.c
@@ -161,6 +161,34 @@ static int navi10_ih_toggle_ring_interrupts(struct amdgpu_device *adev,
tmp = RREG32(ih_regs->ih_rb_cntl);
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0));
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_GPU_TS_ENABLE, 1);
+
+ if (enable) {
+ /* Unset the CLEAR_OVERFLOW bit to make sure the next step
+ * is switching the bit from 0 to 1
+ */
+ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
+ if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
+ if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
+ return -ETIMEDOUT;
+ } else {
+ WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
+ }
+
+ /* Clear RB_OVERFLOW bit */
+ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
+ if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
+ if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
+ return -ETIMEDOUT;
+ } else {
+ WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
+ }
+
+ /* Unset the CLEAR_OVERFLOW bit immediately so new overflows
+ * can be detected.
+ */
+ tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
+ }
+
/* enable_intr field is only valid in ring0 */
if (ih == &adev->irq.ih)
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 359/507] drm/amdgpu: stop the schedulers before preparing the GPU reset
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (357 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 358/507] drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts for navi10_ih Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 360/507] drm/amdgpu: Ensure that harvest information gets set Greg Kroah-Hartman
` (147 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Prike Liang, Lijo Lazar,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prike Liang <Prike.Liang@amd.com>
[ Upstream commit 5b40c07c7ae9f80ec5277bc44c63f354ff581077 ]
amdgpu_device_halt_activities() only stops the ring schedulers after
amdgpu_amdkfd_pre_reset() and amdgpu_userq_pre_reset(). With a hung MES
every REMOVE_QUEUE in amdgpu_userq_pre_reset() waits for its timeout, so
the schedulers keep pushing jobs to the hardware for seconds after the
reset has started:
GPU reset begin!. Source: 6
MES failed to respond to msg=REMOVE_QUEUE fence_wait_ret=528494 status=0x0
WARNING: amdgpu_device.c:928 at amdgpu_device_skip_hw_access+0x73/0x90 [amdgpu]
Workqueue: sdma0 drm_sched_run_job_work [gpu_sched]
Call Trace:
amdgpu_mm_wdoorbell64+0x20/0x70 [amdgpu]
sdma_v6_0_ring_set_wptr+0xa6/0x180 [amdgpu]
amdgpu_ring_commit+0x5b/0xa0 [amdgpu]
amdgpu_ib_schedule+0x64a/0x8f0 [amdgpu]
amdgpu_job_run+0xa2/0x220 [amdgpu]
drm_sched_run_job_work+0x10c/0x300 [gpu_sched]
Stop the schedulers of all devices in the reset list first. None of the
preparation steps needs them, and jobs submitted meanwhile simply wait
until amdgpu_device_sched_resume().
Fixes: 290f46cf5726 ("drm/amdgpu: Implement user queue reset functionality")
Signed-off-by: Prike Liang <Prike.Liang@amd.com>
Acked-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit ea55250ab5594032541c455e1b84e8a7c15a2ba4)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 28 ++++++++++++----------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 10fc1981fb640..948886fffb4ad 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -5515,7 +5515,21 @@ static void amdgpu_device_halt_activities(struct amdgpu_device *adev,
struct amdgpu_device *tmp_adev = NULL;
int i;
- /* block all schedulers and reset given job's ring */
+ /* Stop job submission first, the preparation below can take seconds */
+ list_for_each_entry(tmp_adev, device_list, reset_list) {
+ for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
+ struct amdgpu_ring *ring = tmp_adev->rings[i];
+
+ if (!amdgpu_ring_sched_ready(ring))
+ continue;
+
+ drm_sched_wqueue_stop(&ring->sched);
+
+ if (need_emergency_restart)
+ amdgpu_job_stop_all_jobs_on_sched(&ring->sched);
+ }
+ }
+
list_for_each_entry(tmp_adev, device_list, reset_list) {
amdgpu_device_set_mp1_state(tmp_adev);
@@ -5551,18 +5565,6 @@ static void amdgpu_device_halt_activities(struct amdgpu_device *adev,
amdgpu_ras_suspend(tmp_adev);
amdgpu_userq_pre_reset(tmp_adev);
-
- for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
- struct amdgpu_ring *ring = tmp_adev->rings[i];
-
- if (!amdgpu_ring_sched_ready(ring))
- continue;
-
- drm_sched_wqueue_stop(&ring->sched);
-
- if (need_emergency_restart)
- amdgpu_job_stop_all_jobs_on_sched(&ring->sched);
- }
atomic_inc(&tmp_adev->gpu_reset_counter);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 360/507] drm/amdgpu: Ensure that harvest information gets set
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (358 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 359/507] drm/amdgpu: stop the schedulers before preparing the GPU reset Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 361/507] drm/amdgpu: publish IH enabled before PSP programs IH_RB_CNTL Greg Kroah-Hartman
` (146 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kent Russell, Mario Limonciello,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kent Russell <kent.russell@amd.com>
[ Upstream commit 4c5ec969b9b011e824f1850d7ffe4fa5c41ba890 ]
After the earlier patch exported IP discovery on probe failure, there was
an unexpected consequence where harvest info was not populated. The
early-exit in amdgpu_discovery_sysfs_init meant that we never called
amdgpu_discovery_get_harvest_info, which is where we set the actual
harvest value. The first time we call amdgpu_discovery_sysfs_recurse
with NULL instead of adev, most values can get set. The 2nd time
amdgpu_discovery_sysfs_recurse is called, we bail early.
To keep the logic of the first patch intact, ensuring that older kernels
can still discover the IP blocks, add a separate call in the early-exit
section that sets the harvest information.
This should be the only functionality that is missed in this flow, as the
rest of the calls either work fine with adev=NULL, or use the discovery_bin
directly.
Fixes: 402e04f11ff7 ("drm/amdgpu: Export ip_discovery sysfs on probe failure")
Assisted-by: LLM Claude
Signed-off-by: Kent Russell <kent.russell@amd.com>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit ca0812a625d112df556e37550e6accceea33e485)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 44 +++++++++++++++++--
1 file changed, 40 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 7ab2ad2c5ba99..6d9a3e3b35468 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -1402,6 +1402,40 @@ static int amdgpu_discovery_sysfs_recurse(struct amdgpu_device *adev,
return 0;
}
+#define list_to_kobj(el) container_of(el, struct kobject, entry)
+
+static void amdgpu_discovery_sysfs_update_harvest(struct amdgpu_device *adev)
+{
+ struct ip_discovery_top *ip_top = adev->discovery.ip_top;
+ struct ip_die_entry *ip_die_entry;
+ struct list_head *el_die, *el_hw_id, *el_hw_inst;
+ struct ip_hw_id *hw_id;
+ struct kset *die_kset;
+ struct ip_hw_instance *ip_inst;
+
+ if (!ip_top)
+ return;
+
+ die_kset = &ip_top->die_kset;
+
+ guard(spinlock)(&die_kset->list_lock);
+ list_for_each(el_die, &die_kset->list) {
+ ip_die_entry = to_ip_die_entry(list_to_kobj(el_die));
+
+ list_for_each(el_hw_id, &ip_die_entry->ip_kset.list) {
+ hw_id = to_ip_hw_id(list_to_kobj(el_hw_id));
+
+ list_for_each(el_hw_inst, &hw_id->hw_id_kset.list) {
+ ip_inst = to_ip_hw_instance(list_to_kobj(el_hw_inst));
+ ip_inst->harvest =
+ amdgpu_discovery_get_harvest_info(
+ adev, ip_inst->hw_id,
+ ip_inst->num_instance);
+ }
+ }
+ }
+}
+
static int amdgpu_discovery_sysfs_init(struct amdgpu_device *adev)
{
uint8_t *discovery_bin = adev->discovery.bin;
@@ -1412,9 +1446,13 @@ static int amdgpu_discovery_sysfs_init(struct amdgpu_device *adev)
if (!discovery_bin)
return -EINVAL;
- /* If early init already created sysfs in standalone mode, skip normal init */
- if (adev->discovery.ip_top && adev->discovery.ip_top->standalone_mode)
+ /* If early init already created sysfs in standalone mode, update harvest info
+ * now that adev is fully initialized, then skip the rest of normal init.
+ */
+ if (adev->discovery.ip_top && adev->discovery.ip_top->standalone_mode) {
+ amdgpu_discovery_sysfs_update_harvest(adev);
return 0;
+ }
ip_top = kzalloc_obj(*ip_top);
if (!ip_top)
@@ -1469,8 +1507,6 @@ static int amdgpu_discovery_sysfs_init(struct amdgpu_device *adev)
/* -------------------------------------------------- */
-#define list_to_kobj(el) container_of(el, struct kobject, entry)
-
static void amdgpu_discovery_sysfs_ip_hw_free(struct ip_hw_id *ip_hw_id)
{
struct list_head *el, *tmp;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 361/507] drm/amdgpu: publish IH enabled before PSP programs IH_RB_CNTL
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (359 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 360/507] drm/amdgpu: Ensure that harvest information gets set Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 362/507] drm/amd/display: Avoid closing unowned DDC pins Greg Kroah-Hartman
` (145 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Danijel Slivka, Milan Milicevic,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Milan Milicevic <Milan.Milicevic@amd.com>
[ Upstream commit 9d550dd1a3b4b96da49f3560a84b5c2413a88cd3 ]
On SR-IOV, programming IH_RB_CNTL through PSP is slow enough for the
first MSI to arrive before ih->enabled is set. amdgpu_ih_process()
then drops the interrupt, rptr stays at 0, and RPTR_REARM never
generates another edge, so every ring hits the fence fallback timer.
Set ih->enabled before psp_reg_program() on the indirect IH path for
Navi10 and IH v6.0, and clear it if programming fails.
Signed-off-by: Danijel Slivka <Danijel.Slivka@amd.com>
Signed-off-by: Milan Milicevic <Milan.Milicevic@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit b2f9434f9d17c94798e8d8957af3adc4a9949016)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/ih_v6_0.c | 13 ++++++++++++-
drivers/gpu/drm/amd/amdgpu/navi10_ih.c | 13 ++++++++++++-
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c b/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c
index 333e9c30c091d..535c84e55558f 100644
--- a/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/ih_v6_0.c
@@ -168,8 +168,19 @@ static int ih_v6_0_toggle_ring_interrupts(struct amdgpu_device *adev,
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
- if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
+ /*
+ * PSP programming of IH_RB_CNTL is slow enough for MSI to
+ * arrive before this call returns. Publish ih->enabled first
+ * so amdgpu_ih_process() consumes that IV and rearms.
+ */
+ if (enable) {
+ ih->enabled = true;
+ smp_wmb();
+ }
+ if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) {
+ ih->enabled = false;
return -ETIMEDOUT;
+ }
} else {
WREG32(ih_regs->ih_rb_cntl, tmp);
}
diff --git a/drivers/gpu/drm/amd/amdgpu/navi10_ih.c b/drivers/gpu/drm/amd/amdgpu/navi10_ih.c
index 1e23d123e7f77..bed0eb4b6ec3b 100644
--- a/drivers/gpu/drm/amd/amdgpu/navi10_ih.c
+++ b/drivers/gpu/drm/amd/amdgpu/navi10_ih.c
@@ -194,8 +194,19 @@ static int navi10_ih_toggle_ring_interrupts(struct amdgpu_device *adev,
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));
if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
- if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
+ /*
+ * PSP programming of IH_RB_CNTL is slow enough for MSI to
+ * arrive before this call returns. Publish ih->enabled first
+ * so amdgpu_ih_process() consumes that IV and rearms.
+ */
+ if (enable) {
+ ih->enabled = true;
+ smp_wmb();
+ }
+ if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) {
+ ih->enabled = false;
return -ETIMEDOUT;
+ }
} else {
WREG32(ih_regs->ih_rb_cntl, tmp);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 362/507] drm/amd/display: Avoid closing unowned DDC pins
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (360 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 361/507] drm/amdgpu: publish IH enabled before PSP programs IH_RB_CNTL Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 363/507] drm/amd/display: Reset DET of HUBPs without a plane before outstanding updates Greg Kroah-Hartman
` (144 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jerry Zuo, Mario Limonciello,
Alex Deucher, Alex Hung, Dan Wheeler, Leo Li, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung <alex.hung@amd.com>
[ Upstream commit e7ba638b8116cb5f1a5690f543052371215f1626 ]
[WHY]
dal_ddc_open() cleans up pins it acquires on later failures. If the
data-pin open fails, this attempt acquired nothing. If opening the
clock pin or configuring fails, dal_ddc_open() closes the pins it
opened. An extra dal_ddc_close() is unnecessary and unsafe:
GPIO_RESULT_ALREADY_OPENED can mean AUX owns the existing handles,
and closing them here would disrupt AUX.
[HOW]
Remove the extra dal_ddc_close() from the failed-open path.
Cc: Jerry Zuo <jerry.zuo@amd.com>
Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Reviewed-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 175ae7772b68757b4932f34ff862923cab7abe21)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../drm/amd/display/dc/link/protocols/link_dp_capability.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
index 24e3bbec15ffb..8ff364d465de0 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c
@@ -2601,12 +2601,8 @@ bool dp_is_sink_present(struct dc_link *link)
* which indicates we need additional delay
*/
- if (dal_ddc_open(ddc, GPIO_MODE_INPUT,
- GPIO_DDC_CONFIG_TYPE_MODE_I2C) != GPIO_RESULT_OK) {
- dal_ddc_close(ddc);
-
+ if (dal_ddc_open(ddc, GPIO_MODE_INPUT, GPIO_DDC_CONFIG_TYPE_MODE_I2C) != GPIO_RESULT_OK)
return present;
- }
/*
* Read GPIO: DP sink is present if both clock and data pins are zero
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 363/507] drm/amd/display: Reset DET of HUBPs without a plane before outstanding updates
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (361 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 362/507] drm/amd/display: Avoid closing unowned DDC pins Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 364/507] drm/amdgpu/gfx12: disallow GFXOFF while updating the SPM VMID Greg Kroah-Hartman
` (143 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dillon Varone, Mario Limonciello,
Alex Deucher, Roman Li, Alex Hung, Dan Wheeler, Leo Li,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roman Li <Roman.Li@amd.com>
[ Upstream commit f3afbf7d832ab138655afc96bd42226775d03ce7 ]
[WHY]
DC asserts with:
WARNING: dc/hubbub/dcn401/dcn401_hubbub.c at dcn401_program_compbuf_segments
Call Trace:
<TASK>
dcn401_program_outstanding_updates+0x36/0x60 [amdgpu]
hwss_process_outstanding_hw_updates+0x33/0x40 [amdgpu]
commit_planes_for_stream+0x171f/0x1ff0 [amdgpu]
dc_update_state_execute+0xaa/0x170 [amdgpu]
dc_update_planes_and_stream+0x42/0x70 [amdgpu]
amdgpu_dm_atomic_commit_tail+0x16a9/0x4020 [amdgpu]
commit_tail+0xc3/0x1b0 [drm_kms_helper]
The DET left by the VBIOS on a HUBP without a plane can be larger than
the DET planned for the new state. The compbuf is sized for the planned
DET, so DET + compbuf can exceed the CRB size. Programming the compbuf
then triggers the ASSERT and sets CONFIG_ERROR in hardware.
[HOW]
Release the DET of HUBPs without a plane before the compbuf is
programmed.
Add hwss_reset_unused_det() and call it in the commit and flip paths,
to cover both seamless and non-seamless boots.
Fixes: 7a1eb6680939 ("drm/amd/display: Perform outstanding programming on full updates")
Cc: Dillon Varone <dillon.varone@amd.com>
Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Roman Li <Roman.Li@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Reviewed-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit c93f6fc7175b445ba3b7c85a1fc31e4e4951bbc9)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/core/dc.c | 6 +++-
.../drm/amd/display/dc/core/dc_hw_sequencer.c | 31 +++++++++++++++++++
.../drm/amd/display/dc/hwss/hw_sequencer.h | 3 ++
3 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 519ac878ada1b..60b903edff2f8 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -2452,6 +2452,8 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
* update pending complete before optimizing bandwidth.
*/
hwss_wait_for_odm_update_pending_complete(dc, context);
+ /* No DET may stay allocated to a HUBP without a plane (e.g. left over from VBIOS) */
+ hwss_reset_unused_det(dc, context);
/* pplib is notified if disp_num changed */
dc->hwss.optimize_bandwidth(dc, context);
/* Need to do otg sync again as otg could be out of sync due to otg
@@ -4885,8 +4887,10 @@ static void commit_planes_for_stream(struct dc *dc,
dc_exit_ips_for_hw_access(dc);
dc_z10_restore(dc);
- if (update_type == UPDATE_TYPE_FULL && dc->optimized_required)
+ if (update_type == UPDATE_TYPE_FULL && dc->optimized_required) {
+ hwss_reset_unused_det(dc, dc->current_state);
hwss_process_outstanding_hw_updates(dc, dc->current_state);
+ }
if (update_type != UPDATE_TYPE_FAST && dc->res_pool->funcs->prepare_mcache_programming)
dc->res_pool->funcs->prepare_mcache_programming(dc, context);
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index ef4987d449cb2..d4dbdf7d05065 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -3047,6 +3047,37 @@ void hwss_wait_for_odm_update_pending_complete(struct dc *dc, struct dc_state *c
hwss_wait_for_all_blank_complete(dc, context);
}
+void hwss_reset_unused_det(struct dc *dc, struct dc_state *context)
+{
+ struct hubbub *hubbub = dc->res_pool->hubbub;
+ unsigned int i, j;
+
+ if (!hubbub || !hubbub->funcs->program_det_segments)
+ return;
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct hubp *hubp = dc->res_pool->hubps[i];
+ bool hubp_in_use = false;
+
+ if (!hubp)
+ continue;
+
+ for (j = 0; j < dc->res_pool->pipe_count; j++) {
+ const struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[j];
+
+ /* A plane-less pipe renders from the DPG, its HUBP (assigned with the stream) needs no DET */
+ if (pipe->plane_state && pipe->plane_res.hubp &&
+ pipe->plane_res.hubp->inst == hubp->inst) {
+ hubp_in_use = true;
+ break;
+ }
+ }
+
+ if (!hubp_in_use)
+ hubbub->funcs->program_det_segments(hubbub, hubp->inst, 0);
+ }
+}
+
void hwss_wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context)
{
int i;
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
index cdf2562a9a402..0d64a0c1913d9 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
@@ -1807,6 +1807,9 @@ void hwss_wait_for_odm_update_pending_complete(struct dc *dc,
void hwss_wait_for_no_pipes_pending(struct dc *dc,
struct dc_state *context);
+void hwss_reset_unused_det(struct dc *dc,
+ struct dc_state *context);
+
void hwss_wait_for_outstanding_hw_updates(struct dc *dc,
struct dc_state *dc_context);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 364/507] drm/amdgpu/gfx12: disallow GFXOFF while updating the SPM VMID
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (362 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 363/507] drm/amd/display: Reset DET of HUBPs without a plane before outstanding updates Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 365/507] drm/amd/display: Fix NULL deref in dcn401_update_clocks_update_dtb_dto Greg Kroah-Hartman
` (142 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Alex Deucher, Jesse Zhang,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <Jesse.Zhang@amd.com>
[ Upstream commit d1551515a3258b43cba60bd7f45bbdd1f4e9e60a ]
gfx_v12_0_update_spm_vmid() does a read-modify-write of RLC_SPM_MC_CNTL
over MMIO without keeping GFX powered, unlike gfx11. When GFX is in
GFXOFF at that point the update doesn't stick, and with the SPM VMID
programmed on submission again, the job of a process with a reserved
VMID can still run with the SPM writing through VMID 0.
On navi48, after a few other submissions and a VM fault on the same VM,
a COPY_DATA of RLC_SPM_MC_CNTL from such a job reads 0 although the
update was called for it:
$ amd_uapi_regression --run-subtest cs-secure-ib-compute,gem-mapping-info-high-va,gpuvm-fault-high-va,reserved-vmid-spm-vmid
amdgpu 0000:03:00.0: [gfxhub] page fault (src_id:0 ring:40 vmid:7 pasid:185)
amdgpu 0000:03:00.0: Faulty UTCL2 client ID: SDMA1 (0xe)
RLC_SPM_MC_CNTL in the job: 0x00000000
With GFXOFF disallowed around the update it reads the reserved VMID 15.
Fixes: 52cb80c12e8a ("drm/amdgpu: Add gfx v12_0 ip block support (v6)")
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 907aebc5578ae09fa5c0e2f0784201295837e60b)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index d69c43f1e194c..60debaa23762d 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -4080,6 +4080,7 @@ static void gfx_v12_0_update_spm_vmid(struct amdgpu_device *adev,
{
u32 reg, data;
+ amdgpu_gfx_off_ctrl(adev, false);
reg = SOC15_REG_OFFSET(GC, 0, regRLC_SPM_MC_CNTL);
if (amdgpu_sriov_is_pp_one_vf(adev))
data = RREG32_NO_KIQ(reg);
@@ -4093,6 +4094,7 @@ static void gfx_v12_0_update_spm_vmid(struct amdgpu_device *adev,
WREG32_SOC15_NO_KIQ(GC, 0, regRLC_SPM_MC_CNTL, data);
else
WREG32_SOC15(GC, 0, regRLC_SPM_MC_CNTL, data);
+ amdgpu_gfx_off_ctrl(adev, true);
if (ring
&& amdgpu_sriov_is_pp_one_vf(adev)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 365/507] drm/amd/display: Fix NULL deref in dcn401_update_clocks_update_dtb_dto
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (363 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 364/507] drm/amdgpu/gfx12: disallow GFXOFF while updating the SPM VMID Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 366/507] drm/amd/display: Drop clock requirements on DCN32 when no displays are active Greg Kroah-Hartman
` (141 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Roman Demidov, Alex Hung,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roman Demidov <roman.demidov.nn@gmail.com>
[ Upstream commit 7fac15d009cf236677a8cddf6bc0e8c85666ac3b ]
[Why]
resource_get_otg_master_for_stream() can return NULL if no OTG master pipe
is found for a given stream. The current code dereferences this pointer
without a NULL check. This may lead to a possible NULL pointer
dereference.
[How]
Add an explicit NULL check and skip the stream if the OTG master is not
found. This is similar to dcn60_update_clocks_update_dtb_dto().
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Fixes: b6d508533fa1 ("drm/amd/display: fix a crash when clock source is reference for non otg master pipe")
Signed-off-by: Roman Demidov <roman.demidov.nn@gmail.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit ffde3d74c1faeeb645b66d02d02fdae3e073941b)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
index 6ee3da89d0582..135eeef68ac4b 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c
@@ -538,6 +538,9 @@ static void dcn401_update_clocks_update_dtb_dto(struct clk_mgr_internal *clk_mgr
otg_master = resource_get_otg_master_for_stream(
&context->res_ctx, context->streams[i]);
ASSERT(otg_master);
+ if (!otg_master)
+ continue;
+
ASSERT(otg_master->clock_source);
ASSERT(otg_master->clock_source->funcs->program_pix_clk);
ASSERT(otg_master->stream_res.pix_clk_params.controller_id >= CONTROLLER_ID_D0);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 366/507] drm/amd/display: Drop clock requirements on DCN32 when no displays are active
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (364 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 365/507] drm/amd/display: Fix NULL deref in dcn401_update_clocks_update_dtb_dto Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 367/507] drm/amd/display: Keep the nominal vtotal while VRR is inactive Greg Kroah-Hartman
` (140 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Misha Nasledov, Alex Hung,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Misha Nasledov <misha@nasledov.com>
[ Upstream commit bba4dc3306483335ddbe065c05b2d8359ec387a4 ]
amdgpu_dm builds the new dc_state as a copy of the old one. When the last
stream is removed, dml1_validate() returns early on pipe_cnt == 0 and
never reaches dcn32_calculate_dlg_params(), so bw.dcn.clk keeps the
dramclk/dcfclk/fclk requirements of the display that was just turned off.
dcn32_update_clocks() then keeps those hard minimums applied.
On an RX 7900 XTX this leaves UCLK at 456 MHz and DCFCLK at 637 MHz with
the monitor off, and the board idles at 28.4 W. With this change they
drop to 96 MHz and 145 MHz and board power falls to 15.3 W.
Reset the clock requirements in that case, as calculate_dlg_params()
already does when no HUBP is active and as the DML2 path does for
stream_count == 0.
Signed-off-by: Misha Nasledov <misha@nasledov.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 0261a0ef89f37ef962fbc9dbc724ebf65fe681cf)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../display/dc/resource/dcn32/dcn32_resource.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
index a2e66761b8ec0..81227df686802 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
@@ -1941,8 +1941,21 @@ static bool dml1_validate(struct dc *dc, struct dc_state *context, enum dc_valid
out = dcn32_internal_validate_bw(dc, context, pipes, &pipe_cnt, &vlevel, validate_mode);
DC_FP_END();
- if (pipe_cnt == 0)
+ if (pipe_cnt == 0) {
+ /* The context is a copy of the previous state, so without this the
+ * clocks the last display needed stay applied with all displays off.
+ */
+ context->bw_ctx.bw.dcn.clk.socclk_khz = 0;
+ context->bw_ctx.bw.dcn.clk.dppclk_khz = 0;
+ context->bw_ctx.bw.dcn.clk.dcfclk_khz = 0;
+ context->bw_ctx.bw.dcn.clk.dcfclk_deep_sleep_khz = 0;
+ context->bw_ctx.bw.dcn.clk.dramclk_khz = 0;
+ context->bw_ctx.bw.dcn.clk.fclk_khz = 0;
+ context->bw_ctx.bw.dcn.clk.p_state_change_support = true;
+ context->bw_ctx.bw.dcn.clk.fclk_p_state_change_support = true;
+ context->bw_ctx.bw.dcn.clk.num_ways = 0;
goto validate_out;
+ }
if (!out)
goto validate_fail;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 367/507] drm/amd/display: Keep the nominal vtotal while VRR is inactive
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (365 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 366/507] drm/amd/display: Drop clock requirements on DCN32 when no displays are active Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 368/507] drm/amd/display: Dont select zero V_TOTAL_MIN/MAX on seamless boot Greg Kroah-Hartman
` (139 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthew Schwartz, Ivan Lipski,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Schwartz <matthew.schwartz@linux.dev>
[ Upstream commit f2853a06e4b923c77a8cba69d76d2222b198256b ]
Commit 33c995709121 ("drm/amd/display: Allow VRR params change if
unsynced with the stream") derives the inactive vtotal from
max_refresh_in_uhz and rounds it up. The round trip through integer
rates can add a line even with VRR off. The ASUS ROG Xbox Ally X20's
120.0004 Hz mode exceeds its 120 Hz EDID maximum, so 1152 lines
become 1153 and the CRTC vblank counter measures 119.89 Hz.
Take both limits from stream->timing.v_total, as
mod_freesync_build_vrr_params() does, which keeps the resync to the
stream's timing. Active VRR keeps the helper's rounding.
Fixes: 33c995709121 ("drm/amd/display: Allow VRR params change if unsynced with the stream")
Signed-off-by: Matthew Schwartz <matthew.schwartz@linux.dev>
Reviewed-by: Ivan Lipski <ivan.lipski@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 428c95d380f07694cbbd9ebe3450214404f57b5a)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index 4bd060e30799a..f154a619b5339 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -1281,10 +1281,8 @@ void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync,
* If VRR is inactive, set vtotal min and max to nominal vtotal
*/
if (in_out_vrr->state == VRR_STATE_INACTIVE) {
- in_out_vrr->adjust.v_total_min =
- mod_freesync_calc_v_total_from_refresh(stream,
- in_out_vrr->max_refresh_in_uhz);
- in_out_vrr->adjust.v_total_max = in_out_vrr->adjust.v_total_min;
+ in_out_vrr->adjust.v_total_min = stream->timing.v_total;
+ in_out_vrr->adjust.v_total_max = stream->timing.v_total;
return;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 368/507] drm/amd/display: Dont select zero V_TOTAL_MIN/MAX on seamless boot
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (366 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 367/507] drm/amd/display: Keep the nominal vtotal while VRR is inactive Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 369/507] drm/amd/display: set allow_freesync before validating a new stream Greg Kroah-Hartman
` (138 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kylie C, Alex Hung, Alex Deucher,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kylie C <kyliepc@proton.me>
[ Upstream commit d13f36e4e055cce03761de590bc8dc6346b1d5c8 ]
Initialize V_TOTAL_MIN/MAX to V_TOTAL before enabling the selectors if
they are still 0, as optc1_program_timing() does without seamless boot.
Tested on Renoir (DCN 2.1) eDP with amdgpu.seamless=1.
This removes the flash between the bios logo & plymouth on my laptop.
Signed-off-by: Kylie C <kyliepc@proton.me>
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 1ad7473e82b9242c4ee7eea82ab16d3f82f01651)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/display/dc/optc/dcn20/dcn20_optc.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn20/dcn20_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn20/dcn20_optc.c
index 73cc8a713556b..2cdfe3d7a0ea6 100644
--- a/drivers/gpu/drm/amd/display/dc/optc/dcn20/dcn20_optc.c
+++ b/drivers/gpu/drm/amd/display/dc/optc/dcn20/dcn20_optc.c
@@ -449,6 +449,13 @@ void optc2_lock_doublebuffer_disable(struct timing_generator *optc)
void optc2_setup_manual_trigger(struct timing_generator *optc)
{
struct optc *optc1 = DCN10TG_FROM_TG(optc);
+ uint32_t v_total, v_total_max;
+
+ REG_GET(OTG_V_TOTAL_MAX, OTG_V_TOTAL_MAX, &v_total_max);
+ if (!v_total_max) {
+ REG_GET(OTG_V_TOTAL, OTG_V_TOTAL, &v_total);
+ optc->funcs->set_vtotal_min_max(optc, v_total, v_total);
+ }
/* Set the min/max selectors unconditionally so that
* DMCUB fw may change OTG timings when necessary
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 369/507] drm/amd/display: set allow_freesync before validating a new stream
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (367 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 368/507] drm/amd/display: Dont select zero V_TOTAL_MIN/MAX on seamless boot Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 370/507] drm/amd/display: Signal PQ EOTF in FreeSync infopacket for DP HDR Greg Kroah-Hartman
` (137 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josh Kasten, Mikhail Gavrilov,
Alex Hung, Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
[ Upstream commit ab18dd3061eb2d92e60c8bbf9a435c25962e449f ]
After resume from S3, DC enables SubVP on a single FreeSync display at
a high refresh rate, although dcn32_allow_subvp_high_refresh_rate() is
meant to keep SubVP off that configuration ("For single display cases,
freesync must be disabled"). On an RX 7900 XTX driving a FreeSync TV
at 3840x2160@120, amdgpu_dm_capabilities reports sub-viewport disabled
after boot and enabled after "rtcwake -m mem", and the memory clock
starts switching. It stays that way until a later commit re-validates
the state; a CRTC gamma change (toggling Night Light) turns SubVP off
again.
The policy reads dc_stream_state::allow_freesync while the new state
is validated, but amdgpu_dm sets that field only in
amdgpu_dm_update_freesync_state_on_stream(), on the first flip after
the commit. A stream created by a modeset is therefore validated as
if FreeSync were off. On resume, dm_destroy_cached_state() drops the
streams and forces a modeset, so the resumed state is validated
without FreeSync.
Set allow_freesync in amdgpu_dm_get_freesync_config_for_crtc(), which
atomic check calls for every active CRTC and which already writes
ignore_msa_timing_param to the stream. It uses vrr_supported, the
condition the flip-time value is derived from. With this change the
same TV keeps SubVP disabled across "rtcwake -m mem".
On this machine SubVP is also what exposes the single-frame scanout
corruption reported in the thread linked below, so the FreeSync
setting stopped working as a workaround after every suspend.
Fixes: 87f0c16e0eeb ("drm/amd/display: Enable SubVP for high refresh rate displays")
Link: https://lore.kernel.org/all/20260829010525.29935-1-mikhail.v.gavrilov@gmail.com/
Link: https://gitlab.freedesktop.org/drm/amd/-/work_items/5714#note_3736349
Tested-by: Josh Kasten <jkasten@gmail.com>
Signed-off-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 29793918b0eb63b6810b248a906f87dd79b70be5)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c
index 7e484adb4120f..f26dd206dffa0 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c
@@ -128,6 +128,14 @@ void amdgpu_dm_get_freesync_config_for_crtc(
vrefresh >= aconnector->min_vfreq &&
vrefresh <= aconnector->max_vfreq;
+ /*
+ * DC reads allow_freesync while validating the new state, for example
+ * to keep SubVP off a single FreeSync display, but it is otherwise set
+ * only on the first flip after the commit. Set it here, so that a
+ * stream created by this commit is not validated without it.
+ */
+ new_crtc_state->stream->allow_freesync = new_crtc_state->vrr_supported;
+
if (new_crtc_state->vrr_supported) {
new_crtc_state->stream->ignore_msa_timing_param = true;
fs_vid_mode = new_crtc_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 370/507] drm/amd/display: Signal PQ EOTF in FreeSync infopacket for DP HDR
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (368 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 369/507] drm/amd/display: set allow_freesync before validating a new stream Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 371/507] drm/amd/pm: populate unique ID for smu 13.0.7 Greg Kroah-Hartman
` (136 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pierre-Loup A. Griffais, Melissa Wen,
Alex Hung, Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Melissa Wen <mwen@igalia.com>
[ Upstream commit 81f923b065801c7d30042bcda31ccb9449b4f58b ]
Commit c2791297013e ("drm/amd/display: Add color bit info to freesync
infoframe") created the app_tf interface for FreeSync HDR and commit
c21a764a98cb ("drm/amd/display: Send PQ bit in AMD VSIF") used it to set
PB9 bit 5 (PQ EOTF) in v2/v3 AMD Freesync infopacket. However, Linux
never made use of this interface: DM ignores what userspace sets
regarding HDR and always passes TRANSFER_FUNC_UNKNOWN as app_tf, so the
PQ bit is never set in the infopacket received by the eDP panel.
Check the EOTF in the HDR static metadata and set the PQ bit in Freesync
infopacket for DP accordingly. This fixes gray-washed HDR on KDE/GNOME
on Framework 13 Pro AI 9 HX 370 (DCN 3.5) and may fix similar issues on
other VRR-capable panels that advertise Replay in its AMD VSDB.
It doesn't affect color/EOTF bits on infopackets for SDR and native
HDMI.
Reported-by: Pierre-Loup A. Griffais <pgriffais@valvesoftware.com>
Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/3200
Signed-off-by: Melissa Wen <mwen@igalia.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit b318f3e13dd73781404670d3b3c6cf2177e0119c)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../display/amdgpu_dm/amdgpu_dm_freesync.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c
index f26dd206dffa0..a51cf46d0e448 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_freesync.c
@@ -162,6 +162,18 @@ void amdgpu_dm_get_freesync_config_for_crtc(
}
EXPORT_IF_KUNIT(amdgpu_dm_get_freesync_config_for_crtc);
+#define DP_HDR_SDP_EOTF_IDX 2
+
+static bool dm_dp_in_hdr_mode(const struct dc_stream_state *stream)
+{
+ const struct dc_info_packet *hdr = &stream->hdr_static_metadata;
+
+ if (!dc_is_dp_signal(stream->signal) || !hdr->valid)
+ return false;
+
+ return hdr->sb[DP_HDR_SDP_EOTF_IDX] == HDMI_EOTF_SMPTE_ST2084;
+}
+
void amdgpu_dm_update_freesync_state_on_stream(
struct amdgpu_display_manager *dm,
struct dm_crtc_state *new_crtc_state,
@@ -177,6 +189,7 @@ void amdgpu_dm_update_freesync_state_on_stream(
bool pack_sdp_v1_3 = false;
struct amdgpu_dm_connector *aconn;
enum vrr_packet_type packet_type = PACKET_TYPE_VRR;
+ enum color_transfer_func app_tf;
if (!new_stream)
return;
@@ -228,12 +241,16 @@ void amdgpu_dm_update_freesync_state_on_stream(
&new_stream->adaptive_sync_infopacket);
}
+ app_tf = dm_dp_in_hdr_mode(new_stream) ?
+ TRANSFER_FUNC_PQ2084 :
+ TRANSFER_FUNC_UNKNOWN;
+
mod_freesync_build_vrr_infopacket(
dm->freesync_module,
new_stream,
&vrr_params,
packet_type,
- TRANSFER_FUNC_UNKNOWN,
+ app_tf,
&vrr_infopacket,
pack_sdp_v1_3);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 371/507] drm/amd/pm: populate unique ID for smu 13.0.7
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (369 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 370/507] drm/amd/display: Signal PQ EOTF in FreeSync infopacket for DP HDR Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 372/507] drm/amdgpu: Fix duplicate dependency fence releases Greg Kroah-Hartman
` (135 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kevin Wang, Kenneth Feng,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kevin Wang <kevin.wang@amd.com>
[ Upstream commit 079f9103d9cde68fb2ccc414e94520f43ee102de ]
The smu 13.0.7 backend does not register get_unique_id, leaving
adev->unique_id at zero and KFD topology without the stable GPU
identifier consumed by HIP.
The failure is observed at:
auto ierr = hipDeviceGetUuid(&uuid, 0);
Fixes: 113cc31dde66 ("drm/amd/pm: add SMU_13_0_7 ppt_funcs for SMU_13_0_7")
Signed-off-by: Kevin Wang <kevin.wang@amd.com>
Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 5e2585daaf8336d9ce1bf52e55a9b7a8cdbf625b)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 20 +++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
index 8285d4a91589a..13e7e33fa0eb2 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
@@ -2912,6 +2912,25 @@ static int smu_v13_0_7_mode1_reset(struct smu_context *smu)
return ret;
}
+static void smu_v13_0_7_get_unique_id(struct smu_context *smu)
+{
+ SmuMetricsExternal_t metrics_external;
+ SmuMetrics_t *metrics = &metrics_external.SmuMetrics;
+ struct amdgpu_device *adev = smu->adev;
+ u32 upper32 = 0, lower32 = 0;
+ int ret;
+
+ ret = smu_cmn_get_metrics_table(smu, &metrics_external, false);
+ if (ret)
+ goto out;
+
+ upper32 = metrics->PublicSerialNumberUpper;
+ lower32 = metrics->PublicSerialNumberLower;
+
+out:
+ adev->unique_id = ((u64)upper32 << 32) | lower32;
+}
+
static void smu_v13_0_7_init_msg_ctl(struct smu_context *smu)
{
struct amdgpu_device *adev = smu->adev;
@@ -2995,6 +3014,7 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = {
.enable_uclk_shadow = smu_v13_0_enable_uclk_shadow,
.set_wbrf_exclusion_ranges = smu_v13_0_set_wbrf_exclusion_ranges,
.interrupt_work = smu_v13_0_interrupt_work,
+ .get_unique_id = smu_v13_0_7_get_unique_id,
};
void smu_v13_0_7_set_ppt_funcs(struct smu_context *smu)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 372/507] drm/amdgpu: Fix duplicate dependency fence releases
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (370 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 371/507] drm/amd/pm: populate unique ID for smu 13.0.7 Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 373/507] drm/amdgpu: Report MES ring wait timeouts Greg Kroah-Hartman
` (134 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Deucher, Erhan Bilgili,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Erhan Bilgili <erhan.bilgili@gmail.com>
[ Upstream commit ea47f84199241dd083d40a241beea665415d4f6c ]
drm_sched_job_add_dependency() consumes its fence reference on success
and failure. Do not release the fence again if
drm_sched_job_add_dependency() fails.
Fixes: 41cc108b2451 ("drm/amdgpu: fix missing dma_fence_put in error path")
Fixes: c1c4a8b21721 ("drm/amdgpu: grab extra fence reference for drm_sched_job_add_dependency")
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Erhan Bilgili <erhan.bilgili@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit e04f3dfb2071451633e6440a3911a9bb65df9144)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 4 +---
drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c | 1 -
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
index d6ae9974c952e..4f31021b21520 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c
@@ -447,10 +447,8 @@ int amdgpu_sync_push_to_job(struct amdgpu_sync *sync, struct amdgpu_job *job)
dma_fence_get(f);
r = drm_sched_job_add_dependency(&job->base, f);
- if (r) {
- dma_fence_put(f);
+ if (r)
return r;
- }
}
return 0;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
index eb8cf0d9d9c59..652266e937664 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_sdma.c
@@ -234,7 +234,6 @@ static int amdgpu_vm_sdma_update(struct amdgpu_vm_update_params *p,
dma_fence_get(fence);
r = drm_sched_job_add_dependency(&p->job->base, fence);
if (r) {
- dma_fence_put(fence);
dma_resv_iter_end(&cursor);
return r;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 373/507] drm/amdgpu: Report MES ring wait timeouts.
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (371 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 372/507] drm/amdgpu: Fix duplicate dependency fence releases Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 374/507] drm/amdgpu: Clamp the ATIF backlight curve to its 99 points Greg Kroah-Hartman
` (133 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Deucher, Erhan Bilgili,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Erhan Bilgili <erhan.bilgili@gmail.com>
[ Upstream commit 122e864861144150e905012b5fb52e63ad5de68d ]
Return -ETIMEDOUT when the fence wait before submission expires instead
of reporting success without submitting the packet.
Fixes: 34e087e8920e ("drm/amdgpu/mes: fix mes ring buffer overflow")
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Erhan Bilgili <erhan.bilgili@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 34341594a87b4a3f28be41e3e70a4787f02b3d9e)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 4 +++-
drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
index c57bcb9a98b19..10bed6f38f309 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
@@ -218,8 +218,10 @@ static int mes_v11_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
r = amdgpu_fence_wait_polling(ring,
seq - ring->fence_drv.num_fences_mask,
timeout);
- if (r < 1)
+ if (r < 1) {
+ r = -ETIMEDOUT;
goto error_undo;
+ }
api_status = (struct MES_API_STATUS *)((char *)pkt + api_status_off);
api_status->api_completion_fence_addr = status_gpu_addr;
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
index ee72afdb0a1d3..bb9892d1bd051 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
@@ -195,8 +195,10 @@ static int mes_v12_0_submit_pkt_and_poll_completion(struct amdgpu_mes *mes,
r = amdgpu_fence_wait_polling(ring,
seq - ring->fence_drv.num_fences_mask,
timeout);
- if (r < 1)
+ if (r < 1) {
+ r = -ETIMEDOUT;
goto error_undo;
+ }
api_status = (struct MES_API_STATUS *)((char *)pkt + api_status_off);
api_status->api_completion_fence_addr = status_gpu_addr;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 374/507] drm/amdgpu: Clamp the ATIF backlight curve to its 99 points
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (372 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 373/507] drm/amdgpu: Report MES ring wait timeouts Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 375/507] drm/amdgpu: drop the dma-buf reference when a KFD import fails Greg Kroah-Hartman
` (132 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hugo Sales, Mario Limonciello,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Sales <hugo@hsal.es>
[ Upstream commit 7ba7655701c5cad5bfa043d464d1e24873e24aab ]
amdgpu_atif_query_backlight_caps() stores the firmware's number_of_points
as data_points but copies only the 99 points that luminance_data[] holds.
number_of_points is a u8, so a firmware table that claims more makes the
custom curve code in amdgpu_dm index past the array, and
dm_query_extended_brightness_caps() copy past the end of the
data_points[] buffer it fills
Clamp the count to ATIF_QBTC_MAX_DATA_POINTS and warn, since a table
that claims more is a firmware bug
Fixes: f729e63743f0 ("drm/amd: Pass luminance data to amdgpu_dm_backlight_caps")
Signed-off-by: Hugo Sales <hugo@hsal.es>
Link: https://patch.msgid.link/20261031153948.127016-1-hugo@hsal.es
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit af8a1c2b7d3de4960e10f94e8ba2fc0ccd168072)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
index 8b8acf98fdfe2..53475f8a3ff16 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
@@ -405,7 +405,11 @@ int amdgpu_atif_query_backlight_caps(struct amdgpu_atif *atif)
characteristics.max_input_signal;
atif->backlight_caps.ac_level = characteristics.ac_level;
atif->backlight_caps.dc_level = characteristics.dc_level;
- atif->backlight_caps.data_points = characteristics.number_of_points;
+ if (characteristics.number_of_points > ATIF_QBTC_MAX_DATA_POINTS)
+ pr_warn(FW_BUG "ATIF: backlight curve has %u points, using the first %u\n",
+ characteristics.number_of_points, ATIF_QBTC_MAX_DATA_POINTS);
+ atif->backlight_caps.data_points = min_t(u8, characteristics.number_of_points,
+ ATIF_QBTC_MAX_DATA_POINTS);
memcpy(atif->backlight_caps.luminance_data,
characteristics.data_points,
sizeof(atif->backlight_caps.luminance_data));
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 375/507] drm/amdgpu: drop the dma-buf reference when a KFD import fails
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (373 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 374/507] drm/amdgpu: Clamp the ATIF backlight curve to its 99 points Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 376/507] drm/amdgpu: unlock the VM and BO when attaching a KFD BO fails Greg Kroah-Hartman
` (131 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Felix Kuehling, Jesse Zhang,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <Jesse.Zhang@amd.com>
[ Upstream commit fb900f8bfd8a16126affd186d21001e4c6533324 ]
import_obj_create() takes a reference on the dma-buf for the new kgd_mem,
but the error path after validating the BO doesn't drop it. Since the
validation reserves the BO interruptibly, an import failing with
-ERESTARTSYS leaks the exported BO with its memory, and keeps the module
in use.
Importing a 64 MiB VRAM BO in a loop while getting SIGUSR1
every 20 us and another thread changes the BO's mappings:
INFO: 171821 imports, VRAM used before 65 MiB, after 129 MiB
modprobe: FATAL: Module amdgpu is in use.
Drop the reference, and free the sync object and the mutex of the kgd_mem
as well. With that VRAM usage returns to 65 MiB after the same test.
Fixes: 0e2e7c5b3d71 ("drm/amdgpu: Attach eviction fence on alloc")
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit b4d1eca2729840148ff2ea957724ce764ca5a94e)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index b59329c42597e..501b1a9f27070 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -2475,6 +2475,9 @@ static int import_obj_create(struct amdgpu_device *adev,
err_remove_mem:
remove_kgd_mem_from_kfd_bo_list(*mem, avm->process_info);
+ amdgpu_sync_free(&(*mem)->sync);
+ mutex_destroy(&(*mem)->lock);
+ dma_buf_put(dma_buf);
drm_vma_node_revoke(&obj->vma_node, drm_priv);
err_free_mem:
kfree(*mem);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 376/507] drm/amdgpu: unlock the VM and BO when attaching a KFD BO fails
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (374 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 375/507] drm/amdgpu: drop the dma-buf reference when a KFD import fails Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 377/507] drm/amdgpu: rewrite all PTEs of the BOs after a VM reset Greg Kroah-Hartman
` (130 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Felix Kuehling, Jesse Zhang,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <Jesse.Zhang@amd.com>
[ Upstream commit e0a1404b34e0002f03f7979cdb791a9b5c3963f5 ]
kfd_mem_attach() locks the page directory and the BO with a drm_exec
transaction on its stack, but leaves through the unwind label without
drm_exec_fini() when locking fails, e.g. when MAP_MEMORY_TO_GPU gets a
signal while the page directory or the BO is busy. Reservations already
acquired then remain locked with their ww_acquire_ctx pointing into the
expired stack frame.
With one thread doing GEM_VA map/unmap on the KFD VM and
another one mapping KFD BOs while getting SIGUSR1 every 20 us:
BUG: KASAN: stack-out-of-bounds in __ww_mutex_lock.constprop.0+0x34f5/0x3da0
ww_mutex_lock_interruptible+0x2f/0x150
drm_exec_lock_obj+0x107/0x2d0 [drm_exec]
kfd_mem_attach+0x4dd/0x1b60 [amdgpu]
and the process ends up in D state.
Finish the transaction before unwinding.
Fixes: fd1fa48b935f ("drm/amdgpu: lock both VM and BO in amdgpu_gem_object_open")
Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 7b885fa27e4b9fa5cbdc64e66fc35872aee296f5)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
index 501b1a9f27070..6c657d6060d65 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -975,11 +975,11 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem,
ret = amdgpu_vm_lock_pd(vm, &exec, 0);
drm_exec_retry_on_contention(&exec);
if (unlikely(ret))
- goto unwind;
+ goto unlock;
ret = drm_exec_lock_obj(&exec, &bo[i]->tbo.base);
drm_exec_retry_on_contention(&exec);
if (unlikely(ret))
- goto unwind;
+ goto unlock;
}
bo_va = amdgpu_vm_bo_find(vm, bo[i]);
@@ -1005,6 +1005,8 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem,
return 0;
+unlock:
+ drm_exec_fini(&exec);
unwind:
for (; i >= 0; i--) {
if (!attachment[i])
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 377/507] drm/amdgpu: rewrite all PTEs of the BOs after a VM reset
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (375 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 376/507] drm/amdgpu: unlock the VM and BO when attaching a KFD BO fails Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 378/507] drm/amdgpu: dont walk the CS chunks when allocating them failed Greg Kroah-Hartman
` (129 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Jesse Zhang,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <Jesse.Zhang@amd.com>
[ Upstream commit 71388e1ed836d7645b4807cead35edf24da00bcd ]
amdgpu_vm_bo_reset_state_machine() moves all idle vm_bos to needs_update
so that their mappings are written again, e.g. after a GPU reset lost
VRAM. Since commit 5be7f6720a0f ("drm/amdgpu: Only set bo->moved when
the BO was actually moved") amdgpu_vm_bo_needs_update() no longer sets
the moved flag, so amdgpu_vm_bo_update() writes nothing for the kernel
and always valid BOs. The same applies to vm_bos already on a
needs_update list, e.g. after an AMDGPU_VM_DELAY_UPDATE mapping, where
only the new mapping gets written.
An SDMA write to an always valid BO after a VRAM-losing reset faults:
amdgpu 0000:03:00.0: VRAM is lost due to GPU reset!
amdgpu 0000:03:00.0: [gfxhub] page fault (src_id:0 ring:40 vmid:7 pasid:9)
amdgpu 0000:03:00.0: in page starting at address 0x0000000100000000 from client 10
Set the moved flag for all vm_bos on the needs_update lists after moving
the idle ones there; the root PD still goes back to idle.
Fixes: 5be7f6720a0f ("drm/amdgpu: Only set bo->moved when the BO was actually moved")
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit d397f95f63cc0f711c3e8f2043edc59b575345ab)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index fc3a8d38d5149..c07f1115f6543 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -269,19 +269,27 @@ static void amdgpu_vm_bo_reset_state_machine(struct amdgpu_vm *vm)
/*
* Don't use list splice here, we need the special handling for the root
- * PD and set the moved flag appropriately.
+ * PD. All mappings must be written again, also of the vm_bos which are
+ * already waiting for an update of some of them, e.g. after a map with
+ * a delayed update, so set the moved flag for everything that needs an
+ * update.
*/
amdgpu_vm_assert_locked(vm);
list_for_each_entry_safe(vm_bo, tmp, &vm->kernel.idle, vm_status)
amdgpu_vm_bo_needs_update(vm_bo);
+ list_for_each_entry(vm_bo, &vm->kernel.needs_update, vm_status)
+ vm_bo->moved = true;
+
list_for_each_entry_safe(vm_bo, tmp, &vm->always_valid.idle, vm_status)
amdgpu_vm_bo_needs_update(vm_bo);
+ list_for_each_entry(vm_bo, &vm->always_valid.needs_update, vm_status)
+ vm_bo->moved = true;
spin_lock(&vm->individual_lock);
- list_for_each_entry_safe(vm_bo, tmp, &vm->individual.idle, vm_status) {
- vm_bo->moved = true;
+ list_for_each_entry_safe(vm_bo, tmp, &vm->individual.idle, vm_status)
list_move(&vm_bo->vm_status, &vm->individual.needs_update);
- }
+ list_for_each_entry(vm_bo, &vm->individual.needs_update, vm_status)
+ vm_bo->moved = true;
spin_unlock(&vm->individual_lock);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 378/507] drm/amdgpu: dont walk the CS chunks when allocating them failed
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (376 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 377/507] drm/amdgpu: rewrite all PTEs of the BOs after a VM reset Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 379/507] drm/amdgpu: Only enable HDMI audio if display supports it Greg Kroah-Hartman
` (128 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jesse Zhang, Christian König,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <Jesse.Zhang@amd.com>
[ Upstream commit ade92d50aad6799a5a9d7e73cd1604fd0576e656 ]
amdgpu_cs_pass1() sets p->nchunks before allocating p->chunks, and the
allocation failure path skips resetting it. amdgpu_cs_parser_fini() then
frees the kdata of nchunks chunks from a NULL array. On navi48 with the
chunk array allocation failed through failslab:
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
RIP: 0010:amdgpu_cs_parser_fini+0x35d/0x710 [amdgpu]
amdgpu_cs_ioctl+0xcae/0x7a20 [amdgpu]
drm_ioctl_kernel+0x180/0x320 [drm]
Set nchunks once the array exists.
Fixes: d38ceaf99ed0 ("drm/amdgpu: add core driver (v4)")
Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 0c828445757b86aaa3ed2638832d76f450022bdf)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index ba9c7dc084384..2739eab3e57ca 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -202,12 +202,13 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p,
if (IS_ERR(chunk_array))
return PTR_ERR(chunk_array);
- p->nchunks = cs->in.num_chunks;
- p->chunks = kvmalloc_objs(struct amdgpu_cs_chunk, p->nchunks);
+ /* parser_fini() walks nchunks chunks, set it once they exist */
+ p->chunks = kvmalloc_objs(struct amdgpu_cs_chunk, cs->in.num_chunks);
if (!p->chunks) {
ret = -ENOMEM;
goto free_chunk;
}
+ p->nchunks = cs->in.num_chunks;
for (i = 0; i < p->nchunks; i++) {
struct drm_amdgpu_cs_chunk __user *chunk_ptr = NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 379/507] drm/amdgpu: Only enable HDMI audio if display supports it
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (377 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 378/507] drm/amdgpu: dont walk the CS chunks when allocating them failed Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 380/507] drm/amdgpu: dont drop the gang dependency fence twice Greg Kroah-Hartman
` (127 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Alex Deucher, renpanpan, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: renpanpan <renpanpan@kylinos.cn>
[ Upstream commit 0de95c96655c8a12df62e47871016f49e5cd8618 ]
The amdgpu legacy DCE audio path (dce_v6/v8/v10) unconditionally calls
audio_enable(pin, true) at the end of afmt_setmode(), regardless of
whether the connected display advertises audio support in its EDID.
This causes a phantom HDMI audio output to appear for displays that
have no audio capability (no basic audio bit, no Audio Data Block in
EDID), because the GPU sets the AUDIO_ENABLED register bit, which
drives the HDA codec's ELDV pin sense, making the codec report the
jack as audio-available.
The radeon, nouveau, and dw-hdmi drivers all gate audio enablement on
display_info.has_audio. Apply the same check to amdgpu's DCE
afmt_setmode functions.
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: renpanpan <renpanpan@kylinos.cn>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 842a45c68e0355eea47796551c8761c0c77e8ce0)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 5 +++--
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c | 5 +++--
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 5 +++--
3 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index f2977fe6d8242..04b18056a9060 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -1705,8 +1705,9 @@ static void dce_v10_0_afmt_setmode(struct drm_encoder *encoder,
WREG32(mmAFMT_RAMP_CONTROL2 + dig->afmt->offset, 0x00000001);
WREG32(mmAFMT_RAMP_CONTROL3 + dig->afmt->offset, 0x00000001);
- /* enable audio after to setting up hw */
- dce_v10_0_audio_enable(adev, dig->afmt->pin, true);
+ /* Only enable audio if the display supports it */
+ if (connector->display_info.has_audio)
+ dce_v10_0_audio_enable(adev, dig->afmt->pin, true);
}
static void dce_v10_0_afmt_enable(struct drm_encoder *encoder, bool enable)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
index c68de0fe1d7d3..585b0a50279f9 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -1748,8 +1748,9 @@ static void dce_v6_0_afmt_setmode(struct drm_encoder *encoder,
dce_v6_0_audio_dp_enable(encoder, 1);
}
- /* enable audio after setting up hw */
- dce_v6_0_audio_enable(adev, dig->afmt->pin, true);
+ /* Only enable audio if the display supports it */
+ if (connector->display_info.has_audio)
+ dce_v6_0_audio_enable(adev, dig->afmt->pin, true);
}
static void dce_v6_0_afmt_enable(struct drm_encoder *encoder, bool enable)
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index c3906270f25ef..1390efa4ea515 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -1653,8 +1653,9 @@ static void dce_v8_0_afmt_setmode(struct drm_encoder *encoder,
WREG32(mmAFMT_RAMP_CONTROL2 + offset, 0x00000001);
WREG32(mmAFMT_RAMP_CONTROL3 + offset, 0x00000001);
- /* enable audio after setting up hw */
- dce_v8_0_audio_enable(adev, dig->afmt->pin, true);
+ /* Only enable audio if the display supports it */
+ if (connector->display_info.has_audio)
+ dce_v8_0_audio_enable(adev, dig->afmt->pin, true);
}
static void dce_v8_0_afmt_enable(struct drm_encoder *encoder, bool enable)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 380/507] drm/amdgpu: dont drop the gang dependency fence twice
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (378 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 379/507] drm/amdgpu: Only enable HDMI audio if display supports it Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 381/507] nvmet: dont return memory contents beyond valid data when reading ANA log page Greg Kroah-Hartman
` (126 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Jesse Zhang,
Alex Deucher, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang <Jesse.Zhang@amd.com>
[ Upstream commit 6d1f901a83603a7d314e4a756b416b11d8dc7e35 ]
drm_sched_job_add_dependency() drops the fence reference when it fails,
but amdgpu_cs_submit() drops it again, so the scheduled fence of a gang
member loses a reference it still needs.
A GFX+COMPUTE gang waiting for another context, with the
xarray node allocation for the leader's dependency failed through
failslab:
WARNING: drivers/dma-buf/dma-fence.c:589 at dma_fence_release+0x34d/0x730, CPU#1: amd_uapi_regres/2993
drm_sched_job_cleanup+0x2c2/0x340 [gpu_sched]
amdgpu_job_free+0xcb/0x3e0 [amdgpu]
amdgpu_cs_parser_fini+0x435/0x710 [amdgpu]
amdgpu_cs_ioctl+0xcd2/0x7a60 [amdgpu]
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000001: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f]
RIP: 0010:dma_fence_signal_timestamp_locked+0x1b8/0x610
Fixes: ed21f6c3fe42 ("drm/amdgpu: fix another missing fence reference in the CS code")
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Jesse Zhang <Jesse.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 5aa070a83c8378810b906cc8bfc650ce69822a7c)
Cc: stable@vger.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 2739eab3e57ca..a03a15cfca961 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1318,10 +1318,8 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
fence = &p->jobs[i]->base.s_fence->scheduled;
dma_fence_get(fence);
r = drm_sched_job_add_dependency(&leader->base, fence);
- if (r) {
- dma_fence_put(fence);
+ if (r)
return r;
- }
}
if (p->gang_size > 1) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 381/507] nvmet: dont return memory contents beyond valid data when reading ANA log page
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (379 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 380/507] drm/amdgpu: dont drop the gang dependency fence twice Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 382/507] arm64: suspend: Save and restore TPIDR2_EL0 across CPU suspend Greg Kroah-Hartman
` (125 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ewan D. Milne, Keith Busch,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ewan D. Milne <emilne@redhat.com>
[ Upstream commit 29b8758b4700357909f06705a0c48c7a60c556d5 ]
The host side does not know how much valid data will be returned by the target
so it will typically provide a buffer larger than the amount of valid data in
the ANA log page. The memory allocation used by the target does not guarantee
that prior kernel memory contents will not be returned past the end of the valid
page data. Fix this to ensure that the SGL is zeroed before copying the data.
Fixes: 72efd25dcf4f ("nvmet: add minimal ANA support")
Cc: stable@vger.kernel.org
Signed-off-by: Ewan D. Milne <emilne@redhat.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/target/admin-cmd.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index e76d4f7453004..3704493dbec97 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -543,6 +543,15 @@ static void nvmet_execute_get_log_page_ana(struct nvmet_req *req)
u16 ngrps = 0;
u16 status;
+ /*
+ * The header and one descriptor per enabled group are the only bytes
+ * written below; zero the whole transfer first so the unwritten tail
+ * does not leak stale kernel memory to the host.
+ */
+ status = nvmet_zero_sgl(req, 0, req->transfer_len);
+ if (status)
+ goto out;
+
status = NVME_SC_INTERNAL;
desc = kmalloc_flex(*desc, nsids, NVMET_MAX_NAMESPACES);
if (!desc)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 382/507] arm64: suspend: Save and restore TPIDR2_EL0 across CPU suspend
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (380 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 381/507] nvmet: dont return memory contents beyond valid data when reading ANA log page Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 383/507] arm64: mm: validate /dev/mem mmap ranges without overflow Greg Kroah-Hartman
` (124 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Will Deacon, Mark Brown, Wei Wang,
Catalin Marinas, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei Wang <wvw@google.com>
[ Upstream commit beeec04046227eba42b7cc5ab32498aa43da9632 ]
TPIDR2_EL0 is a live EL0 register on systems with SME, but
cpu_do_suspend()/cpu_do_resume() don't preserve it. Its value is
UNKNOWN after a warm reset, so the task that initiates suspend can
return to userspace with a corrupted TPIDR2_EL0.
Save and restore it alongside TPIDR_EL0 and TPIDRRO_EL0. The new slot
fits in existing padding, so sizeof(struct cpu_suspend_ctx) is
unchanged.
Fixes: a9d691585950 ("arm64/sme: Implement support for TPIDR2")
Cc: stable@vger.kernel.org
Acked-by: Will Deacon <will@kernel.org>
Reviewed-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Wei Wang <wvw@google.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/include/asm/suspend.h | 2 +-
arch/arm64/mm/proc.S | 8 ++++++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h
index e9ce68d50ba45..a5abf0615594d 100644
--- a/arch/arm64/include/asm/suspend.h
+++ b/arch/arm64/include/asm/suspend.h
@@ -2,7 +2,7 @@
#ifndef __ASM_SUSPEND_H
#define __ASM_SUSPEND_H
-#define NR_CTX_REGS 14
+#define NR_CTX_REGS 15
#define NR_CALLEE_SAVED_REGS 12
/*
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 12aacc74f7647..b1516630904d7 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -113,6 +113,10 @@ SYM_FUNC_START(cpu_do_suspend)
alternative_if ARM64_HAS_TCR2
mrs x2, REG_TCR2_EL1
str x2, [x0, #104]
+alternative_else_nop_endif
+alternative_if ARM64_SME
+ mrs_s x2, SYS_TPIDR2_EL0
+ str x2, [x0, #112]
alternative_else_nop_endif
ret
SYM_FUNC_END(cpu_do_suspend)
@@ -152,6 +156,10 @@ alternative_if ARM64_HAS_TCR2
ldr x2, [x0, #104]
msr REG_TCR2_EL1, x2
alternative_else_nop_endif
+alternative_if ARM64_SME
+ ldr x2, [x0, #112]
+ msr_s SYS_TPIDR2_EL0, x2
+alternative_else_nop_endif
msr sctlr_el1, x12
set_this_cpu_offset x13
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 383/507] arm64: mm: validate /dev/mem mmap ranges without overflow
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (381 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 382/507] arm64: suspend: Save and restore TPIDR2_EL0 across CPU suspend Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 384/507] nvme-pci: add NVME_QUIRK_DMAPOOL_ALIGN_512 for KIOXIA XG10d Greg Kroah-Hartman
` (123 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhao Gongyi, Catalin Marinas,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Gongyi <zhaogongyi@bytedance.com>
[ Upstream commit b0958b1397fb5ffdb995c0ccc74349841929c08d ]
An arm64 syzkaller reproducer creates a FUSE character device with
major:minor 1:1, so opening it uses the /dev/mem file operations. It
maps one page from offset 0xfffffffffffff000 at user address zero.
The next openat() with a NULL pathname triggers a synchronous external
abort (SEA, ESR 0x96000010) in strncpy_from_user() via do_getname(),
panicking the kernel.
valid_mmap_phys_addr_range() checks the exclusive end by adding the
mapping size to the starting address. For this offset, the sum wraps
to zero and passes the PHYS_MASK test, allowing an out-of-range PFN to
reach remap_pfn_range(). The inclusive-end overflow check in
mmap_mem_prepare() does not catch it because the end is ULONG_MAX.
Reject starting PFNs outside PHYS_MASK and compare the inclusive length
against the remaining physical range without overflowing. This also
allows mappings that end exactly at PHYS_MASK, which the old check
incorrectly rejects.
Fixes: 1d18c47c735e ("arm64: MMU fault handling and page table management")
Cc: stable@vger.kernel.org
Signed-off-by: Zhao Gongyi <zhaogongyi@bytedance.com>
[catalin.marinas@arm.com: changed the check to look more like __access_ok()]
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/mm/mmap.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index 32e0771d6477b..e212270d4e09a 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -61,7 +61,9 @@ int valid_phys_addr_range(phys_addr_t addr, size_t size)
*/
int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
{
- return !(((pfn << PAGE_SHIFT) + size) & ~PHYS_MASK);
+ const phys_addr_t limit = PHYS_MASK + 1;
+
+ return size <= limit && pfn <= (limit - size) >> PAGE_SHIFT;
}
static int __init adjust_protection_map(void)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 384/507] nvme-pci: add NVME_QUIRK_DMAPOOL_ALIGN_512 for KIOXIA XG10d
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (382 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 383/507] arm64: mm: validate /dev/mem mmap ranges without overflow Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 385/507] ovl: look up the index by the decoded origin Greg Kroah-Hartman
` (122 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sasha Levin, Keith Busch
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
[ Upstream commit c64d9b2c1f4fd1d8fa52dab37b48428a99c4d58d ]
The KIOXIA XG10d reads past the end of a PRP list that completely fills
a 256 byte small pool block. When that block is the last one in its
dmapool page, the read lands on the next page, which usually isn't
mapped. The IOMMU faults it and the controller craps itself:
arm-smmu-v3 arm-smmu-v3.0.auto: event: F_TRANSLATION client: 0001:09:00.0 sid: 0x20900 ssid: 0x0 iova: 0xff7fe000 ipa: 0x0
nvme nvme0: controller is down; will reset: CSTS=0xffffffff, PCI_STATUS=0xffff
Filling the block requires a slightly larger write, and those became common
with commit 2e8e30b3cf9f ("Revert "nvme-pci: clamp max_hw_sectors based on
DMA optimized limitation"").
Do what we do for other disks and use 512 byte aligned small pool blocks
for this controller.
Cc: stable@vger.kernel.org # 6.4.x
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/pci.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 77317e5d00f9f..b7c5a18b899b9 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -4198,6 +4198,8 @@ static const struct pci_device_id nvme_id_table[] = {
.driver_data = NVME_QUIRK_BOGUS_NID, },
{ PCI_DEVICE(0x1344, 0x6004), /* Micron 4100AT */
.driver_data = NVME_QUIRK_DMAPOOL_ALIGN_512, },
+ { PCI_DEVICE(0x1e0f, 0x0032), /* KIOXIA XG10d */
+ .driver_data = NVME_QUIRK_DMAPOOL_ALIGN_512, },
{ PCI_DEVICE(0x1c5c, 0x1504), /* SK Hynix PC400 */
.driver_data = NVME_QUIRK_DISABLE_WRITE_ZEROES, },
{ PCI_DEVICE(0x1c5c, 0x174a), /* SK Hynix P31 SSD */
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 385/507] ovl: look up the index by the decoded origin
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (383 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 384/507] nvme-pci: add NVME_QUIRK_DMAPOOL_ALIGN_512 for KIOXIA XG10d Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 386/507] selftests/fscontext_ns: expect EINVAL for overlay descendant userns create Greg Kroah-Hartman
` (121 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Amir Goldstein,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit 520ef67f47f69255695859b0008281a384d0bc20 ]
A file opened by file handle on an overlay with nfs_export=on can show
the stale lower data of a file that was copied up to the upper layer.
While the file opened this way stays in the inode cache, a lookup of the
copied up file by path fails with ESTALE for all users. The open can
also succeed for a file that was removed, where it has to fail with
ESTALE. This happens with a handle that has one byte changed. The handle
comes from an NFS client, or from a process that calls
open_by_handle_at() with CAP_DAC_READ_SEARCH in the initial user
namespace.
When a file in a lower layer is about to be modified, overlayfs first
copies it to the upper layer (copy up). With nfs_export=on, each copy up
also creates an entry in the index directory, a directory that overlayfs
keeps for itself on the upper filesystem.
The handle of an overlay file that comes from a lower layer wraps the
handle of its lower inode. Overlayfs calls this lower inode the origin.
The overlay handle stays valid after a copy up.
To decode such a handle, ovl_lower_fh_to_d() first decodes the wrapped
handle to the origin. If no overlay inode is cached for the origin, it
looks in the index directory:
- An index entry there leads to the upper file.
- A whiteout, the marker that overlayfs uses for a removed file, means
that the overlay file was removed.
The name of an index entry is the handle that copy up encoded for the
origin, as a hex string.
ovl_lower_fh_to_d() builds the name for this lookup from the bytes that
the caller passed in. But handles with different bytes can decode to the
same inode:
- Overlayfs ignores some flag bits of the handle.
- A lower filesystem can accept a different fid type, extra bytes, or
generation 0 for any generation.
Such a handle decodes to the origin but misses the index entry or the
whiteout. So the decode returns an overlay inode that has only the lower
file.
While that inode is cached, a path lookup of a copied up file fails with
ESTALE, since the upper file that the lookup finds does not match the
cached inode, which has none.
Reproduced on tmpfs and on ext4 with open_by_handle_at(), after a copy
up and a mount cycle. A handle in which one flag bit, the fid type, the
length or the generation was changed read the old lower data, and path
lookups returned ESTALE.
Fix this by re-encoding the decoded origin and building the index name
from that handle.
Fixes: f71bd9cfb692 ("ovl: decode indexed non-dir file handles")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/filesystems/overlayfs.rst | 3 ++-
fs/overlayfs/export.c | 4 ++--
fs/overlayfs/namei.c | 13 ++++++++++---
fs/overlayfs/overlayfs.h | 2 +-
4 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/Documentation/filesystems/overlayfs.rst b/Documentation/filesystems/overlayfs.rst
index 16c35b491dad4..4c241d220bc23 100644
--- a/Documentation/filesystems/overlayfs.rst
+++ b/Documentation/filesystems/overlayfs.rst
@@ -731,7 +731,8 @@ When decoding an overlay file handle, the following steps are followed:
1. Find underlying layer by UUID and path type information.
2. Decode the underlying filesystem file handle to underlying dentry.
- 3. For a lower file handle, lookup the handle in index directory by name.
+ 3. For a lower file handle, encode the decoded underlying inode again and
+ lookup that handle in index directory by name.
4. If a whiteout is found in index, return ESTALE. This represents an
overlay object that was deleted after its file handle was encoded.
5. For a non-directory, instantiate a disconnected overlay dentry from the
diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c
index 9aae20c59608a..bd998a3d8b95c 100644
--- a/fs/overlayfs/export.c
+++ b/fs/overlayfs/export.c
@@ -713,9 +713,9 @@ static struct dentry *ovl_lower_fh_to_d(struct super_block *sb,
}
}
- /* Then lookup indexed upper/whiteout by origin fh */
+ /* Then lookup indexed upper/whiteout by origin */
if (ovl_indexdir(sb)) {
- index = ovl_get_index_fh(ofs, fh);
+ index = ovl_get_index_origin(ofs, origin.dentry);
err = PTR_ERR(index);
if (IS_ERR(index)) {
index = NULL;
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index c6127edb9be95..64d63b260709c 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -781,14 +781,21 @@ int ovl_get_index_name(struct ovl_fs *ofs, struct dentry *origin,
return err;
}
-/* Lookup index by file handle for NFS export */
-struct dentry *ovl_get_index_fh(struct ovl_fs *ofs, struct ovl_fh *fh)
+/*
+ * Lookup index by decoded origin for NFS export.
+ *
+ * The name of an index is the hex of the file handle that copy up encoded.
+ * The bytes of the handle to decode cannot be used as the name, because a
+ * lower fs may decode many handles to the same inode. For example, it may
+ * ignore the fid type, extra fid bytes or a zero generation.
+ */
+struct dentry *ovl_get_index_origin(struct ovl_fs *ofs, struct dentry *origin)
{
struct dentry *index;
struct qstr name;
int err;
- err = ovl_get_index_name_fh(fh, &name);
+ err = ovl_get_index_name(ofs, origin, &name);
if (err)
return ERR_PTR(err);
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index b32089a104291..a5aa22cc79a83 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -748,7 +748,7 @@ int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index);
int ovl_get_index_name_fh(const struct ovl_fh *fh, struct qstr *name);
int ovl_get_index_name(struct ovl_fs *ofs, struct dentry *origin,
struct qstr *name);
-struct dentry *ovl_get_index_fh(struct ovl_fs *ofs, struct ovl_fh *fh);
+struct dentry *ovl_get_index_origin(struct ovl_fs *ofs, struct dentry *origin);
struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
struct dentry *origin, bool verify);
int ovl_path_next(int idx, struct dentry *dentry, struct path *path,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 386/507] selftests/fscontext_ns: expect EINVAL for overlay descendant userns create
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (384 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 385/507] ovl: look up the index by the decoded origin Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 387/507] l2tp: only return sessions of the given tunnel in l2tp_session_get() Greg Kroah-Hartman
` (120 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, kernel test robot, Amir Goldstein,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amir Goldstein <amir73il@gmail.com>
[ Upstream commit db1c5da238dc80a61ab429a7b71b0e2835766c45 ]
Commit a518e63c3775 ("ovl: return EINVAL instead of EIO in case of
mismatched user_ns") changed the errno for completing an overlay
fscontext from another user namespace. Update the overlay test variant
to match binfmt_misc.
Reported-by: kernel test robot <yi1.lai@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202611020115.2281e158-lkp@intel.com
Fixes: a518e63c3775 ("ovl: return EINVAL instead of EIO in case of mismatched user_ns")
Cc: stable@vger.kernel.org
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../selftests/filesystems/fscontext_ns/fscontext_ns_test.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/filesystems/fscontext_ns/fscontext_ns_test.c b/tools/testing/selftests/filesystems/fscontext_ns/fscontext_ns_test.c
index 0f30a3e6e197d..535bf1f4e1a30 100644
--- a/tools/testing/selftests/filesystems/fscontext_ns/fscontext_ns_test.c
+++ b/tools/testing/selftests/filesystems/fscontext_ns/fscontext_ns_test.c
@@ -193,7 +193,7 @@ FIXTURE_VARIANT_ADD(fscontext_ns, binfmt_misc) {
FIXTURE_VARIANT_ADD(fscontext_ns, overlay) {
.fsname = "overlay",
- .expected_errno = EIO,
+ .expected_errno = EINVAL,
};
TEST_F(fscontext_ns, create_from_descendant_userns)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 387/507] l2tp: only return sessions of the given tunnel in l2tp_session_get()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (385 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 386/507] selftests/fscontext_ns: expect EINVAL for overlay descendant userns create Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 388/507] drm/nouveau/nvkm: clear use.enabled when subdev init fails Greg Kroah-Hartman
` (119 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hengyu Liang, Guillaume Nault,
Paolo Abeni, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengyu Liang <hengyul@cs.unc.edu>
[ Upstream commit a75facf4bb3e866103ddca4f47a6f3ca4b090d8b ]
Commit 5f77c18ea556 ("l2tp: use IDR for all session lookups") made
pppol2tp_connect() and the netlink session commands find sessions with
l2tp_session_get(), passing the socket of the tunnel they name.
L2TPv3 session IDs are unique per network namespace, except that
sessions carried over UDP are only unique per UDP socket, the socket of
their tunnel. However, l2tp_v3_session_get() only checks the socket when
another session has the same session ID. Otherwise it returns the
session, whichever tunnel it belongs to. As of now, a session command
that names the wrong tunnel acts on a session of another tunnel, and a
PPPoL2TP socket for a second L2TPv3 tunnel fails with EEXIST, because it
finds session 0 of the first tunnel.
The issue can be reproduced with:
ip l2tp add tunnel tunnel_id 3 peer_tunnel_id 3 encap udp \
local 127.0.0.1 remote 127.0.0.1 udp_sport 5003 udp_dport 6003
ip l2tp add tunnel tunnel_id 4 peer_tunnel_id 4 encap udp \
local 127.0.0.1 remote 127.0.0.1 udp_sport 5004 udp_dport 6004
ip l2tp add session tunnel_id 3 session_id 7 peer_session_id 7
ip l2tp del session tunnel_id 4 session_id 7
ip l2tp show session
Before that commit, the delete fails with "No such device", and session
7 of tunnel 3 is still listed. After that commit, the delete succeeds,
and session 7 of tunnel 3 is gone.
This patch will make l2tp_session_get() return NULL when the L2TPv3
session it finds does not belong to the given socket. The receive path
calls l2tp_v3_session_get() directly and is not changed.
Fixes: 5f77c18ea556 ("l2tp: use IDR for all session lookups")
Cc: stable@vger.kernel.org
Signed-off-by: Hengyu Liang <hengyul@cs.unc.edu>
Acked-by: Guillaume Nault <gnault@redhat.com>
Link: https://patch.msgid.link/20261030032617.4065353-1-hengyul@cs.unc.edu
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/l2tp/l2tp_core.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 7e042a3e648ce..0cd3e38bf662f 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -315,10 +315,19 @@ EXPORT_SYMBOL_GPL(l2tp_v2_session_get);
struct l2tp_session *l2tp_session_get(const struct net *net, struct sock *sk, int pver,
u32 tunnel_id, u32 session_id)
{
+ struct l2tp_session *session;
+
if (pver == L2TP_HDR_VER_2)
return l2tp_v2_session_get(net, tunnel_id, session_id);
- else
- return l2tp_v3_session_get(net, sk, session_id);
+
+ /* l2tp_v3_session_get() doesn't check sk if the ID hasn't collided */
+ session = l2tp_v3_session_get(net, sk, session_id);
+ if (session && session->tunnel->sock != sk) {
+ l2tp_session_put(session);
+ return NULL;
+ }
+
+ return session;
}
EXPORT_SYMBOL_GPL(l2tp_session_get);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 388/507] drm/nouveau/nvkm: clear use.enabled when subdev init fails
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (386 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 387/507] l2tp: only return sessions of the given tunnel in l2tp_session_get() Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 389/507] drm/dp: keep MOT set between messages when no_zero_sized is set Greg Kroah-Hartman
` (118 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Rosen Penev, Dave Airlie,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <rosenp@gmail.com>
[ Upstream commit a1f7f37417bacf2eaf80a8ce6b598b1fa56f8906 ]
On Kepler boards without the video decode falcon firmware installed
(msvld/mspdec/msppp), every other VA-API decode attempt binds to an
engine with no ucode loaded. The submitted work never completes, which
leads to a context switch timeout, a channel recovery that cannot reset
the engine, and eviction waits on fences that never signal. The process
ends up stuck in D state, or killed by SIGBUS when it touches a buffer
evicted after the wait times out:
msvld: unable to load firmware data
msvld: init failed, -19
fifo: SCHED_ERROR 0a [CTXSW_TIMEOUT]
vo[5444]: channel 14 killed!
WARNING: drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c:117 at nvkm_runl_rc+0x2a4/0x3b0 [nouveau]
[TTM] Buffer eviction failed
WARNING: drivers/gpu/drm/nouveau/nouveau_bo.c:1092 at nouveau_bo_move_ntfy.part.0+0x9b/0x100 [nouveau]
Tracing nvkm_subdev_ref() and nvkm_subdev_init_() shows the pattern:
a reference taken with enabled=0 runs nvkm_falcon_init(), which
returns -ENODEV; the next reference sees enabled=1 and succeeds
without running it.
Clear use.enabled when init() fails, so that every later reference
retries init and fails cleanly. The other readers of use.enabled are
fini() handlers that use it to skip teardown, which they now also do
after a failed init().
On a GK107 (Quadro K1100M) without video firmware, playing H.264 with
mpv --hwdec=auto: without this patch the GPU channel is killed within a
minute and mpv hangs; with it, VA-API decoder creation fails, mpv falls
back to software decoding, and no faults are logged.
Fixes: 8478cd5a740a ("drm/nouveau/nvkm: add locking to subdev/engine init paths")
Cc: stable@vger.kernel.org
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Link: https://patch.msgid.link/20261101200428.16959-1-rosenp@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/nouveau/nvkm/core/subdev.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c
index aab5a73f467a1..ff6858f5e5d32 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c
@@ -157,6 +157,7 @@ nvkm_subdev_init_(struct nvkm_subdev *subdev)
ret = subdev->func->init(subdev);
if (ret) {
nvkm_error(subdev, "init failed, %d\n", ret);
+ subdev->use.enabled = false;
return ret;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 389/507] drm/dp: keep MOT set between messages when no_zero_sized is set
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (387 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 388/507] drm/nouveau/nvkm: clear use.enabled when subdev init fails Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 390/507] drm/nouveau/devinit/gf100-: try to avoid double-running vbios scripts Greg Kroah-Hartman
` (117 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Finn Zeruhn, Dave Airlie,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Finn Zeruhn <fzeruhn@icloud.com>
[ Upstream commit 06bb2e5c71e9983519929a8482bea89da6d80ad8 ]
When aux->no_zero_sized is set, drm_dp_i2c_xfer() cannot use a bare
address packet to close the transaction, so it clears MOT on the last
data packet instead. The check only looks at the position within the
current i2c_msg, so MOT is cleared at the end of every message and each
one is terminated by an I2C stop.
This breaks E-DDC reads of EDID blocks 2 and up. Those are read as three
messages: a write of the segment pointer to 0x30, a write of the offset
to 0x50, and the read. The stop after the first message resets the
segment pointer, so the read returns segment 0 again.
On a Pimax Dream Air (three EDID blocks, native timings in a DisplayID
extension in block 2) connected to an RTX 5070 Ti with nouveau, block 2
reads back as a copy of block 0. The checksum is valid, so nothing is
reported, and the connector only offers fallback modes.
Clear MOT only on the last packet of the last message, as the commit
that added the option describes. With this, block 2 reads correctly and
the native 7104x3840 modes are listed for the Dream Air.
The same problem was pointed out by the Sashiko review of the patch that
sets no_zero_sized for all DisplayPort connectors in nouveau.
Fixes: f0ddbb1eed18 ("drm/dp: add option to disable zero sized address only transactions.")
Link: https://lore.kernel.org/all/20260827015758.0B4FB1F000E9@smtp.kernel.org/
Cc: stable@vger.kernel.org
Signed-off-by: Finn Zeruhn <fzeruhn@icloud.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Link: https://patch.msgid.link/20261002212833.9674-1-fzeruhn@icloud.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/display/drm_dp_helper.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
index 488fd123a01ad..7676285c19f87 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -2192,7 +2192,8 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
msg.buffer = msgs[i].buf + j;
msg.size = min(transfer_size, msgs[i].len - j);
- if (j + msg.size == msgs[i].len && aux->no_zero_sized)
+ if (aux->no_zero_sized && i == num - 1 &&
+ j + msg.size == msgs[i].len)
msg.request &= ~DP_AUX_I2C_MOT;
err = drm_dp_i2c_drain_msg(aux, &msg);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 390/507] drm/nouveau/devinit/gf100-: try to avoid double-running vbios scripts
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (388 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 389/507] drm/dp: keep MOT set between messages when no_zero_sized is set Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 391/507] ALSA: ump: Fix dropped data bytes at UMP System message conversion Greg Kroah-Hartman
` (116 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ilia Mirkin, Dave Airlie,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilia Mirkin <imirkin@alum.mit.edu>
[ Upstream commit 2139cb633d48ebbbaec88d2e5a8ebe8e774df4fb ]
Turns out some VBIOSes don't actually set the bit in question in 2240c.
Use the nv50-style detection to try avoiding running the vbios twice.
Fixes: a6a0f67ca7aa ("drm/nouveau/devinit/gf100-: detect if BIOS invoked devinit")
Link: https://bugs.freedesktop.org/show_bug.cgi?id=97620
Cc: <stable@vger.kernel.org> # v4.6+
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Link: https://patch.msgid.link/20170128205347.17453-1-imirkin@alum.mit.edu
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../drm/nouveau/nvkm/subdev/devinit/gf100.c | 20 +++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c
index 5368e705e7fd6..186e09ea0cb10 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gf100.c
@@ -27,6 +27,7 @@
#include <subdev/bios/init.h>
#include <subdev/bios/pll.h>
#include <subdev/clk/pll.h>
+#include <subdev/vga.h>
int
gf100_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq)
@@ -99,6 +100,25 @@ gf100_devinit_preinit(struct nvkm_devinit *base)
* can use it as a reliable way to know whether we should run devinit.
*/
base->post = ((nvkm_rd32(device, 0x2240c) & BIT(1)) == 0);
+
+ /*
+ * However some VBIOS init sequences miss this bit. So fall back to
+ * the nv50 method of checking if the bit is not set. Running the
+ * VBIOS multiple times may have detrimental effects.
+ */
+ if (base->post) {
+ u64 disable = nvkm_devinit_disable(base);
+ /* magic to detect whether or not x86 vbios code has
+ * executed the devinit scripts to initialise the
+ * board. only works if there's a display engine.
+ */
+ if (!(disable & (1ULL << NVKM_ENGINE_DISP))) {
+ if (nvkm_rdvgac(device, 0, 0x00) ||
+ nvkm_rdvgac(device, 0, 0x1a)) {
+ base->post = false;
+ }
+ }
+ }
}
static const struct nvkm_devinit_func
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 391/507] ALSA: ump: Fix dropped data bytes at UMP System message conversion
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (389 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 390/507] drm/nouveau/devinit/gf100-: try to avoid double-running vbios scripts Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 392/507] ALSA: hda/realtek: Enable bass speakers on Alienware m17 R3 Greg Kroah-Hartman
` (115 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, HyeongJun An, Takashi Iwai,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: HyeongJun An <sammiee5311@gmail.com>
[ Upstream commit ac1cac4c1f1b143650f7261ae78f64a3e22fa4d6 ]
The cvt_ump_system_to_legacy() function switches on
ump_message_status_code(), which returns only the upper 4 bits of the
status. The case labels are the full 0xf1, 0xf2 and 0xf3 values, so they
never match. MIDI Time Code, Song Position and Song Select are converted
to the status byte alone, and their data bytes are lost.
Switch on the full status byte in buf[0] instead.
Both callers of snd_ump_convert_from_ump() pass the result on as is: the
legacy rawmidi input of a UMP endpoint, and the MIDI 1.0 path of the
f_midi2 USB gadget.
Fixes: 0b5288f5fe63 ("ALSA: ump: Add legacy raw MIDI support")
Cc: stable@vger.kernel.org
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Link: https://patch.msgid.link/20261029130538.1985867-1-sammiee5311@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/core/ump_convert.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/core/ump_convert.c b/sound/core/ump_convert.c
index 0a7972d91ec52..ecbd894f4c83a 100644
--- a/sound/core/ump_convert.c
+++ b/sound/core/ump_convert.c
@@ -69,7 +69,7 @@ static u32 upscale_14_to_32bit(u16 src)
static int cvt_ump_system_to_legacy(u32 data, unsigned char *buf)
{
buf[0] = ump_message_status_channel(data);
- switch (ump_message_status_code(data)) {
+ switch (buf[0]) {
case UMP_SYSTEM_STATUS_MIDI_TIME_CODE:
case UMP_SYSTEM_STATUS_SONG_SELECT:
buf[1] = (data >> 8) & 0x7f;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 392/507] ALSA: hda/realtek: Enable bass speakers on Alienware m17 R3
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (390 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 391/507] ALSA: ump: Fix dropped data bytes at UMP System message conversion Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 393/507] ALSA: cs46xx: Handle SCB creation failures before dereferencing Greg Kroah-Hartman
` (114 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Simpson, Takashi Iwai,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Simpson <chris@nilk.net>
[ Upstream commit eb296114d5ba4d335a640dbbbbc9618fded0ffe7 ]
The Alienware m17 R3 (ALC289, PCI SSID 1028:09d1) has a second speaker
pair, the bass speakers, on pin 0x17, which the BIOS leaves unconnected
(0x411111f0). No PCI SSID quirk matches the machine, so it gets
ALC269_FIXUP_DELL4_MIC_NO_PRESENCE from the fallback pin quirk table,
and only the speakers on pin 0x14 play.
Use ALC289_FIXUP_DUAL_SPK, as on the Alienware x16 R2 and Dell XPS 15
9510/9520: it sets pin 0x17 up as a speaker on DAC 0x02, so one volume
control covers both pairs, and chains to
ALC269_FIXUP_DELL4_MIC_NO_PRESENCE, so the headset mic setup is
unchanged.
Tested on an Alienware m17 R3 (BIOS 1.38.0), Linux 7.3 with this change
applied: the bass speakers play, and volume and mute cover both pairs,
also after suspend and resume. Headphones and a headset mic were not
tested.
I used Claude Code (Claude Opus 5.5) to find the unused pin, pick the
existing fixup and write this patch and changelog; I did the listening
tests myself.
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Chris Simpson <chris@nilk.net>
Link: https://patch.msgid.link/20261029-alc289-m17r3-v1-1-5d3eac605e7a@nilk.net
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/hda/codecs/realtek/alc269.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c
index 68650004ce0f9..1288b180df752 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -7335,6 +7335,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x097e, "Dell Precision", ALC289_FIXUP_DUAL_SPK),
SND_PCI_QUIRK(0x1028, 0x098d, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x09bf, "Dell Precision", ALC233_FIXUP_ASUS_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1028, 0x09d1, "Alienware m17 R3", ALC289_FIXUP_DUAL_SPK),
SND_PCI_QUIRK(0x1028, 0x0a2e, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC),
SND_PCI_QUIRK(0x1028, 0x0a30, "Dell", ALC236_FIXUP_DELL_AIO_HEADSET_MIC),
SND_PCI_QUIRK(0x1028, 0x0a38, "Dell Latitude 7520", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE_QUIET),
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 393/507] ALSA: cs46xx: Handle SCB creation failures before dereferencing
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (391 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 392/507] ALSA: hda/realtek: Enable bass speakers on Alienware m17 R3 Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 394/507] ALSA: bcd2000: Fix use-after-free of MIDI URBs on file close Greg Kroah-Hartman
` (113 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Kazinsky, Takashi Iwai,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Kazinsky <a.kazinsky@ideco.ru>
[ Upstream commit 023d3e1176202339cd94a3d732e3aec74e36ba22 ]
With CONFIG_PM_SLEEP enabled, cs46xx_dsp_create_scb() can return NULL
if kmemdup() fails to allocate the SCB data saved for resume.
cs46xx_dsp_scb_and_task_init() and _dsp_create_generic_scb() dereference
the returned pointer without checking it, causing a NULL pointer
dereference on allocation failure.
Check both return values before accessing the SCB descriptors.
Return -ENOMEM when creating the null SCB fails and propagate NULL
from _dsp_create_generic_scb().
Found by Linux Verification Center (linuxtesting.org) with SVACE
static analysis tool.
Fixes: 41116e926cb9 ("ALSA: cs46xx - Fix suspend/resume with new DSP")
Cc: stable@vger.kernel.org
Signed-off-by: Alex Kazinsky <a.kazinsky@ideco.ru>
Link: https://patch.msgid.link/20261030142529.415697-1-a.kazinsky@ideco.ru
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/pci/cs46xx/dsp_spos.c | 2 ++
sound/pci/cs46xx/dsp_spos_scb_lib.c | 3 ++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index a77e6f5a14ada..57b0a6321e0b6 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -1104,6 +1104,8 @@ int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip)
null_scb.entry_point = null_algorithm->address;
ins->the_null_scb = cs46xx_dsp_create_scb(chip, "nullSCB", (u32 *)&null_scb, NULL_SCB_ADDR);
+ if (!ins->the_null_scb)
+ return -ENOMEM;
ins->the_null_scb->task_entry = null_algorithm;
ins->the_null_scb->sub_list_ptr = ins->the_null_scb;
ins->the_null_scb->next_scb_ptr = ins->the_null_scb;
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index fd19365026b4a..c5208e42cde95 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -274,7 +274,8 @@ _dsp_create_generic_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u
dev_dbg(chip->card->dev, "dsp_spos: creating SCB <%s>\n", name);
scb = cs46xx_dsp_create_scb(chip,name,scb_data,dest);
-
+ if (!scb)
+ return NULL;
scb->sub_list_ptr = ins->the_null_scb;
scb->next_scb_ptr = ins->the_null_scb;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 394/507] ALSA: bcd2000: Fix use-after-free of MIDI URBs on file close
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (392 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 393/507] ALSA: cs46xx: Handle SCB creation failures before dereferencing Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 395/507] ALSA: usx2y: Refuse a retried DSP load after a failure Greg Kroah-Hartman
` (112 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, YuanZhe Liu, Takashi Iwai,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: YuanZhe Liu <25031212351@stu.xidian.edu.cn>
[ Upstream commit f6c7bb1f0799591a62be75b9bcf84245b4f208b7 ]
bcd2000_disconnect() calls snd_card_disconnect(), which only prevents
new opens, and then frees the MIDI URBs. A rawmidi file that was
already open can still be closed afterwards, and its close callback,
bcd2000_midi_output_close(), calls usb_kill_urb() on midi_out_urb.
The URB pointers are cleared on disconnect and their accesses are
serialized with midi_lock, but bcd2000_midi_output_close() reads
midi_out_urb without that lock. The check can therefore pass just
before the pointer is cleared, and usb_kill_urb() then runs on the URB
that has already been freed:
BUG: KASAN: slab-use-after-free in usb_kill_urb+0x74/0x80
Read of size 8 at addr ffff8880078e7d40
usb_kill_urb
bcd2000_midi_output_close
close_substream
rawmidi_release_priv
snd_rawmidi_release
Allocated by: usb_alloc_urb <- bcd2000_init_midi <- bcd2000_probe
Freed by: usb_free_urb <- bcd2000_midi_free
<- bcd2000_disconnect
Take the lock in bcd2000_midi_output_close() and reference the URB with
usb_get_urb() before releasing it. The URB then stays valid until
usb_put_urb() after usb_kill_urb() has returned, even if a disconnect
frees it in the meantime. usb_kill_urb() itself cannot run under
midi_lock, as the completion handler takes the same lock.
Fixes: b47a22290d58 ("ALSA: MIDI driver for Behringer BCD2000 USB device")
Cc: stable@vger.kernel.org
Signed-off-by: YuanZhe Liu <25031212351@stu.xidian.edu.cn>
Link: https://patch.msgid.link/20261031190936.5696-1-25031212351@stu.xidian.edu.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/bcd2000/bcd2000.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c
index 2bd49bf827489..0fd086cac9552 100644
--- a/sound/usb/bcd2000/bcd2000.c
+++ b/sound/usb/bcd2000/bcd2000.c
@@ -183,10 +183,24 @@ static int bcd2000_midi_output_open(struct snd_rawmidi_substream *substream)
static int bcd2000_midi_output_close(struct snd_rawmidi_substream *substream)
{
struct bcd2000 *bcd2k = substream->rmidi->private_data;
+ struct urb *urb = NULL;
- if (bcd2k->midi_out_active && bcd2k->midi_out_urb) {
- usb_kill_urb(bcd2k->midi_out_urb);
- bcd2k->midi_out_active = 0;
+ /*
+ * Reference the URB under the lock so that it stays valid until
+ * usb_kill_urb() returns, even if a disconnect frees it in the
+ * meantime. usb_kill_urb() cannot run under the lock, as the
+ * completion handler takes the same lock.
+ */
+ scoped_guard(spinlock_irqsave, &bcd2k->midi_lock) {
+ if (bcd2k->midi_out_active && bcd2k->midi_out_urb) {
+ urb = usb_get_urb(bcd2k->midi_out_urb);
+ bcd2k->midi_out_active = 0;
+ }
+ }
+
+ if (urb) {
+ usb_kill_urb(urb);
+ usb_put_urb(urb);
}
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 395/507] ALSA: usx2y: Refuse a retried DSP load after a failure
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (393 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 394/507] ALSA: bcd2000: Fix use-after-free of MIDI URBs on file close Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 396/507] ALSA: usb-audio: qcom: Check the return value of qmi_handle_init() Greg Kroah-Hartman
` (111 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bin Yu, Cheng Wen, YuanZhe Liu,
Takashi Iwai, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: YuanZhe Liu <25031212351@stu.xidian.edu.cn>
[ Upstream commit 1f8101b6adc87a3ddbd51fcb6609251591758026 ]
snd_usx2y_hwdep_dsp_load() sets up the asynchronous sequence URBs and
the interrupt URB when the FPGA firmware image with index 1 is loaded,
and then creates the ALSA devices. If usx2y_in04_init() or
usx2y_create_alsa_devices() fails, the URBs that were already set up
are left in place.
The core keeps the index unloaded when the callback fails, so user
space may issue the same request again. The second attempt then enters
usx2y_async_seq04_init() or usx2y_in04_init() with the URBs still
allocated and trips WARN_ON(usx2y->as04.buffer) or
WARN_ON(usx2y->in04_urb).
The URBs cannot be released at this point: the card may already have
registered PCM devices that user space can still open, and the
disconnect handler accesses the URBs without holding the DSP lock.
Mark the chip as hung instead, so that a retried request is refused
with -ENODEV and the assertions keep their meaning. The URBs are
released by snd_usx2y_card_private_free() when the card is freed.
A failing usx2y_async_seq04_init() still releases its own URBs, so that
path remains retryable.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Co-developed-by: Bin Yu <byu@xidian.edu.cn>
Signed-off-by: Bin Yu <byu@xidian.edu.cn>
Co-developed-by: Cheng Wen <wencheng@xidian.edu.cn>
Signed-off-by: Cheng Wen <wencheng@xidian.edu.cn>
Signed-off-by: YuanZhe Liu <25031212351@stu.xidian.edu.cn>
Link: https://patch.msgid.link/20261031191557.8460-1-25031212351@stu.xidian.edu.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/usx2y/usX2Yhwdep.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 7f153a2fcdd81..3800c5b5887c8 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -179,6 +179,9 @@ static int snd_usx2y_hwdep_dsp_load(struct snd_hwdep *hw,
int lret, err;
char *buf;
+ if (priv->chip_status & USX2Y_STAT_CHIP_HUP)
+ return -ENODEV;
+
buf = memdup_user(dsp->image, dsp->length);
if (IS_ERR(buf))
return PTR_ERR(buf);
@@ -201,11 +204,13 @@ static int snd_usx2y_hwdep_dsp_load(struct snd_hwdep *hw,
err = usx2y_in04_init(priv);
if (err) {
dev_err(&dev->dev, "usx2y_in04_init error\n");
+ priv->chip_status |= USX2Y_STAT_CHIP_HUP;
return err;
}
err = usx2y_create_alsa_devices(hw->card);
if (err) {
dev_err(&dev->dev, "usx2y_create_alsa_devices error %i\n", err);
+ priv->chip_status |= USX2Y_STAT_CHIP_HUP;
return err;
}
priv->chip_status |= USX2Y_STAT_CHIP_INIT;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 396/507] ALSA: usb-audio: qcom: Check the return value of qmi_handle_init()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (394 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 395/507] ALSA: usx2y: Refuse a retried DSP load after a failure Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 397/507] ALSA: hda/realtek: Enable mute and mic-mute LEDs on HP ENVY 17-cr0xxx Greg Kroah-Hartman
` (110 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yuqiang Sun, Takashi Iwai,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuqiang Sun <izaiahsun@gmail.com>
[ Upstream commit a3cf5ebab5f1db9e6f751e2a08df05a84f37ea57 ]
qc_usb_audio_probe() overwrites the return value of qmi_handle_init()
with that of qmi_add_server() without checking it. When
qmi_handle_init() fails, it has already freed the receive buffer and
destroyed the workqueue, and qmi->sock may hold an error pointer. If
QRTR is not available, qmi_handle_init() returns -EPROBE_DEFER and
qmi->sock is ERR_PTR(-EAFNOSUPPORT), so qmi_add_server() passes it to
kernel_sendmsg():
BUG: unable to handle page fault for address: ffffffffffffffb7
RIP: 0010:selinux_socket_sendmsg+0xa0/0x590
Call Trace:
security_socket_sendmsg+0x29/0x50
__sock_sendmsg+0x43/0x150
kernel_sendmsg+0xd6/0x180
qmi_send_new_server+0x1b8/0x2b0
qmi_add_server+0x165/0x200
qc_usb_audio_probe+0xf4/0x2e0
really_probe+0x2b4/0x850
Had the probe gone on, the error and remove paths would call
qmi_handle_release() on the half-initialized handle, which destroys the
workqueue and frees the receive buffer a second time.
Return the error from qmi_handle_init(), so that -EPROBE_DEFER defers
the probe, and check qmi_add_server() as well.
The bug was found with kbound, a static analysis prototype for
ownership mismatches at kernel interfaces, on v7.2.12; it is present in
mainline.
Build-tested with x86_64 and arm64 allmodconfig (W=1, sparse): no new
warnings. Run-tested on QEMU (x86_64, KVM) with KASAN and kmemleak, with
the driver built in and a test module that registers the
q6usb.qc-usb-audio-offload auxiliary device. Without QRTR, the probe
crashes as above without this patch; with it the device is deferred and
removing it again reports nothing. With QRTR the probe succeeds, and
removal reports nothing either.
Fixes: 326bbc348298 ("ALSA: usb-audio: qcom: Introduce QC USB SND offloading support")
Cc: stable@vger.kernel.org
Signed-off-by: Yuqiang Sun <izaiahsun@gmail.com>
Link: https://patch.msgid.link/20261102035237.56253-1-izaiahsun@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/qcom/qc_audio_offload.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/sound/usb/qcom/qc_audio_offload.c b/sound/usb/qcom/qc_audio_offload.c
index e4bfd43a2488b..5ee568e0454cb 100644
--- a/sound/usb/qcom/qc_audio_offload.c
+++ b/sound/usb/qcom/qc_audio_offload.c
@@ -1969,8 +1969,13 @@ static int qc_usb_audio_probe(struct auxiliary_device *auxdev,
QMI_UAUDIO_STREAM_REQ_MSG_V01_MAX_MSG_LEN,
&uaudio_svc_ops_options,
&uaudio_stream_req_handlers);
+ if (ret)
+ goto free_qmi_hdl;
+
ret = qmi_add_server(svc->uaudio_svc_hdl, UAUDIO_STREAM_SERVICE_ID_V01,
UAUDIO_STREAM_SERVICE_VERS_V01, 0);
+ if (ret)
+ goto release_qmi_hdl;
uaudio_svc = svc;
@@ -1987,7 +1992,9 @@ static int qc_usb_audio_probe(struct auxiliary_device *auxdev,
release_qmi:
qc_usb_audio_cleanup_qmi_dev();
+release_qmi_hdl:
qmi_handle_release(svc->uaudio_svc_hdl);
+free_qmi_hdl:
kfree(svc->uaudio_svc_hdl);
free_svc:
kfree(svc);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 397/507] ALSA: hda/realtek: Enable mute and mic-mute LEDs on HP ENVY 17-cr0xxx
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (395 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 396/507] ALSA: usb-audio: qcom: Check the return value of qmi_handle_init() Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 398/507] ALSA: hda/tas2781: Only accept CRC-less V1 data if all entries are valid Greg Kroah-Hartman
` (109 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Alexandr, Takashi Iwai, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexandr <youdoit@mail.ru>
[ Upstream commit cf79cc4996bf936fe159af2a600519b3ebd4ccb7 ]
The HP ENVY Laptop 17-cr0xxx (subsystem ID 103c:8a2e) has mute and
mic-mute LEDs on the F8 and F5 keys that never light up on Linux: the
existing quirk entry only sets up the CS35L41 amplifiers.
The board uses the same LED wiring as the HP ENVY x360 15-ey0xxx
(103c:8a31): the mute LED is driven by COEF 0x0b bits 3:2 and the
mic-mute LED by GPIO2 with inverted polarity. Both were verified with
hda-verb on the actual hardware. Switch the entry to
ALC287_FIXUP_CS35L41_I2C_2_HP_MUTE_LEDS, which chains the amplifier
setup with ALC245_FIXUP_HP_X360_MUTE_LEDS, and use the DMI product name
of the board.
Fixes: aa8e3ef4fe53 ("ALSA: hda/realtek: Add quirks for various HP ENVY models")
Cc: <stable@vger.kernel.org>
Signed-off-by: Alexandr <youdoit@mail.ru>
Link: https://patch.msgid.link/20261103142121.74032-1-youdoit@mail.ru
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/hda/codecs/realtek/alc269.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c
index 1288b180df752..dd3466c3129d7 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -7606,7 +7606,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8a2b, "HP Envy 15", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8a2c, "HP Envy 16", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8a2d, "HP Envy 16", ALC287_FIXUP_CS35L41_I2C_2),
- SND_PCI_QUIRK(0x103c, 0x8a2e, "HP Envy 16", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x103c, 0x8a2e, "HP ENVY Laptop 17-cr0xxx", ALC287_FIXUP_CS35L41_I2C_2_HP_MUTE_LEDS),
SND_PCI_QUIRK(0x103c, 0x8a30, "HP Envy 17", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8a31, "HP ENVY x360 2-in-1 Laptop 15-ey0xxx", ALC287_FIXUP_CS35L41_I2C_2_HP_MUTE_LEDS),
SND_PCI_QUIRK(0x103c, 0x8a34, "HP Pavilion x360 2-in-1 Laptop 14-ek0xxx", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 398/507] ALSA: hda/tas2781: Only accept CRC-less V1 data if all entries are valid
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (396 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 397/507] ALSA: hda/realtek: Enable mute and mic-mute LEDs on HP ENVY 17-cr0xxx Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 399/507] ALSA: line6: Reject capture buffers smaller than two packets Greg Kroah-Hartman
` (108 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cristian Castellano,
Mohamed Yassine Jebabli, Takashi Iwai, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mohamed Yassine Jebabli <med.jebabli@gmail.com>
[ Upstream commit 8dbab764f1e0a92c3fac0ce070ce30c0c33c2692 ]
Commit 408249089c48 ("ALSA: hda/tas2781: Accept V1 calibration data
without CRC") only checked the first device entry. On machines where
the BIOS populates fewer entries than p->ndev, the remaining all-zero
entries are applied and tas2781_cali_preproc() divides by zero on
playback open.
Accept CRC-less V1 data only if every expected entry is non-zero and
self-consistent (R0 * 1/R0 close to 1.0), otherwise reject it as
before.
Fixes: 408249089c48 ("ALSA: hda/tas2781: Accept V1 calibration data without CRC")
Reported-by: Cristian Castellano <cristian.castellano@icloud.com>
Closes: https://lore.kernel.org/all/4e500063-d985-46b6-a0a1-3feaa77c4b2f@leemhuis.info/
Cc: stable@vger.kernel.org
Signed-off-by: Mohamed Yassine Jebabli <med.jebabli@gmail.com>
Link: https://patch.msgid.link/20261103-tas2781-v1-nocrc-fix-v1-1-a769c27f21ce@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/hda/codecs/side-codecs/tas2781_hda.c | 27 +++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/sound/hda/codecs/side-codecs/tas2781_hda.c b/sound/hda/codecs/side-codecs/tas2781_hda.c
index e0da299df780c..9162173ccb105 100644
--- a/sound/hda/codecs/side-codecs/tas2781_hda.c
+++ b/sound/hda/codecs/side-codecs/tas2781_hda.c
@@ -50,6 +50,31 @@ static void cali_cnv(unsigned char *data, unsigned int base, int offset)
(u32 *)®_data, TASDEV_CALIB_N);
}
+/*
+ * V1 data without CRC is only trusted if every expected device has a
+ * populated, self-consistent entry: R0 (Q27) * 1/R0 (Q31) must be
+ * close to 1.0 in Q58.
+ */
+static bool tas2781_v1_nocrc_valid(const unsigned int *v, int ndev)
+{
+ const u64 one = 1ULL << 58;
+ int i;
+
+ if (ndev <= 0 || ndev > 4)
+ return false;
+
+ for (i = 0; i < ndev; i++) {
+ const unsigned int *e = &v[i * 5];
+ u64 prod = (u64)e[0] * e[1];
+
+ if (!e[0] || !e[1] ||
+ prod < one - one / 10 || prod > one + one / 10)
+ return false;
+ }
+
+ return true;
+}
+
static void tas2781_apply_calib(struct tasdevice_priv *p)
{
struct calidata *cali_data = &p->cali_data;
@@ -145,7 +170,7 @@ static void tas2781_apply_calib(struct tasdevice_priv *p)
* but leave TimeStamp and CRC zeroed.
*/
if (!tmp_val[20] && !tmp_val[21] &&
- tmp_val[0] && tmp_val[1]) {
+ tas2781_v1_nocrc_valid(tmp_val, p->ndev)) {
dev_warn(p->dev,
"%s: V1 data without CRC, accepting\n",
__func__);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 399/507] ALSA: line6: Reject capture buffers smaller than two packets
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (397 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 398/507] ALSA: hda/tas2781: Only accept CRC-less V1 data if all entries are valid Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 400/507] ALSA: caiaq: free the EP4 URB when input setup fails Greg Kroah-Hartman
` (107 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sinan Turunc, Takashi Iwai,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sinan Turunc <enscrpt@pm.me>
[ Upstream commit db51425c9eb038a8e40e09b837afde015ae9e3ec ]
line6_capture_copy() splits the copy into the ALSA ring buffer once at
the buffer end and wraps pos_done once, which is only correct when one
packet holds at most buffer_size frames. The packet size comes from the
device's endpoint, and the per-device hw structs allow 64-byte periods
with periods_min 1, so a packet can be larger than the whole buffer.
audio_in_callback() logs an oversized packet and then copies it anyway.
The packet size is known at probe time, so constrain
SNDRV_PCM_HW_PARAM_BUFFER_BYTES in snd_line6_capture_open() to at least
twice the larger of the two endpoints' packet sizes. Two rather than
one, because pos_done advances by the packet and wraps once, so a buffer
of exactly one packet leaves the position unchanged after every packet.
hw_params then rejects a buffer that cannot hold two packets, and the
single wrap is valid for every configuration that gets through. Keep a
guard in line6_capture_copy() that drops an oversized packet with a
ratelimited error, for the case that should no longer be reachable.
Reproduced on 7.3-rc7 with a USB/IP device presenting the GuitarPort
interface layout and 1024-byte packets into a 128-byte buffer: ALSA
logged "invalid position: pos = 224, buffer size = 32" and the driver
logged "driver bug: len" on every following packet. With this patch a
1024-byte buffer is refused at hw_params, and a 2048-byte buffer streams
for 30 s with no report and with the position moving inside the buffer.
Fixes: 705ececd1c60 ("Staging: add line6 usb driver")
Cc: stable@vger.kernel.org
Signed-off-by: Sinan Turunc <enscrpt@pm.me>
Link: https://patch.msgid.link/20261103132227.696-1-enscrpt@pm.me
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/line6/capture.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c
index ceee51eeda0df..32922b7f2ffc7 100644
--- a/sound/usb/line6/capture.c
+++ b/sound/usb/line6/capture.c
@@ -94,6 +94,18 @@ void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize)
if (runtime == NULL)
return;
+ /*
+ * snd_line6_capture_open() constrains the buffer to hold at least
+ * two packets, so this cannot happen for a conforming device. Drop
+ * the packet rather than overrun the single wrap below.
+ */
+ if (unlikely(frames > runtime->buffer_size)) {
+ dev_err_ratelimited(line6pcm->line6->ifcdev,
+ "packet of %d frames exceeds %lu-frame buffer, dropping\n",
+ frames, runtime->buffer_size);
+ return;
+ }
+
if (line6pcm->in.pos_done + frames > runtime->buffer_size) {
/*
The transferred area goes over buffer boundary,
@@ -231,6 +243,23 @@ static int snd_line6_capture_open(struct snd_pcm_substream *substream)
if (err < 0)
return err;
+ /*
+ * line6_capture_copy() wraps the ring buffer once per packet and
+ * advances pos_done by the packet, which only works when the buffer
+ * holds more than one packet: with exactly one, pos_done gains a
+ * buffer and loses it again on every packet. The packet size comes
+ * from the device, so bound the buffer by two packets here. The
+ * impulse-response path copies a playback URB into this ring, so
+ * take the larger of the two endpoints.
+ */
+ err = snd_pcm_hw_constraint_minmax(runtime,
+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+ 2 * max(line6pcm->max_packet_size_in,
+ line6pcm->max_packet_size_out),
+ UINT_MAX);
+ if (err < 0)
+ return err;
+
line6_pcm_acquire(line6pcm, LINE6_STREAM_CAPTURE_HELPER, false);
runtime->hw = line6pcm->properties->capture_hw;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 400/507] ALSA: caiaq: free the EP4 URB when input setup fails
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (398 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 399/507] ALSA: line6: Reject capture buffers smaller than two packets Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 401/507] ALSA: usx2y: Require a buffer of two URBs Greg Kroah-Hartman
` (106 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Takashi Iwai,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
[ Upstream commit d21746bafdb8e1a5fc9bdcb86f603d827a500a62 ]
The three controllers that use the EP4 input URB allocate it before
checking the endpoint type and before registering the input device. On
failure they jump to exit_free_idev, which clears cdev->input_dev but
leaves cdev->ep4_in_urb set. The card teardown then calls
snd_usb_caiaq_input_free(), which returns early because input_dev is
NULL, so the URB is never freed.
Release the URB before dropping the input device on the error path.
Fixes: 6da7a2aa899f ("ALSA: usb/caiaq: Add support for Traktor Kontrol X1")
Cc: stable@vger.kernel.org
Assisted-by: DeepSeek-V4.1-Flash and OpenAI Codex
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20261104025341.1527407-1-vulab@iscas.ac.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/caiaq/input.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c
index 8d924330c54c8..309a361ca9f75 100644
--- a/sound/usb/caiaq/input.c
+++ b/sound/usb/caiaq/input.c
@@ -840,6 +840,8 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *cdev)
return 0;
exit_free_idev:
+ usb_free_urb(cdev->ep4_in_urb);
+ cdev->ep4_in_urb = NULL;
input_free_device(input);
cdev->input_dev = NULL;
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 401/507] ALSA: usx2y: Require a buffer of two URBs
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (399 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 400/507] ALSA: caiaq: free the EP4 URB when input setup fails Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 402/507] ALSA: usx2y: Guard the playback copy Greg Kroah-Hartman
` (105 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sinan Turunc, Takashi Iwai,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sinan Turunc <enscrpt@pm.me>
[ Upstream commit 4cbb826b3b36df6c275454287ba1df4564a5370b ]
usx2y_urb_capt_retire() wraps the ring buffer once per packet and
usx2y_urb_play_prepare() once per URB of nr_of_packs() packets of up to
50 frames. Both assume that the data fits in the buffer, and the hw
constraints only require about two 1 ms periods, so a packet larger
than the buffer on capture, or a URB larger than the buffer on playback,
violates that assumption.
Constrain SNDRV_PCM_HW_PARAM_BUFFER_SIZE in snd_usx2y_pcm_open() to at
least two URBs, 2 * nr_of_packs() * 50 frames, for both directions. The
bound is in frames and derived from the driver's own packet limit, so it
does not read the endpoint, whose altsetting is only selected in
prepare. Two URBs rather than one, because the position advances by a
URB on playback and only moves when a URB is less than the whole buffer.
Keep a guard in usx2y_urb_capt_retire() that drops a packet larger than
the buffer, for the case the constraint makes unreachable.
With nrpacks above about 163 (S16_LE) or 109 (S24_3LE) the bound exceeds
the 64 KiB buffer the substream preallocates (twice that with the
preallocation raised to its 128 KiB maximum), so hw_params fails for
those module settings. That is intended: the driver cannot be safe with
a URB larger than half the largest buffer.
Reproduced on 7.3-rc7 with a USB/IP device presenting the US-122
interface layout and 1024-byte packets into a 512-byte capture buffer:
BUG: KASAN: out-of-bounds in i_usx2y_urb_complete+0x1285/0x1ac0
Read of size 18446744073709551104 at addr ffff88800e448800 by task vhci_rx/83
Tested on 7.3-rc7 with the same device, S16_LE at 44100 Hz, nrpacks 4,
so the bound is 400 frames. A 128-frame capture buffer and a 200-frame
playback buffer are refused at hw_params with EINVAL. A 400-frame buffer
streams for 30 s in each direction with the position advancing inside
the buffer and no KASAN report; the capture guard did not fire. The
same 400-frame capture buffer with S24_3LE, which selects altsetting 2
in prepare, streams for 30 s with the same result.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Sinan Turunc <enscrpt@pm.me>
Link: https://patch.msgid.link/20261104122136.1518-2-enscrpt@pm.me
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/usx2y/usbusx2yaudio.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index a3a0bc13632b8..1e1d0cfbd167c 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -51,6 +51,18 @@ static int usx2y_urb_capt_retire(struct snd_usx2y_substream *subs)
dev_dbg(&usx2y->dev->dev, "%s: 0 == len ERROR!\n", __func__);
continue;
}
+ /*
+ * snd_usx2y_pcm_open() constrains the buffer to hold at least
+ * two URBs, so this cannot happen for a device that keeps its
+ * packets at 50 frames. Drop the packet rather than exceed the
+ * single wrap below.
+ */
+ if (unlikely(len > runtime->buffer_size)) {
+ dev_err_ratelimited(&usx2y->dev->dev,
+ "%s: packet of %i frames exceeds %lu-frame buffer, dropping\n",
+ __func__, len, runtime->buffer_size);
+ continue;
+ }
/* copy a data chunk */
if ((hwptr_done + len) > runtime->buffer_size) {
@@ -888,6 +900,18 @@ static int snd_usx2y_pcm_open(struct snd_pcm_substream *substream)
runtime->private_data = subs;
subs->pcm_substream = substream;
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 1000, 200000);
+ /*
+ * Capture wraps the ring buffer once per packet and playback once
+ * per URB of nr_of_packs() packets of at most 50 frames (see
+ * usx2y_urb_play_prepare()). Playback needs the buffer to hold more
+ * than one URB and capture more than one packet; use the URB bound
+ * for both, and two URBs rather than one, because the position only
+ * advances when a URB is less than the whole buffer. The bound is in
+ * frames and does not depend on the altsetting, which is selected
+ * in prepare.
+ */
+ snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+ 2 * nr_of_packs() * 50, UINT_MAX);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 402/507] ALSA: usx2y: Guard the playback copy
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (400 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 401/507] ALSA: usx2y: Require a buffer of two URBs Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 403/507] ext2: preserve IOMAP_F_DIRTY for extending direct writes Greg Kroah-Hartman
` (104 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sinan Turunc, Takashi Iwai,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sinan Turunc <enscrpt@pm.me>
[ Upstream commit e2c6de52ffacb2c0f4076884ee3fdb744735a4cb ]
usx2y_urb_play_prepare() sums the packet lengths of a whole URB, copies
that many frames with a single wrap, and sizes each playback packet from
the capture packet's actual_length. Three things are unchecked: that the
URB fits in the ring buffer, that a packet fits in the playback
endpoint's maxpacksize, from which tmpbuf is allocated, and that
actual_length is a whole number of frames. The ISO descriptors take the
raw actual_length while transfer_buffer_length and the copies take
count * stride, so a packet that is not a multiple of the stride makes
the descriptors add up to more than the buffer, by up to stride - 1
bytes per packet.
Return -EPIPE, as the existing packet-size check does, when the URB is
larger than the buffer or a packet is larger than maxpacksize, and size
each descriptor from whole frames, so the descriptors add up to
transfer_buffer_length and each stays within maxpacksize. The buffer
case is prevented by the previous patch and this is the guard for it;
the other two depend only on the device.
The first case is reachable on the unpatched driver with ordinary
packets: on 7.3-rc7, a USB/IP device presenting the US-122 interface
layout and sending 48-frame packets, with a 100-frame playback buffer
(two 50-frame periods, inside the stock constraints), KASAN reports:
BUG: KASAN: out-of-bounds in i_usx2y_urb_complete+0x79b/0x1ac0
Read of size 18446744073709551280 at addr ffff88800e6b02e0 by task vhci_rx/80
With both patches, the same device and a 200-frame playback buffer is
refused at hw_params with EINVAL, and a 400-frame buffer plays for 30 s
with the position advancing inside the buffer, no KASAN report and
neither guard message. The maxpacksize check is not exercised: the
emulated device reports the same wMaxPacketSize on both endpoints.
The descriptor case is visible with capture packets of 195 bytes at
stride 4 (48 frames and 3 bytes): without this change the four
descriptors add up to 780 bytes for 768 bytes of data, and USB/IP's
completion check refuses the URB ("total length of iso packets 780 not
equal to actual length of buffer 768", -EPROTO), after which the driver
stops the streams. With this patch every descriptor is 192 bytes, the
descriptors add up to the data in every URB for 30 s, the position
advances inside the buffer and KASAN reports nothing. The 48-frame
playback run above is unchanged.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Sinan Turunc <enscrpt@pm.me>
Link: https://patch.msgid.link/20261104122136.1518-3-enscrpt@pm.me
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/usx2y/usbusx2yaudio.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 1e1d0cfbd167c..798c9bb5386a2 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -118,14 +118,31 @@ static int usx2y_urb_play_prepare(struct snd_usx2y_substream *subs,
__func__, counts);
return -EPIPE;
}
+ if (counts * usx2y->stride > subs->maxpacksize) {
+ dev_err_ratelimited(&usx2y->dev->dev,
+ "%s: packet of %i bytes exceeds maxpacksize %u\n",
+ __func__, counts * usx2y->stride,
+ subs->maxpacksize);
+ return -EPIPE;
+ }
/* set up descriptor */
urb->iso_frame_desc[pack].offset = pack ?
urb->iso_frame_desc[pack - 1].offset +
urb->iso_frame_desc[pack - 1].length :
0;
- urb->iso_frame_desc[pack].length = cap_urb->iso_frame_desc[pack].actual_length;
+ urb->iso_frame_desc[pack].length = counts * usx2y->stride;
}
if (atomic_read(&subs->state) >= STATE_PRERUNNING) {
+ /*
+ * The copy below wraps once, which needs count <= buffer_size.
+ * snd_usx2y_pcm_open() guarantees it; guard anyway.
+ */
+ if (unlikely(count > runtime->buffer_size)) {
+ dev_err_ratelimited(&usx2y->dev->dev,
+ "%s: URB of %i frames exceeds %lu-frame buffer, stopping\n",
+ __func__, count, runtime->buffer_size);
+ return -EPIPE;
+ }
if (subs->hwptr + count > runtime->buffer_size) {
/* err, the transferred area goes over buffer boundary.
* copy the data to the temp buffer.
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 403/507] ext2: preserve IOMAP_F_DIRTY for extending direct writes
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (401 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 402/507] ALSA: usx2y: Guard the playback copy Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 404/507] net/smc: dont spin in smc_rx_recvmsg() while a pipe holds spliced data Greg Kroah-Hartman
` (103 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hungyu Lin, Jan Kara, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hungyu Lin <dennylin0707@gmail.com>
[ Upstream commit 4f91b042af212ca0b610e43f9a975ddc7f0d0923 ]
ext2_iomap_begin() sets IOMAP_F_DIRTY for writes that may extend i_size,
but clears the flag after ext2_get_blocks(). When the write uses an
existing mapped block, iomap can then use FUA and skip
generic_write_sync(), even though ext2_dio_write_end_io() updates the
inode size. An O_DSYNC write can therefore return without persisting
the new size.
For example, on a FUA-capable device, a 512-byte O_DIRECT|O_DSYNC write
at offset 512 into a fsynced one-byte file returns successfully and
extends the in-memory size to 1024, while an immediate read of the
on-disk inode still shows size 1. An explicit fsync persists the new
size.
Move setting of IOMAP_F_DIRTY after the initialization.
Fixes: fb5de4358e1a ("ext2: Move direct-io to use iomap")
Cc: stable@vger.kernel.org
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
Link: https://patch.msgid.link/20261029013616.97194-1-dennylin0707@gmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ext2/inode.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index a9245f0cda4d4..53edda7217f33 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -801,6 +801,12 @@ static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
(first_block << blkbits) < i_size_read(inode))
create = 0;
+ ret = ext2_get_blocks(inode, first_block, max_blocks,
+ &bno, &new, &boundary, create);
+ if (ret < 0)
+ return ret;
+
+ iomap->flags = 0;
/*
* Writes that span EOF might trigger an IO size update on completion,
* so consider them to be dirty for the purposes of O_DSYNC even if
@@ -808,13 +814,6 @@ static int ext2_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
*/
if ((flags & IOMAP_WRITE) && offset + length > i_size_read(inode))
iomap->flags |= IOMAP_F_DIRTY;
-
- ret = ext2_get_blocks(inode, first_block, max_blocks,
- &bno, &new, &boundary, create);
- if (ret < 0)
- return ret;
-
- iomap->flags = 0;
iomap->offset = (u64)first_block << blkbits;
iomap->bdev = inode->i_sb->s_bdev;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 404/507] net/smc: dont spin in smc_rx_recvmsg() while a pipe holds spliced data
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (402 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 403/507] ext2: preserve IOMAP_F_DIRTY for extending direct writes Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 405/507] net: count last skb of each sk_backlog pass in __release_sock() Greg Kroah-Hartman
` (102 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bryam Vargas, Dust Li, Paolo Abeni,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryam Vargas <hexlabsecurity@proton.me>
[ Upstream commit 8288ba942cfd20621c05e16978b7c3da91513ae1 ]
While bytes spliced off the RMB are still in a pipe, recvmsg() waits
for the pipe to release them before it copies the data behind them.
The path to that wait skips the timeout and signal checks, and
smc_rx_wait() returns at once on RCV_SHUTDOWN. With a signal pending,
after SHUT_RD, or once the peer closes or shuts down writing,
recvmsg() spins on a CPU until the pipe is drained, and SIGKILL cannot
stop it. MSG_DONTWAIT and an expired SO_RCVTIMEO wait there too
instead of returning -EAGAIN.
Check the timeout and signals before that wait, and end it when the
pipe releases the data or the connection is killed, not on RCV_SHUTDOWN.
A zero-length read returns 0 without waiting for the pipe; a
non-blocking one returns -EAGAIN while poll() still reports the socket
readable (splice() can still take those bytes). The wait sets
SOCKWQ_ASYNC_WAITDATA like smc_rx_wait(), so a byte arriving behind
the pipe raises no SIGIO on a reader already asleep for it, and a full
barrier orders its wait queue entry before its read of splice_pending,
so no wake is lost.
Fixes: 9014db202cb7 ("smc: add support for splice()")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Reviewed-by: Dust Li <dust.li@linux.alibaba.com>
Link: https://patch.msgid.link/20261029-b4-disp-da7f8e6a-v2-1-9052904adf72@proton.me
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/smc/smc_rx.c | 39 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 38 insertions(+), 1 deletion(-)
diff --git a/net/smc/smc_rx.c b/net/smc/smc_rx.c
index 197fddc6271f0..63c178c10bf1a 100644
--- a/net/smc/smc_rx.c
+++ b/net/smc/smc_rx.c
@@ -286,6 +286,27 @@ int smc_rx_wait(struct smc_sock *smc, long *timeo, size_t peeked,
return rc;
}
+/* Wait for the pipe to release the spliced data. Unlike smc_rx_wait()
+ * it does not end on shutdown or sk_err, the data is already in the
+ * RMB; smc_conn_kill() wakes it and the caller checks conn->killed.
+ */
+static void smc_rx_wait_splice(struct smc_sock *smc, long *timeo)
+{
+ DEFINE_WAIT_FUNC(wait, woken_wake_function);
+ struct smc_connection *conn = &smc->conn;
+ struct sock *sk = &smc->sk;
+
+ sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
+ add_wait_queue(sk_sleep(sk), &wait);
+ /* pairs with the smp_mb() in wq_has_sleeper(): the release drops
+ * splice_pending, then looks for a sleeper
+ */
+ smp_mb();
+ sk_wait_event(sk, timeo, !atomic_read(&conn->splice_pending), &wait);
+ remove_wait_queue(sk_sleep(sk), &wait);
+ sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
+}
+
static int smc_rx_recv_urg(struct smc_sock *smc, struct msghdr *msg, int len,
int flags)
{
@@ -443,7 +464,23 @@ int smc_rx_recvmsg(struct smc_sock *smc, struct msghdr *msg,
/* could be just 1 byte, even after waiting on data above */
readable = smc_rx_data_available(conn, peeked_bytes);
splbytes = atomic_read(&conn->splice_pending);
- if (!readable || (msg && splbytes)) {
+ if (msg && splbytes) {
+ /* a pipe holds bytes ahead of these; the copy path
+ * skips the timeout and signal checks
+ */
+ if (!read_remaining)
+ break;
+ if (!timeo || signal_pending(current)) {
+ if (!read_done)
+ read_done = timeo ?
+ sock_intr_errno(timeo) :
+ -EAGAIN;
+ break;
+ }
+ smc_rx_wait_splice(smc, &timeo);
+ continue;
+ }
+ if (!readable) {
if (splbytes)
func = smc_rx_data_available_and_no_splice_pend;
else
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 405/507] net: count last skb of each sk_backlog pass in __release_sock()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (403 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 404/507] net/smc: dont spin in smc_rx_recvmsg() while a pipe holds spliced data Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 406/507] net: ethernet: ti: am65-cpsw-nuss: Enable timestamping of unicast PTP packets Greg Kroah-Hartman
` (101 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ray Zhang, Kuniyuki Iwashima,
Eric Dumazet, Paolo Abeni, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ray Zhang <sgzhang@google.com>
[ Upstream commit c4e4056b21355356f6a95bcdf03a850edd9f49e7 ]
Running 500 concurrent TCPv6 streams (neper "tcp_stream -6 -T 1 -F 500")
on a 2-core Cortex-A53 (CONFIG_PREEMPT_NONE=y, HZ=1000, LATENCY_WARN)
triggers resched_latency_warn() in __release_sock():
[ 3655.311821] sched: CPU 0 need_resched set for > 100006892 ns (100 ticks) without schedule
[ 3655.311889] Call trace:
...
[ 3655.311944] resched_latency_warn+0x7c/0x88
[ 3655.311958] sched_tick+0x1c0/0x418
...
[ 3655.312578] net_rx_action+0x238/0x438
...
[ 3655.312641] do_softirq+0x4c/0x90
[ 3655.312651] __local_bh_enable_ip+0x84/0x90
[ 3655.312663] local_bh_enable+0x1c/0x28
[ 3655.312674] __dev_queue_xmit+0x4a8/0xb00
...
[ 3655.312782] tcp_v6_do_rcv+0x240/0x5f8
[ 3655.312793] __release_sock+0x9c/0x188
[ 3655.312806] release_sock+0x150/0x168
[ 3655.312817] tcp_sendmsg+0x4c/0x70
__release_sock() can loop past 100 ms without calling cond_resched():
- Each outer-loop pass drains sk_backlog, but "if (!skb) break;" runs
before "++nb", so a pass of B skbs only adds B - 1 to nb (0 for 1 skb).
- With 500 TCPv6 streams and NAPI sharing two Cortex-A53 cores, runnable
tasks keep TIF_NEED_RESCHED set on CPU 0.
- During spin_unlock_bh() and TX softirqs (__dev_queue_xmit() ->
local_bh_enable()), tcp_add_backlog() coalesces arriving pure ACKs into
a single tail skb.
- Repeated 1-skb passes never advance nb or call cond_resched(),
triggering resched_latency_warn() after 100 ticks.
Restore the do-while loop and drop "if (!skb) break;" so every skb
increments nb across passes and calls cond_resched() every 16 skbs.
Reproduced the issue and verified the fix on two 2-core Cortex-A53 hosts
(CONFIG_PREEMPT_NONE=y, HZ=1000, LATENCY_WARN, latency_warn_once=0) with
a userspace reproducer over /dev/net/tun:
- CPU 0 runs a TCPv6 sender and a second runnable task while CPU 1 writes
pure ACKs to /dev/net/tun (~30k TCPBacklogCoalesce/run), sustaining
1-skb sk_backlog refills in __release_sock() for ~400 ms (ftrace).
- Before: CPU 0 stayed unscheduled in __release_sock(), hitting
resched_latency_warn() 293 and 275 times on the two hosts (> 100.9 ms).
- After: cond_resched() yielded CPU 0 inside __release_sock(), with
0 resched_latency_warn() hits on both hosts.
- Also observed no regression with the workload from
commit 16c610162d1f ("net: call cond_resched() less often in
__release_sock()"), "super_netperf 4 -H srv -T,10 -l 3000 &".
Fixes: 16c610162d1f ("net: call cond_resched() less often in __release_sock()")
Cc: stable@vger.kernel.org
Signed-off-by: Ray Zhang <sgzhang@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/20261101075145.698399-1-sgzhang@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/sock.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/net/core/sock.c b/net/core/sock.c
index e8551df8330ff..1108543f9fec5 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3262,7 +3262,7 @@ void __release_sock(struct sock *sk)
spin_unlock_bh(&sk->sk_lock.slock);
- while (1) {
+ do {
next = skb->next;
prefetch(next);
DEBUG_NET_WARN_ON_ONCE(skb_dst_is_noref(skb));
@@ -3270,12 +3270,10 @@ void __release_sock(struct sock *sk)
sk_backlog_rcv(sk, skb);
skb = next;
- if (!skb)
- break;
if (!(++nb & 15))
cond_resched();
- }
+ } while (skb);
spin_lock_bh(&sk->sk_lock.slock);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 406/507] net: ethernet: ti: am65-cpsw-nuss: Enable timestamping of unicast PTP packets
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (404 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 405/507] net: count last skb of each sk_backlog pass in __release_sock() Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 407/507] drm/etnaviv: Fix NULL dereference on unbind without PPU flop reset Greg Kroah-Hartman
` (100 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, James Clark,
Sebastian Andrzej Siewior, Paolo Abeni, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Clark <jjc@jclark.com>
[ Upstream commit 6887a8f98244ba4c0fbe2d2461b9b8f8a300e326 ]
On a BeagleY-AI (J722S), ptp4l as a unicast master (unicast_listen) logs
"received DELAY_REQ without timestamp" for each unicast Delay_Req, and
its port goes to FAULTY after "timed out while polling for tx timestamp"
for the first unicast Sync.
am65_cpsw_nuss_hwtstamp_set() does not set the TS_UNI_EN bit (bit 24) of
the port's TS_CTL_LTYPE2 register. According to the TRM (J722S TRM
SPRUJB3D, 12.2.1.4.7.13.5.1 Ethernet Port Receive Event and
12.2.1.4.7.13.5.2 Ethernet Port Transmit Event), this bit must be set
for the port to timestamp PTP event messages over UDP sent to a unicast
address; without it, only messages sent to the PTP multicast addresses
selected by the TS_107 and TS_129 to TS_132 bits are timestamped. TI's
netcp_ethss driver for the Keystone 2 Ethernet switch, which has the
same timestamping registers, always sets TS_UNI_EN.
Set TS_UNI_EN along with the other bits. With this change, ptp4l in the
same setup gets timestamps for the unicast Delay_Req and Sync messages.
Fixes: b1f66a5bee07 ("net: ethernet: ti: am65-cpsw-nuss: enable packet timestamping support")
Cc: stable@vger.kernel.org
Signed-off-by: James Clark <jjc@jclark.com>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Link: https://patch.msgid.link/20261102135117.419539-1-jjc@jclark.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/ti/am65-cpsw-nuss.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
index 6330540979d70..f54cfcb7d1530 100644
--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
@@ -128,6 +128,7 @@
#define AM65_CPSW_PN_TS_CTL_LTYPE2_TS_319 BIT(21)
#define AM65_CPSW_PN_TS_CTL_LTYPE2_TS_320 BIT(22)
#define AM65_CPSW_PN_TS_CTL_LTYPE2_TS_TTL_NONZERO BIT(23)
+#define AM65_CPSW_PN_TS_CTL_LTYPE2_TS_UNI_EN BIT(24)
/* The PTP event messages - Sync, Delay_Req, Pdelay_Req, and Pdelay_Resp. */
#define AM65_CPSW_TS_EVENT_MSG_TYPE_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3))
@@ -1857,7 +1858,8 @@ static int am65_cpsw_nuss_hwtstamp_set(struct net_device *ndev,
AM65_CPSW_PN_TS_CTL_LTYPE2_TS_132 |
AM65_CPSW_PN_TS_CTL_LTYPE2_TS_319 |
AM65_CPSW_PN_TS_CTL_LTYPE2_TS_320 |
- AM65_CPSW_PN_TS_CTL_LTYPE2_TS_TTL_NONZERO;
+ AM65_CPSW_PN_TS_CTL_LTYPE2_TS_TTL_NONZERO |
+ AM65_CPSW_PN_TS_CTL_LTYPE2_TS_UNI_EN;
ts_ctrl = AM65_CPSW_TS_EVENT_MSG_TYPE_BITS <<
AM65_CPSW_PN_TS_CTL_MSG_TYPE_EN_SHIFT;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 407/507] drm/etnaviv: Fix NULL dereference on unbind without PPU flop reset
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (405 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 406/507] net: ethernet: ti: am65-cpsw-nuss: Enable timestamping of unicast PTP packets Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 408/507] drm/etnaviv: Flush the tile status cache through both the PE and BLT Greg Kroah-Hartman
` (99 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lucas Stach, Christian Gmeiner,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Gmeiner <cgmeiner@igalia.com>
[ Upstream commit a0560a12d8c1a03e925c5d9be8479da75663a40f ]
flop_reset_data_ppu is only allocated on GPUs that need the PPU flop
reset. However, etnaviv_unbind(..) frees it unconditionally, and
etnaviv_cmdbuf_free(..) dereferences cmdbuf->suballoc before checking
whether cmdbuf is NULL.
As a result, unloading the driver on GPUs that do not need the PPU
flop reset causes a NULL pointer dereference at address 0.
Fixes: 85ba57ad88cf ("drm/etnaviv: Add PPU flop reset")
Cc: stable@vger.kernel.org
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
Link: https://patch.msgid.link/20261102-etnaviv-unbind-flop-fix-v1-1-588fd16f6768@igalia.com
Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/etnaviv/etnaviv_drv.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 08aca9035fc1a..ec1352c1b09fa 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -601,8 +601,10 @@ static void etnaviv_unbind(struct device *dev)
component_unbind_all(dev, drm);
- etnaviv_cmdbuf_free(priv->flop_reset_data_ppu);
- kfree(priv->flop_reset_data_ppu);
+ if (priv->flop_reset_data_ppu) {
+ etnaviv_cmdbuf_free(priv->flop_reset_data_ppu);
+ kfree(priv->flop_reset_data_ppu);
+ }
etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 408/507] drm/etnaviv: Flush the tile status cache through both the PE and BLT
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (406 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 407/507] drm/etnaviv: Fix NULL dereference on unbind without PPU flop reset Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 409/507] drm/sched: Fix out of bounds entity priority check Greg Kroah-Hartman
` (98 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lucas Stach, Christian Gmeiner,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Gmeiner <cgmeiner@igalia.com>
[ Upstream commit c1a757f8df1363032623fa9b1baaba0dcf34de6d ]
Since commit f232d9ec029c ("drm/etnaviv: fix TS cache flushing on GPUs
with BLT engine"), jobs on GPUs with a BLT engine use a BLT command to
flush the tile status cache instead of TS_FLUSH_CACHE, which is broken
on most of these GPUs.
GC7000 r6008/r6009 and GC8200 r6401 are the other way around:
TS_FLUSH_CACHE works, but the BLT command does not flush the cache.
The vendor driver handles these GPUs using TS_FLUSH_CACHE, but the
etnaviv kernel driver has no way to identify them.
As a result, dirty tile status cache lines survive the end of a job.
They are written back by the next cache flush, using the page table of
the job issuing it. If that job belongs to another process, the write
goes to the wrong address space.
On GC7000 r6009 this causes MMU faults and GPU recoveries blamed on an
innocent process. I see around 1100 per run of a multisample
depth/stencil test running alongside two other GPU clients.
Emit both flushes at the end of every job on GPUs with a BLT engine.
Whichever does not work on a given GPU is a no-op. Since dirty lines
are only written back once, this costs one additional state load per
job.
Fixes: f232d9ec029c ("drm/etnaviv: fix TS cache flushing on GPUs with BLT engine")
Cc: stable@vger.kernel.org
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
Link: https://patch.msgid.link/20261102-etna-pe-ts-flush-v1-1-e4454ed86f85@igalia.com
Signed-off-by: Christian Gmeiner <cgmeiner@igalia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/etnaviv/etnaviv_buffer.c | 40 +++++++++++-------------
1 file changed, 18 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
index 03b2576af67fd..99c91a9eecf1f 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
@@ -168,6 +168,17 @@ u16 etnaviv_buffer_config_pta(struct etnaviv_gpu *gpu, unsigned short id)
return buffer->user_size / 8;
}
+static void etnaviv_cmd_flush_ts(struct etnaviv_cmdbuf *buffer, bool has_blt)
+{
+ CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, VIVS_TS_FLUSH_CACHE_FLUSH);
+
+ if (has_blt) {
+ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
+ CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);
+ CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
+ }
+}
+
void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
{
struct etnaviv_cmdbuf *buffer = &gpu->buffer;
@@ -191,7 +202,7 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
unsigned int dwords = 7;
if (has_blt)
- dwords += 10;
+ dwords += 11;
link_target = etnaviv_buffer_reserve(gpu, buffer, dwords);
@@ -204,16 +215,8 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
}
CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, flush);
- if (gpu->exec_state == ETNA_PIPE_3D) {
- if (has_blt) {
- CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
- CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);
- CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
- } else {
- CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
- VIVS_TS_FLUSH_CACHE_FLUSH);
- }
- }
+ if (gpu->exec_state == ETNA_PIPE_3D)
+ etnaviv_cmd_flush_ts(buffer, has_blt);
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
if (has_blt) {
@@ -400,12 +403,12 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
return_dwords = 7;
/*
- * When the BLT engine is present we need 6 more dwords in the return
+ * When the BLT engine is present we need 7 more dwords in the return
* target: 3 enable/flush/disable + 4 enable/semaphore stall/disable,
- * but we don't need the normal TS flush state.
+ * on top of the normal TS flush state.
*/
if (has_blt)
- return_dwords += 6;
+ return_dwords += 7;
return_target = etnaviv_buffer_reserve(gpu, buffer, return_dwords);
CMD_LINK(cmdbuf, return_dwords, return_target);
@@ -422,14 +425,7 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
VIVS_GL_FLUSH_CACHE_DEPTH |
VIVS_GL_FLUSH_CACHE_COLOR |
VIVS_GL_FLUSH_CACHE_SHADER_L1);
- if (has_blt) {
- CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
- CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);
- CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
- } else {
- CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
- VIVS_TS_FLUSH_CACHE_FLUSH);
- }
+ etnaviv_cmd_flush_ts(buffer, has_blt);
}
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 409/507] drm/sched: Fix out of bounds entity priority check
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (407 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 408/507] drm/etnaviv: Flush the tile status cache through both the PE and BLT Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 410/507] drm/sched: Adjust run-queue when changing priority at runtime Greg Kroah-Hartman
` (97 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tvrtko Ursulin, Christian König,
Danilo Krummrich, Matthew Brost, Philipp Stanner, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
[ Upstream commit cda6f72545f2372234c72f93fd1be61841295e19 ]
When the out of range priority at entity init time is clamped to the
number of run queues in the supplied scheduler the internal run-queue
priority needs to be adjusted as well.
There is no impact since none of the drivers hit the clamping path, but
we still need to address it by moving the entity->rq_priority assignment
to after the clamping is done.
Note that a lot of this will hopefully get removed once again when the
single run-queue simplification lands.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Fixes: 2fa4d8e2c109 ("drm/sched: Add fair scheduling policy")
Cc: Christian König <christian.koenig@amd.com>
Cc: Danilo Krummrich <dakr@kernel.org>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Philipp Stanner <phasta@kernel.org>
Cc: stable@vger.kernel.org # v7.2+
Signed-off-by: Philipp Stanner <phasta@kernel.org>
Link: https://patch.msgid.link/20261021094227.48034-2-tvrtko.ursulin@igalia.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/scheduler/sched_entity.c | 27 +++++++++++-------------
1 file changed, 12 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
index 673ca9cbf3628..adaf7764ed33c 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -130,10 +130,7 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
INIT_LIST_HEAD(&entity->list);
entity->guilty = guilty;
- entity->priority = priority;
entity->last_user = current->group_leader;
- entity->rq_priority = drm_sched_policy == DRM_SCHED_POLICY_FAIR ?
- DRM_SCHED_PRIORITY_KERNEL : priority;
entity->num_sched_list = num_sched_list;
entity->sched_list = num_sched_list > 1 ? sched_list : NULL;
RCU_INIT_POINTER(entity->last_scheduled, NULL);
@@ -145,26 +142,26 @@ int drm_sched_entity_init(struct drm_sched_entity *entity,
* not to do this and to fix their DRM calling order.
*/
pr_warn("%s: called with uninitialized scheduler\n", __func__);
- } else {
- enum drm_sched_priority p = entity->priority;
-
+ } else if (priority >= sched_list[0]->num_user_rqs) {
/*
* The "priority" of an entity cannot exceed the number of
* run-queues of a scheduler. Protect against num_rqs being 0,
* by converting to signed. Choose the lowest priority
* available.
*/
- if (p >= sched_list[0]->num_user_rqs) {
- dev_err(sched_list[0]->dev, "entity with out-of-bounds priority:%u num_user_rqs:%u\n",
- p, sched_list[0]->num_user_rqs);
- p = max_t(s32,
- (s32)sched_list[0]->num_user_rqs - 1,
- (s32)DRM_SCHED_PRIORITY_KERNEL);
- entity->priority = p;
- }
- entity->rq = sched_list[0]->sched_rq[entity->rq_priority];
+ dev_err(sched_list[0]->dev, "entity with out-of-bounds priority:%u num_user_rqs:%u\n",
+ priority, sched_list[0]->num_user_rqs);
+ priority = max_t(s32,
+ (s32)sched_list[0]->num_user_rqs - 1,
+ (s32)DRM_SCHED_PRIORITY_KERNEL);
}
+ entity->priority = priority;
+ entity->rq_priority = drm_sched_policy == DRM_SCHED_POLICY_FAIR ?
+ DRM_SCHED_PRIORITY_KERNEL : priority;
+ if (sched_list[0]->sched_rq)
+ entity->rq = sched_list[0]->sched_rq[entity->rq_priority];
+
init_completion(&entity->entity_idle);
/* We start in an idle state. */
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 410/507] drm/sched: Adjust run-queue when changing priority at runtime
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (408 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 409/507] drm/sched: Fix out of bounds entity priority check Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 411/507] mptcp: pm: kernel: use RCU to free endpoint listeners Greg Kroah-Hartman
` (96 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tvrtko Ursulin, Christian König,
Danilo Krummrich, Matthew Brost, Philipp Stanner, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
[ Upstream commit 75709a35da45bc67f94c9ceb91bf8871fdfe4d9e ]
Another consequence of the recent revert of
commit 77a6809f1dc3 ("drm/sched: Remove FIFO and RR and simplify to a single run queue")
is that after the revert we need to adjust entity->rq_priority when
runtime priority changes are requested.
Only amdgpu does that so the impact is minimal. Also considering dynamic
priority changes are largely broken there, due currently broken entity
scheduler list handling where the special case of a single scheduler can
never change it's run-queue. And coupled with the fact for the rest a two-
tier approach of drm_sched_entity_set_priority() and
drm_sched_entity_modify_sched() is used, where later directly maps to
different hardware queue priority by replacing the set of schedulers
completely.
Hence the regression is limited to rings which have multiple instances
other than compute and graphics, which would be SDMA only, for which I am
not sure any userspace actually does dynamic priority changes in the first
place.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com>
Fixes: 2fa4d8e2c109 ("drm/sched: Add fair scheduling policy")
Cc: Christian König <christian.koenig@amd.com>
Cc: Danilo Krummrich <dakr@kernel.org>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Philipp Stanner <phasta@kernel.org>
Cc: stable@vger.kernel.org # v7.2+
[phasta: fix checkpatch error]
Signed-off-by: Philipp Stanner <phasta@kernel.org>
Link: https://patch.msgid.link/20261021094227.48034-3-tvrtko.ursulin@igalia.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/scheduler/sched_entity.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c
index adaf7764ed33c..0206bbad2ce09 100644
--- a/drivers/gpu/drm/scheduler/sched_entity.c
+++ b/drivers/gpu/drm/scheduler/sched_entity.c
@@ -454,6 +454,8 @@ void drm_sched_entity_set_priority(struct drm_sched_entity *entity,
{
spin_lock(&entity->lock);
entity->priority = priority;
+ if (drm_sched_policy != DRM_SCHED_POLICY_FAIR)
+ entity->rq_priority = priority;
spin_unlock(&entity->lock);
}
EXPORT_SYMBOL(drm_sched_entity_set_priority);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 411/507] mptcp: pm: kernel: use RCU to free endpoint listeners
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (409 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 410/507] drm/sched: Adjust run-queue when changing priority at runtime Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 412/507] udf: dont let the extent type hide an exhausted free-space table extent Greg Kroah-Hartman
` (95 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyle Zeng, Matthieu Baerts (NGI0),
Paolo Abeni, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kyle Zeng <kylebot@openai.com>
[ Upstream commit 49b09ae0bf57b4230187d4cdd0a370558e44a6e8 ]
mptcp_pm_nl_create_listen_socket() starts the TCP listener directly
instead of going through mptcp_listen(). It consequently misses setting
SOCK_RCU_FREE on the parent MPTCP socket.
tcp_child_process() can invoke the listener's subflow_data_ready()
callback without holding the MPTCP parent lock or a reference to the
parent. An authenticated MP_JOIN racing with endpoint teardown can
therefore access the parent after its last reference has been dropped.
The ADD_ADDR error path can also close an already published listener.
Set SOCK_RCU_FREE before __inet_listen_sk() publishes the TCP listener,
matching mptcp_listen(). This protects the parent on every subsequent
close path, including a failed endpoint addition.
Fixes: 1729cf186d8a ("mptcp: create the listening socket for new port")
Cc: stable@vger.kernel.org
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20261030042255.74216-1-kylebot@openai.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mptcp/pm_kernel.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c
index 1a77508132354..f7396628490e3 100644
--- a/net/mptcp/pm_kernel.c
+++ b/net/mptcp/pm_kernel.c
@@ -906,6 +906,7 @@ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
* old status is known (TCP_CLOSE).
*/
inet_sk_state_store(newsk, TCP_LISTEN);
+ sock_set_flag(newsk, SOCK_RCU_FREE);
lock_sock(ssk);
WRITE_ONCE(mptcp_subflow_ctx(ssk)->pm_listener, true);
err = __inet_listen_sk(ssk, backlog);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 412/507] udf: dont let the extent type hide an exhausted free-space table extent
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (410 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 411/507] mptcp: pm: kernel: use RCU to free endpoint listeners Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 413/507] udf: check the unallocated space table when it is loaded Greg Kroah-Hartman
` (94 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+799a0e744ac47f928024,
syzbot+43fc5ba6dcb33e3261ca, Matthias Goergens, Jan Kara,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthias Goergens <matthias.goergens@gmail.com>
[ Upstream commit da582d84fcf5f2f0c1d7760e1a899ca7cedb80fc ]
udf_table_new_block() takes the first block of the free-space table
extent closest to the goal. It keeps that extent's type and length
together in goal_elen, subtracts one block, and deletes the extent only
if goal_elen then reaches zero. UDF 2.60 section 2.3.7.1 requires the
free-space extents of an Unallocated Space Entry to be of type 1
(allocated but not recorded), and mkudffs writes them that way. For
such an extent the type bits keep goal_elen non-zero, so taking its last
block leaves a type-1 extent of length zero behind, starting at the
block after the extent, which is in use.
The next allocation that picks this empty extent returns that in-use
block. Subtracting a block from 0x40000000 then borrows from the type
bits, and the extent becomes type 0 with a length of 2^30 - blocksize:
about a gigabyte of "free" space overlapping live metadata, the other
table extents and whatever lies behind the partition. From then on
blocks are handed out twice, or past the end of the partition.
Extents that udf_table_free_blocks() adds are type 0, where the check
works, so only tables written by mkudffs or by another implementation
are affected. Nothing more than filling such a filesystem is needed:
on a fresh 1 MiB "mkudffs --space=unalloctable" image, creating empty
files until the partition is full writes file entries over the reserve
volume descriptor sequence and the backup anchor, and df then reports a
negative amount of used space.
On syzbot's images the same double allocation is what the two reports
below trip over. In the first, ftruncate() extends a new file with
enough hole extents to need a chain of allocation extent descriptors;
one AED is placed on another inode's file entry, and a later one is
placed on the block of the AED currently being filled, which
udf_setup_indirect_aext() zeroes, so __udf_add_aext() finds
lengthAllocDescs out of step with its cursor. In the second, an AED
is placed past the end of the device, sb_getblk() fails, and the error
path of udf_do_extend_file() calls udf_truncate_extents() on an extent
list that no longer covers i_size.
Keep the type separately from the length, as udf_table_prealloc_blocks()
already does.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: syzbot+799a0e744ac47f928024@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=799a0e744ac47f928024
Reported-by: syzbot+43fc5ba6dcb33e3261ca@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=43fc5ba6dcb33e3261ca
Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com>
Link: https://patch.msgid.link/6b51c38d2d069544053c542470950e2a448b0b8d.1793349907.git.matthias.goergens@gmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/udf/balloc.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index 30cec56001491..2ec577b4321c9 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -572,7 +572,7 @@ static udf_pblk_t udf_table_new_block(struct super_block *sb,
uint32_t elen, goal_elen = 0;
struct kernel_lb_addr eloc, goal_eloc;
struct extent_position epos, goal_epos;
- int8_t etype;
+ int8_t etype, goal_etype = 0;
struct udf_inode_info *iinfo = UDF_I(table);
int ret = 0;
@@ -623,7 +623,8 @@ static udf_pblk_t udf_table_new_block(struct super_block *sb,
goal_epos.block = epos.block;
goal_epos.offset = epos.offset - adsize;
goal_eloc = eloc;
- goal_elen = (etype << 30) | elen;
+ goal_elen = elen;
+ goal_etype = etype;
}
}
@@ -647,7 +648,8 @@ static udf_pblk_t udf_table_new_block(struct super_block *sb,
goal_elen -= sb->s_blocksize;
if (goal_elen)
- udf_write_aext(table, &goal_epos, &goal_eloc, goal_elen, 1);
+ udf_write_aext(table, &goal_epos, &goal_eloc,
+ (goal_etype << 30) | goal_elen, 1);
else
udf_delete_aext(table, goal_epos, &freed);
brelse(goal_epos.bh);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 413/507] udf: check the unallocated space table when it is loaded
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (411 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 412/507] udf: dont let the extent type hide an exhausted free-space table extent Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 414/507] udf: fix preallocation discarding before an empty allocation extent Greg Kroah-Hartman
` (93 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthias Goergens, Jan Kara,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthias Goergens <matthias.goergens@gmail.com>
[ Upstream commit e614c3e35a6699ed691b4d17e1ec4230e34aa3eb ]
udf_table_new_block() hands out the first block of the extent closest
to its goal and trusts that the extent covers at least one whole block
inside the partition. Nothing checks that. A zero-length extent makes
it return the block the extent points at, which need not be free, and
the subtraction of one block then underflows the length into the type
bits, turning the entry into a bogus continuation. An extent running
past the end of the partition makes it return blocks behind the
partition.
Such tables are not only found on crafted images: until the previous
commit, udf_table_new_block() itself left zero-length extents behind
in tables written by mkudffs, and then converted them into extents
running past the partition.
Check every extent once when the table is loaded, and refuse
read-write access if one is empty, is not a whole number of blocks, or
does not lie inside the partition, in the same way as for other
allocation information the kernel cannot use. Check first that the
table is an Unallocated Space Entry at all: the walk starts at the
offset of the allocation descriptors in one, and for a file entry that
offset lies before the inode's in-memory copy of the descriptors.
Treat a chain of allocation extent descriptors that leads back to
itself the same way: the walk would otherwise return the same extents
forever, and the mount would never finish. Let a fatal signal
interrupt the walk and fail the mount.
Refusing read-write access to an empty extent is deliberate. It shows
that an old kernel took the last block but left the entry behind. If
consumed again, the entry returns an in-use block and turns into a huge
bogus extent. Refusing the table before that
happens avoids this second allocation; the filesystem can still be
mounted read-only. The check cannot detect every overlap that may
already exist in a damaged table.
This patch should be backported together with the previous one: that
patch stops creating new empty extents, and this one rejects existing
ones before they are consumed again.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com>
Link: https://patch.msgid.link/81233decd91f4a48bf4d74e3d15b547c7711e39f.1793349907.git.matthias.goergens@gmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/udf/super.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 79 insertions(+), 1 deletion(-)
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 5351755aca3ec..7570506ff2dde 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1106,6 +1106,73 @@ static int check_partition_desc(struct super_block *sb,
return 0;
}
+/*
+ * Check the Unallocated Space Table once when it is loaded: the allocator
+ * hands out blocks from the start of each extent and trusts that every
+ * extent covers at least one whole block inside the partition.
+ */
+static int udf_check_unalloc_table(struct super_block *sb,
+ struct inode *table, u32 partition_len)
+{
+ struct extent_position epos = {
+ .block = UDF_I(table)->i_location,
+ .offset = sizeof(struct unallocSpaceEntry),
+ };
+ struct kernel_lb_addr eloc;
+ uint32_t elen, blocks;
+ struct kernel_lb_addr seen_block = {};
+ uint32_t seen_offset = 0;
+ u64 steps = 0, period = 1;
+ int8_t etype;
+ int ret;
+
+ /* The walk below assumes the layout of an Unallocated Space Entry */
+ if (!UDF_I(table)->i_use) {
+ udf_err(sb, "unallocated space table is not an unallocated space entry\n");
+ return -EFSCORRUPTED;
+ }
+
+ while ((ret = udf_next_aext(table, &epos, &eloc, &elen, &etype, 1)) > 0) {
+ blocks = elen >> sb->s_blocksize_bits;
+ if (!blocks || (elen & (sb->s_blocksize - 1)) ||
+ eloc.logicalBlockNum >= partition_len ||
+ blocks > partition_len - eloc.logicalBlockNum) {
+ udf_err(sb, "invalid unallocated space table extent (block %u, length %u)\n",
+ eloc.logicalBlockNum, elen);
+ ret = -EFSCORRUPTED;
+ break;
+ }
+ /*
+ * A chain of allocation extents can lead back to itself, and
+ * then the walk returns the same extents forever. Remember a
+ * position at doubling intervals; a walk that comes back to it
+ * is in a loop.
+ */
+ if (epos.block.logicalBlockNum == seen_block.logicalBlockNum &&
+ epos.block.partitionReferenceNum ==
+ seen_block.partitionReferenceNum &&
+ epos.offset == seen_offset) {
+ udf_err(sb, "unallocated space table loops back on itself\n");
+ ret = -EFSCORRUPTED;
+ break;
+ }
+ if (++steps == period) {
+ seen_block = epos.block;
+ seen_offset = epos.offset;
+ steps = 0;
+ period <<= 1;
+ }
+ if (fatal_signal_pending(current)) {
+ udf_err(sb, "interrupted while checking the unallocated space table\n");
+ ret = -EINTR;
+ break;
+ }
+ cond_resched();
+ }
+ brelse(epos.bh);
+ return ret;
+}
+
static int udf_fill_partdesc_info(struct super_block *sb,
struct partitionDesc *p, int p_index)
{
@@ -1166,6 +1233,16 @@ static int udf_fill_partdesc_info(struct super_block *sb,
p_index);
return PTR_ERR(inode);
}
+ err = udf_check_unalloc_table(sb, inode, map->s_partition_len);
+ if (err) {
+ iput(inode);
+ if (err == -EINTR)
+ return err;
+ if (!sb_rdonly(sb))
+ return -EACCES;
+ UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT);
+ return 0;
+ }
map->s_uspace.s_table = inode;
map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_TABLE;
udf_debug("unallocSpaceTable (part %d) @ %llu\n",
@@ -2233,8 +2310,9 @@ static int udf_fill_super(struct super_block *sb, struct fs_context *fc)
/*
* EACCES is special - we want to propagate to
* upper layers that we cannot handle RW mount.
+ * EINTR means that a fatal signal is pending.
*/
- if (ret == -EACCES)
+ if (ret == -EACCES || ret == -EINTR)
break;
} else
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 414/507] udf: fix preallocation discarding before an empty allocation extent
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (412 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 413/507] udf: check the unallocated space table when it is loaded Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 415/507] udf: dont use eloc after the end of the unallocated space table Greg Kroah-Hartman
` (92 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jan Kara, Matthias Goergens,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthias Goergens <matthias.goergens@gmail.com>
[ Upstream commit 0c52750caaaccee8b0e929450fe6538ec4985722 ]
udf_discard_prealloc() finds the last extent of a file by peeking at
the next one with udf_next_aext() and stopping when that returns 0.
The peek reads into eloc and elen, and the code then uses them as the
last extent. But when udf_next_aext() returns 0 they hold no defined
value: if the extent list ends in a continuation descriptor that leads
to an empty allocation extent, they describe that continuation, i.e.
the block of the empty allocation extent, one block long.
The kernel creates such lists itself: when udf_delete_aext() removes
the only descriptor of the last allocation extent in a list, it leaves
that allocation extent empty and the continuation to it in place.
If the last extent is a preallocation, udf_discard_prealloc() deletes
it with udf_delete_aext(), which finds the following allocation extent
empty, so it also removes the continuation and frees that allocation
extent's block. udf_discard_prealloc() then frees eloc and elen: that
block a second time, instead of the preallocated blocks. On a space
bitmap the preallocated blocks leak and the free block count drifts.
On an unallocated space table the second free adds a second free
extent for the same block, which is later handed out twice: fsx as run
by generic/091 and generic/263 ends up with two parts of its test file
in one block and reads back bad data.
Peek into separate variables, so that eloc and elen keep the last
extent that udf_next_aext() returned with 1.
Fixes: cfe4c1b25dd6 ("udf: Fix preallocation discarding at indirect extent boundary")
Cc: stable@vger.kernel.org
Suggested-by: Jan Kara <jack@suse.cz>
Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com>
Link: https://patch.msgid.link/480eccd1264a4cea5226fc36ed108931b2c403fb.1793349907.git.matthias.goergens@gmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/udf/truncate.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
index 0990f94b85518..75151a59f0da6 100644
--- a/fs/udf/truncate.c
+++ b/fs/udf/truncate.c
@@ -124,8 +124,8 @@ void udf_discard_prealloc(struct inode *inode)
{
struct extent_position epos = {};
struct extent_position prev_epos = {};
- struct kernel_lb_addr eloc;
- uint32_t elen;
+ struct kernel_lb_addr eloc, tmpeloc;
+ uint32_t elen, tmpelen;
uint64_t lbcount = 0;
int8_t etype = -1;
struct udf_inode_info *iinfo = UDF_I(inode);
@@ -141,7 +141,8 @@ void udf_discard_prealloc(struct inode *inode)
/* Find the last extent in the file */
while (1) {
- ret = udf_next_aext(inode, &epos, &eloc, &elen, &tmpetype, 0);
+ ret = udf_next_aext(inode, &epos, &tmpeloc, &tmpelen,
+ &tmpetype, 0);
if (ret < 0)
goto out;
if (ret == 0)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 415/507] udf: dont use eloc after the end of the unallocated space table
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (413 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 414/507] udf: fix preallocation discarding before an empty allocation extent Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 416/507] MIPS: mm: Fix the cache error vector jump for XKPHYS kernels Greg Kroah-Hartman
` (91 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthias Goergens, Jan Kara,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthias Goergens <matthias.goergens@gmail.com>
[ Upstream commit 94401199df90e1c2a50c6e4b73618ac5a4ba83ba ]
When udf_next_aext() returns 0, its eloc, elen and etype outputs hold
no defined value. Two walks of the unallocated space table still use
eloc after the walk has reached the end of the table.
udf_table_prealloc_blocks() looks for a free extent starting at
first_block and decides whether it found one by comparing eloc with
first_block after the walk. If the table's list ends in a continuation
descriptor that leads to an empty allocation extent, eloc is then the
block of that allocation extent, which is in use, and if that is
first_block, the block is handed out as preallocation. Once
udf_discard_prealloc() no longer frees the wrong block, this is what
still makes fsx in generic/091 and generic/263 read back bad data on a
table, in about one run in four. Only take the extent if the walk
stopped at it.
When udf_table_free_blocks() cannot merge the freed blocks into an
existing extent, it appends a new one and sets only its block number,
so the partition reference comes from whatever eloc held after the
walk, and with long allocation descriptors it is written to disk. For
a table without extents, eloc was never set. Take the partition
reference from the freed blocks instead. Short allocation descriptors
do not store the partition reference, which is why this half remains a
latent long-descriptor fix rather than a reproduced failure.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com>
Link: https://patch.msgid.link/fd9ca4c4ba98c00c012ec861f6c0bc08a3b1d07b.1793349907.git.matthias.goergens@gmail.com
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/udf/balloc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index 2ec577b4321c9..75124188e7452 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -457,6 +457,7 @@ static void udf_table_free_blocks(struct super_block *sb,
int adsize;
+ eloc.partitionReferenceNum = bloc->partitionReferenceNum;
eloc.logicalBlockNum = start;
elen = EXT_RECORDED_ALLOCATED |
(count << sb->s_blocksize_bits);
@@ -532,7 +533,7 @@ static int udf_table_prealloc_blocks(struct super_block *sb,
eloc.logicalBlockNum, elen, first_block);
}
- if (first_block == eloc.logicalBlockNum) {
+ if (ret > 0 && first_block == eloc.logicalBlockNum) {
epos.offset -= adsize;
alloc_count = (elen >> sb->s_blocksize_bits);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 416/507] MIPS: mm: Fix the cache error vector jump for XKPHYS kernels
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (414 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 7.3 415/507] udf: dont use eloc after the end of the unallocated space table Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 417/507] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only Greg Kroah-Hartman
` (90 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Imre Kaloz, Thomas Bogendoerfer,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Kaloz <kaloz@kernel.org>
[ Upstream commit 30b76362f80d39d80f1197c88b284d9fa7952356 ]
except_vec2_generic jumps to cache_parity_error with a j, which cannot
leave the vector's 256MB region. An XKPHYS kernel such as IP30's, linked
at 512MB, is outside it, so the j targets an unbacked address and its
speculative fetch raises bus errors on unrelated fetches. Jump to the
handler's uncached XKPHYS address instead.
Fixes: 7505576d1c1a ("MIPS: add support for SGI Octane (IP30)")
Cc: stable@vger.kernel.org
Signed-off-by: Imre Kaloz <kaloz@kernel.org>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/mips/mm/cex-gen.S | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/mips/mm/cex-gen.S b/arch/mips/mm/cex-gen.S
index e528583d13311..6989fe274aab8 100644
--- a/arch/mips/mm/cex-gen.S
+++ b/arch/mips/mm/cex-gen.S
@@ -8,6 +8,7 @@
*
* Cache error handler
*/
+#include <asm/addrspace.h>
#include <asm/asm.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
@@ -37,6 +38,21 @@
nop
nop
+#if defined(CONFIG_64BIT) && VMLINUX_LOAD_ADDRESS >= XKPHYS && \
+ VMLINUX_LOAD_ADDRESS < XKSEG
+ /*
+ * An XKPHYS kernel may lie outside the 256MB region a j from the
+ * vector reaches, so jump to the handler's uncached XKPHYS address.
+ */
+ PTR_LA k0, cache_parity_error
+ PTR_LI k1, TO_PHYS_MASK
+ and k0, k0, k1
+ PTR_LI k1, UNCAC_BASE
+ or k0, k0, k1
+ jr k0
+ nop
+#else
j cache_parity_error
nop
+#endif
END(except_vec2_generic)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 417/507] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (415 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 416/507] MIPS: mm: Fix the cache error vector jump for XKPHYS kernels Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 418/507] MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses Greg Kroah-Hartman
` (89 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Imre Kaloz, Thomas Bogendoerfer,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Kaloz <kaloz@kernel.org>
[ Upstream commit 4e65c502b8975e7c3c3d84aba59cd04af1dd6b8a ]
Masking PCI interrupts in the MACE PCI control register overwrites the
error and arbitration enables set at init, and a read-modify-write can
hang CRIME 1.1 machines under DMA load. Enable the slot interrupts once
and mask them in CRIME.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Imre Kaloz <kaloz@kernel.org>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/mips/pci/pci-ip32.c | 7 ++++--
arch/mips/sgi-ip32/ip32-irq.c | 45 +++--------------------------------
2 files changed, 8 insertions(+), 44 deletions(-)
diff --git a/arch/mips/pci/pci-ip32.c b/arch/mips/pci/pci-ip32.c
index 7ae89d0c70990..30aca6f76563d 100644
--- a/arch/mips/pci/pci-ip32.c
+++ b/arch/mips/pci/pci-ip32.c
@@ -125,10 +125,13 @@ static int __init mace_init(void)
{
PCIBIOS_MIN_IO = 0x1000;
- /* Clear any outstanding errors and enable interrupts */
+ /*
+ * Clear any outstanding errors and enable interrupts. PCI interrupts
+ * are masked in CRIME, so the per-slot enables stay on.
+ */
mace->pci.error_addr = 0;
mace->pci.error = 0;
- mace->pci.control = 0xff008500;
+ mace->pci.control = 0xff0085ff;
printk("MACE PCI rev %d\n", mace->pci.rev);
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index 29d04468a06b8..b9c72af481edb 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -160,38 +160,6 @@ static struct irq_chip crime_edge_interrupt = {
.irq_unmask = crime_enable_irq,
};
-/*
- * This is for MACE PCI interrupts. We can decrease bus traffic by masking
- * as close to the source as possible. This also means we can take the
- * next chunk of the CRIME register in one piece.
- */
-
-static unsigned long macepci_mask;
-
-static void enable_macepci_irq(struct irq_data *d)
-{
- macepci_mask |= MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
- mace->pci.control = macepci_mask;
- crime_mask |= 1 << (d->irq - CRIME_IRQ_BASE);
- crime->imask = crime_mask;
-}
-
-static void disable_macepci_irq(struct irq_data *d)
-{
- crime_mask &= ~(1 << (d->irq - CRIME_IRQ_BASE));
- crime->imask = crime_mask;
- flush_crime_bus();
- macepci_mask &= ~MACEPCI_CONTROL_INT(d->irq - MACEPCI_SCSI0_IRQ);
- mace->pci.control = macepci_mask;
- flush_mace_bus();
-}
-
-static struct irq_chip ip32_macepci_interrupt = {
- .name = "IP32 MACE PCI",
- .irq_mask = disable_macepci_irq,
- .irq_unmask = enable_macepci_irq,
-};
-
/* This is used for MACE ISA interrupts. That means bits 4-6 in the
* CRIME register.
*/
@@ -299,8 +267,8 @@ static struct irq_chip ip32_maceisa_edge_interrupt = {
.irq_unmask = enable_maceisa_irq,
};
-/* This is used for regular non-ISA, non-PCI MACE interrupts. That means
- * bits 0-3 and 7 in the CRIME register.
+/* This is used for regular non-ISA MACE interrupts. That means bits 0-3
+ * and 7-15 in the CRIME register.
*/
static void enable_mace_irq(struct irq_data *d)
@@ -436,20 +404,13 @@ void __init arch_init_irq(void)
mips_cpu_irq_init();
for (irq = CRIME_IRQ_BASE; irq <= IP32_IRQ_MAX; irq++) {
switch (irq) {
- case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
+ case MACE_VID_IN1_IRQ ... MACEPCI_SHARED2_IRQ:
irq_set_chip_and_handler_name(irq,
&ip32_mace_interrupt,
handle_level_irq,
"level");
break;
- case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ:
- irq_set_chip_and_handler_name(irq,
- &ip32_macepci_interrupt,
- handle_level_irq,
- "level");
- break;
-
case CRIME_CPUERR_IRQ:
case CRIME_MEMERR_IRQ:
irq_set_chip_and_handler_name(irq,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 418/507] MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (416 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 417/507] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 419/507] srcu: Add list_splice_init_srcu() Greg Kroah-Hartman
` (88 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Imre Kaloz, Thomas Bogendoerfer,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Kaloz <kaloz@kernel.org>
[ Upstream commit a55a7df2cf788234850d9053ecc25a5470175929 ]
mace_pci_read_config() clears the master abort interrupt enable in the
MACE PCI control register around each config read. A register read
followed by two register writes can hang CRIME 1.1 under DMA load.
Ack master aborts in the error register instead, and follow every
write with a read so back-to-back accesses cannot form that sequence.
Fixes: c990081bf87b ("[MIPS] Fix IP32 breakage")
Cc: stable@vger.kernel.org
Signed-off-by: Imre Kaloz <kaloz@kernel.org>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/mips/pci/ops-mace.c | 26 +++++++++++++++++++-------
arch/mips/pci/pci-ip32.c | 2 ++
2 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/arch/mips/pci/ops-mace.c b/arch/mips/pci/ops-mace.c
index 951d8070fb486..8827e5f2ea460 100644
--- a/arch/mips/pci/ops-mace.c
+++ b/arch/mips/pci/ops-mace.c
@@ -35,15 +35,27 @@ static inline int mkaddr(struct pci_bus *bus, unsigned int devfn,
(reg & 0xfc);
}
+/*
+ * On CRIME 1.1, a MACE PCI register read followed by two register writes
+ * can hang the machine under DMA load, so every register write in this
+ * file is followed by a read. Config cycles to empty slots end in a
+ * master abort; ack it with interrupts still off so the bridge error
+ * interrupt does not report it.
+ */
+static void mace_pci_ack_abort(void)
+{
+ u32 error = mace->pci.error;
+
+ if (error & MACEPCI_ERROR_MASTER_ABORT) {
+ mace->pci.error = error & ~MACEPCI_ERROR_MASTER_ABORT;
+ mace->pci.error;
+ }
+}
static int
mace_pci_read_config(struct pci_bus *bus, unsigned int devfn,
int reg, int size, u32 *val)
{
- u32 control = mace->pci.control;
-
- /* disable master aborts interrupts during config read */
- mace->pci.control = control & ~MACEPCI_CONTROL_MAR_INT;
mace->pci.config_addr = mkaddr(bus, devfn, reg);
switch (size) {
case 1:
@@ -56,9 +68,7 @@ mace_pci_read_config(struct pci_bus *bus, unsigned int devfn,
*val = mace->pci.config_data.l;
break;
}
- /* ack possible master abort */
- mace->pci.error &= ~MACEPCI_ERROR_MASTER_ABORT;
- mace->pci.control = control;
+ mace_pci_ack_abort();
/*
* someone forgot to set the ultra bit for the onboard
* scsi chips; we fake it here
@@ -77,6 +87,7 @@ mace_pci_write_config(struct pci_bus *bus, unsigned int devfn,
int reg, int size, u32 val)
{
mace->pci.config_addr = mkaddr(bus, devfn, reg);
+ mace->pci.error;
switch (size) {
case 1:
mace->pci.config_data.b[(reg & 3) ^ 3] = val;
@@ -88,6 +99,7 @@ mace_pci_write_config(struct pci_bus *bus, unsigned int devfn,
mace->pci.config_data.l = val;
break;
}
+ mace_pci_ack_abort();
DPRINTK("write%d: reg=%08x,val=%02x\n", size * 8, reg, val);
diff --git a/arch/mips/pci/pci-ip32.c b/arch/mips/pci/pci-ip32.c
index 30aca6f76563d..41ec8453c865d 100644
--- a/arch/mips/pci/pci-ip32.c
+++ b/arch/mips/pci/pci-ip32.c
@@ -77,6 +77,8 @@ static irqreturn_t macepci_error(int irq, void *dev)
}
mace->pci.error = flags;
+ /* follow the write with a read, see mace_pci_ack_abort() */
+ mace->pci.error;
return IRQ_HANDLED;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 419/507] srcu: Add list_splice_init_srcu()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (417 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 418/507] MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 420/507] nvme: wait for SRCU readers before splicing the namespace list Greg Kroah-Hartman
` (87 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Qiliang Yuan,
Paul E. McKenney, Keith Busch, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiliang Yuan <odys.yuan@gmail.com>
[ Upstream commit d06917d0ba226206dbd606330d73a8eb1e3029c1 ]
list_splice_init_rcu() makes a list look empty to new readers, waits for
the current ones with the given sync function, and only then links the
entries into the new list. The sync function takes no argument, so it
can wait for RCU readers but not for the readers of an srcu_struct.
Passing synchronize_rcu() for a list read under SRCU still builds, but
leaves SRCU readers on the entries while the last one's next pointer is
moved onto the new list head. nvme_remove_namespaces() does this today.
Add list_splice_init_srcu(), which waits for the readers of the given
srcu_struct instead.
Cc: stable@vger.kernel.org
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Qiliang Yuan <odys.yuan@gmail.com>
Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/srcu.h | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/include/linux/srcu.h b/include/linux/srcu.h
index 7d9bc06df98d0..1c221861ba43f 100644
--- a/include/linux/srcu.h
+++ b/include/linux/srcu.h
@@ -18,6 +18,7 @@
#include <linux/mutex.h>
#include <linux/rcupdate.h>
+#include <linux/rculist.h>
#include <linux/workqueue.h>
#include <linux/rcu_segcblist.h>
@@ -103,6 +104,41 @@ void call_srcu(struct srcu_struct *ssp, struct rcu_head *head,
void cleanup_srcu_struct(struct srcu_struct *ssp);
void synchronize_srcu(struct srcu_struct *ssp);
+/**
+ * list_splice_init_srcu - splice an SRCU-protected list into an existing list
+ * @list: the SRCU-protected list to splice
+ * @head: the place in the existing list to splice the first list into
+ * @ssp: the srcu_struct that readers of @list use
+ *
+ * Like list_splice_init_rcu(), but wait for the SRCU readers of @list
+ * instead of RCU ones, so that none of them can follow a next pointer
+ * onto @head.
+ *
+ * Note that this function blocks, and that the caller must prevent any
+ * other updates to @list.
+ */
+static inline void list_splice_init_srcu(struct list_head *list,
+ struct list_head *head,
+ struct srcu_struct *ssp)
+{
+ struct list_head *first = list->next;
+ struct list_head *last = list->prev;
+ struct list_head *next = head->next;
+
+ if (list_empty(list))
+ return;
+
+ INIT_LIST_HEAD_RCU(list);
+ synchronize_srcu(ssp);
+ ASSERT_EXCLUSIVE_ACCESS(*first);
+ ASSERT_EXCLUSIVE_ACCESS(*last);
+
+ last->next = next;
+ rcu_assign_pointer(list_next_rcu(head), first);
+ first->prev = head;
+ next->prev = last;
+}
+
#define SRCU_GET_STATE_COMPLETED 0x1
/**
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 420/507] nvme: wait for SRCU readers before splicing the namespace list
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (418 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 419/507] srcu: Add list_splice_init_srcu() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 421/507] nvmet: bound the traddr and trsvcid configfs writes Greg Kroah-Hartman
` (86 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qiliang Yuan, Christoph Hellwig,
Keith Busch, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiliang Yuan <odys.yuan@gmail.com>
[ Upstream commit 8a0449832b50cd4f99f2d2952cfc1476e5f26d0f ]
Readers walk ctrl->namespaces under ctrl->srcu, and some of them sleep
there, e.g. nvme_wait_freeze() waiting for I/O to drain.
nvme_remove_namespaces() moves the list onto its on-stack ns_list with
list_splice_init_rcu(), which only waits for RCU readers before
relinking the entries. A reader still on the last namespace then follows
its next pointer to ns_list instead of ctrl->namespaces and treats the
stack as a namespace. Deleting a controller while a Format NVM
passthrough waits for a delayed read on the last namespace gives:
BUG: KASAN: stack-out-of-bounds in nvme_wait_freeze+0x102/0x120
Read of size 8 at addr ff110001d2f3fc38 by task nvme/4413
Call Trace:
nvme_wait_freeze
nvme_passthru_start
nvme_submit_user_cmd
nvme_user_cmd
nvme_dev_ioctl
BUG: unable to handle page fault for address: ffffffff8af04850
Use list_splice_init_srcu() instead, which waits for the SRCU readers.
This also takes the RCU grace period out of every controller deletion.
Deleting 64 tcp controllers with one namespace each, median of 3 runs on
each of two boots per kernel:
before after
nvme disconnect-all (ms) 3491 / 3509 2996 / 3165
nvme_remove_namespaces() avg (ms) 39.0 / 40.5 31.9 / 34.7
Fixes: be647e2c76b2 ("nvme: use srcu for iterating namespace list")
Cc: stable@vger.kernel.org
Signed-off-by: Qiliang Yuan <odys.yuan@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/core.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 9ea9db0271c2d..a0811b49710ce 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -4755,9 +4755,8 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl)
nvme_change_ctrl_state(ctrl, NVME_CTRL_DELETING_NOIO);
mutex_lock(&ctrl->namespaces_lock);
- list_splice_init_rcu(&ctrl->namespaces, &ns_list, synchronize_rcu);
+ list_splice_init_srcu(&ctrl->namespaces, &ns_list, &ctrl->srcu);
mutex_unlock(&ctrl->namespaces_lock);
- synchronize_srcu(&ctrl->srcu);
list_for_each_entry_safe(ns, next, &ns_list, list)
nvme_ns_remove(ns);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 421/507] nvmet: bound the traddr and trsvcid configfs writes
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (419 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 420/507] nvme: wait for SRCU readers before splicing the namespace list Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 422/507] perf/core: Dont send SIGTRAP after exec removed the event Greg Kroah-Hartman
` (85 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shao Mingyin, Christoph Hellwig,
Keith Busch, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shao Mingyin <shao.mingyin@zte.com.cn>
[ Upstream commit cf399d4abbeddc317f8160a79fefb4016c469862 ]
nvmet_addr_traddr_store() and nvmet_addr_trsvcid_store() reject a write
only when count is larger than NVMF_TRADDR_SIZE (256) respectively
NVMF_TRSVCID_SIZE (32). A write of exactly that many characters is
accepted, and the following
sscanf(page, "%s\n", port->disc_addr.traddr)
has no field width. configfs terminates the buffer at page[count], so
the scan writes 256 characters plus the trailing NUL, i.e. 257 bytes,
into traddr[256]. The extra byte lands in the following tsas field of
the discovery log entry, silently clearing the first TSAS byte (the
RDMA queue type, or the TLS section type for TCP). trsvcid has the
same off-by-one with a 32-byte write; there the extra byte lands in
the reserved bytes that follow trsvcid.
Limit the scans to one byte less than the destination arrays. The
count checks can stay as they are so that a normal newline-terminated
write is still accepted.
Fixes: 9ba2a5cb8896 ("nvmet: filter newlines from user input")
Cc: stable@vger.kernel.org
Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/target/configfs.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index 83b86180c50f8..61107bcfc895e 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -150,7 +150,7 @@ static ssize_t nvmet_addr_traddr_store(struct config_item *item,
if (nvmet_is_port_enabled(port, __func__))
return -EACCES;
- if (sscanf(page, "%s\n", port->disc_addr.traddr) != 1)
+ if (sscanf(page, "%255s", port->disc_addr.traddr) != 1)
return -EINVAL;
return count;
}
@@ -242,7 +242,7 @@ static ssize_t nvmet_addr_trsvcid_store(struct config_item *item,
if (nvmet_is_port_enabled(port, __func__))
return -EACCES;
- if (sscanf(page, "%s\n", port->disc_addr.trsvcid) != 1)
+ if (sscanf(page, "%31s", port->disc_addr.trsvcid) != 1)
return -EINVAL;
return count;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 422/507] perf/core: Dont send SIGTRAP after exec removed the event
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (420 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 421/507] nvmet: bound the traddr and trsvcid configfs writes Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 423/507] sched/fair: Clear throttle state when leaving the fair class Greg Kroah-Hartman
` (84 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Danish Khateeb,
Peter Zijlstra (Intel), Ingo Molnar, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danish Khateeb <danishkhateeb03@gmail.com>
[ Upstream commit 6f083fbccd5f06889bc08e1182bd02c0383b9121 ]
A sigtrap event must also set remove_on_exec, so that its SIGTRAP never
reaches a program after exec. But the signal is sent from task work,
which only runs on the way back to user space. If the event overflows
shortly before execve(), the task work can still be pending when the
task enters execve(), and then runs when execve() returns. By then
perf_event_exec() has removed the event and the new program has default
signal handlers, so the SIGTRAP kills it.
The exec_stress test in the remove_on_exec selftest catches this and
fails about half the time in a VM. A process that opens a sigtrap event
on itself and then calls execve() is killed by SIGTRAP in 15% to 50% of
runs, both on an AMD machine running v7.2 and in a VM, with or without
close-on-exec on the event fd.
Commit ffb684f2aa14 ("perf: Fix race between perf_event_exit_task() and
perf_pending_task()") made perf_sigtrap() return once
perf_event_exit_task() has set ctx->task to TASK_TOMBSTONE. Exec only
calls perf_event_exit_task() when the new program is not dumpable, such
as a setuid one. An ordinary exec keeps the context and only removes the
remove_on_exec events, so the SIGTRAP is still sent.
perf_event_exit_event() sets PERF_EVENT_STATE_EXIT when exec removes the
event. If the event fd is close-on-exec and was the last reference to
the file, exec also queues the file release as task work. Task work runs
newest first, so perf_release() runs before the SIGTRAP work and moves
the event on to PERF_EVENT_STATE_DEAD. So don't send the signal when the
event state is PERF_EVENT_STATE_EXIT or lower, which means the event has
been removed. That also covers PERF_EVENT_STATE_REVOKED, where the PMU
is gone.
Fixes: 97ba62b27867 ("perf: Add support for SIGTRAP on perf events")
Assisted-by: LLM
Signed-off-by: Danish Khateeb <danishkhateeb03@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261015152013.106040-1-danishkhateeb03@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/events/core.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index c4217c996f5a1..9b90b6831de7c 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7634,6 +7634,15 @@ static void perf_sigtrap(struct perf_event *event)
if (event->ctx->task == TASK_TOMBSTONE)
return;
+ /*
+ * The event was removed after this signal was queued, e.g. by exec()
+ * (remove_on_exec), which may also have closed its fd (close-on-exec).
+ * The new program has default signal handlers, so a SIGTRAP would
+ * kill it.
+ */
+ if (READ_ONCE(event->state) <= PERF_EVENT_STATE_EXIT)
+ return;
+
/*
* We'd expect this to only occur if the irq_work is delayed and either
* ctx->task or current has changed in the meantime. This can be the
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 423/507] sched/fair: Clear throttle state when leaving the fair class
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (421 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 422/507] perf/core: Dont send SIGTRAP after exec removed the event Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 424/507] x86/nmi: Ignore negative NMI handler durations Greg Kroah-Hartman
` (83 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daehyeon Ko, Peter Zijlstra (Intel),
Ingo Molnar, Aaron Lu, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
[ Upstream commit c282051fc2cae2ea54770ebe435dbea090272c25 ]
Task-based CFS bandwidth throttling removes a task's fair sched_entity
while the scheduler core still considers the task queued. p->throttled
carries the fair-specific state across dequeue/enqueue operations.
DEQUEUE_CLASS removes the task from cfs_rq->throttled_limbo_list
but retains the bit. If the last finite CFS quota is disabled while
the task runs in another class, it is absent from the unthrottle walk and
the bit survives.
Returning to fair while cfs_bandwidth_used() is false then performs a real
fair enqueue with p->throttled still set.
After bandwidth is re-enabled, a class-change dequeue treats the
stale bit as limbo state and skips __dequeue_task(). p->se.on_rq therefore
remains set, and put_prev_task_fair() places the entity in the EEVDF tree
while the task moves to RT. On exit, the fair picker can select the
TASK_DEAD task. __schedule() then returns to do_task_dead(),
which hits BUG().
Keep p->throttled across migrations and group moves, but clear it on
DEQUEUE_CLASS because fair-specific state must not outlive fair-class
membership. A later return to fair uses the normal enqueue path. That path
still respects a throttled cfs_rq.
A KASAN, LOCKDEP and DEBUG_LIST v7.3 kernel reproduced the do_task_dead()
BUG in 3/3 root and 3/3 delegated uid-1000 runs with CapPrm=CapEff=0 and
RLIMIT_RTPRIO=1. The fix passed both matrices plus a 3/3 class-switch
control with bandwidth continuously enabled, without a scheduler warning,
KASAN report, lockdep splat or crash.
An AI coding assistant analyzed the state mismatch and drafted the initial
reproducer, fix candidate and this changelog. The source paths, trigger,
controls and results were rechecked against the cited revisions.
Fixes: e1fad12dcb66 ("sched/fair: Switch to task based throttle model")
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Aaron Lu <ziqianlu@bytedance.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261022235234.150957-1-4ncienth@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/sched/fair.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index b35e23f93bcd2..913630c0b0590 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -7021,8 +7021,8 @@ static void dequeue_throttled_task(struct task_struct *p, int flags)
WARN_ON_ONCE(p->se.on_rq);
list_del_init(&p->throttle_node);
- /* task blocked after throttled */
- if (flags & DEQUEUE_SLEEP) {
+ /* Task blocked after throttling or is leaving the fair class: */
+ if (flags & (DEQUEUE_SLEEP | DEQUEUE_CLASS)) {
p->throttled = false;
return;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 424/507] x86/nmi: Ignore negative NMI handler durations
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (422 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 423/507] sched/fair: Clear throttle state when leaving the fair class Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 425/507] iommu/amd: Skip non-IVMD entries when parsing IVRS memory definitions Greg Kroah-Hartman
` (82 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Breno Leitao, Peter Zijlstra (Intel),
Ingo Molnar, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <leitao@debian.org>
[ Upstream commit ade63af6cfb7b3ca19ced28730fd6461e8d1d410 ]
I am seeing NMI handlers in the Meta fleet reported as running for
about 584 years. Over 30 days, 11 AMD and Intel machines logged 637
such lines, for example:
AMD EPYC 9D25 (family 0x1a, model 0x11, stepping 0x0):
[ 1650.616627] INFO: NMI handler (nmi_cpu_backtrace_handler.llvm.9643156322683129580) took too long to run: 18446744073709.551 msecs
Intel Xeon Platinum 8321HC (family 0x6, model 0x55, stepping 0xb):
[360448.230129] INFO: NMI handler (perf_event_nmi_handler) took too long to run: 18446744071018.936 msecs
Intel Xeon D-2191A (family 0x6, model 0x55, stepping 0x4):
[81787.188959] INFO: NMI handler (ghes_notify_nmi) took too long to run: 18446744073709.545 msecs
nmi_handle() times each handler with two sched_clock() reads. When the
second read is lower than the first, the u64 subtraction wraps, and
nmi_check_duration() treats the result as a duration. In the three
examples, the clock went back by less than 1 us, by 2.7 s and by about
6 us.
The wrapped value is also stored in action->max_duration. Every later
real duration is smaller, so the handler is never reported again until
the next boot.
Whatever makes the clock read lower, a negative difference is not a
duration, so return before it is stored or reported. A clock that steps
forward is not covered, since that cannot be told from a real stall.
A backwards clock is still worth knowing about, so print the size of
the step once per boot. This uses pr_warn_once() rather than WARN, as a
stack trace says nothing about the clock and panic_on_warn machines
should not go down for it.
Fixes: 2ab00456ea8a ("x86: Warn when NMI handlers take large amounts of time")
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261027-nmi_negative-v1-1-b436a005eb8a@debian.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kernel/nmi.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
index 3c9f60d6ca5a7..cb46da482c855 100644
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -115,6 +115,14 @@ static void nmi_check_duration(struct nmiaction *action, u64 duration)
{
int remainder_ns, decimal_msecs;
+ /* sched_clock() went backwards? */
+ if ((s64)duration < 0) {
+ pr_warn_once("NMI handler (%ps): sched_clock() went backwards by %lld ns on CPU%d\n",
+ action->handler, -(s64)duration,
+ smp_processor_id());
+ return;
+ }
+
if (duration < nmi_longest_ns || duration < action->max_duration)
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 425/507] iommu/amd: Skip non-IVMD entries when parsing IVRS memory definitions
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (423 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 424/507] x86/nmi: Ignore negative NMI handler durations Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 426/507] iommu/amd: remove obsolete domain pointer warning on release Greg Kroah-Hartman
` (81 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Akshay Jindal, Vasant Hegde,
Joerg Roedel, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akshay Jindal <Akshay.Jindal@amd.com>
[ Upstream commit e62df37e0eff4d670e78bbd415be2c1675883c15 ]
init_memory_definitions() walks every top-level subtable including the
IVHD blocks (type 0x10/0x11/0x40) in the IVRS ACPI table. It interprets
each one as a 'struct ivmd_header', solely on m->flags, without first
checking that the subtable's type actually is one of the IVMD types
(ACPI_IVMD_TYPE, ACPI_IVMD_TYPE_ALL, ACPI_IVMD_TYPE_RANGE).
if (m->flags & (IVMD_FLAG_UNITY_MAP | IVMD_FLAG_EXCL_RANGE))
init_unity_map_range(m, table);
IVMD_FLAG_UNITY_MAP (0x01) occupies the same bit position as the IVHD
flags field's HtTunEn bit. Unlike real hardware, QEMU's AMD IOMMU
emulation sets HtTunEn unconditionally (flags=0xD1 for type 0x10,
0x11 for type 0x11), so every QEMU-emitted IVHD block is misidentified
as a unity-map/exclusion-range IVMD entry, which subsequently results
in the creation of a bogus pci segment. Eg:
AMD-Vi: PCI segment : 0x4000, last bdf : 0x0000
Fix by checking the subtable's type before treating it as IVMD.
Fixes: be2a022c0dd0 ("x86, AMD IOMMU: add functions to parse IOMMU memory mapping requirements for devices")
Cc: stable@vger.kernel.org
Signed-off-by: Akshay Jindal <Akshay.Jindal@amd.com>
Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iommu/amd/init.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index 0506617b27c29..2632764197b04 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -2708,6 +2708,15 @@ static int __init init_unity_map_range(struct ivmd_header *m,
return 0;
}
+static bool ivrs_block_type_ivmd(u8 type)
+{
+ if (type == ACPI_IVMD_TYPE ||
+ type == ACPI_IVMD_TYPE_ALL ||
+ type == ACPI_IVMD_TYPE_RANGE)
+ return true;
+ return false;
+}
+
/* iterates over all memory definitions we find in the ACPI table */
static int __init init_memory_definitions(struct acpi_table_header *table)
{
@@ -2719,10 +2728,11 @@ static int __init init_memory_definitions(struct acpi_table_header *table)
while (p < end) {
m = (struct ivmd_header *)p;
+ p += m->length;
+ if (!ivrs_block_type_ivmd(m->type))
+ continue;
if (m->flags & (IVMD_FLAG_UNITY_MAP | IVMD_FLAG_EXCL_RANGE))
init_unity_map_range(m, table);
-
- p += m->length;
}
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 426/507] iommu/amd: remove obsolete domain pointer warning on release
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (424 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 425/507] iommu/amd: Skip non-IVMD entries when parsing IVRS memory definitions Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 427/507] arm64: kexec_file: Fix elf_headers memory leak in retry loop Greg Kroah-Hartman
` (80 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kevin Mitchell, Jason Gunthorpe,
Vasant Hegde, Joerg Roedel, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kevin Mitchell <kevmitch@arista.com>
[ Upstream commit fa77b023eb80cdb297ff32f6b13786e483a81ca8 ]
A warning is triggered in amd_iommu_release_device() on removal of a
device with an IOMMU_RESV_DIRECT region. The warning is based on the
false assumption that correct attachment to the release_domain will
always result in a NULL dev_data->domain pointer. For devices with
IOMMU_RESV_DIRECT (and consequently dev->iommu->require_direct), the
release domain is the permanent identity_domain which sets
itself to dev_data->domain on attach.
This behaviour was added in commit e94160488e65 ("iommu: Generic support
for RMRs during device release"). Commit c21b34762e2f ("iommu/amd: Set
release_domain to blocked_domain") caused it to take effect for AMD
IOMMU.
Remove the warning as it is no longer strictly an error to have a non-NULL
domain pointer. As this leaves amd_iommu_release_device() empty, remove it.
The warning was observed for a device with direct mapped region:
/sys/bus/pci/devices/0000:04:00.0/iommu_group/reserved_regions:
0x00000000fee00000 0x00000000feefffff msi
0x000000fd00000000 0x000000ffffffffff reserved
0x0000fffd00000000 0x0000ffffffffffff direct
Upon hotunplug:
[ 28.715475] pcieport 0000:00:03.1: pciehp: Slot(0-3): Link Down
[ 28.715482] pcieport 0000:00:03.1: pciehp: Slot(0-3): Card not present
[ 28.715601] ------------[ cut here ]------------
[ 28.715603] WARNING: drivers/iommu/amd/iommu.c:2521 at amd_iommu_release_device+0x5d/0x70, CPU#4: irq/29-pciehp/99
[ 28.715657] RIP: 0010:amd_iommu_release_device+0x5d/0x70
[ 28.715687] Call Trace:
[ 28.715689] <TASK>
[ 28.715694] iommu_deinit_device+0x84/0x110
[ 28.715699] __iommu_group_remove_device+0xa8/0xd0
[ 28.715703] iommu_bus_notifier+0x48/0x70
[ 28.715707] notifier_call_chain+0x48/0xe0
[ 28.715712] blocking_notifier_call_chain+0x45/0x60
[ 28.715716] bus_notify+0x3b/0x60
[ 28.715720] device_del+0x259/0x3b0
[ 28.715730] pci_remove_bus_device+0x85/0x100
[ 28.715735] pciehp_unconfigure_device+0x9d/0x180
[ 28.715743] __pciehp_disable_slot+0x47/0xe0
[ 28.715747] pciehp_handle_presence_or_link_change+0x80/0x5e0
[ 28.715753] pciehp_ist+0x162/0x290
Fixes: c21b34762e2f ("iommu/amd: Set release_domain to blocked_domain")
Cc: stable@vger.kernel.org
Signed-off-by: Kevin Mitchell <kevmitch@arista.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iommu/amd/iommu.c | 17 ++++-------------
1 file changed, 4 insertions(+), 13 deletions(-)
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 893cd2be11a26..b19496f8c1b0f 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -489,6 +489,10 @@ static void setup_aliases(struct amd_iommu *iommu, struct device *dev)
clone_aliases(iommu, dev);
}
+/*
+ * We keep dev_data around for unplugged devices and reuse it when the
+ * device is re-plugged - not doing so would introduce a ton of races.
+ */
static struct iommu_dev_data *find_dev_data(struct amd_iommu *iommu, u16 devid)
{
struct iommu_dev_data *dev_data;
@@ -2548,18 +2552,6 @@ static struct iommu_device *amd_iommu_probe_device(struct device *dev)
return iommu_dev;
}
-static void amd_iommu_release_device(struct device *dev)
-{
- struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
-
- WARN_ON(dev_data->domain);
-
- /*
- * We keep dev_data around for unplugged devices and reuse it when the
- * device is re-plugged - not doing so would introduce a ton of races.
- */
-}
-
static struct iommu_group *amd_iommu_device_group(struct device *dev)
{
if (dev_is_pci(dev))
@@ -3205,7 +3197,6 @@ const struct iommu_ops amd_iommu_ops = {
.domain_alloc_paging_flags = amd_iommu_domain_alloc_paging_flags,
.domain_alloc_sva = amd_iommu_domain_alloc_sva,
.probe_device = amd_iommu_probe_device,
- .release_device = amd_iommu_release_device,
.device_group = amd_iommu_device_group,
.get_resv_regions = amd_iommu_get_resv_regions,
.is_attach_deferred = amd_iommu_is_attach_deferred,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 427/507] arm64: kexec_file: Fix elf_headers memory leak in retry loop
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (425 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 426/507] iommu/amd: remove obsolete domain pointer warning on release Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 428/507] x86/boot: Fix off-by-one error in sme_clear_pgd() Greg Kroah-Hartman
` (79 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Will Deacon, Thomas Huth,
Breno Leitao, Andrew Morton, Yeoreum Yun, Baoquan He,
Catalin Marinas, Jinjie Ruan, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <ruanjinjie@huawei.com>
[ Upstream commit ac302aea3d824ccc99f29b8e499c365cb9a684a9 ]
A retry allocates new elf headers and overwrites image->elf_headers,
leaking the previous buffer.
Free it before assigning.
Cc: Will Deacon <will@kernel.org>
Cc: Thomas Huth <thuth@redhat.com>
Cc: Breno Leitao <leitao@debian.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Yeoreum Yun <yeoreum.yun@arm.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: stable@vger.kernel.org
Fixes: 108aa503657e ("arm64: kexec_file: try more regions if loading segments fails")
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Jinjie Ruan <ruanjinjie@huawei.com>
[catalin.marinas@arm.com: drop the redundant NULL check before vfree()]
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kernel/machine_kexec_file.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c
index 854d872dfd0f5..14f453dd09465 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -112,6 +112,8 @@ int load_other_segments(struct kimage *image,
vfree(headers);
goto out_err;
}
+
+ vfree(image->elf_headers);
image->elf_headers = headers;
image->elf_load_addr = kbuf.mem;
image->elf_headers_sz = headers_sz;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 428/507] x86/boot: Fix off-by-one error in sme_clear_pgd()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (426 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 427/507] arm64: kexec_file: Fix elf_headers memory leak in retry loop Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 429/507] arm64: sdei: Run the event handler on the kernel vectors Greg Kroah-Hartman
` (78 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thorsten Blum, Borislav Petkov (AMD),
Tom Lendacky, stable, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <blum@kernel.org>
[ Upstream commit cb319926808b1cca522d2087a13205e840beb45b ]
The mapping helpers __sme_map_range_pmd() and __sme_map_range_pte(), and
therefore sme_encrypt_kernel(), use exclusive end addresses and stop
before vaddr reaches vaddr_end.
However, sme_clear_pgd() treats vaddr_end as inclusive when calculating
the last PGD entry to clear. If vaddr_end is PGD-aligned, the first PGD
entry outside the range is cleared too.
Use vaddr_end - 1 to calculate the last PGD entry within the range.
Fixes: 6ebcb060713f ("x86/mm: Add support to encrypt the kernel in-place")
Signed-off-by: Thorsten Blum <blum@kernel.org>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Cc: <stable@kernel.org>
Link: https://patch.msgid.link/20260918142714.242711-2-blum@kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/boot/startup/sme.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/boot/startup/sme.c b/arch/x86/boot/startup/sme.c
index c07a2c381ed1f..2d5cb3f7eee63 100644
--- a/arch/x86/boot/startup/sme.c
+++ b/arch/x86/boot/startup/sme.c
@@ -99,7 +99,7 @@ static void __init sme_clear_pgd(struct sme_populate_pgd_data *ppd)
pgd_t *pgd_p;
pgd_start = ppd->vaddr & PGDIR_MASK;
- pgd_end = ppd->vaddr_end & PGDIR_MASK;
+ pgd_end = (ppd->vaddr_end - 1) & PGDIR_MASK;
pgd_size = (((pgd_end - pgd_start) / PGDIR_SIZE) + 1) * sizeof(pgd_t);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 429/507] arm64: sdei: Run the event handler on the kernel vectors
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (427 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 428/507] x86/boot: Fix off-by-one error in sme_clear_pgd() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 430/507] arm64: sdei: Preserve the interrupted contexts exception registers Greg Kroah-Hartman
` (77 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kiryl Shutsemau (Meta),
Catalin Marinas, Breno Leitao, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiryl Shutsemau (Meta) <kas@kernel.org>
[ Upstream commit 9bf6ee7952c7ee151c30e0fffcfc61b58127c899 ]
With KPTI, VBAR_EL1 holds the trampoline vectors from the return to EL0
until the next exception from EL0 maps the kernel and installs the
kernel vectors. The trampoline vectors only handle exceptions from EL0;
their current-EL half is zero-filled.
An SDEI event is dispatched regardless of PSTATE.DAIF, so it lands there
whenever the CPU is in user space. The SDEI entry trampoline maps the
kernel but leaves VBAR_EL1 alone. An exception taken by the handler then
executes the zeros, takes an undefined instruction exception to the same
vector, and loops there forever. The event never completes and the CPU
is lost; RCU stall reports are the first sign of it.
RAS notifications land in user space whenever a task consumes the
error, and NMI backtraces land wherever the CPU happens to be. The GHES
handler takes no exception on its own, but any exception in the handler
path does it: a WARN, a kprobe hit, or a fault fixed up by a _nofault()
accessor.
Install the kernel vectors in __sdei_handler() when VBAR_EL1 holds the
trampoline vectors, and restore it before returning to firmware. The
switch covers irqentry_nmi_enter() and irqentry_nmi_exit() too, as Usama
Arif pointed out: their tracepoints and context tracking WARNs can take
an exception as well.
The IRQ-like resume into user space must still go through the
trampoline to map the kernel. do_sdei_event() takes the interrupted
VBAR_EL1 and keeps basing the resume address on it.
Fixes: 79e9aa59dc29 ("arm64: sdei: Add trampoline code for remapping the kernel")
Cc: stable@vger.kernel.org
Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Tested-by: Breno Leitao <leitao@debian.org>
[catalin.marinas@arm.com: use raw_cpu_read() for this_cpu_vector]
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/include/asm/sdei.h | 3 ++-
arch/arm64/kernel/entry-common.c | 21 ++++++++++++++++++++-
arch/arm64/kernel/sdei.c | 6 ++++--
3 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/include/asm/sdei.h b/arch/arm64/include/asm/sdei.h
index b2248bd3cb58f..a78a5337ff854 100644
--- a/arch/arm64/include/asm/sdei.h
+++ b/arch/arm64/include/asm/sdei.h
@@ -44,7 +44,8 @@ asmlinkage unsigned long __sdei_handler(struct pt_regs *regs,
struct sdei_registered_event *arg);
unsigned long do_sdei_event(struct pt_regs *regs,
- struct sdei_registered_event *arg);
+ struct sdei_registered_event *arg,
+ unsigned long vbar);
unsigned long sdei_arch_get_entry_point(int conduit);
#define sdei_arch_get_entry_point(x) sdei_arch_get_entry_point(x)
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index 72c03ccea59fe..5e026311744a1 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -30,6 +30,7 @@
#include <asm/stacktrace.h>
#include <asm/sysreg.h>
#include <asm/system_misc.h>
+#include <asm/vectors.h>
/*
* Handle IRQ/context state management when entering from kernel mode.
@@ -1002,6 +1003,7 @@ asmlinkage void noinstr __noreturn handle_bad_stack(struct pt_regs *regs)
asmlinkage noinstr unsigned long
__sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg)
{
+ unsigned long vbar;
irqentry_state_t state;
unsigned long ret;
@@ -1027,10 +1029,27 @@ __sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg)
else if (cpu_has_pan())
set_pstate_pan(0);
+ /*
+ * With KPTI, VBAR_EL1 holds the trampoline vectors from the return to
+ * EL0 until the next exception from EL0 maps the kernel. They only
+ * handle exceptions from EL0: an exception taken here would run their
+ * empty current-EL half and never come back. Switch to the kernel
+ * vectors. The IRQ-like resume keeps using the interrupted VBAR, so it
+ * still goes through the trampoline.
+ */
+ vbar = read_sysreg(vbar_el1);
+ if (arm64_kernel_unmapped_at_el0() &&
+ vbar == (unsigned long)raw_cpu_read(this_cpu_vector)) {
+ write_sysreg((unsigned long)vectors, vbar_el1);
+ isb();
+ }
+
state = irqentry_nmi_enter(regs);
- ret = do_sdei_event(regs, arg);
+ ret = do_sdei_event(regs, arg, vbar);
irqentry_nmi_exit(regs, state);
+ write_sysreg(vbar, vbar_el1);
+
return ret;
}
#endif /* CONFIG_ARM_SDE_INTERFACE */
diff --git a/arch/arm64/kernel/sdei.c b/arch/arm64/kernel/sdei.c
index 778f2a1faac86..260c13106009c 100644
--- a/arch/arm64/kernel/sdei.c
+++ b/arch/arm64/kernel/sdei.c
@@ -200,16 +200,18 @@ unsigned long sdei_arch_get_entry_point(int conduit)
* SDEI_EV_HANDLED - success, return to the interrupted context.
* SDEI_EV_FAILED - failure, return this error code to firmware.
* virtual-address - success, return to this address.
+ *
+ * vbar is the interrupted context's VBAR_EL1, for the IRQ-like resume.
*/
unsigned long __kprobes do_sdei_event(struct pt_regs *regs,
- struct sdei_registered_event *arg)
+ struct sdei_registered_event *arg,
+ unsigned long vbar)
{
u32 mode;
int i, err = 0;
int clobbered_registers = 4;
u64 elr = read_sysreg(elr_el1);
u32 kernel_mode = read_sysreg(CurrentEL) | 1; /* +SPSel */
- unsigned long vbar = read_sysreg(vbar_el1);
if (arm64_kernel_unmapped_at_el0())
clobbered_registers++;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 430/507] arm64: sdei: Preserve the interrupted contexts exception registers
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (428 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 429/507] arm64: sdei: Run the event handler on the kernel vectors Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 431/507] ata: libata-pmp: disable the SEMB port on Marvell 88SM9705 Greg Kroah-Hartman
` (76 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kiryl Shutsemau (Meta), Breno Leitao,
Catalin Marinas, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiryl Shutsemau (Meta) <kas@kernel.org>
[ Upstream commit 58c1eb84e97701c583605ba2fd553b69afba2245 ]
An SDEI event is dispatched by firmware regardless of PSTATE.DAIF, so it
can interrupt the kernel where the exception registers are live:
- exception entry, before kernel_entry has saved ELR_EL1/SPSR_EL1 and
before the C handler has read ESR_EL1/FAR_EL1;
- exception return, after kernel_exit has loaded ELR_EL1/SPSR_EL1 and
before the ERET.
An IRQ or pseudo-NMI cannot arrive there with PSTATE.I set. Firmware
saves only x0-x17, PC and PSTATE around an SDEI event, so a synchronous
exception taken by the handler overwrites the interrupted context's
ELR, SPSR, ESR and FAR. do_sdei_event() only notices that ELR changed,
and warns.
The interrupted context then carries on with the handler's state. A
task interrupted on its way into the kernel can be sent SIGILL for the
handler's kernel data abort. A task interrupted on its way back to user
space ERETs to EL1, at the handler's fixup address, with user registers
loaded.
With SDEI delivering NMI backtraces, this happens in normal operation.
The handler runs show_regs(), which reads through possibly-NULL pointers
with the _nofault() accessors. print_worker_info() faults this way for a
kworker that is not running a work item, and a single sysrq-l warned
once per such kworker.
Save ELR, SPSR, ESR and FAR in __sdei_handler() before
irqentry_nmi_enter(), which can take an exception too, and restore them
after irqentry_nmi_exit().
Once they are restored, a nested exception is harmless if its handler is
safe in NMI context. That holds for EL1 data aborts on translation,
permission and access-flag faults, which never take the mmap lock in NMI
context, and for BRK. Warn once, with the syndrome, about any other
exception class.
Fixes: f5df26961853 ("arm64: kernel: Add arch-specific SDEI entry code and CPU masking")
Cc: stable@vger.kernel.org
Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Tested-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kernel/entry-common.c | 21 ++++++++++++-
arch/arm64/kernel/sdei.c | 53 ++++++++++++++++++++++++++------
2 files changed, 64 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index 5e026311744a1..92b2fe0b27849 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -1003,7 +1003,7 @@ asmlinkage void noinstr __noreturn handle_bad_stack(struct pt_regs *regs)
asmlinkage noinstr unsigned long
__sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg)
{
- unsigned long vbar;
+ unsigned long elr, spsr, esr, far, vbar;
irqentry_state_t state;
unsigned long ret;
@@ -1029,6 +1029,17 @@ __sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg)
else if (cpu_has_pan())
set_pstate_pan(0);
+ /*
+ * Nothing saved the interrupted context's exception registers on the
+ * way in, and it may be in the middle of exception entry or return
+ * (SDEI ignores DAIF). Save them before anything can take an exception
+ * and overwrite them.
+ */
+ elr = read_sysreg(elr_el1);
+ spsr = read_sysreg(spsr_el1);
+ esr = read_sysreg(esr_el1);
+ far = read_sysreg(far_el1);
+
/*
* With KPTI, VBAR_EL1 holds the trampoline vectors from the return to
* EL0 until the next exception from EL0 maps the kernel. They only
@@ -1048,6 +1059,14 @@ __sdei_handler(struct pt_regs *regs, struct sdei_registered_event *arg)
ret = do_sdei_event(regs, arg, vbar);
irqentry_nmi_exit(regs, state);
+ /*
+ * Put them back unconditionally. An unchanged ELR does not rule out a
+ * nested exception: one may have returned to the same address.
+ */
+ write_sysreg(elr, elr_el1);
+ write_sysreg(spsr, spsr_el1);
+ write_sysreg(esr, esr_el1);
+ write_sysreg(far, far_el1);
write_sysreg(vbar, vbar_el1);
return ret;
diff --git a/arch/arm64/kernel/sdei.c b/arch/arm64/kernel/sdei.c
index 260c13106009c..1b902da8ba43c 100644
--- a/arch/arm64/kernel/sdei.c
+++ b/arch/arm64/kernel/sdei.c
@@ -195,6 +195,31 @@ unsigned long sdei_arch_get_entry_point(int conduit)
return 0;
}
+/*
+ * Exceptions an SDEI handler may take without harm once __sdei_handler() has
+ * restored the interrupted context's exception registers. Their handlers are
+ * safe in NMI context:
+ * - EL1 data aborts on translation, permission and access-flag faults:
+ * faulthandler_disabled() is true in NMI context, so do_page_fault() never
+ * takes the mmap lock. This covers the _nofault() accessors used by the
+ * generic dump_stack()/show_regs() code (e.g. print_worker_info()).
+ * - BRK: kprobes, WARN/BUG, kCFI and UBSAN traps, all NMI-capable.
+ * Anything else taken at EL1 is fatal on its own, or unexpected here.
+ */
+static bool sdei_nested_exception_ok(unsigned long esr)
+{
+ switch (ESR_ELx_EC(esr)) {
+ case ESR_ELx_EC_DABT_CUR:
+ return esr_fsc_is_translation_fault(esr) ||
+ esr_fsc_is_permission_fault(esr) ||
+ esr_fsc_is_access_flag_fault(esr);
+ case ESR_ELx_EC_BRK64:
+ return true;
+ default:
+ return false;
+ }
+}
+
/*
* do_sdei_event() returns one of:
* SDEI_EV_HANDLED - success, return to the interrupted context.
@@ -211,6 +236,7 @@ unsigned long __kprobes do_sdei_event(struct pt_regs *regs,
int i, err = 0;
int clobbered_registers = 4;
u64 elr = read_sysreg(elr_el1);
+ u64 nested_elr, nested_esr, nested_far;
u32 kernel_mode = read_sysreg(CurrentEL) | 1; /* +SPSel */
if (arm64_kernel_unmapped_at_el0())
@@ -223,18 +249,27 @@ unsigned long __kprobes do_sdei_event(struct pt_regs *regs,
}
err = sdei_event_handler(regs, arg);
- if (err)
- return SDEI_EV_FAILED;
- if (elr != read_sysreg(elr_el1)) {
- /*
- * We took a synchronous exception from the SDEI handler.
- * This could deadlock, and if you interrupt KVM it will
- * hyp-panic instead.
- */
- pr_warn("unsafe: exception during handler\n");
+ /*
+ * A synchronous exception taken by the handler has overwritten the
+ * exception registers; __sdei_handler() puts them back. Only the last
+ * one's syndrome survives; report it if it is not one known to be
+ * harmless.
+ *
+ * If the event interrupted a KVM world switch, VBAR points at the KVM
+ * hyp vectors and any such exception is a hyp panic instead.
+ */
+ nested_elr = read_sysreg(elr_el1);
+ nested_esr = read_sysreg(esr_el1);
+ nested_far = read_sysreg(far_el1);
+ if (nested_elr != elr && !sdei_nested_exception_ok(nested_esr)) {
+ pr_warn_once("unexpected exception during handler: ESR %#llx FAR %#llx near %pS\n",
+ nested_esr, nested_far, (void *)nested_elr);
}
+ if (err)
+ return SDEI_EV_FAILED;
+
mode = regs->pstate & (PSR_MODE32_BIT | PSR_MODE_MASK);
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 431/507] ata: libata-pmp: disable the SEMB port on Marvell 88SM9705
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (429 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 430/507] arm64: sdei: Preserve the interrupted contexts exception registers Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 432/507] x86/mm: Fix global ASID handed out to two processes Greg Kroah-Hartman
` (75 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyrylo Biryuk, Marco Ziliani,
Niklas Cassel, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marco Ziliani <rylos78@gmail.com>
[ Upstream commit 6b67cdb463b006e57f15e3fe4ea03b00f0ac9ee5 ]
The Marvell 88SM9705 is a 1-to-5 SATA port multiplier with one
additional SEMB (SATA Enclosure Management Bridge) port [1]. Ports
0-4 are device ports and port 5 is the SEMB. The number of fan-out
ports in GSCR[2] is 6 when the SEMB is enabled and 5 when it is not,
so on boards without the SEMB there is no link 5 and this quirk does
nothing. That includes the common 8-port PCIe cards that pair an
88SE9215 with an 88SM9705, which report 5 ports.
The SEMB port never answers SRST. libata probes it like a device
port, and every EH round on the PMP ends in a retry loop that lasts
about a minute before EH gives up, then starts over:
ata19.15: Port Multiplier 1.2, 0x1b4b:0x9705 r160, 6 ports, feat 0x1/0x1f
ata19.05: hard resetting link
ata19.05: failed to resume link (SControl 0)
ata19.05: softreset failed (1st FIS failed)
ata19.05: hard resetting link
...
ata20.05: reset failed, giving up
Disk discovery waits for this, including disks on other controllers.
libata.force only partly works around it. The "disable" horkage
only takes effect after IDENTIFY, which the SEMB link never reaches.
"norst" on port 5 stops the retry loop, but the disks still come up
about a minute later than with this change (see below).
Treat port 5 the same way as port 4 of the Marvell 88SM4140 and mark
the link ATA_LFLAG_DISABLED.
Tested on a Synology DX1222 expansion unit (four 88SM9705 r160 behind
a Marvell 88SE9235, passed through to a KVM guest, 6 disks), 7.4-rc1
with and without this change, one boot each:
softreset reset failed, last disk
failed giving up attached
7.4-rc1, no libata.force 60 12 197 s
7.4-rc1, libata.force=N.05:norst 0 0 70 s
7.4-rc1 + this patch, no force 0 0 11 s
The problem was first found on a Synology DX1215 with the same chain,
where this change brought the disks up after about 20 s instead of
about 200 s, including a disk on a separate AHCI controller.
Each PMP still logs one "failed to resume link (SControl 0)" for port 5
at probe time.
Link: https://www.marvell.com/content/dam/marvell/en/public-collateral/storage/marvell-storage-88sm9705-functional-specifications-2015-06.pdf [1]
Cc: stable@vger.kernel.org
Tested-by: Kyrylo Biryuk <illofspeed@gmail.com>
Signed-off-by: Marco Ziliani <rylos78@gmail.com>
Link: https://lore.kernel.org/r/20261107-pmp-88sm9705-v2-1-18eed983d3db@gmail.com
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ata/libata-pmp.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index 904f418387d11..43991e54eb081 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -482,6 +482,20 @@ static void sata_pmp_quirks(struct ata_port *ap)
if (link->pmp == 4)
link->flags |= ATA_LFLAG_DISABLED;
}
+ } else if (vendor == 0x1b4b && devid == 0x9705) {
+ /*
+ * Marvell 88SM9705 quirks
+ *
+ * 1-to-5 PMP with an extra SEMB port. It reports 6 ports and
+ * port 5 is the SEMB, which never answers SRST: EH spends about
+ * a minute per round retrying it, and disk discovery waits for
+ * that. Seen behind a Marvell 88SE9235 in the Synology DX1215
+ * and DX1222.
+ */
+ ata_for_each_link(link, ap, EDGE) {
+ if (link->pmp == 5)
+ link->flags |= ATA_LFLAG_DISABLED;
+ }
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 432/507] x86/mm: Fix global ASID handed out to two processes
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (430 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 431/507] ata: libata-pmp: disable the SEMB port on Marvell 88SM9705 Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 433/507] iommu/amd: Force device table to maximum size Greg Kroah-Hartman
` (74 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Rik van Riel,
Borislav Petkov (AMD), Thomas Gleixner, Dave Hansen, stable,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit 5cdc3746fa163fb4e8d05fa3cabf46bc6aa7df75 ]
On AMD CPUs with INVLPGB, two live processes can get the same MAX_ASID_AVAILABLE
global ASID value. The two then hit each other's TLB entries, so each can read
or corrupt the other's memory.
The global ASID space is managed lazily. When a global ASID is freed, its bit is
set in the global_asid_freed bitmap. Once the free ASID search reaches the end
of the global_asid_used bitmap, a global flush is done to really reclaim the
lazily freed global ASIDs.
However, the current code can assign the same global ASID to two different
processes, if one process is assigned MAX_ASID_AVAILABLE - 1, another process
MAX_ASID_AVAILABLE, and both stick around (keeping their global ASID numbers in
use) until the search wraps around again. At that point a third process could
also get assigned MAX_ASID_AVAILABLE.
the highest ASID stays in use, so it is not handed out again
last_global_asid stays below it, so no reset
the clear bits run out
find_next_zero_bit() returns MAX_ASID_AVAILABLE
global_asid_available > 0, so the failure is not caught
MAX_ASID_AVAILABLE is handed out as an ASID
A search only looks at the bits below MAX_ASID_AVAILABLE, so it cannot see that
this value is in use. The next failed search hands it out again, even if the
first process still holds it.
The fix used here is to reset the global ASID space after a failed search, and
to search again. If that search fails too, no global ASID is handed out.
The test for !global_asid_available is removed, because use_global_asid() only
calls allocate_global_asid() if global_asid_available > 0. The remaining test is
for a condition that should be impossible.
[ riel: simplify code, massage changelog and comment ]
Fixes: d504d1247e36 ("x86/mm: Add global ASID allocation helper functions")
Signed-off-by: Chris Mason <mason@kernel.org>
Signed-off-by: Rik van Riel <riel@surriel.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Cc: <stable@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/mm/tlb.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 0c4da320831cb..53dcab39566f2 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -320,13 +320,19 @@ static u16 allocate_global_asid(void)
lockdep_assert_held(&global_asid_lock);
- /* The previous allocation hit the edge of available address space */
- if (last_global_asid >= MAX_ASID_AVAILABLE - 1)
- reset_global_asid_space();
-
asid = find_next_zero_bit(global_asid_used, MAX_ASID_AVAILABLE, last_global_asid);
- if (asid >= MAX_ASID_AVAILABLE && !global_asid_available) {
+ /*
+ * Nothing is free between last_global_asid and MAX_ASID_AVAILABLE.
+ * Flush lazy-freed ASIDs and reset the search space.
+ */
+ if (asid >= MAX_ASID_AVAILABLE) {
+ reset_global_asid_space();
+ asid = find_next_zero_bit(global_asid_used, MAX_ASID_AVAILABLE,
+ last_global_asid);
+ }
+
+ if (asid >= MAX_ASID_AVAILABLE) {
/* This should never happen. */
VM_WARN_ONCE(1, "Unable to allocate global ASID despite %d available\n",
global_asid_available);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 433/507] iommu/amd: Force device table to maximum size
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (431 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 432/507] x86/mm: Fix global ASID handed out to two processes Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 434/507] ceph: clamp the inline data length in ceph_fill_inline_data() Greg Kroah-Hartman
` (73 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Suravee Suthikulpanit, Joerg Roedel,
Linus Torvalds
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
commit 6e2213dae78b41976c60133eb10cf99e81916638 upstream.
IOMMU can perform out-of-bounds read of the device table entry (DTE)
that is adjacent to the last DTE and falls outside the device table.
For example, if the device table can hold 0 to N-1 entries, then the
IOMMU can be made to fetch the Nth entry, which falls outside the
device table.
The device table is owned by the hypervisor (HV) and is assigned in 4KB
pages that are contiguous in system physical address (SPA). If the
out-of-bound DTE falls on a guest-owned page, then the guest can exploit
this bug to setup malicious table walks to corrupt HV pages and/or bring
down the system. Note that this bug does not manifest when the device
table size is set to its maximum size of 2MB.
Therefore, force the device table size to the maximum 2MB on affected
processors. These are CPU family 0x17 (Zen1/Zen2) through family 0x1a
(Zen5/BRH).
This is a mitigation for CVE-2024-21963.
kdump reuses the previous kernel's device table only when the size
encoded in the IOMMU device-table register matches
pci_seg->dev_table_size. A mixed rollout disagrees: the unpatched
kernel uses the IVRS-derived size and the patched kernel uses 2MB,
so __reuse_device_table() rejects the table. On SNP-capable IOMMUs
that rejection panics the kdump kernel. Kernels that both have this
patch agree on 2MB and reuse succeeds. Update the production kernel
and the crash kernel together.
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iommu/amd/init.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -1720,6 +1720,21 @@ static int __init init_iommu_from_acpi(s
return 0;
}
+/*
+ * Apply workaround for Zen1 to Zen5(BRH) generation of processors.
+ * References: CVE-2024-21963
+ */
+static bool __init amd_iommu_force_max_dev_table(void)
+{
+ if (boot_cpu_data.x86 >= 0x17 && boot_cpu_data.x86 <= 0x1a) {
+ if (cpu_feature_enabled(X86_FEATURE_ZEN6))
+ return false;
+ else
+ return true;
+ }
+ return false;
+}
+
/* Allocate PCI segment data structure */
static struct amd_iommu_pci_seg *__init alloc_pci_segment(u16 id,
struct acpi_table_header *ivrs_base)
@@ -1742,9 +1757,15 @@ static struct amd_iommu_pci_seg *__init
pci_seg->last_bdf = last_bdf;
DUMP_printk("PCI segment : 0x%0x, last bdf : 0x%04x\n", id, last_bdf);
- pci_seg->dev_table_size =
- max(roundup_pow_of_two((last_bdf + 1) * DEV_TABLE_ENTRY_SIZE),
- SZ_4K);
+ if (amd_iommu_force_max_dev_table()) {
+ pr_info("Force device table to maximum size\n");
+ pci_seg->dev_table_size = SZ_2M;
+ } else {
+ pci_seg->dev_table_size =
+ max(roundup_pow_of_two((last_bdf + 1) *
+ DEV_TABLE_ENTRY_SIZE),
+ SZ_4K);
+ }
pci_seg->id = id;
init_llist_head(&pci_seg->dev_data_list);
^ permalink raw reply [flat|nested] 508+ messages in thread
* [PATCH 7.3 434/507] ceph: clamp the inline data length in ceph_fill_inline_data()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (432 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 433/507] iommu/amd: Force device table to maximum size Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 435/507] vxlan: Stop rejecting dynamic FDB entries with a nexthop ID Greg Kroah-Hartman
` (72 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guanglei Zhu, Alex Markuze,
Ilya Dryomov, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guanglei Zhu <zhugl3@xiaopeng.com>
[ Upstream commit 9c1d14d3b66b3e1dd96ee664c0dd2548f2b77a52 ]
The MDS decides how much inline data to attach to a reply, and the
client parses inline_len without any upper bound: ceph_decode_need()
only verifies that the message actually carries that many bytes.
ceph_fill_inline_data() then copies the data into a single page
with no length check, so a malicious or buggy MDS returning more
inline data than the page can hold writes past its end.
Clamp the length to PAGE_SIZE so both callers, handle_cap_grant()
and fill_inode(), are covered.
Cc: stable@vger.kernel.org
Fixes: 31c542a199d7 ("ceph: add inline data to pagecache")
Signed-off-by: Guanglei Zhu <zhugl3@xiaopeng.com>
Reviewed-by: Alex Markuze <amarkuze@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
[ Adapted for 7.3.y: folio_size()/memcpy_to_folio() → PAGE_SIZE and the page API; the trees with pr_warn_ratelimited_client() keep the warning (7.3, 6.18, 6.12, 6.6) and the trees without it (6.1, 5.15, 5.10) drop it. ]
Signed-off-by: Guanglei Zhu <zhugl3@xiaopeng.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ceph/addr.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index e07a7b1d3663c..f32a533f41009 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -2220,6 +2220,12 @@ void ceph_fill_inline_data(struct inode *inode, struct page *locked_page,
doutc(cl, "%p %llx.%llx len %zu locked_page %p\n", inode,
ceph_vinop(inode), len, locked_page);
+ if (len > PAGE_SIZE) {
+ pr_warn_ratelimited_client(cl, "oversized inline data %zu\n",
+ len);
+ len = PAGE_SIZE;
+ }
+
if (len > 0) {
void *kaddr = kmap_atomic(page);
memcpy(kaddr, data, len);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 435/507] vxlan: Stop rejecting dynamic FDB entries with a nexthop ID
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (433 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 434/507] ceph: clamp the inline data length in ceph_fill_inline_data() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 436/507] batman-adv: tt: only transmit local ROAM flag together with DEL Greg Kroah-Hartman
` (71 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sascha Frey, Ido Schimmel,
Nikolay Aleksandrov, Paolo Abeni, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <idosch@nvidia.com>
[ Upstream commit 7308ef8b4a6779a39f68d053c19b53a5c584a663 ]
Commit 98fc57d16744 ("vxlan: reject dynamic fdb entries that reference a
nexthop id") started rejecting FDB entries that point to FDB nexthops
unless they are configured as "permanent" or "static". The intent was to
prevent such entries from being aged out by vxlan_cleanup(), which runs
without RTNL and can therefore race with other VXLAN devices that modify
the same per-nexthop FDB list.
However, FRR installs remote MACs that are behind a multihomed Ethernet
Segment (EVPN-MH) as dynamic FDB entries that point to an FDB nexthop
group. Since the above commit, these entries are rejected and traffic
towards the corresponding MACs is flooded to all the remote VTEPs.
These entries are also marked as externally learned ("extern_learn")
and are therefore skipped by vxlan_cleanup(), but exempting externally
learned entries from the checks is not enough: vxlan_cleanup() reads
the state and flags of an entry without the hash lock, so an entry that
is concurrently changed from dynamic and externally learned to static
can still be aged out.
Instead, remove the checks added by the above commit and make
vxlan_cleanup() skip FDB entries that point to FDB nexthops. Such
entries can only be configured from user space, cannot be learned and
cannot roam, so there is no reason to age them out. The nexthop pointer
of an FDB entry is set before the entry is linked and is only cleared
after it was unlinked and an RCU grace period has passed, so it can be
checked without the hash lock.
Adjust the test cases added by the above commit and add a test case
that checks that dynamic FDB entries that point to FDB nexthops are not
aged out. Without the fix:
# ./fib_nexthops.sh -t "ipv4_fdb_grp_fcnal ipv6_fdb_grp_fcnal"
IPv4 fdb groups functional
--------------------------
[...]
TEST: Fdb mac add with nexthop group and dynamic state [FAIL]
TEST: Fdb mac add with nexthop group and extern_learn [FAIL]
TEST: Fdb mac without nexthop group aged out [ OK ]
TEST: Fdb mac with nexthop group not aged out [FAIL]
[...]
IPv6 fdb groups functional
--------------------------
[...]
TEST: Fdb mac add with nexthop group and dynamic state [FAIL]
TEST: Fdb mac add with nexthop group and extern_learn [FAIL]
TEST: Fdb mac without nexthop group aged out [ OK ]
TEST: Fdb mac with nexthop group not aged out [FAIL]
[...]
Tests passed: 44
Tests failed: 6
Tests skipped: 0
With the fix:
# ./fib_nexthops.sh -t "ipv4_fdb_grp_fcnal ipv6_fdb_grp_fcnal"
IPv4 fdb groups functional
--------------------------
[...]
TEST: Fdb mac add with nexthop group and dynamic state [ OK ]
TEST: Fdb mac add with nexthop group and extern_learn [ OK ]
TEST: Fdb mac without nexthop group aged out [ OK ]
TEST: Fdb mac with nexthop group not aged out [ OK ]
[...]
IPv6 fdb groups functional
--------------------------
[...]
TEST: Fdb mac add with nexthop group and dynamic state [ OK ]
TEST: Fdb mac add with nexthop group and extern_learn [ OK ]
TEST: Fdb mac without nexthop group aged out [ OK ]
TEST: Fdb mac with nexthop group not aged out [ OK ]
[...]
Tests passed: 50
Tests failed: 0
Tests skipped: 0
Fixes: 1274e1cc4226 ("vxlan: ecmp support for mac fdb entries")
Fixes: 98fc57d16744 ("vxlan: reject dynamic fdb entries that reference a nexthop id")
Cc: stable@vger.kernel.org
Reported-by: Sascha Frey <sf@techfak.net>
Closes: https://lore.kernel.org/netdev/20261028142928.GA8406@techfak.de/
Tested-by: Sascha Frey <sf@techfak.net>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20261030133750.28668-1-idosch@nvidia.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
[ idosch: fixed a small conflict in vxlan_fdb_add() and vxlan_cleanup() ]
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/vxlan/vxlan_core.c | 14 ++------
tools/testing/selftests/net/fib_nexthops.sh | 40 ++++++++++++++-------
2 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index 3390e341d1e58..7ecd73a5a3745 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -996,12 +996,6 @@ static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan,
return -EOPNOTSUPP;
}
- if (rcu_access_pointer(f->nh) &&
- !(state & (NUD_PERMANENT | NUD_NOARP))) {
- NL_SET_ERR_MSG(extack, "Cannot make a nexthop fdb dynamic");
- return -EOPNOTSUPP;
- }
-
/* Do not allow an externally learned entry to take over an entry added
* by the user.
*/
@@ -1263,11 +1257,6 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
if (err)
return err;
- if (nhid && !(ndm->ndm_state & (NUD_PERMANENT | NUD_NOARP))) {
- NL_SET_ERR_MSG(extack, "A nexthop fdb cannot be dynamic");
- return -EINVAL;
- }
-
if (vxlan->default_dst.remote_ip.sa.sa_family != ip.sa.sa_family)
return -EAFNOSUPPORT;
@@ -2887,6 +2876,9 @@ static void vxlan_cleanup(struct timer_list *t)
if (f->flags & NTF_EXT_LEARNED)
continue;
+ if (rcu_access_pointer(f->nh))
+ continue;
+
timeout = READ_ONCE(f->updated) + vxlan->cfg.age_interval * HZ;
if (time_before_eq(timeout, jiffies)) {
spin_lock(&vxlan->hash_lock);
diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh
index 431d7bed76224..adbec51917eb8 100755
--- a/tools/testing/selftests/net/fib_nexthops.sh
+++ b/tools/testing/selftests/net/fib_nexthops.sh
@@ -425,6 +425,14 @@ stop_ip_monitor()
return $rc
}
+fdb_entry_aged()
+{
+ local mac=$1
+ local dev=$2
+
+ ! $BRIDGE fdb get to $mac dev $dev self &> /dev/null
+}
+
check_nexthop_fdb_support()
{
$IP nexthop help 2>&1 | grep -q fdb
@@ -538,14 +546,18 @@ ipv6_fdb_grp_fcnal()
log_test $? 0 "Fdb mac add with nexthop group and static state"
run_cmd "$BRIDGE fdb add 02:02:00:00:00:16 dev vx10 nhid 102 self dynamic"
- log_test $? 255 "Fdb mac add with nexthop group and dynamic state"
+ log_test $? 0 "Fdb mac add with nexthop group and dynamic state"
+
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:17 dev vx10 nhid 102 self dynamic extern_learn"
+ log_test $? 0 "Fdb mac add with nexthop group and extern_learn"
- run_cmd "$BRIDGE fdb add 02:02:00:00:00:17 dev vx10 nhid 102 self"
- run_cmd "$BRIDGE fdb replace 02:02:00:00:00:17 dev vx10 dst 2001:db8:91::11 self dynamic"
- log_test $? 255 "Fdb mac replace with nexthop group and dynamic state"
+ run_cmd "$IP link set dev vx10 up type vxlan ageing 1"
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:18 dev vx10 dst 2001:db8:91::11 self dynamic"
+ slowwait 20 fdb_entry_aged 02:02:00:00:00:18 vx10
+ log_test $? 0 "Fdb mac without nexthop group aged out"
- run_cmd "$BRIDGE fdb append 02:02:00:00:00:17 dev vx10 dst 2001:db8:91::11 self dynamic"
- log_test $? 255 "Fdb mac append with nexthop group and dynamic state"
+ run_cmd "$BRIDGE fdb get to 02:02:00:00:00:16 dev vx10 self"
+ log_test $? 0 "Fdb mac with nexthop group not aged out"
run_cmd "$IP -6 ro add 2001:db8:101::1/128 nhid 66"
log_test $? 2 "Route add with fdb nexthop"
@@ -688,14 +700,18 @@ ipv4_fdb_grp_fcnal()
log_test $? 0 "Fdb mac add with nexthop group and static state"
run_cmd "$BRIDGE fdb add 02:02:00:00:00:16 dev vx10 nhid 102 self dynamic"
- log_test $? 255 "Fdb mac add with nexthop group and dynamic state"
+ log_test $? 0 "Fdb mac add with nexthop group and dynamic state"
+
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:17 dev vx10 nhid 102 self dynamic extern_learn"
+ log_test $? 0 "Fdb mac add with nexthop group and extern_learn"
- run_cmd "$BRIDGE fdb add 02:02:00:00:00:17 dev vx10 nhid 102 self"
- run_cmd "$BRIDGE fdb replace 02:02:00:00:00:17 dev vx10 dst 10.0.0.3 self dynamic"
- log_test $? 255 "Fdb mac replace with nexthop group and dynamic state"
+ run_cmd "$IP link set dev vx10 up type vxlan ageing 1"
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:18 dev vx10 dst 10.0.0.3 self dynamic"
+ slowwait 20 fdb_entry_aged 02:02:00:00:00:18 vx10
+ log_test $? 0 "Fdb mac without nexthop group aged out"
- run_cmd "$BRIDGE fdb append 02:02:00:00:00:17 dev vx10 dst 10.0.0.3 self dynamic"
- log_test $? 255 "Fdb mac append with nexthop group and dynamic state"
+ run_cmd "$BRIDGE fdb get to 02:02:00:00:00:16 dev vx10 self"
+ log_test $? 0 "Fdb mac with nexthop group not aged out"
run_cmd "$IP ro add 172.16.0.0/22 nhid 16"
log_test $? 2 "Route add with fdb nexthop"
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 436/507] batman-adv: tt: only transmit local ROAM flag together with DEL
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (434 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 435/507] vxlan: Stop rejecting dynamic FDB entries with a nexthop ID Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 437/507] batman-adv: tt: clear ROAM flag when re-adding a pending local client Greg Kroah-Hartman
` (70 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sven Eckelmann, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <sven@narfation.org>
commit 10f24f058417024a2c19cb8d88a6a0678a58a21b upstream.
BATADV_TT_CLIENT_ROAM is part of BATADV_TT_REMOTE_MASK but on the wire it
only has a defined meaning together with BATADV_TT_CLIENT_DEL: the
originator no longer serves the client because it roamed to another node.
Such a DEL is only relevant for events (non-full table requests).
An ADD carrying ROAM is processed (by accident) by the receiver like a
ROAMING_ADV: a newly created global entry is marked as roaming and is
excluded from the global CRC. But the sender includes it in its local CRC.
But such a behavior doesn't make sense for non-ROAM_ADV because a new TTVN
is meant as announced commit of the local TT table of a node and should
therefore not be used to create a temporary (roam) global entry in a node.
At the moment, such an ADD with the BATADV_TT_CLIENT_ROAM flag set can
happen due to two mechanisms:
batadv_tt_local_valid() copies all flags of the local entry into a full
table response. It is not synchronized with batadv_tt_local_mark_removed().
An entry which was marked as ROAM|PENDING by a ROAMING_ADV is still part of
the current TTVN and is sent with the ROAM flag set. The receivers then
create a roaming global entry for it and detect a CRC mismatch, which
causes them to request the full table again.
The same can happen for an ADD change which is queued for an entry which
(still) has the ROAM flag set. For example when only the dynamic WIFI or
ISOLA flags were updated.
It is not triggered by batadv_send_other_tt_response() because
batadv_tt_global_valid() is already taking care of filtering out
BATADV_TT_CLIENT_ROAM entries.
For the two problematic announcement mechanism, only send the ROAM flag of
local entries together with a DEL.
This only fixes the ROAM marking of the global entry and the resulting CRC
mismatch. When the requester of the full table is the node which sent the
ROAMING_ADV, the still announced entry will (independent of the ROAM flag)
cause batadv_tt_global_purge_local() to remove the requester's own (new)
local entry for the client. This is not addressed here.
Cc: stable@vger.kernel.org
Fixes: 27b37ebfa2d2 ("batman-adv: correctly pass the client flag on tt_response")
Fixes: 068ee6e204e1 ("batman-adv: roaming handling mechanism redesign")
[ use direct tt_common_entry->flags access ]
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/batman-adv/translation-table.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index b1dae5e1bc23d..d1b1b8459279b 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -436,7 +436,6 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
if (!tt_change_node)
return;
- tt_change_node->change.flags = flags;
memset(tt_change_node->change.reserved, 0,
sizeof(tt_change_node->change.reserved));
ether_addr_copy(tt_change_node->change.addr, common->addr);
@@ -444,6 +443,15 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
del_op_requested = flags & BATADV_TT_CLIENT_DEL;
+ /* the ROAM flag is only meaningful for the receiver in combination
+ * with a DEL. An ADD with ROAM would be interpreted as a roaming
+ * advertisement
+ */
+ if (!del_op_requested)
+ flags &= ~BATADV_TT_CLIENT_ROAM;
+
+ tt_change_node->change.flags = flags;
+
/* check for ADD+DEL, DEL+ADD, ADD+ADD or DEL+DEL events */
spin_lock_bh(&bat_priv->tt.changes_list_lock);
changes = READ_ONCE(bat_priv->tt.local_changes);
@@ -2851,8 +2859,12 @@ static bool batadv_tt_local_valid(const void *entry_ptr,
if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
return false;
+ /* the entry is (still) announced. A ROAM flag of an entry which is
+ * pending to be removed must not be transmitted. Otherwise, the
+ * receiver would handle it like a roaming advertisement
+ */
if (flags)
- *flags = tt_common_entry->flags;
+ *flags = tt_common_entry->flags & ~BATADV_TT_CLIENT_ROAM;
return true;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 437/507] batman-adv: tt: clear ROAM flag when re-adding a pending local client
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (435 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 436/507] batman-adv: tt: only transmit local ROAM flag together with DEL Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 438/507] batman-adv: tt: send ROAM_ADV on each roamed back client Greg Kroah-Hartman
` (69 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sven Eckelmann, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <sven@narfation.org>
commit cc2186d7854785b30d423f5d43757b086b300e55 upstream.
When a ROAMING_ADV is received for an announced local client,
batadv_tt_local_mark_removed() sets BATADV_TT_CLIENT_ROAM, queues a
DEL|ROAM change and marks the entry as BATADV_TT_CLIENT_PENDING. If the
client sends a frame again before the next TTVN commit,
batadv_tt_local_add_existing() only clears the PENDING flag and returns
early. The ADD cancels the queued DEL, but the entry keeps the ROAM flag:
* batadv_is_my_client() reports the client as not served by this node
* batadv_tt_local_client_is_roaming() reroutes unicast frames for it to
the node which sent the ROAMING_ADV
The ROAM flag is only removed with the next frame of the client.
Since BATADV_TT_CLIENT_ROAM is set together with BATADV_TT_CLIENT_PENDING,
it has to be cleared also at the same time with BATADV_TT_CLIENT_PENDING
when the client roamed back.
Cc: stable@vger.kernel.org
Fixes: 068ee6e204e1 ("batman-adv: roaming handling mechanism redesign")
[ adjust code still in batadv_tt_local_add ]
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/batman-adv/translation-table.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index d1b1b8459279b..0be2f693d5955 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -632,6 +632,7 @@ bool batadv_tt_local_add(struct net_device *mesh_iface, const u8 *addr,
bool iif_is_wifi = false;
struct hlist_head *head;
int packet_size_max;
+ bool added = false;
bool ret = false;
u8 remote_flags;
int hash_added;
@@ -664,7 +665,7 @@ bool batadv_tt_local_add(struct net_device *mesh_iface, const u8 *addr,
* flag can be reset like it was never enqueued
*/
tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING;
- goto add_event;
+ added = true;
}
if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) {
@@ -745,10 +746,12 @@ bool batadv_tt_local_add(struct net_device *mesh_iface, const u8 *addr,
goto out;
}
-add_event:
- batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS);
+ added = true;
check_roaming:
+ if (added)
+ batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS);
+
/* Check whether it is a roaming, but don't do anything if the roaming
* process has already been handled
*/
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 438/507] batman-adv: tt: send ROAM_ADV on each roamed back client
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (436 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 437/507] batman-adv: tt: clear ROAM flag when re-adding a pending local client Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 439/507] batman-adv: tt: only update flags for TT events Greg Kroah-Hartman
` (68 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sven Eckelmann, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <sven@narfation.org>
commit aff4d5d10f2dcb4a9b604e27414dafa1d51b6406 upstream.
When a ROAMING_ADV is received for an announced local client,
batadv_roam_tvlv_unicast_handler_v1() creates a global entry with the
BATADV_TT_CLIENT_ROAM flag set.
If the client sends a frame again before the next TTVN commit,
batadv_tt_local_add_roam() is expected to announce this return via a
ROAM_ADV frame. But this doesn't happen because the global entry (created
by the first ROAMING_ADV) carries BATADV_TT_CLIENT_ROAM until the new
originator announces the client.
Let batadv_tt_local_add_roam() always handle a roamed back client -
independent of the ROAM flag of the global entry:
* trigger sending of the ROAM_ADV frame(s)
* remove the (with the roaming) associated global entry
Cc: stable@vger.kernel.org
Fixes: 068ee6e204e1 ("batman-adv: roaming handling mechanism redesign")
[ adjust code still in batadv_tt_local_add ]
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/batman-adv/translation-table.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 0be2f693d5955..4ade3ca5af99c 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -755,7 +755,8 @@ bool batadv_tt_local_add(struct net_device *mesh_iface, const u8 *addr,
/* Check whether it is a roaming, but don't do anything if the roaming
* process has already been handled
*/
- if (tt_global && !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM)) {
+ if (tt_global &&
+ (roamed_back || !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM))) {
/* These node are probably going to update their tt table */
head = &tt_global->orig_list;
rcu_read_lock();
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 439/507] batman-adv: tt: only update flags for TT events
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (437 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 438/507] batman-adv: tt: send ROAM_ADV on each roamed back client Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 440/507] ata: libata-scsi: reject data-in commands with a data-out buffer Greg Kroah-Hartman
` (67 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sven Eckelmann, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <sven@narfation.org>
commit ad1fd828aa3944efc393b84b0d7c02483f1b5638 upstream.
In the first implementation of the translation table events, it was only
possible to announce:
* ADD: new locally detected client
* DEL: disappeared local client
If an ADD event was queued and then a DEL event was queued in the same
timeslot, it is valid to destroy both events because nothing actually
changed for remode nodes
But with commit 3c4f7ab60cc2 ("batman-adv: improve the TT component to
support runtime flag changes") and subsequent changes, it could also happen
that there are extra ADD events:
* ADD: _NEW_ locally detected client
* ADD: already existing client with new flags
* DEL: disappeared local client
The first and the last type of event could in theory still be removed
together from the (to be announced) events queue. But if the "update flags"
ADD is dropped together with the DEL, it would still leave global
translation table of a remote node in the incorrect state - believing that
the client didn't disappear.
If a detected client was previously announced, a DEL event must only
overwrite the "update flags" ADD but the DEL itself must still continue to
exist in the (to be anounced) events queue. For now, adjustment of the
announced flags is used for everything instead of dropping already queued
up events completely.
Similarly, a DEL followed by an ADD caused both entries to be deleted. But
the new ADD could announce flags changes which were not yet present for the
client before it was marked for DELetion. The new ADD must therefore only
overwrite the DEL - but still be kept.
Cc: stable@vger.kernel.org
Fixes: 3c4f7ab60cc2 ("batman-adv: improve the TT component to support runtime flag changes")
[ Context ]
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/batman-adv/translation-table.c | 29 +++++++++--------------------
1 file changed, 9 insertions(+), 20 deletions(-)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 4ade3ca5af99c..ed8dcb8a66b13 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -418,6 +418,9 @@ batadv_tt_orig_list_entry_put(struct batadv_tt_orig_list_entry *orig_entry)
* @bat_priv: the bat priv with all the mesh interface information
* @tt_local_entry: the TT entry involved in the event
* @event_flags: flags to store in the event structure
+ *
+ * Only a single change per client is queued. It describes the latest state of
+ * the client and a new event therefore replaces an already queued one.
*/
static void batadv_tt_local_event(struct batadv_priv *bat_priv,
struct batadv_tt_local_entry *tt_local_entry,
@@ -429,7 +432,6 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
struct batadv_tt_change_node *entry;
struct batadv_tt_change_node *safe;
bool del_op_requested;
- bool del_op_entry;
size_t changes;
tt_change_node = kmem_cache_alloc(batadv_tt_change_cache, GFP_ATOMIC);
@@ -463,25 +465,12 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
if (entry->change.vid != tt_change_node->change.vid)
continue;
- del_op_entry = entry->change.flags & BATADV_TT_CLIENT_DEL;
- if (del_op_requested != del_op_entry) {
- /* DEL+ADD in the same orig interval have no effect and
- * can be removed to avoid silly behaviour on the
- * receiver side. The other way around (ADD+DEL) can
- * happen in case of roaming of a client still in the
- * NEW state. Roaming of NEW clients is now possible due
- * to automatically recognition of "temporary" clients
- */
- list_del(&entry->list);
- kmem_cache_free(batadv_tt_change_cache, entry);
- changes--;
- } else {
- /* this is a second add or del in the same originator
- * interval. It could mean that flags have been changed
- * (e.g. double add): update them
- */
- entry->change.flags = flags;
- }
+ /* the other nodes may know the client with different
+ * flags. A DEL+ADD must therefore still announce the
+ * current flags and an ADD+DEL must still remove the
+ * client. ADD+ADD and DEL+DEL only update the flags
+ */
+ entry->change.flags = flags;
kmem_cache_free(batadv_tt_change_cache, tt_change_node);
goto update_changes;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 440/507] ata: libata-scsi: reject data-in commands with a data-out buffer
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (438 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 439/507] batman-adv: tt: only update flags for TT events Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 441/507] iommu/arm-smmu-v3: Handle ARM erratum for CONT under invalidation with SVA Greg Kroah-Hartman
` (66 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhao Gongyi, Damien Le Moal,
Niklas Cassel, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhao Gongyi <zhaogongyi@bytedance.com>
[ Upstream commit a4845f077415ef32fe672c841e2fc58ae9e28273 ]
SG_IO can submit a data-in SCSI command with DMA_TO_DEVICE. The
scatterlist can then contain pages pinned without write access.
ata_scsi_rbuf_fill() writes simulated replies to that scatterlist;
in the reported case, the copy tried to write the shared zero page
and faulted in the kernel.
The same mismatch can affect SG_IO commands translated by libata.
ZBC IN and GET PHYSICAL ELEMENT STATUS completion handlers can modify
the receive buffer even if the drive aborts the command. For ATAPI,
the successful INQUIRY completion also rewrites the buffer in
atapi_fixup_inquiry().
Reject these mismatched commands before the buffer is written or the
command is issued. Report ABORTED COMMAND / DATA IN BUFFER ERROR because
the CDB itself can be valid; the supplied transfer direction is wrong.
Backport notes: Use the older five-argument ata_scsi_set_sense()
interface and spell DATA IN BUFFER ERROR as ASC/ASCQ 0x4b/0x0a.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Link: https://lore.kernel.org/r/20261104130638.37882-1-zhaogongyi@bytedance.com
Cc: stable@vger.kernel.org
Signed-off-by: Zhao Gongyi <zhaogongyi@bytedance.com>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ata/libata-scsi.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index b86ac50f16b9e..023de0e633b71 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1984,6 +1984,18 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
if (xlat_func(qc))
goto done;
+ /*
+ * A data-out request may contain pages pinned without write access.
+ * Reject a translated data-in command before issuing it, since its
+ * completion handler may write to the buffer even if the device fails.
+ */
+ if (unlikely(cmd->sc_data_direction == DMA_TO_DEVICE &&
+ ata_is_data(qc->tf.protocol) &&
+ !(qc->tf.flags & ATA_TFLAG_WRITE))) {
+ ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0x4b, 0x0a);
+ goto done;
+ }
+
return ata_scsi_qc_issue(ap, qc);
done:
@@ -2015,6 +2027,12 @@ static void ata_scsi_rbuf_fill(struct ata_device *dev, struct scsi_cmnd *cmd,
unsigned long flags;
unsigned int len;
+ /* A data-out request may contain pages pinned without write access. */
+ if (cmd->sc_data_direction == DMA_TO_DEVICE) {
+ ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0x4b, 0x0a);
+ return;
+ }
+
spin_lock_irqsave(&ata_scsi_rbuf_lock, flags);
memset(ata_scsi_rbuf, 0, ATA_SCSI_RBUF_SIZE);
@@ -3108,6 +3126,13 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
qc->complete_fn = atapi_qc_complete;
+ /* atapi_fixup_inquiry() writes to the buffer on successful completion. */
+ if (scmd->sc_data_direction == DMA_TO_DEVICE &&
+ scmd->cmnd[0] == INQUIRY) {
+ ata_scsi_set_sense(dev, scmd, ABORTED_COMMAND, 0x4b, 0x0a);
+ return 1;
+ }
+
qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
if (scmd->sc_data_direction == DMA_TO_DEVICE) {
qc->tf.flags |= ATA_TFLAG_WRITE;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 441/507] iommu/arm-smmu-v3: Handle ARM erratum for CONT under invalidation with SVA
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (439 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 440/507] ata: libata-scsi: reject data-in commands with a data-out buffer Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 442/507] ASoC: cs35l56: Wait for firmware timer expiry before system suspend Greg Kroah-Hartman
` (65 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vijayanand Jitta, Mostafa Saleh,
Pranjal Shrivastava, Nicolin Chen, Pranjal Shrivastava,
Jason Gunthorpe, Will Deacon, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <jgg@nvidia.com>
[ Upstream commit 84c6089a365ff5547f9ea30cb407dc5fe3124fd3 ]
The erratum (MMU-700: #3777127, S3: #3673557) deals with under
invalidation of a CONT PTE grouping in the SMMU. The recommended work
around is to use a range invalidation that spans the entire CONT. The only
user of CONT in the kernel right now is through SVA sharing a CPU page
table that contains a CONT created by the mm.
Previously it was thought that this errata was dealt with because the
driver always uses range invalidation. However, there is a subtle detail
in the errata that the invalidation range must fully enclose the entire
CONT for it to work.
It seems that two sequential range invalidations, with a split point
falling inside a CONT grouping, will not prevent the errata.
The SMMU's range invalidation generation algorithm does not produce a
single invalidation for a single SVA invalidation request, nor does the mm
carefully align the SVA invalidation ranges to accommodate the splitting
of the invalidation into several ranges.
Thus, when processing a SVA invalidation, the range invalidation splitting
routine can generate a range invalidation that is split in the middle of
the CONT and risk under invalidation from this errata. This condition
could be triggered by a malicious userspace manipulating the TLB gathers
via mmap/mprotect/munmap.
Update the errata list to the include the S3 variation, detect the IOMMUs
that have it, and then have SVA invalidations use a simplified version of
the over invalidation algorithm from the tlbi rework series. This ensures
that a single range invalidation is issued for a single MMU notifier
callback and now the range invalidation is guarenteed to cover any posible
CONT.
Future work to add CONT to iommu_domain page tables should either use this
one-invalidate/one-range invalidation algorithm or disable CONT support in
the iommu_domain.
Cc: stable@vger.kernel.org
Cc: Vijayanand Jitta <vijayanand.jitta@oss.qualcomm.com>
Fixes: 3f1ce8e85ee0 ("iommu/arm-smmu-v3: Share process page tables")
Reviewed-by: Mostafa Saleh <smostafa@google.com>
Reviewed-by: Pranjal Shrivastava <peaan@google.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Pranjal Shrivastava <praan@google.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Will Deacon <will@kernel.org>
[ sashal: Adjusted header context to account for the missing ARM_SMMU_OPT_OVR_INSTCFG_DATA definition. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/arch/arm64/silicon-errata.rst | 3 +-
.../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c | 7 ++
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 89 +++++++++++++++----
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 5 ++
4 files changed, 87 insertions(+), 17 deletions(-)
diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index 99a1eb4b833dd..95faec78b7f70 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -273,7 +273,8 @@ stable kernels.
+----------------+-----------------+-----------------+-----------------------------+
| ARM | MMU L1 | #3878312 | N/A |
+----------------+-----------------+-----------------+-----------------------------+
-| ARM | MMU S3 | #3995052 | N/A |
+| ARM | MMU S3 | #3995052, | N/A |
+| | | #3673557 | |
+----------------+-----------------+-----------------+-----------------------------+
| ARM | GIC-700 | #2941627 | ARM64_ERRATUM_2941627 |
+----------------+-----------------+-----------------+-----------------------------+
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
index 0a429c64fbf3e..3f50298a1c14c 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
@@ -215,6 +215,13 @@ bool arm_smmu_sva_supported(struct arm_smmu_device *smmu)
if (system_supports_haft())
feat_mask |= ARM_SMMU_FEAT_HAFT;
+ /*
+ * The workaround for ARM_SMMU_OPT_FULL_CONT_RANGE_INV requires range
+ * invalidation support.
+ */
+ if (smmu->options & ARM_SMMU_OPT_FULL_CONT_RANGE_INV)
+ feat_mask |= ARM_SMMU_FEAT_RANGE_INV;
+
if ((smmu->features & feat_mask) != feat_mask)
return false;
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 81baafaffc410..b510dd47f2315 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -2538,6 +2538,37 @@ static void arm_smmu_cmdq_batch_add_range(struct arm_smmu_device *smmu,
}
}
+/*
+ * Generate a range invalidation for ARM_SMMU_OPT_FULL_CONT_RANGE_INV by
+ * ensuring the entire SVA requested range is covered with a single range
+ * invalidation command. The scale is adjusted so that the range invalidation
+ * may extend past the end of the requested range. This ensures that any CONT
+ * the MM is invalidating is covered by a single range invalidation. TTL and
+ * LEAF are always 0 because this is only used by SVA.
+ */
+static bool arm_smmu_cmdq_batch_add_range_inv(struct arm_smmu_device *smmu,
+ struct arm_smmu_cmdq_batch *cmds,
+ struct arm_smmu_cmd *cmd,
+ unsigned long iova, size_t size,
+ u8 tgsz_lg2)
+{
+ u64 cur_tg = iova >> tgsz_lg2;
+ u64 num_tg = ((iova + size - 1) >> tgsz_lg2) - cur_tg + 1;
+ unsigned int scale = fls64((num_tg - 1) / 32);
+
+ if (scale > 31)
+ return false;
+
+ cmd->data[0] |=
+ FIELD_PREP(CMDQ_TLBI_0_NUM,
+ DIV_ROUND_UP_ULL(num_tg, 1ULL << scale) - 1) |
+ FIELD_PREP(CMDQ_TLBI_0_SCALE, scale);
+ cmd->data[1] = FIELD_PREP(CMDQ_TLBI_1_TG, (tgsz_lg2 - 10) / 2) |
+ (cur_tg << tgsz_lg2);
+ arm_smmu_cmdq_batch_add_cmd_p(smmu, cmds, cmd);
+ return true;
+}
+
static bool arm_smmu_inv_size_too_big(struct arm_smmu_device *smmu, size_t size,
size_t granule)
{
@@ -2565,21 +2596,30 @@ static bool arm_smmu_inv_size_too_big(struct arm_smmu_device *smmu, size_t size,
static void arm_smmu_inv_to_cmdq_batch(struct arm_smmu_inv *inv,
struct arm_smmu_cmdq_batch *cmds,
struct arm_smmu_cmd *cmd,
- bool leaf,
+ bool single_range_inv, bool leaf,
unsigned long iova, size_t size,
unsigned int granule)
{
- if (arm_smmu_inv_size_too_big(inv->smmu, size, granule)) {
- struct arm_smmu_cmd nsize_cmd = *cmd;
+ struct arm_smmu_cmd nsize_cmd;
+
+ if (arm_smmu_inv_size_too_big(inv->smmu, size, granule))
+ goto full_inv;
- u64p_replace_bits(&nsize_cmd.data[0], inv->nsize_opcode,
- CMDQ_0_OP);
- arm_smmu_cmdq_batch_add_cmd_p(inv->smmu, cmds, &nsize_cmd);
+ if (single_range_inv && size > granule) {
+ if (!arm_smmu_cmdq_batch_add_range_inv(inv->smmu, cmds, cmd,
+ iova, size, inv->pgsize))
+ goto full_inv;
return;
}
- arm_smmu_cmdq_batch_add_range(inv->smmu, cmds, cmd, leaf,
- iova, size, granule, inv->pgsize);
+ arm_smmu_cmdq_batch_add_range(inv->smmu, cmds, cmd, leaf, iova, size,
+ granule, inv->pgsize);
+ return;
+
+full_inv:
+ nsize_cmd = *cmd;
+ u64p_replace_bits(&nsize_cmd.data[0], inv->nsize_opcode, CMDQ_0_OP);
+ arm_smmu_cmdq_batch_add_cmd_p(inv->smmu, cmds, &nsize_cmd);
}
static inline bool arm_smmu_invs_end_batch(struct arm_smmu_inv *cur,
@@ -2600,7 +2640,8 @@ static inline bool arm_smmu_invs_end_batch(struct arm_smmu_inv *cur,
static void __arm_smmu_domain_inv_range(struct arm_smmu_invs *invs,
unsigned long iova, size_t size,
- unsigned int granule, bool leaf)
+ unsigned int granule,
+ bool single_range_inv, bool leaf)
{
struct arm_smmu_cmdq_batch cmds = {};
struct arm_smmu_inv *cur;
@@ -2630,14 +2671,16 @@ static void __arm_smmu_domain_inv_range(struct arm_smmu_invs *invs,
case INV_TYPE_S1_ASID:
cmd = arm_smmu_make_cmd_tlbi(cur->size_opcode,
cur->id, 0);
- arm_smmu_inv_to_cmdq_batch(cur, &cmds, &cmd, leaf,
- iova, size, granule);
+ arm_smmu_inv_to_cmdq_batch(cur, &cmds, &cmd,
+ single_range_inv, leaf, iova,
+ size, granule);
break;
case INV_TYPE_S2_VMID:
cmd = arm_smmu_make_cmd_tlbi(cur->size_opcode,
0, cur->id);
- arm_smmu_inv_to_cmdq_batch(cur, &cmds, &cmd, leaf,
- iova, size, granule);
+ arm_smmu_inv_to_cmdq_batch(cur, &cmds, &cmd,
+ single_range_inv, leaf, iova,
+ size, granule);
break;
case INV_TYPE_S2_VMID_S1_CLEAR:
/* CMDQ_OP_TLBI_S12_VMALL already flushed S1 entries */
@@ -2684,6 +2727,9 @@ void arm_smmu_domain_inv_range(struct arm_smmu_domain *smmu_domain,
unsigned int granule, bool leaf)
{
struct arm_smmu_invs *invs;
+ bool single_range_inv =
+ smmu_domain->stage == ARM_SMMU_DOMAIN_SVA &&
+ (smmu_domain->smmu->options & ARM_SMMU_OPT_FULL_CONT_RANGE_INV);
/*
* An invalidation request must follow some IOPTE change and then load
@@ -2723,10 +2769,12 @@ void arm_smmu_domain_inv_range(struct arm_smmu_domain *smmu_domain,
unsigned long flags;
read_lock_irqsave(&invs->rwlock, flags);
- __arm_smmu_domain_inv_range(invs, iova, size, granule, leaf);
+ __arm_smmu_domain_inv_range(invs, iova, size, granule,
+ single_range_inv, leaf);
read_unlock_irqrestore(&invs->rwlock, flags);
} else {
- __arm_smmu_domain_inv_range(invs, iova, size, granule, leaf);
+ __arm_smmu_domain_inv_range(invs, iova, size, granule,
+ single_range_inv, leaf);
}
rcu_read_unlock();
@@ -5009,11 +5057,20 @@ static void arm_smmu_device_iidr_probe(struct arm_smmu_device *smmu)
/* Arm errata 2268618, 2812531 */
smmu->features &= ~ARM_SMMU_FEAT_NESTING;
}
+ /* Arm errata 3777127 */
+ smmu->options |= ARM_SMMU_OPT_FULL_CONT_RANGE_INV;
break;
case IIDR_PRODUCTID_ARM_MMU_L1:
+ /* Arm errata 3878312 */
+ smmu->features &= ~ARM_SMMU_FEAT_BTM;
+ break;
case IIDR_PRODUCTID_ARM_MMU_S3:
- /* Arm errata 3878312/3995052 */
+ /* Arm errata 3995052 */
smmu->features &= ~ARM_SMMU_FEAT_BTM;
+ /* Arm errata 3673557 */
+ if (variant < 1 || (variant == 1 && revision < 1))
+ smmu->options |=
+ ARM_SMMU_OPT_FULL_CONT_RANGE_INV;
break;
}
break;
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index dd2fee2f560e6..094ce28c862f5 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -934,6 +934,11 @@ struct arm_smmu_device {
#define ARM_SMMU_OPT_MSIPOLL (1 << 2)
#define ARM_SMMU_OPT_CMDQ_FORCE_SYNC (1 << 3)
#define ARM_SMMU_OPT_TEGRA241_CMDQV (1 << 4)
+/*
+ * Range invalidation is mandatory and one range invalidation must fully span an
+ * invalidated CONT
+ */
+#define ARM_SMMU_OPT_FULL_CONT_RANGE_INV (1 << 6)
u32 options;
struct arm_smmu_cmdq cmdq;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 442/507] ASoC: cs35l56: Wait for firmware timer expiry before system suspend
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (440 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 441/507] iommu/arm-smmu-v3: Handle ARM erratum for CONT under invalidation with SVA Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 443/507] mtd: spi-nor: macronix: Restore fallback parameters for MX25L12805D Greg Kroah-Hartman
` (64 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ferenc Lengyel, Richard Fitzgerald,
Mark Brown, Sercan GOKMEN, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <rf@opensource.cirrus.com>
commit 6cc7db9fdd06c992ee38793b2d556524fc0cf574 upstream.
On CS35L5x firmware older than 3.13.7 (B0 silicon) and 4.7.16 (B2 silicon)
a SoundWire bus reset is not allowed within 250ms of the last firmware
timer start.
This is already avoided during runtime suspend by the various idle
timeouts. System suspend can happen at any time so needs special
protection. The driver cannot cancel the firmware timer, so it must wait
long enough for the timer to expire.
The delay is placed in the suspend stage because typically this has less
impact on end users than delays in resuming. The amp is in PS3 power
state when suspending and no new timers will be started in this state.
An extra 10ms is added to the delay to avoid a race on the exact instant
the firmware timer expires.
There is no need to have the delay for every driver instance. The timers
on each amp will expire in parallel, so the delay is only needed once.
A global flag is used so that the first instance to reach its suspend()
callback will delay and then clear the flag. The cs35l56_fw_idle_wait_lock
mutex is to ensure this is still safe if async_suspend was ever enabled
for SoundWire devices.
Fixes: e496112529006 ("ASoC: cs35l56: Add driver for Cirrus Logic CS35L56")
Reported-by: Ferenc Lengyel <leferi99@gmail.com>
Closes: https://github.com/thesofproject/linux/issues/5898
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20261020135706.3573260-1-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sercan GOKMEN <gokmensercan@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/sound/cs35l56.h | 4 ++++
sound/soc/codecs/cs35l56-sdw.c | 27 +++++++++++++++++++++-
sound/soc/codecs/cs35l56-shared.c | 38 +++++++++++++++++++++++++++++++
sound/soc/codecs/cs35l56.c | 17 ++++++++++++++
sound/soc/codecs/cs35l56.h | 1 +
5 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h
index 747e10ec1a274..ce6383c2c60cc 100644
--- a/include/sound/cs35l56.h
+++ b/include/sound/cs35l56.h
@@ -209,6 +209,9 @@ struct snd_ctl_elem_value;
#define CS35L56_GPIO_FN_GPIO 0x00000001
+/* DSP1_FW_VER */
+#define CS35L56_FW_MAIN_VERSION_MASK GENMASK(19, 0)
+
/* Mixer input sources */
#define CS35L56_INPUT_SRC_NONE 0x00
#define CS35L56_INPUT_SRC_ASP1RX1 0x08
@@ -446,6 +449,7 @@ int cs35l56_cal_set_status_get(struct cs35l56_base *cs35l56_base,
int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base,
bool *fw_missing, unsigned int *fw_version);
void cs35l56_warn_if_firmware_missing(struct cs35l56_base *cs35l56_base);
+bool cs35l56_needs_wait_for_firmware_timer_expiry(struct cs35l56_base *cs35l56_base);
void cs35l56_log_tuning(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp);
int cs35l56_hw_init(struct cs35l56_base *cs35l56_base);
int cs35l56_get_speaker_id(struct cs35l56_base *cs35l56_base);
diff --git a/sound/soc/codecs/cs35l56-sdw.c b/sound/soc/codecs/cs35l56-sdw.c
index e10f04d677f4d..a49ad69644b5a 100644
--- a/sound/soc/codecs/cs35l56-sdw.c
+++ b/sound/soc/codecs/cs35l56-sdw.c
@@ -9,6 +9,7 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/soundwire/sdw.h>
@@ -36,6 +37,9 @@
#define CS35L56_LATE_READ_POLL_US 10
#define CS35L56_LATE_READ_TIMEOUT_US 1000
+static DEFINE_MUTEX(cs35l56_fw_idle_wait_lock);
+static bool cs35l56_fw_idle_wait_pending;
+
static int cs35l56_sdw_poll_mem_status(struct sdw_slave *peripheral,
unsigned int mask,
unsigned int match)
@@ -387,14 +391,34 @@ static int __maybe_unused cs35l56_sdw_runtime_resume(struct device *dev)
return 0;
}
+static int cs35l56_sdw_system_suspend_prepare(struct device *dev)
+{
+ cs35l56_fw_idle_wait_pending = true;
+
+ return 0;
+}
+
static int __maybe_unused cs35l56_sdw_system_suspend(struct device *dev)
{
struct cs35l56_private *cs35l56 = dev_get_drvdata(dev);
+ int ret;
if (cs35l56->sdw_attached)
cs35l56_mask_soundwire_interrupts(cs35l56);
- return cs35l56_system_suspend(dev);
+ ret = cs35l56_system_suspend(dev);
+ if (ret < 0)
+ return ret;
+
+ scoped_guard(mutex, &cs35l56_fw_idle_wait_lock) {
+ if (cs35l56_fw_idle_wait_pending && cs35l56->needs_wait_for_fw_idle) {
+ dev_dbg(cs35l56->base.dev, "Wait for FW timer expiry\n");
+ msleep(CS35L56_FW_REQ_ACTIVE_TIMEOUT_MS + 10);
+ cs35l56_fw_idle_wait_pending = false;
+ }
+ }
+
+ return 0;
}
static int cs35l56_sdw_probe(struct sdw_slave *peripheral, const struct sdw_device_id *id)
@@ -460,6 +484,7 @@ static void cs35l56_sdw_remove(struct sdw_slave *peripheral)
}
static const struct dev_pm_ops cs35l56_sdw_pm = {
+ .prepare = cs35l56_sdw_system_suspend_prepare,
SET_RUNTIME_PM_OPS(cs35l56_sdw_runtime_suspend, cs35l56_sdw_runtime_resume, NULL)
SYSTEM_SLEEP_PM_OPS(cs35l56_sdw_system_suspend, cs35l56_system_resume)
LATE_SYSTEM_SLEEP_PM_OPS(cs35l56_system_suspend_late, cs35l56_system_resume_early)
diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c
index 7b3e37d462d61..b37f65cd4d336 100644
--- a/sound/soc/codecs/cs35l56-shared.c
+++ b/sound/soc/codecs/cs35l56-shared.c
@@ -1379,6 +1379,44 @@ void cs35l56_warn_if_firmware_missing(struct cs35l56_base *cs35l56_base)
}
EXPORT_SYMBOL_NS_GPL(cs35l56_warn_if_firmware_missing, "SND_SOC_CS35L56_SHARED");
+bool cs35l56_needs_wait_for_firmware_timer_expiry(struct cs35l56_base *cs35l56_base)
+{
+ unsigned int fw_ver;
+ bool prot_sts;
+ int ret;
+
+ switch (cs35l56_base->type) {
+ case 0x54:
+ case 0x56:
+ case 0x57:
+ switch (cs35l56_base->rev) {
+ case 0xb0:
+ ret = cs35l56_read_prot_status(cs35l56_base, &prot_sts, &fw_ver);
+ if (ret)
+ return true;
+
+ if ((fw_ver & CS35L56_FW_MAIN_VERSION_MASK) < 0x30d07)
+ return true;
+
+ return false;
+ case 0xb2:
+ ret = cs35l56_read_prot_status(cs35l56_base, &prot_sts, &fw_ver);
+ if (ret)
+ return true;
+
+ if ((fw_ver & CS35L56_FW_MAIN_VERSION_MASK) < 0x40710)
+ return true;
+
+ return false;
+ default:
+ return false;
+ }
+ default:
+ return false;
+ }
+}
+EXPORT_SYMBOL_NS_GPL(cs35l56_needs_wait_for_firmware_timer_expiry, "SND_SOC_CS35L56_SHARED");
+
void cs35l56_log_tuning(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp)
{
__be32 pid, sid, tid;
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index 279db3f13f1e3..573cc71a1910d 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -1693,6 +1693,10 @@ int cs35l56_system_resume(struct device *dev)
dev_dbg(dev, "system_resume\n");
+ /* Assume the firmware reset to default until we can check it */
+ if (cs35l56->base.init_done)
+ cs35l56->needs_wait_for_fw_idle = true;
+
/*
* We might have done a hard reset or the CS35L56 was power-cycled
* so wait for control port to be ready.
@@ -1707,6 +1711,16 @@ int cs35l56_system_resume(struct device *dev)
if (ret)
return ret;
+ if (cs35l56->sdw_peripheral && cs35l56->base.init_done) {
+ ret = pm_runtime_resume_and_get(cs35l56->base.dev);
+ if (ret < 0)
+ return ret;
+
+ cs35l56->needs_wait_for_fw_idle =
+ cs35l56_needs_wait_for_firmware_timer_expiry(&cs35l56->base);
+ pm_runtime_put_autosuspend(cs35l56->base.dev);
+ }
+
/* Firmware won't have been loaded if the component hasn't probed */
if (!cs35l56->component)
return 0;
@@ -2231,6 +2245,9 @@ int cs35l56_init(struct cs35l56_private *cs35l56)
if (ret)
return dev_err_probe(cs35l56->base.dev, ret, "Failed to write ASP1_CONTROL3\n");
+ cs35l56->needs_wait_for_fw_idle =
+ cs35l56_needs_wait_for_firmware_timer_expiry(&cs35l56->base);
+
cs35l56->base.init_done = true;
complete_all(&cs35l56->init_completion);
diff --git a/sound/soc/codecs/cs35l56.h b/sound/soc/codecs/cs35l56.h
index f7cf8aa653e28..b46f410f0e093 100644
--- a/sound/soc/codecs/cs35l56.h
+++ b/sound/soc/codecs/cs35l56.h
@@ -43,6 +43,7 @@ struct cs35l56_private {
bool soft_resetting;
bool sdw_attached;
bool component_registered;
+ bool needs_wait_for_fw_idle;
struct completion init_completion;
int speaker_id;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 443/507] mtd: spi-nor: macronix: Restore fallback parameters for MX25L12805D
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (441 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 442/507] ASoC: cs35l56: Wait for firmware timer expiry before system suspend Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 444/507] media: microchip-isc: store the unshifted PFE_CFG0 BPS value Greg Kroah-Hartman
` (63 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cheng Ming Lin, Michael Walle,
Russell Senior, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cheng Ming Lin <chengminglin@mxic.com.tw>
[ Upstream commit 01739ccea21b69818dc071096a249e6f84a6b13d ]
In a previous effort to drop flash_info fields and rely on SFDP, the
static size and no_sfdp_flags were removed from the MX25L12805D entry
(JEDEC ID 0xc22018).
At that time, the legacy MX25L12805D was already EOL and unavailable
for physical testing. Verification was inadvertently performed using
the newer MX25L12833F, which shares the same JEDEC ID but supports
SFDP. As a result, the probe succeeded during testing, leading to
the mistaken removal of the fallback parameters.
Since the actual MX25L12805D lacks SFDP support entirely, it strictly
requires these static parameters.
Restore .size = SZ_16M and .no_sfdp_flags = SECT_4K to this entry
to fix the probe failure for the legacy part.
Fixes: 947c86e481a0 ("mtd: spi-nor: macronix: Drop the redundant flash info fields")
Cc: stable@vger.kernel.org
Signed-off-by: Cheng Ming Lin <chengminglin@mxic.com.tw>
Reviewed-by: Michael Walle <mwalle@kernel.org>
Tested-by: Russell Senior <russell@personaltelco.net>
Signed-off-by: Michael Walle <mwalle@kernel.org>
[ sashal: Adjusted patch context to account for the absent mx25l12805d_4pp3b_fixups hook. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mtd/spi-nor/macronix.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c
index e97f5cbd9aad2..c854a1163a475 100644
--- a/drivers/mtd/spi-nor/macronix.c
+++ b/drivers/mtd/spi-nor/macronix.c
@@ -132,7 +132,9 @@ static const struct flash_info macronix_nor_parts[] = {
}, {
/* MX25L12805D */
.id = SNOR_ID(0xc2, 0x20, 0x18),
+ .size = SZ_16M,
.flags = SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP,
+ .no_sfdp_flags = SECT_4K,
}, {
/* MX25L25635E, MX25L25645G */
.id = SNOR_ID(0xc2, 0x20, 0x19),
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 444/507] media: microchip-isc: store the unshifted PFE_CFG0 BPS value
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (442 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 443/507] mtd: spi-nor: macronix: Restore fallback parameters for MX25L12805D Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 445/507] media: microchip-isc: fix WB offset and gain register field masking Greg Kroah-Hartman
` (62 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eugen Hristev, Balakrishnan Sambath,
Hans Verkuil, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Balakrishnan Sambath <balakrishnan.s@microchip.com>
[ Upstream commit 14cbe597504a04c5c49342d0566438e2b438a948 ]
pfe_cfg0_bps held a pre-shifted BPS value (ISC_PFE_CFG0_BPS_EIGHT was
0x4 << 28) ORed straight into the register. The other format selectors
like cfa_baycfg store the bare field value and position it at the write,
so this one was inconsistent.
Store the bare BPS value and apply it with FIELD_PREP() at the PFE_CFG0
write, and fix the pfe_cfg0_bps comment to match. No functional change.
Suggested-by: Eugen Hristev <ehristev@kernel.org>
Signed-off-by: Balakrishnan Sambath <balakrishnan.s@microchip.com>
Reviewed-by: Eugen Hristev <ehristev@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Stable-dep-of: 6e9eaa3b9387 ("media: microchip-isc: fix WB offset and gain register field masking")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/platform/microchip/microchip-isc-base.c | 4 +++-
drivers/media/platform/microchip/microchip-isc-regs.h | 10 +++++-----
drivers/media/platform/microchip/microchip-isc.h | 4 +++-
3 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/media/platform/microchip/microchip-isc-base.c b/drivers/media/platform/microchip/microchip-isc-base.c
index 21d108eb93c7b..e5ecf6ffd24a8 100644
--- a/drivers/media/platform/microchip/microchip-isc-base.c
+++ b/drivers/media/platform/microchip/microchip-isc-base.c
@@ -8,6 +8,7 @@
* Author: Eugen Hristev <eugen.hristev@microchip.com>
*
*/
+#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/math64.h>
@@ -291,7 +292,8 @@ static int isc_configure(struct isc_device *isc)
struct isc_subdev_entity *subdev = isc->current_subdev;
int ret;
- pfe_cfg0 = isc->config.sd_format->pfe_cfg0_bps;
+ pfe_cfg0 = FIELD_PREP(ISC_PFE_CFG0_BPS_MASK,
+ isc->config.sd_format->pfe_cfg0_bps);
pipeline = isc->config.bits_pipeline;
dcfg = isc->config.dcfg_imode | isc->dcfg;
diff --git a/drivers/media/platform/microchip/microchip-isc-regs.h b/drivers/media/platform/microchip/microchip-isc-regs.h
index e77e1d9a1db87..185ef0eab7ad3 100644
--- a/drivers/media/platform/microchip/microchip-isc-regs.h
+++ b/drivers/media/platform/microchip/microchip-isc-regs.h
@@ -31,11 +31,11 @@
#define ISC_PFE_CFG0_MODE_PROGRESSIVE (0x0 << 4)
#define ISC_PFE_CFG0_MODE_MASK GENMASK(6, 4)
-#define ISC_PFE_CFG0_BPS_EIGHT (0x4 << 28)
-#define ISC_PFG_CFG0_BPS_NINE (0x3 << 28)
-#define ISC_PFG_CFG0_BPS_TEN (0x2 << 28)
-#define ISC_PFG_CFG0_BPS_ELEVEN (0x1 << 28)
-#define ISC_PFG_CFG0_BPS_TWELVE (0x0 << 28)
+#define ISC_PFE_CFG0_BPS_EIGHT 0x4
+#define ISC_PFG_CFG0_BPS_NINE 0x3
+#define ISC_PFG_CFG0_BPS_TEN 0x2
+#define ISC_PFG_CFG0_BPS_ELEVEN 0x1
+#define ISC_PFG_CFG0_BPS_TWELVE 0x0
#define ISC_PFE_CFG0_BPS_MASK GENMASK(30, 28)
#define ISC_PFE_CFG0_COLEN BIT(12)
diff --git a/drivers/media/platform/microchip/microchip-isc.h b/drivers/media/platform/microchip/microchip-isc.h
index f5e322c2e36bc..d7bcd74efff92 100644
--- a/drivers/media/platform/microchip/microchip-isc.h
+++ b/drivers/media/platform/microchip/microchip-isc.h
@@ -62,7 +62,9 @@ struct isc_subdev_entity {
* @mbus_code: V4L2 media bus format code.
* @cfa_baycfg: If this format is RAW BAYER, indicate the type of bayer.
this is either BGBG, RGRG, etc.
- * @pfe_cfg0_bps: Number of hardware data lines connected to the ISC
+ * @pfe_cfg0_bps: ISC_PFE_CFG0 BPS field value (e.g. ISC_PFE_CFG0_BPS_EIGHT),
+ written into PFE_CFG0 with FIELD_PREP(ISC_PFE_CFG0_BPS_MASK)
+ at configure time.
* @raw: If the format is raw bayer.
*/
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 445/507] media: microchip-isc: fix WB offset and gain register field masking
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (443 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 444/507] media: microchip-isc: store the unshifted PFE_CFG0 BPS value Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 446/507] KVM: arm64: Pass kvm_s2_fault_desc to fault_supports_stage2_huge_mapping() Greg Kroah-Hartman
` (61 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eugen Hristev, Balakrishnan Sambath,
Hans Verkuil, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Balakrishnan Sambath <balakrishnan.s@microchip.com>
[ Upstream commit 6e9eaa3b93870e4edac1bd2539fe113c24663eaf ]
ISC_WB_O_* and ISC_WB_G_* each pack two 13-bit fields. A negative offset
sign-extends and corrupts the adjacent field. Add masks for the two
fields and write them with FIELD_PREP(), which masks each value into its
field, so sign extension can no longer bleed across.
Fixes: 73c1a577b839 ("media: atmel: atmel-isc: reworked white balance feature")
Cc: stable@vger.kernel.org
Reviewed-by: Eugen Hristev <ehristev@kernel.org>
Signed-off-by: Balakrishnan Sambath <balakrishnan.s@microchip.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../platform/microchip/microchip-isc-base.c | 16 ++++++++--------
.../platform/microchip/microchip-isc-regs.h | 6 ++++++
2 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/drivers/media/platform/microchip/microchip-isc-base.c b/drivers/media/platform/microchip/microchip-isc-base.c
index e5ecf6ffd24a8..963d5fd53b589 100644
--- a/drivers/media/platform/microchip/microchip-isc-base.c
+++ b/drivers/media/platform/microchip/microchip-isc-base.c
@@ -63,17 +63,17 @@ static inline void isc_update_awb_ctrls(struct isc_device *isc)
/* In here we set our actual hw pipeline config */
regmap_write(isc->regmap, ISC_WB_O_RGR,
- ((ctrls->offset[ISC_HIS_CFG_MODE_R])) |
- ((ctrls->offset[ISC_HIS_CFG_MODE_GR]) << 16));
+ FIELD_PREP(ISC_WB_O_LO, ctrls->offset[ISC_HIS_CFG_MODE_R]) |
+ FIELD_PREP(ISC_WB_O_HI, ctrls->offset[ISC_HIS_CFG_MODE_GR]));
regmap_write(isc->regmap, ISC_WB_O_BGB,
- ((ctrls->offset[ISC_HIS_CFG_MODE_B])) |
- ((ctrls->offset[ISC_HIS_CFG_MODE_GB]) << 16));
+ FIELD_PREP(ISC_WB_O_LO, ctrls->offset[ISC_HIS_CFG_MODE_B]) |
+ FIELD_PREP(ISC_WB_O_HI, ctrls->offset[ISC_HIS_CFG_MODE_GB]));
regmap_write(isc->regmap, ISC_WB_G_RGR,
- ctrls->gain[ISC_HIS_CFG_MODE_R] |
- (ctrls->gain[ISC_HIS_CFG_MODE_GR] << 16));
+ FIELD_PREP(ISC_WB_G_LO, ctrls->gain[ISC_HIS_CFG_MODE_R]) |
+ FIELD_PREP(ISC_WB_G_HI, ctrls->gain[ISC_HIS_CFG_MODE_GR]));
regmap_write(isc->regmap, ISC_WB_G_BGB,
- ctrls->gain[ISC_HIS_CFG_MODE_B] |
- (ctrls->gain[ISC_HIS_CFG_MODE_GB] << 16));
+ FIELD_PREP(ISC_WB_G_LO, ctrls->gain[ISC_HIS_CFG_MODE_B]) |
+ FIELD_PREP(ISC_WB_G_HI, ctrls->gain[ISC_HIS_CFG_MODE_GB]));
}
static inline void isc_reset_awb_ctrls(struct isc_device *isc)
diff --git a/drivers/media/platform/microchip/microchip-isc-regs.h b/drivers/media/platform/microchip/microchip-isc-regs.h
index 185ef0eab7ad3..cabecf128b37a 100644
--- a/drivers/media/platform/microchip/microchip-isc-regs.h
+++ b/drivers/media/platform/microchip/microchip-isc-regs.h
@@ -149,6 +149,12 @@
/* ISC White Balance Gain for B, GB Register */
#define ISC_WB_G_BGB 0x0000006c
+/* Each WB offset/gain register packs two 13-bit fields, low and high */
+#define ISC_WB_O_LO GENMASK(12, 0) /* R or B offset [12:0] */
+#define ISC_WB_O_HI GENMASK(28, 16) /* GR or GB offset [28:16] */
+#define ISC_WB_G_LO GENMASK(12, 0) /* R or B gain [12:0] */
+#define ISC_WB_G_HI GENMASK(28, 16) /* GR or GB gain [28:16] */
+
/* ISC Color Filter Array Control Register */
#define ISC_CFA_CTRL 0x00000070
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 446/507] KVM: arm64: Pass kvm_s2_fault_desc to fault_supports_stage2_huge_mapping()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (444 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 445/507] media: microchip-isc: fix WB offset and gain register field masking Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 447/507] KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort() Greg Kroah-Hartman
` (60 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Donnefort, Fuad Tabba,
Wei-Lin Chang, Marc Zyngier, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Donnefort <vdonnefort@google.com>
[ Upstream commit 10c5cc50f056a6425305557063ad70c3eb0e686b ]
Pass the fault descriptor to fault_supports_stage2_huge_mapping() instead
of passing memslot and hva separately so it can access other s2fd
members such as vcpu. This implies to pass that same s2fd argument to
transparent_hugepage_adjust().
No functional change intended.
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
Reviewed-by: Wei-Lin Chang <weilin.chang@arm.com>
Link: https://patch.msgid.link/20260928095454.3255918-3-vdonnefort@google.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
Stable-dep-of: 80b0b86dc5e4 ("KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/mmu.c | 39 +++++++++++++++++++--------------------
1 file changed, 19 insertions(+), 20 deletions(-)
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index bf6d6526639fa..291696dda0741 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1362,12 +1362,21 @@ static void kvm_send_hwpoison_signal(unsigned long address, short lsb)
send_sig_mceerr(BUS_MCEERR_AR, (void __user *)address, lsb, current);
}
-static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot,
- unsigned long hva,
+struct kvm_s2_fault_desc {
+ struct kvm_vcpu *vcpu;
+ phys_addr_t fault_ipa;
+ struct kvm_s2_trans *nested;
+ struct kvm_memory_slot *memslot;
+ unsigned long hva;
+};
+
+static bool fault_supports_stage2_huge_mapping(const struct kvm_s2_fault_desc *s2fd,
unsigned long map_size)
{
- gpa_t gpa_start;
+ struct kvm_memory_slot *memslot = s2fd->memslot;
+ unsigned long hva = s2fd->hva;
hva_t uaddr_start, uaddr_end;
+ gpa_t gpa_start;
size_t size;
/* The memslot and the VMA are guaranteed to be aligned to PAGE_SIZE */
@@ -1436,9 +1445,9 @@ static bool fault_supports_stage2_huge_mapping(struct kvm_memory_slot *memslot,
* Returns the size of the mapping.
*/
static long
-transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,
- unsigned long hva, kvm_pfn_t *pfnp, gfn_t *gfnp)
+transparent_hugepage_adjust(const struct kvm_s2_fault_desc *s2fd, kvm_pfn_t *pfnp, gfn_t *gfnp)
{
+ struct kvm *kvm = s2fd->vcpu->kvm;
kvm_pfn_t pfn = *pfnp;
gfn_t gfn = *gfnp;
@@ -1447,8 +1456,8 @@ transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,
* sure that the HVA and IPA are sufficiently aligned and that the
* block map is contained within the memslot.
*/
- if (fault_supports_stage2_huge_mapping(memslot, hva, PMD_SIZE)) {
- int sz = get_user_mapping_size(kvm, hva);
+ if (fault_supports_stage2_huge_mapping(s2fd, PMD_SIZE)) {
+ int sz = get_user_mapping_size(kvm, s2fd->hva);
if (sz < 0)
return sz;
@@ -1585,14 +1594,6 @@ static enum kvm_pgtable_prot adjust_nested_exec_perms(struct kvm *kvm,
return prot;
}
-struct kvm_s2_fault_desc {
- struct kvm_vcpu *vcpu;
- phys_addr_t fault_ipa;
- struct kvm_s2_trans *nested;
- struct kvm_memory_slot *memslot;
- unsigned long hva;
-};
-
static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
{
bool write_fault, exec_fault;
@@ -1779,7 +1780,7 @@ static short kvm_s2_resolve_vma_size(const struct kvm_s2_fault_desc *s2fd,
switch (vma_shift) {
#ifndef __PAGETABLE_PMD_FOLDED
case PUD_SHIFT:
- if (fault_supports_stage2_huge_mapping(s2fd->memslot, s2fd->hva, PUD_SIZE))
+ if (fault_supports_stage2_huge_mapping(s2fd, PUD_SIZE))
break;
fallthrough;
#endif
@@ -1787,7 +1788,7 @@ static short kvm_s2_resolve_vma_size(const struct kvm_s2_fault_desc *s2fd,
vma_shift = PMD_SHIFT;
fallthrough;
case PMD_SHIFT:
- if (fault_supports_stage2_huge_mapping(s2fd->memslot, s2fd->hva, PMD_SIZE))
+ if (fault_supports_stage2_huge_mapping(s2fd, PMD_SIZE))
break;
fallthrough;
case CONT_PTE_SHIFT:
@@ -2027,9 +2028,7 @@ static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,
if (perm_fault_granule > PAGE_SIZE) {
mapping_size = perm_fault_granule;
} else {
- mapping_size = transparent_hugepage_adjust(kvm, s2fd->memslot,
- s2fd->hva, &pfn,
- &gfn);
+ mapping_size = transparent_hugepage_adjust(s2fd, &pfn, &gfn);
if (mapping_size < 0) {
ret = mapping_size;
goto out_unlock;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 447/507] KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (445 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 446/507] KVM: arm64: Pass kvm_s2_fault_desc to fault_supports_stage2_huge_mapping() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 448/507] media: microchip-isc: fix ISC_PFG_CFG0_BPS macro name typo Greg Kroah-Hartman
` (59 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Fuad Tabba,
Vincent Donnefort, Marc Zyngier, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fuad Tabba <fuad.tabba@linux.dev>
[ Upstream commit 80b0b86dc5e4344e62a2fd3ee43d0ef816fe9122 ]
gmem_abort() maps at s2fd->fault_ipa, which HPFAR_EL2 holds at 4K
granularity whatever the page size. The generic page-table code aligns
it, but pkvm_pgtable_stage2_map() looks up existing mappings over
[addr, addr + size), so on a pKVM host with pages larger than 4K a
guest_memfd-backed guest that faults past the first 4K of a page can
find its neighbour's mapping, get -EAGAIN and take the same fault
forever.
The memory fault exit reports s2fd->fault_ipa too, which for a nested
guest's fault is the nested IPA rather than the canonical one
kvm_gmem_get_pfn() failed on.
Take the addresses from kvm_s2_fault_vma_info instead, as
user_mem_abort() does, and report the canonical gfn in the memory fault
exit. kvm_s2_fault_get_vma_info() itself isn't called: a guest_memfd
memslot's userspace_addr doesn't need to be backed by a VMA.
Fixes: a7b57e0995927 ("KVM: arm64: Handle guest_memfd-backed guest page faults")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/r/20260913175105.A57AC1F000FF@smtp.kernel.org
Cc: stable@vger.kernel.org
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Link: https://patch.msgid.link/20260928095454.3255918-4-vdonnefort@google.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/mmu.c | 67 ++++++++++++++++++++++----------------------
1 file changed, 34 insertions(+), 33 deletions(-)
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 291696dda0741..9ebc17d3e0c00 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1594,6 +1594,24 @@ static enum kvm_pgtable_prot adjust_nested_exec_perms(struct kvm *kvm,
return prot;
}
+struct kvm_s2_fault_vma_info {
+ unsigned long mmu_seq;
+ long vma_pagesize;
+ vm_flags_t vm_flags;
+ unsigned long max_map_size;
+ struct page *page;
+ kvm_pfn_t pfn;
+ gfn_t gfn;
+ bool device;
+ bool mte_allowed;
+ bool is_vma_cacheable;
+ bool map_writable;
+ bool map_non_cacheable;
+};
+
+static gfn_t get_canonical_gfn(const struct kvm_s2_fault_desc *s2fd,
+ const struct kvm_s2_fault_vma_info *s2vi);
+
static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
{
bool write_fault, exec_fault;
@@ -1601,12 +1619,10 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
enum kvm_pgtable_walk_flags flags = KVM_PGTABLE_WALK_SHARED;
enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
struct kvm_pgtable *pgt = s2fd->vcpu->arch.hw_mmu->pgt;
- unsigned long mmu_seq;
- struct page *page;
+ struct kvm_s2_fault_vma_info s2vi = {};
struct kvm *kvm = s2fd->vcpu->kvm;
void *memcache = NULL;
- kvm_pfn_t pfn;
- gfn_t gfn;
+ gfn_t canonical_gfn;
int ret;
if (!perm_fault) {
@@ -1616,24 +1632,23 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
return ret;
}
- if (s2fd->nested)
- gfn = kvm_s2_trans_output(s2fd->nested) >> PAGE_SHIFT;
- else
- gfn = s2fd->fault_ipa >> PAGE_SHIFT;
+ s2vi.vma_pagesize = PAGE_SIZE;
+ s2vi.gfn = ALIGN_DOWN(s2fd->fault_ipa, s2vi.vma_pagesize) >> PAGE_SHIFT;
+ canonical_gfn = get_canonical_gfn(s2fd, &s2vi);
write_fault = kvm_is_write_fault(s2fd->vcpu);
exec_fault = kvm_vcpu_trap_is_exec_fault(s2fd->vcpu);
VM_WARN_ON_ONCE(write_fault && exec_fault);
- mmu_seq = kvm->mmu_invalidate_seq;
+ s2vi.mmu_seq = kvm->mmu_invalidate_seq;
/* Pairs with the smp_wmb() in kvm_mmu_invalidate_end(). */
smp_rmb();
- ret = kvm_gmem_get_pfn(kvm, s2fd->memslot, gfn, &pfn, &page, NULL);
+ ret = kvm_gmem_get_pfn(kvm, s2fd->memslot, canonical_gfn, &s2vi.pfn, &s2vi.page, NULL);
if (ret) {
- kvm_prepare_memory_fault_exit(s2fd->vcpu, s2fd->fault_ipa, PAGE_SIZE,
- write_fault, exec_fault, false);
+ kvm_prepare_memory_fault_exit(s2fd->vcpu, gfn_to_gpa(canonical_gfn),
+ s2vi.vma_pagesize, write_fault, exec_fault, false);
return ret;
}
@@ -1650,7 +1665,7 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
prot = adjust_nested_exec_perms(kvm, s2fd->nested, prot);
kvm_fault_lock(kvm);
- if (mmu_invalidate_retry(kvm, mmu_seq)) {
+ if (mmu_invalidate_retry(kvm, s2vi.mmu_seq)) {
ret = -EAGAIN;
goto out_unlock;
}
@@ -1661,39 +1676,25 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
* PTE, which will be preserved.
*/
prot &= ~KVM_NV_GUEST_MAP_SZ;
- ret = KVM_PGT_FN(kvm_pgtable_stage2_relax_perms)(pgt, s2fd->fault_ipa,
+ ret = KVM_PGT_FN(kvm_pgtable_stage2_relax_perms)(pgt, gfn_to_gpa(s2vi.gfn),
prot, flags);
} else {
- ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, s2fd->fault_ipa, PAGE_SIZE,
- __pfn_to_phys(pfn), prot,
+ ret = KVM_PGT_FN(kvm_pgtable_stage2_map)(pgt, gfn_to_gpa(s2vi.gfn),
+ s2vi.vma_pagesize,
+ __pfn_to_phys(s2vi.pfn), prot,
memcache, flags);
}
out_unlock:
- kvm_release_faultin_page(kvm, page, !!ret, prot & KVM_PGTABLE_PROT_W);
+ kvm_release_faultin_page(kvm, s2vi.page, !!ret, prot & KVM_PGTABLE_PROT_W);
kvm_fault_unlock(kvm);
if ((prot & KVM_PGTABLE_PROT_W) && !ret)
- mark_page_dirty_in_slot(kvm, s2fd->memslot, gfn);
+ mark_page_dirty_in_slot(kvm, s2fd->memslot, canonical_gfn);
return ret != -EAGAIN ? ret : 0;
}
-struct kvm_s2_fault_vma_info {
- unsigned long mmu_seq;
- long vma_pagesize;
- vm_flags_t vm_flags;
- unsigned long max_map_size;
- struct page *page;
- kvm_pfn_t pfn;
- gfn_t gfn;
- bool device;
- bool mte_allowed;
- bool is_vma_cacheable;
- bool map_writable;
- bool map_non_cacheable;
-};
-
static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
{
unsigned int flags = FOLL_HWPOISON | FOLL_LONGTERM | FOLL_WRITE;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 448/507] media: microchip-isc: fix ISC_PFG_CFG0_BPS macro name typo
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (446 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 447/507] KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 449/507] media: microchip-isc: fix SBGGR10 Bayer pattern Greg Kroah-Hartman
` (58 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Balakrishnan Sambath, Eugen Hristev,
Hans Verkuil, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Balakrishnan Sambath <balakrishnan.s@microchip.com>
[ Upstream commit 96defd0723fc893db6ccf5f4968323db4af0b0aa ]
The BPS field macros for ISC_PFE_CFG0 were spelled ISC_PFG_CFG0_BPS_*
(NINE, TEN, ELEVEN, TWELVE). The register is PFE, not PFG. Rename them
to ISC_PFE_CFG0_BPS_* to match the register and the EIGHT and MASK
macros. No functional change.
Signed-off-by: Balakrishnan Sambath <balakrishnan.s@microchip.com>
Reviewed-by: Eugen Hristev <ehristev@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Stable-dep-of: bb96c78c5f87 ("media: microchip-isc: fix SBGGR10 Bayer pattern")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../platform/microchip/microchip-isc-regs.h | 8 ++++----
.../platform/microchip/microchip-sama5d2-isc.c | 18 +++++++++---------
.../platform/microchip/microchip-sama7g5-isc.c | 18 +++++++++---------
3 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/drivers/media/platform/microchip/microchip-isc-regs.h b/drivers/media/platform/microchip/microchip-isc-regs.h
index cabecf128b37a..fe145b142b826 100644
--- a/drivers/media/platform/microchip/microchip-isc-regs.h
+++ b/drivers/media/platform/microchip/microchip-isc-regs.h
@@ -32,10 +32,10 @@
#define ISC_PFE_CFG0_MODE_MASK GENMASK(6, 4)
#define ISC_PFE_CFG0_BPS_EIGHT 0x4
-#define ISC_PFG_CFG0_BPS_NINE 0x3
-#define ISC_PFG_CFG0_BPS_TEN 0x2
-#define ISC_PFG_CFG0_BPS_ELEVEN 0x1
-#define ISC_PFG_CFG0_BPS_TWELVE 0x0
+#define ISC_PFE_CFG0_BPS_NINE 0x3
+#define ISC_PFE_CFG0_BPS_TEN 0x2
+#define ISC_PFE_CFG0_BPS_ELEVEN 0x1
+#define ISC_PFE_CFG0_BPS_TWELVE 0x0
#define ISC_PFE_CFG0_BPS_MASK GENMASK(30, 28)
#define ISC_PFE_CFG0_COLEN BIT(12)
diff --git a/drivers/media/platform/microchip/microchip-sama5d2-isc.c b/drivers/media/platform/microchip/microchip-sama5d2-isc.c
index 5bd109e93a8fb..57a5aae3cabfb 100644
--- a/drivers/media/platform/microchip/microchip-sama5d2-isc.c
+++ b/drivers/media/platform/microchip/microchip-sama5d2-isc.c
@@ -147,49 +147,49 @@ static struct isc_format sama5d2_formats_list[] = {
{
.fourcc = V4L2_PIX_FMT_SBGGR10,
.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TEN,
.cfa_baycfg = ISC_BAY_CFG_RGRG,
},
{
.fourcc = V4L2_PIX_FMT_SGBRG10,
.mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TEN,
.cfa_baycfg = ISC_BAY_CFG_GBGB,
},
{
.fourcc = V4L2_PIX_FMT_SGRBG10,
.mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TEN,
.cfa_baycfg = ISC_BAY_CFG_GRGR,
},
{
.fourcc = V4L2_PIX_FMT_SRGGB10,
.mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TEN,
.cfa_baycfg = ISC_BAY_CFG_RGRG,
},
{
.fourcc = V4L2_PIX_FMT_SBGGR12,
.mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TWELVE,
.cfa_baycfg = ISC_BAY_CFG_BGBG,
},
{
.fourcc = V4L2_PIX_FMT_SGBRG12,
.mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TWELVE,
.cfa_baycfg = ISC_BAY_CFG_GBGB,
},
{
.fourcc = V4L2_PIX_FMT_SGRBG12,
.mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TWELVE,
.cfa_baycfg = ISC_BAY_CFG_GRGR,
},
{
.fourcc = V4L2_PIX_FMT_SRGGB12,
.mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TWELVE,
.cfa_baycfg = ISC_BAY_CFG_RGRG,
},
{
@@ -210,7 +210,7 @@ static struct isc_format sama5d2_formats_list[] = {
{
.fourcc = V4L2_PIX_FMT_Y10,
.mbus_code = MEDIA_BUS_FMT_Y10_1X10,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TEN,
},
};
diff --git a/drivers/media/platform/microchip/microchip-sama7g5-isc.c b/drivers/media/platform/microchip/microchip-sama7g5-isc.c
index d978ce448a4d2..a841266ffc30f 100644
--- a/drivers/media/platform/microchip/microchip-sama7g5-isc.c
+++ b/drivers/media/platform/microchip/microchip-sama7g5-isc.c
@@ -156,49 +156,49 @@ static struct isc_format sama7g5_formats_list[] = {
{
.fourcc = V4L2_PIX_FMT_SBGGR10,
.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TEN,
.cfa_baycfg = ISC_BAY_CFG_RGRG,
},
{
.fourcc = V4L2_PIX_FMT_SGBRG10,
.mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TEN,
.cfa_baycfg = ISC_BAY_CFG_GBGB,
},
{
.fourcc = V4L2_PIX_FMT_SGRBG10,
.mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TEN,
.cfa_baycfg = ISC_BAY_CFG_GRGR,
},
{
.fourcc = V4L2_PIX_FMT_SRGGB10,
.mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TEN,
.cfa_baycfg = ISC_BAY_CFG_RGRG,
},
{
.fourcc = V4L2_PIX_FMT_SBGGR12,
.mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TWELVE,
.cfa_baycfg = ISC_BAY_CFG_BGBG,
},
{
.fourcc = V4L2_PIX_FMT_SGBRG12,
.mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TWELVE,
.cfa_baycfg = ISC_BAY_CFG_GBGB,
},
{
.fourcc = V4L2_PIX_FMT_SGRBG12,
.mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TWELVE,
.cfa_baycfg = ISC_BAY_CFG_GRGR,
},
{
.fourcc = V4L2_PIX_FMT_SRGGB12,
.mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TWELVE,
.cfa_baycfg = ISC_BAY_CFG_RGRG,
},
{
@@ -224,7 +224,7 @@ static struct isc_format sama7g5_formats_list[] = {
{
.fourcc = V4L2_PIX_FMT_Y10,
.mbus_code = MEDIA_BUS_FMT_Y10_1X10,
- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN,
+ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TEN,
},
};
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 449/507] media: microchip-isc: fix SBGGR10 Bayer pattern
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (447 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 448/507] media: microchip-isc: fix ISC_PFG_CFG0_BPS macro name typo Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 450/507] ALSA: usb-audio: keep MIDI input running for Roland TD-11 Greg Kroah-Hartman
` (57 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Balakrishnan Sambath, Eugen Hristev,
Hans Verkuil, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Balakrishnan Sambath <balakrishnan.s@microchip.com>
[ Upstream commit bb96c78c5f87072913f8825faebe64bf711a503c ]
SBGGR10 was mapped to ISC_BAY_CFG_RGRG instead of ISC_BAY_CFG_BGBG,
causing red/blue channel swap.
Fixes: 1e8f401474d6 ("media: atmel: atmel-isc: reworked driver and formats")
Cc: stable@vger.kernel.org
Signed-off-by: Balakrishnan Sambath <balakrishnan.s@microchip.com>
Reviewed-by: Eugen Hristev <ehristev@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/platform/microchip/microchip-sama5d2-isc.c | 2 +-
drivers/media/platform/microchip/microchip-sama7g5-isc.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/microchip/microchip-sama5d2-isc.c b/drivers/media/platform/microchip/microchip-sama5d2-isc.c
index 57a5aae3cabfb..5e41eee45dbd7 100644
--- a/drivers/media/platform/microchip/microchip-sama5d2-isc.c
+++ b/drivers/media/platform/microchip/microchip-sama5d2-isc.c
@@ -148,7 +148,7 @@ static struct isc_format sama5d2_formats_list[] = {
.fourcc = V4L2_PIX_FMT_SBGGR10,
.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
.pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TEN,
- .cfa_baycfg = ISC_BAY_CFG_RGRG,
+ .cfa_baycfg = ISC_BAY_CFG_BGBG,
},
{
.fourcc = V4L2_PIX_FMT_SGBRG10,
diff --git a/drivers/media/platform/microchip/microchip-sama7g5-isc.c b/drivers/media/platform/microchip/microchip-sama7g5-isc.c
index a841266ffc30f..9e78ea07b013a 100644
--- a/drivers/media/platform/microchip/microchip-sama7g5-isc.c
+++ b/drivers/media/platform/microchip/microchip-sama7g5-isc.c
@@ -157,7 +157,7 @@ static struct isc_format sama7g5_formats_list[] = {
.fourcc = V4L2_PIX_FMT_SBGGR10,
.mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
.pfe_cfg0_bps = ISC_PFE_CFG0_BPS_TEN,
- .cfa_baycfg = ISC_BAY_CFG_RGRG,
+ .cfa_baycfg = ISC_BAY_CFG_BGBG,
},
{
.fourcc = V4L2_PIX_FMT_SGBRG10,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 450/507] ALSA: usb-audio: keep MIDI input running for Roland TD-11
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (448 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 449/507] media: microchip-isc: fix SBGGR10 Bayer pattern Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 451/507] ALSA: usb-audio: Protect Roland control activation Greg Kroah-Hartman
` (56 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Hobson, Takashi Iwai,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Hobson <nicholas.hobson@outlook.com>
[ Upstream commit 2e4c9ab2574eeaa7b893c7d35b4a9f60fd681ddd ]
The TD-11 hands MIDI handling off to the host once connected via
USB. If no MIDI input port is opened on the host, the device itself
becomes unusable as a standalone instrument until its input is
serviced, independent of anything happening on the computer.
Add a per-device keep_input_running flag, set for the TD-11 in
snd_usbmidi_detect_roland(), and check it alongside the existing
opened[1] check in snd_usbmidi_input_start()/snd_usbmidi_input_stop()
so that input is started at device creation and never stopped for
these devices, regardless of whether a client has the input port
open.
Signed-off-by: Nicholas Hobson <nicholas.hobson@outlook.com>
Link: https://patch.msgid.link/MN2PR15MB3472557AF39DC3A4CA9E753FF8BD2@MN2PR15MB3472.namprd15.prod.outlook.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Stable-dep-of: 19b42c1fff7f ("ALSA: usb-audio: Protect Roland control activation")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/midi.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 7e5b1b13360f0..353217b3629b7 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -113,6 +113,7 @@ struct snd_usb_midi {
unsigned int opened[2];
unsigned char disconnected;
unsigned char input_running;
+ unsigned char keep_input_running;
struct snd_kcontrol *roland_load_ctl;
};
@@ -1172,7 +1173,7 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir,
snd_usbmidi_input_start(&umidi->list);
} else {
umidi->opened[dir]--;
- if (!umidi->opened[1])
+ if (!umidi->opened[1] && !umidi->keep_input_running)
snd_usbmidi_input_stop(&umidi->list);
if (!umidi->opened[0] && !umidi->opened[1]) {
if (umidi->roland_load_ctl) {
@@ -2262,6 +2263,10 @@ static int snd_usbmidi_detect_roland(struct snd_usb_midi *umidi,
struct usb_host_interface *hostif;
u8 *cs_desc;
+ /* TD-11 becomes unusable if input isn't serviced continuously */
+ if (umidi->usb_id == USB_ID(0x0582, 0x0151))
+ umidi->keep_input_running = 1;
+
intf = umidi->iface;
if (!intf)
return -ENOENT;
@@ -2469,7 +2474,7 @@ void snd_usbmidi_input_start(struct list_head *p)
int i;
umidi = list_entry(p, struct snd_usb_midi, list);
- if (umidi->input_running || !umidi->opened[1])
+ if (umidi->input_running || (!umidi->opened[1] && !umidi->keep_input_running))
return;
for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
snd_usbmidi_input_start_ep(umidi, umidi->endpoints[i].in);
@@ -2644,6 +2649,10 @@ int __snd_usbmidi_create(struct snd_card *card,
if (err < 0)
goto exit;
+ /* start input for devices that need continuous servicing */
+ if (umidi->keep_input_running)
+ snd_usbmidi_input_start(&umidi->list);
+
usb_autopm_get_interface_no_resume(umidi->iface);
list_add_tail(&umidi->list, midi_list);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 451/507] ALSA: usb-audio: Protect Roland control activation
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (449 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 450/507] ALSA: usb-audio: keep MIDI input running for Roland TD-11 Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 452/507] f2fs: fix to avoid folio->mapping dereference in is_{meta, node}_folio() Greg Kroah-Hartman
` (55 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Takashi Iwai,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
[ Upstream commit 19b42c1fff7f220a6346c614d79ce1bda6d95b40 ]
The USB MIDI driver changes the Roland MIDI Input Mode control's access
flags directly from the rawmidi open and close paths. These changes are
not protected by the ALSA control core and the corresponding notifications
can race with control access.
Use snd_ctl_activate_id() so that the control core updates the access flags
and sends the notification under its lock. Release the USB MIDI mutex
before calling it because the control write path holds controls_rwsem while
roland_load_put() takes the USB MIDI mutex.
Keep the state transition and alternate-setting change under the USB MIDI
mutex; rawmidi's open mutex serializes the enclosing open and close paths.
Fixes: 96f61d9ade82 ("sound: usb-audio: allow switching altsetting on Roland USB MIDI devices")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Link: https://patch.msgid.link/20260929141726.2166899-1-runyu.xiao@seu.edu.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/midi.c | 53 ++++++++++++++++++++++++------------------------
1 file changed, 27 insertions(+), 26 deletions(-)
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 353217b3629b7..1099e5b814113 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -1150,41 +1150,42 @@ static int substream_open(struct snd_rawmidi_substream *substream, int dir,
int open)
{
struct snd_usb_midi *umidi = substream->rmidi->private_data;
- struct snd_kcontrol *ctl;
+ struct snd_ctl_elem_id ctl_id;
+ bool activate_ctl = false;
+ bool active;
guard(rwsem_read)(&umidi->disc_rwsem);
if (umidi->disconnected)
return open ? -ENODEV : 0;
- guard(mutex)(&umidi->mutex);
- if (open) {
- if (!umidi->opened[0] && !umidi->opened[1]) {
- if (umidi->roland_load_ctl) {
- ctl = umidi->roland_load_ctl;
- ctl->vd[0].access |=
- SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(umidi->card,
- SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
- update_roland_altsetting(umidi);
+ scoped_guard(mutex, &umidi->mutex) {
+ if (open) {
+ if (!umidi->opened[0] && !umidi->opened[1]) {
+ if (umidi->roland_load_ctl) {
+ ctl_id = umidi->roland_load_ctl->id;
+ activate_ctl = true;
+ active = false;
+ update_roland_altsetting(umidi);
+ }
}
- }
- umidi->opened[dir]++;
- if (umidi->opened[1])
- snd_usbmidi_input_start(&umidi->list);
- } else {
- umidi->opened[dir]--;
- if (!umidi->opened[1] && !umidi->keep_input_running)
- snd_usbmidi_input_stop(&umidi->list);
- if (!umidi->opened[0] && !umidi->opened[1]) {
- if (umidi->roland_load_ctl) {
- ctl = umidi->roland_load_ctl;
- ctl->vd[0].access &=
- ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- snd_ctl_notify(umidi->card,
- SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
+ umidi->opened[dir]++;
+ if (umidi->opened[1])
+ snd_usbmidi_input_start(&umidi->list);
+ } else {
+ umidi->opened[dir]--;
+ if (!umidi->opened[1] && !umidi->keep_input_running)
+ snd_usbmidi_input_stop(&umidi->list);
+ if (!umidi->opened[0] && !umidi->opened[1]) {
+ if (umidi->roland_load_ctl) {
+ ctl_id = umidi->roland_load_ctl->id;
+ activate_ctl = true;
+ active = true;
+ }
}
}
}
+ if (activate_ctl)
+ snd_ctl_activate_id(umidi->card, &ctl_id, active);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 452/507] f2fs: fix to avoid folio->mapping dereference in is_{meta, node}_folio()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (450 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 451/507] ALSA: usb-audio: Protect Roland control activation Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 453/507] f2fs: fix to check continuousness in f2fs_sync_meta_pages() correctly Greg Kroah-Hartman
` (54 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Zhiguo Niu, Chao Yu,
Jaegeuk Kim, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit b5a71253c5c7e1139eab2f3e1e13e0bf2cbcaac7 ]
Otherwise, it may cause NULL pointer dereference in race condition:
Thread A Thread B
- f2fs_setattr
- f2fs_truncate
- f2fs_truncate_blocks
- f2fs_do_truncate_blocks
- f2fs_truncate_inode_blocks
- truncate_dnode
- truncate_node
- invalidate_mapping_pages
- folio->mapping = NULL
- folio_lock
- is_node_folio
- F2FS_F_SB(folio): dereference on folio->mapping
Cc: stable@kernel.org
Fixes: 019a8912425e ("f2fs: introduce is_{meta,node}_folio")
Reported-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
Closes: https://lore.kernel.org/linux-f2fs-devel/c5d29b31-e764-4782-9639-be84b1b2bfc2@kernel.org
Signed-off-by: Chao Yu <chao@kernel.org>
Reviewed-by: Zhiguo Niu <zhiguo.niu@unisoc.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ sashal: retained IS_DNODE(folio) and is_cold_node(folio) calls without the upstream sbi arguments ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/checkpoint.c | 4 ++--
fs/f2fs/data.c | 7 ++++---
fs/f2fs/f2fs.h | 10 +++++-----
fs/f2fs/gc.c | 2 +-
fs/f2fs/node.c | 20 ++++++++++----------
fs/f2fs/segment.c | 2 +-
6 files changed, 23 insertions(+), 22 deletions(-)
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 4b59f30ef45d5..794b1cb9221ef 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -291,7 +291,7 @@ static struct folio *__get_meta_folio(struct f2fs_sb_info *sbi, pgoff_t index,
f2fs_update_iostat(sbi, NULL, FS_META_READ_IO, F2FS_BLKSIZE);
folio_lock(folio);
- if (unlikely(!is_meta_folio(folio))) {
+ if (unlikely(!is_meta_folio(sbi, folio))) {
f2fs_folio_put(folio, true);
goto repeat;
}
@@ -638,7 +638,7 @@ long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, long nr_to_write,
folio_lock(folio);
- if (unlikely(!is_meta_folio(folio))) {
+ if (unlikely(!is_meta_folio(sbi, folio))) {
continue_unlock:
folio_unlock(folio);
continue;
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index cfd81bfc28a22..c161d8061e693 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -172,7 +172,8 @@ static void f2fs_finish_read_bio(struct bio *bio, bool in_task)
dec_page_count(F2FS_F_SB(folio), __read_io_type(folio));
if (bio->bi_status == BLK_STS_OK &&
- F2FS_F_SB(folio)->node_inode && is_node_folio(folio) &&
+ F2FS_F_SB(folio)->node_inode &&
+ is_node_folio(F2FS_F_SB(folio), folio) &&
f2fs_sanity_check_node_footer(F2FS_F_SB(folio),
folio, folio->index, NODE_TYPE_REGULAR, true))
bio->bi_status = BLK_STS_IOERR;
@@ -359,12 +360,12 @@ static void f2fs_write_end_bio(struct bio *bio)
}
}
- if (is_node_folio(folio)) {
+ if (is_node_folio(sbi, folio)) {
f2fs_sanity_check_node_footer(sbi, folio,
folio->index, NODE_TYPE_REGULAR, true);
f2fs_bug_on(sbi, folio->index != nid_of_node(folio));
}
- if (f2fs_in_warm_node_list(folio))
+ if (f2fs_in_warm_node_list(sbi, folio))
f2fs_del_fsync_node_entry(sbi, folio);
dec_page_count(sbi, type);
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 0c85d90307f70..f0024647153dd 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -2316,14 +2316,14 @@ static inline struct address_space *NODE_MAPPING(struct f2fs_sb_info *sbi)
return sbi->node_inode->i_mapping;
}
-static inline bool is_meta_folio(struct folio *folio)
+static inline bool is_meta_folio(struct f2fs_sb_info *sbi, struct folio *folio)
{
- return folio->mapping == META_MAPPING(F2FS_F_SB(folio));
+ return folio->mapping == META_MAPPING(sbi);
}
-static inline bool is_node_folio(struct folio *folio)
+static inline bool is_node_folio(struct f2fs_sb_info *sbi, struct folio *folio)
{
- return folio->mapping == NODE_MAPPING(F2FS_F_SB(folio));
+ return folio->mapping == NODE_MAPPING(sbi);
}
static inline bool is_sbi_flag_set(struct f2fs_sb_info *sbi, unsigned int type)
@@ -3994,7 +3994,7 @@ enum node_type;
int f2fs_check_nid_range(struct f2fs_sb_info *sbi, nid_t nid);
bool f2fs_available_free_memory(struct f2fs_sb_info *sbi, int type);
-bool f2fs_in_warm_node_list(struct folio *folio);
+bool f2fs_in_warm_node_list(struct f2fs_sb_info *sbi, struct folio *folio);
void f2fs_init_fsync_node_info(struct f2fs_sb_info *sbi);
void f2fs_del_fsync_node_entry(struct f2fs_sb_info *sbi, struct folio *folio);
void f2fs_reset_fsync_node_info(struct f2fs_sb_info *sbi);
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 0a00180c21dc2..738a5543f086a 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1429,7 +1429,7 @@ static int move_data_block(struct inode *inode, block_t bidx,
F2FS_BLKSIZE);
folio_lock(mfolio);
- if (unlikely(!is_meta_folio(mfolio) ||
+ if (unlikely(!is_meta_folio(fio.sbi, mfolio) ||
!folio_test_uptodate(mfolio))) {
err = -EIO;
f2fs_folio_put(mfolio, true);
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 86c2e67e43b6a..b23fe1383009a 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -330,9 +330,9 @@ static unsigned int __gang_lookup_nat_set(struct f2fs_nm_info *nm_i,
start, nr);
}
-bool f2fs_in_warm_node_list(struct folio *folio)
+bool f2fs_in_warm_node_list(struct f2fs_sb_info *sbi, struct folio *folio)
{
- return is_node_folio(folio) && IS_DNODE(folio) && is_cold_node(folio);
+ return is_node_folio(sbi, folio) && IS_DNODE(folio) && is_cold_node(folio);
}
void f2fs_init_fsync_node_info(struct f2fs_sb_info *sbi)
@@ -1290,7 +1290,7 @@ int f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from)
goto fail;
if (offset[1] == 0 && get_nid(folio, offset[0], true)) {
folio_lock(folio);
- BUG_ON(!is_node_folio(folio));
+ BUG_ON(!is_node_folio(sbi, folio));
set_nid(folio, offset[0], 0, true);
folio_unlock(folio);
}
@@ -1605,7 +1605,7 @@ static struct folio *__get_node_folio(struct f2fs_sb_info *sbi, pgoff_t nid,
folio_lock(folio);
- if (unlikely(!is_node_folio(folio))) {
+ if (unlikely(!is_node_folio(sbi, folio))) {
f2fs_folio_put(folio, true);
goto repeat;
}
@@ -1724,7 +1724,7 @@ static struct folio *last_fsync_dnode(struct f2fs_sb_info *sbi, nid_t ino)
folio_lock(folio);
- if (unlikely(!is_node_folio(folio))) {
+ if (unlikely(!is_node_folio(sbi, folio))) {
continue_unlock:
folio_unlock(folio);
continue;
@@ -1834,7 +1834,7 @@ static bool __write_node_folio(struct folio *folio, bool atomic, bool do_fsync,
f2fs_need_dentry_mark(sbi, ino_of_node(folio)));
/* should add to global list before clearing PAGECACHE status */
- if (f2fs_in_warm_node_list(folio)) {
+ if (f2fs_in_warm_node_list(sbi, folio)) {
seq = f2fs_add_fsync_node_entry(sbi, folio);
if (seq_id)
*seq_id = seq;
@@ -1958,7 +1958,7 @@ int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
folio_lock(folio);
- if (unlikely(!is_node_folio(folio))) {
+ if (unlikely(!is_node_folio(sbi, folio))) {
continue_unlock:
folio_unlock(folio);
continue;
@@ -2016,7 +2016,7 @@ int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
f2fs_debug(sbi, "Retry to write fsync mark: ino=%u, idx=%lx",
ino, last_folio->index);
folio_lock(last_folio);
- if (unlikely(!is_node_folio(last_folio))) {
+ if (unlikely(!is_node_folio(sbi, last_folio))) {
f2fs_folio_put(last_folio, true);
ret = -EAGAIN;
goto out;
@@ -2094,7 +2094,7 @@ void f2fs_flush_inline_data(struct f2fs_sb_info *sbi)
folio_lock(folio);
- if (unlikely(!is_node_folio(folio)))
+ if (unlikely(!is_node_folio(sbi, folio)))
goto unlock;
if (!folio_test_dirty(folio))
goto unlock;
@@ -2166,7 +2166,7 @@ int f2fs_sync_node_pages(struct f2fs_sb_info *sbi,
else if (!folio_trylock(folio))
continue;
- if (unlikely(!is_node_folio(folio))) {
+ if (unlikely(!is_node_folio(sbi, folio))) {
continue_unlock:
folio_unlock(folio);
continue;
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index f3a73b6c24c3f..09d044c6a166d 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -4158,7 +4158,7 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio)
__func__, fio->ino, folio->index, type,
fio->old_blkaddr, fio->new_blkaddr, err);
folio_end_writeback(folio);
- if (f2fs_in_warm_node_list(folio))
+ if (f2fs_in_warm_node_list(fio->sbi, folio))
f2fs_del_fsync_node_entry(fio->sbi, folio);
f2fs_bug_on(fio->sbi, !is_set_ckpt_flags(fio->sbi,
CP_ERROR_FLAG));
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 453/507] f2fs: fix to check continuousness in f2fs_sync_meta_pages() correctly
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (451 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 452/507] f2fs: fix to avoid folio->mapping dereference in is_{meta, node}_folio() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 454/507] ALSA: hda/realtek: Fix speakers on ASUS ExpertBook PM3606CHA Greg Kroah-Hartman
` (53 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Chao Yu, Jaegeuk Kim,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit 1383cff4ccf3c8833c6255edffa29eb67c6419bb ]
In f2fs_sync_meta_pages(), whenever i becomes zero inside while loop,
below check may be skipped, it failed to check the continuousness:
if (nr_to_write != LONG_MAX && i != 0 &&
folio->index != prev +
folio_nr_pages(fbatch.folios[i-1])) {
Cc: stable@kernel.org
Fixes: 580e7a492608 ("f2fs: convert f2fs_sync_meta_pages() to use filemap_get_folios_tag()")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ sashal: adapted f2fs_sync_meta_caches() changes to folio-based f2fs_sync_meta_pages(), using folio_nr_pages() to advance the expected index ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/checkpoint.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 794b1cb9221ef..a84517023e54f 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -610,7 +610,7 @@ long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, long nr_to_write,
enum iostat_type io_type)
{
struct address_space *mapping = META_MAPPING(sbi);
- pgoff_t index = 0, prev = ULONG_MAX;
+ pgoff_t index = 0, next = ULONG_MAX;
struct folio_batch fbatch;
long nwritten = 0;
int nr_folios;
@@ -629,9 +629,8 @@ long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, long nr_to_write,
for (i = 0; i < nr_folios; i++) {
struct folio *folio = fbatch.folios[i];
- if (nr_to_write != LONG_MAX && i != 0 &&
- folio->index != prev +
- folio_nr_pages(fbatch.folios[i-1])) {
+ if (nr_to_write != LONG_MAX && next != ULONG_MAX &&
+ folio->index != next) {
folio_batch_release(&fbatch);
goto stop;
}
@@ -659,7 +658,7 @@ long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, long nr_to_write,
break;
}
nwritten += folio_nr_pages(folio);
- prev = folio->index;
+ next = folio->index + folio_nr_pages(folio);
if (unlikely(nwritten >= nr_to_write))
break;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 454/507] ALSA: hda/realtek: Fix speakers on ASUS ExpertBook PM3606CHA
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (452 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 453/507] f2fs: fix to check continuousness in f2fs_sync_meta_pages() correctly Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 455/507] ALSA: hda/realtek: Fix internal mic on Minisforum V3 and V3 SE Greg Kroah-Hartman
` (52 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Saim Masood, Takashi Iwai,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Saim Masood <s.m.saim074@gmail.com>
[ Upstream commit 556cca74b6ec6f0bc6a3dc27473487de3cc8c8fe ]
The internal speakers of the ASUS ExpertBook PM3606CHA (Realtek ALC256,
PCI SSID 1043:3501) stay silent with the default codec setup, and the
headphone jack is not detected either. The codec needs COEF values that
differ from its power-on defaults: COEF 0x10, 0x16, 0x35, 0x37 and 0x57
on NID 0x20 have to be set to the values used by the Windows driver.
Toggling the codec GPIOs, and the existing ALC256 fixups alone, make no
difference.
Apply the COEFs from a new fixup at the INIT action, so that they are
restored after resume as well. Chain to ALC256_FIXUP_ASUS_MIC_NO_PRESENCE
to keep the headset mic and the jack detection working, which the
fallback pin quirk provided before for this machine.
The COEF values were found by the reporter of the Ubuntu bug below, who
compared the codec state against the one under the Windows driver.
Tested on an ASUS ExpertBook PM3606CHA (BIOS PM3606CHA.304) with the
change applied to v7.2.5: with this fixup alone, the speakers, the
headphones with jack detection, and the headset mic all work, also
after suspend and resume.
Link: https://bugs.launchpad.net/bugs/2167288
Signed-off-by: Saim Masood <s.m.saim074@gmail.com>
Link: https://patch.msgid.link/065927dd-cabf-449a-992d-64887eedda01@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Stable-dep-of: 72107104d4f5 ("ALSA: hda/realtek: Fix internal mic on Minisforum V3 and V3 SE")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/hda/codecs/realtek/alc269.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c
index dd3466c3129d7..03f03080bbeb5 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -3537,6 +3537,27 @@ static void alc233_fixup_no_audio_jack(struct hda_codec *codec,
alc_process_coef_fw(codec, alc233_fixup_no_audio_jack_coefs);
}
+static const struct coef_fw alc256_asus_speaker_coefs[] = {
+ WRITE_COEF(0x10, 0x7f20), WRITE_COEF(0x16, 0x0c50), WRITE_COEF(0x35, 0x8d6a),
+ WRITE_COEF(0x37, 0xfe06), WRITE_COEF(0x57, 0x7f7f),
+ {}
+};
+
+static void alc256_fixup_asus_speaker_coefs(struct hda_codec *codec,
+ const struct hda_fixup *fix,
+ int action)
+{
+ /*
+ * The internal speakers of the ASUS ExpertBook PM3606CHA stay silent
+ * with the default COEF values. These are the values set by the
+ * Windows driver. They are applied on every init so that they are
+ * restored after resume, too.
+ */
+ if (action != HDA_FIXUP_ACT_INIT)
+ return;
+ alc_process_coef_fw(codec, alc256_asus_speaker_coefs);
+}
+
static void alc256_fixup_mic_no_presence_and_resume(struct hda_codec *codec,
const struct hda_fixup *fix,
int action)
@@ -4391,6 +4412,7 @@ enum {
ALC285_LENOVO_DAC_RENAME,
ALC287_FIXUP_YOGA9_SPEAKER2_TO_DAC1,
ALC256_FIXUP_IPASON_SMARTBOOK_S1,
+ ALC256_FIXUP_ASUS_SPEAKER_COEFS,
};
/* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -7208,6 +7230,12 @@ static const struct hda_fixup alc269_fixups[] = {
{ }
},
},
+ [ALC256_FIXUP_ASUS_SPEAKER_COEFS] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc256_fixup_asus_speaker_coefs,
+ .chained = true,
+ .chain_id = ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
+ },
};
static const struct hda_quirk alc269_fixup_tbl[] = {
@@ -7991,6 +8019,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x31e1, "ASUS B5605CCA", ALC294_FIXUP_ASUS_CS35L41_SPI_2),
SND_PCI_QUIRK(0x1043, 0x31f1, "ASUS B3605CCA", ALC294_FIXUP_ASUS_CS35L41_SPI_2),
SND_PCI_QUIRK(0x1043, 0x3391, "ASUS PM3606CKA", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x1043, 0x3501, "ASUS PM3606CHA", ALC256_FIXUP_ASUS_SPEAKER_COEFS),
SND_PCI_QUIRK(0x1043, 0x3601, "ASUS PM5406CGA", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x1043, 0x3611, "ASUS PM5606CGA", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x1043, 0x3701, "ASUS P5406CCA", ALC245_FIXUP_CS35L41_SPI_2),
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 455/507] ALSA: hda/realtek: Fix internal mic on Minisforum V3 and V3 SE
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (453 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 454/507] ALSA: hda/realtek: Fix speakers on ASUS ExpertBook PM3606CHA Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 456/507] sctp: hold shkey across socket migration Greg Kroah-Hartman
` (51 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jared Wuerzburger, Takashi Iwai,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jared Wuerzburger <jwuerz@gmail.com>
[ Upstream commit 72107104d4f522405c9dfdfbaeb230e371c295ee ]
On the Minisforum V3 and V3 SE (ALC245, PCI SSID 1f4c:e001) the
internal digital microphone array never produces any audio. The DMIC
pin 0x12 is parsed correctly ("Internal Mic=0x12"), but the headset mic
jack pin 0x19 (BIOS pin config 0x04a19050, jack detect enabled) has no
presence detect wired on these boards: reading GET_PIN_SENSE on 0x19
always returns "present" (as it does on the unused, unconnected pin
0x18), while the headphone jack 0x21 reports correctly.
The generic parser therefore sets up auto-mic switching and, believing
an external mic is always plugged in, permanently routes the ADC to the
empty jack (mixer 0x23 input 0x19 unmuted, input 0x12 muted). The
"Mic Jack" kcontrol reports "on" with nothing plugged in.
Mark pin 0x19 as having no presence detect. The parser then stops
auto-switching and exposes a normal "Capture Source" (Internal Mic /
Mic) control, which desktop audio stacks drive from their Internal
Microphone / Microphone ports. The existing bass speaker DAC routing is
kept by chaining to ALC245_FIXUP_BASS_HP_DAC.
Tested on both models with the same pin config applied through a
snd-hda-intel patch firmware ([pincfg] 0x19 0x04a19150):
- V3 SE (Ryzen 7 7735U, BIOS 1.03), kernel 7.2.6
- V3 (Ryzen 7 8840U, BIOS 1.06), kernel 7.2.7
Both boards report the same codec SSID and the same 0x19 default. On
both, the internal mic records at a normal level, headphone jack
detection on 0x21 still switches output, and the bass routing is
retained (DAC1/DAC2 Playback Volume controls present). A headset mic
on the combo jack was not tested (none available); with this change it
has to be selected manually. V3 users already report that the jack mic
gets no input [1], which is the other symptom of the same broken
presence detect.
The patched alc269.c was build-tested with W=1 on tiwai/sound.git
for-linus (7.3-rc3) without new warnings.
The diagnosis, the fixup and this changelog were written with the help
of an AI coding assistant; I reviewed them and tested the change on the
hardware listed above.
Fixes: e34743018249 ("ALSA: hda/realtek: Add quirk for Minisforum V3 SE")
Link: https://github.com/mudkipme/awesome-minisforum-v3/issues/14 [1]
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Jared Wuerzburger <jwuerz@gmail.com>
Link: https://patch.msgid.link/20260928152925.69032-1-jwuerz@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/hda/codecs/realtek/alc269.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c
index 03f03080bbeb5..49c4d01759b06 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -4413,6 +4413,7 @@ enum {
ALC287_FIXUP_YOGA9_SPEAKER2_TO_DAC1,
ALC256_FIXUP_IPASON_SMARTBOOK_S1,
ALC256_FIXUP_ASUS_SPEAKER_COEFS,
+ ALC245_FIXUP_MINISFORUM_V3_MIC_NO_PRESENCE,
};
/* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -7236,6 +7237,15 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
},
+ [ALC245_FIXUP_MINISFORUM_V3_MIC_NO_PRESENCE] = {
+ .type = HDA_FIXUP_PINS,
+ .v.pins = (const struct hda_pintbl[]) {
+ { 0x19, 0x04a19150 }, /* headset mic jack, no presence detect */
+ { }
+ },
+ .chained = true,
+ .chain_id = ALC245_FIXUP_BASS_HP_DAC
+ },
};
static const struct hda_quirk alc269_fixup_tbl[] = {
@@ -8475,7 +8485,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1ee7, 0x2081, "HONOR MRB-XXX M1020", ALC256_FIXUP_HONOR_MRB_XXX_M1020_AUDIO),
SND_PCI_QUIRK(0x1f4c, 0xb020, "Minisforum AI X1 Pro",
ALC245_FIXUP_MINISFORUM_JACK_DETECT),
- SND_PCI_QUIRK(0x1f4c, 0xe001, "Minisforum V3 (SE)", ALC245_FIXUP_BASS_HP_DAC),
+ SND_PCI_QUIRK(0x1f4c, 0xe001, "Minisforum V3 (SE)",
+ ALC245_FIXUP_MINISFORUM_V3_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1f66, 0x0105, "Ayaneo Portable Game Player", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x2014, 0x800a, "Positivo ARN50", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
SND_PCI_QUIRK(0x2039, 0x0001, "Inspur S14-G1", ALC295_FIXUP_CHROME_BOOK),
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 456/507] sctp: hold shkey across socket migration
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (454 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 455/507] ALSA: hda/realtek: Fix internal mic on Minisforum V3 and V3 SE Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 457/507] sctp: re-point retained control chunks on association migration Greg Kroah-Hartman
` (50 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyle Zeng, David Lee, Xin Long,
Jakub Kicinski, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lee <david.lee@trailofbits.com>
[ Upstream commit ad1320865b1826ffa2e81e37c49535751e81335c ]
sctp_sock_migrate() transfers queued DATA skbs from the old socket to the
new one. skb_orphan() invokes sctp_wfree() during that transfer and drops
the skb-owned shared-key reference.
If userspace has removed that key from the association, this can be the
final reference. The following sctp_set_owner_w() then dereferences the
freed chunk->shkey while trying to take the new owner reference.
Take a temporary shared-key reference before orphaning the skb and release
it after the new owner has taken its reference. This preserves the selected
authentication key throughout the ownership transfer.
Bug found and triaged by OpenAI Security Research and
validated by Trail of Bits.
Fixes: 1b1e0bc99474 ("sctp: add refcnt support for sh_key")
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Signed-off-by: David Lee <david.lee@trailofbits.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20261009074244.3718-2-juny24602@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 52ffeaa358d1 ("sctp: re-point retained control chunks on association migration")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sctp/socket.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index c616f1609d0cf..b5e205eca3077 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -148,9 +148,19 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
static void sctp_clear_owner_w(struct sctp_chunk *chunk)
{
+ /* Keep the shkey alive until the new owner takes its reference. */
+ if (chunk->shkey)
+ sctp_auth_shkey_hold(chunk->shkey);
skb_orphan(chunk->skb);
}
+static void sctp_set_owner_w_migrate(struct sctp_chunk *chunk)
+{
+ sctp_set_owner_w(chunk);
+ if (chunk->shkey)
+ sctp_auth_shkey_release(chunk->shkey);
+}
+
#define traverse_and_process() \
do { \
msg = chunk->msg; \
@@ -9649,7 +9659,7 @@ static int sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
lock_sock_nested(newsk, SINGLE_DEPTH_NESTING);
sctp_for_each_tx_datachunk(assoc, true, sctp_clear_owner_w);
sctp_assoc_migrate(assoc, newsk);
- sctp_for_each_tx_datachunk(assoc, false, sctp_set_owner_w);
+ sctp_for_each_tx_datachunk(assoc, false, sctp_set_owner_w_migrate);
/* If the association on the newsk is already closed before accept()
* is called, set RCV_SHUTDOWN flag.
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 457/507] sctp: re-point retained control chunks on association migration
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (455 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 456/507] sctp: hold shkey across socket migration Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 458/507] fs/ntfs3: validate the EA value length in ntfs_read_ea() Greg Kroah-Hartman
` (49 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, TencentOS Corvus AI,
Jun Yang, Xin Long, Jakub Kicinski, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jun Yang <junvyyang@tencent.com>
[ Upstream commit 52ffeaa358d1f3d91aa87a26ad90d77769cff74b ]
sctp_sock_migrate() transfers DATA chunk ownership but leaves retained
control chunks pointing at the old socket. A later retransmission can
therefore access the socket after it has been freed.
Extend the migration walk to cover retained control chunks and use
sctp_control_set_owner_w() to assign their new owner. Reuse the DATA
ownership check so each chunk is processed once per pass, even when it
is reachable through multiple lists or retained pointers.
Preserve a control chunk's existing authentication key across migration
so its final release can still generate SCTP_AUTH_FREE_KEY when needed.
Fixes: d04adf1b3551 ("sctp: reset owner sk for data chunks on out queues when migrating a sock")
Cc: stable@kernel.org
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Signed-off-by: Jun Yang <junvyyang@tencent.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20261009074244.3718-3-juny24602@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/sctp/sm.h | 1 +
net/sctp/sm_make_chunk.c | 5 ++--
net/sctp/socket.c | 53 ++++++++++++++++++++++++++++++----------
3 files changed, 44 insertions(+), 15 deletions(-)
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 3bfd261a53cc9..76605d1ee8391 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -252,6 +252,7 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
struct sctp_fwdtsn_skip *skiplist);
struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc,
__u16 key_id);
+void sctp_control_set_owner_w(struct sctp_chunk *chunk);
struct sctp_chunk *sctp_make_strreset_req(const struct sctp_association *asoc,
__u16 stream_num, __be16 *stream_list,
bool out, bool in);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 8933caadcdb66..0896ec6c75ce7 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -94,7 +94,7 @@ static void sctp_control_release_owner(struct sk_buff *skb)
}
}
-static void sctp_control_set_owner_w(struct sctp_chunk *chunk)
+void sctp_control_set_owner_w(struct sctp_chunk *chunk)
{
struct sctp_association *asoc = chunk->asoc;
struct sk_buff *skb = chunk->skb;
@@ -107,7 +107,8 @@ static void sctp_control_set_owner_w(struct sctp_chunk *chunk)
* For now don't do anything for now.
*/
if (chunk->auth) {
- chunk->shkey = asoc->shkey;
+ if (!chunk->shkey)
+ chunk->shkey = asoc->shkey;
sctp_auth_shkey_hold(chunk->shkey);
}
skb->sk = asoc ? asoc->base.sk : NULL;
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index b5e205eca3077..b5a57f61ee6d1 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -156,9 +156,24 @@ static void sctp_clear_owner_w(struct sctp_chunk *chunk)
static void sctp_set_owner_w_migrate(struct sctp_chunk *chunk)
{
- sctp_set_owner_w(chunk);
- if (chunk->shkey)
- sctp_auth_shkey_release(chunk->shkey);
+ struct sctp_shared_key *shkey = chunk->shkey;
+
+ if (chunk->msg)
+ sctp_set_owner_w(chunk);
+ else
+ sctp_control_set_owner_w(chunk);
+
+ if (shkey)
+ sctp_auth_shkey_release(shkey);
+}
+
+static void sctp_process_tx_chunk(struct sctp_association *asoc,
+ struct sctp_chunk *chunk, bool clear,
+ void (*cb)(struct sctp_chunk *))
+{
+ if ((clear && asoc->base.sk == chunk->skb->sk) ||
+ (!clear && asoc->base.sk != chunk->skb->sk))
+ cb(chunk);
}
#define traverse_and_process() \
@@ -166,17 +181,14 @@ do { \
msg = chunk->msg; \
if (msg == prev_msg) \
continue; \
- list_for_each_entry(c, &msg->chunks, frag_list) { \
- if ((clear && asoc->base.sk == c->skb->sk) || \
- (!clear && asoc->base.sk != c->skb->sk)) \
- cb(c); \
- } \
+ list_for_each_entry(c, &msg->chunks, frag_list) \
+ sctp_process_tx_chunk(asoc, c, clear, cb); \
prev_msg = msg; \
} while (0)
-static void sctp_for_each_tx_datachunk(struct sctp_association *asoc,
- bool clear,
- void (*cb)(struct sctp_chunk *))
+static void sctp_for_each_tx_chunk(struct sctp_association *asoc,
+ bool clear,
+ void (*cb)(struct sctp_chunk *))
{
struct sctp_datamsg *msg, *prev_msg = NULL;
@@ -199,6 +211,21 @@ static void sctp_for_each_tx_datachunk(struct sctp_association *asoc,
list_for_each_entry(chunk, &q->out_chunk_list, list)
traverse_and_process();
+
+ list_for_each_entry(chunk, &q->control_chunk_list, list)
+ sctp_process_tx_chunk(asoc, chunk, clear, cb);
+
+ list_for_each_entry(chunk, &asoc->asconf_ack_list, transmitted_list)
+ sctp_process_tx_chunk(asoc, chunk, clear, cb);
+
+ list_for_each_entry(chunk, &asoc->addip_chunk_list, list)
+ sctp_process_tx_chunk(asoc, chunk, clear, cb);
+
+ if (asoc->strreset_chunk)
+ sctp_process_tx_chunk(asoc, asoc->strreset_chunk, clear, cb);
+
+ if (asoc->addip_last_asconf)
+ sctp_process_tx_chunk(asoc, asoc->addip_last_asconf, clear, cb);
}
static void sctp_for_each_rx_skb(struct sctp_association *asoc, struct sock *sk,
@@ -9657,9 +9684,9 @@ static int sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
* paths won't try to lock it and then oldsk.
*/
lock_sock_nested(newsk, SINGLE_DEPTH_NESTING);
- sctp_for_each_tx_datachunk(assoc, true, sctp_clear_owner_w);
+ sctp_for_each_tx_chunk(assoc, true, sctp_clear_owner_w);
sctp_assoc_migrate(assoc, newsk);
- sctp_for_each_tx_datachunk(assoc, false, sctp_set_owner_w_migrate);
+ sctp_for_each_tx_chunk(assoc, false, sctp_set_owner_w_migrate);
/* If the association on the newsk is already closed before accept()
* is called, set RCV_SHUTDOWN flag.
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 458/507] fs/ntfs3: validate the EA value length in ntfs_read_ea()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (456 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 457/507] sctp: re-point retained control chunks on association migration Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 459/507] platform/chrome: Fix typos in comments Greg Kroah-Hartman
` (48 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuejie Shi, Konstantin Komarov,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuejie Shi <syjcnss@gmail.com>
[ Upstream commit 351817226fbf0031c4c63d1f5d7f15c3172312eb ]
ntfs_read_ea() checks the $EA list for consistency, but it only
recomputes the packed size of an entry when the entry's own size field is
zero:
for (off = 0; off < size; off += ea_size) {
const struct EA_FULL *ef = Add2Ptr(ea_p, off);
u32 bytes = size - off;
...
if (ef->size) {
ea_size = le32_to_cpu(ef->size);
if (ea_size > bytes)
goto out1;
continue; /* <- elength never checked */
}
...
ea_size = ALIGN(struct_size(ef, name,
1 + ef->name_len +
le16_to_cpu(ef->elength)),
4);
if (ea_size > bytes)
goto out1;
}
ef->size is non-zero for every entry except the last one, and it is what
ntfs3 itself writes (ntfs_set_ea() stores exactly that aligned packed
size), so in practice elength is not validated at all. find_ea() then
uses unpacked_ea_size(), which also prefers ea->size when it is set, so
it agrees and hands the entry back.
ntfs_get_ea() copies elength bytes with no further bound of its own:
len = le16_to_cpu(ea->elength);
...
if (len > size) { /* size is the *caller's* buffer */
err = -ERANGE;
...
}
memcpy(buffer, ea->name + ea->name_len + 1, len);
so a caller that supplies a large enough buffer receives up to 64 KiB of
whatever follows the small $EA allocation -- straight to userspace via
getxattr(2).
Compute the packed size unconditionally and require it to fit in the
entry. Hoist the "bytes < offsetof(struct EA_FULL, name)" test above the
ef->size branch as well: name_len and elength were being read there
without it, which is itself a small over-read of the kmalloc'd buffer
when fewer than 8 bytes are left. The old "bytes < sizeof(ef->size)"
test is subsumed by it.
# mkntfs image; create /mnt/ntfs/poc with user.ntfs6 set, then rewrite
# that EA_FULL's elength from 0xf to 0xff00 on the raw device
mount -t ntfs3 -o ro /dev/vda /mnt/ntfs
getxattr("/mnt/ntfs/poc", "user.ntfs6", buf, 128 * 1024);
BUG: KASAN: slab-out-of-bounds in ntfs_get_ea+0x294/0x3e0
Read of size 65280 at addr ffff0000cca53acf by task xattr_probe/142
__asan_memcpy+0x3c/0xa0
ntfs_get_ea+0x294/0x3e0
ntfs_getxattr+0x284/0x318
__vfs_getxattr+0x104/0x160
vfs_getxattr+0x1b4/0x1e0
do_getxattr+0xcc/0x230
path_getxattrat+0x184/0x270
__arm64_sys_getxattr+0x64/0x80
Allocated by task 142:
__kmalloc_noprof+0x294/0x668
ntfs_read_ea+0x1e4/0x420
ntfs_get_ea+0x2c8/0x3e0
The buggy address belongs to the object at ffff0000cca53a80
which belongs to the cache kmalloc-96 of size 96
The object being over-read is the one ntfs_read_ea() just allocated, and
it is 96 bytes.
Entries written by ntfs3 and by Windows set size to the aligned packed
size, so the new test does not reject anything a working filesystem
produces.
Fixes: be71b5cba2e6 ("fs/ntfs3: Add attrib operations")
Cc: stable@vger.kernel.org
Signed-off-by: Yuejie Shi <syjcnss@gmail.com>
[almaz.alexandrovich@paragon-software.com: applied as-is, logic is the same but the code is cleaner]
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
[ sashal: adjusted context on top of c22f91d82cb9, which already validates ef->size ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs3/xattr.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c
index 594ef6860b93b..fb7276d4a4285 100644
--- a/fs/ntfs3/xattr.c
+++ b/fs/ntfs3/xattr.c
@@ -146,29 +146,32 @@ static int ntfs_read_ea(struct ntfs_inode *ni, struct EA_FULL **ea,
for (off = 0; off < size; off += ea_size) {
const struct EA_FULL *ef = Add2Ptr(ea_p, off);
u32 bytes = size - off;
- size_t need;
-
- /* Check if we can use field ea->size. */
- if (bytes < sizeof(ef->size))
- goto out1;
+ u32 packed_size;
/* Check if we can use fields ef->name_len and ef->elength. */
if (bytes < offsetof(struct EA_FULL, name))
goto out1;
- /* Size needed to hold this record's name and value. */
- need = struct_size(ef, name,
- 1 + ef->name_len + le16_to_cpu(ef->elength));
+ /*
+ * The name and the value have to fit in the entry whether or
+ * not ef->size is set, because ntfs_get_ea() copies elength
+ * bytes out of this buffer and checks them only against the
+ * caller supplied buffer size.
+ */
+ packed_size =
+ ALIGN(struct_size(ef, name,
+ 1 + ef->name_len +
+ le16_to_cpu(ef->elength)),
+ 4);
if (ef->size) {
ea_size = le32_to_cpu(ef->size);
- /* ef->size must fit the list and cover the record. */
- if (ea_size > bytes || ea_size < need)
+ if (ea_size > bytes || packed_size > ea_size)
goto out1;
continue;
}
- ea_size = ALIGN(need, 4);
+ ea_size = packed_size;
if (ea_size > bytes)
goto out1;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 459/507] platform/chrome: Fix typos in comments
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (457 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 458/507] fs/ntfs3: validate the EA value length in ntfs_read_ea() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 460/507] platform/chrome: cros_usbpd_notify: Only use drvdata when parent is GOOG0004 Greg Kroah-Hartman
` (47 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hemanth Selam, Tzung-Bi Shih,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hemanth Selam <hemanth.selam@gmail.com>
[ Upstream commit 2d23d5e9cb468baf6e4fa78d0dd7e8555759385d ]
Fix typos in comments, reported by scripts/checkpatch.pl using the
misspelling list in scripts/spelling.txt. Only touches comments, no code
changes.
Assisted-by: Cursor:claude-opus-5
Signed-off-by: Hemanth Selam <hemanth.selam@gmail.com>
Link: https://lore.kernel.org/r/20260904110900.20435-2-hemanth.selam@gmail.com
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Stable-dep-of: ca75b38b1a3c ("platform/chrome: cros_usbpd_notify: Only use drvdata when parent is GOOG0004")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/chrome/cros_ec_ishtp.c | 2 +-
drivers/platform/chrome/cros_usbpd_notify.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/platform/chrome/cros_ec_ishtp.c b/drivers/platform/chrome/cros_ec_ishtp.c
index 3766cef81fe82..b21a27ad37625 100644
--- a/drivers/platform/chrome/cros_ec_ishtp.c
+++ b/drivers/platform/chrome/cros_ec_ishtp.c
@@ -369,7 +369,7 @@ static void ish_event_cb(struct ishtp_cl_device *cl_device)
* @cros_ish_cl: ISHTP client instance
* @reset: true if called from reset handler
*
- * This function complete the initializtion of the client.
+ * This function complete the initialization of the client.
*
* Return: 0 for success, negative error code for failure.
*/
diff --git a/drivers/platform/chrome/cros_usbpd_notify.c b/drivers/platform/chrome/cros_usbpd_notify.c
index d842c05f4db00..6f5eea4938cb4 100644
--- a/drivers/platform/chrome/cros_usbpd_notify.c
+++ b/drivers/platform/chrome/cros_usbpd_notify.c
@@ -64,7 +64,7 @@ static void cros_usbpd_get_event_and_notify(struct device *dev,
/*
* We still send a 0 event out to older devices which don't
- * have the updated device heirarchy.
+ * have the updated device hierarchy.
*/
if (!ec_dev) {
dev_dbg(dev,
@@ -115,7 +115,7 @@ static int cros_usbpd_notify_probe_acpi(struct platform_device *pdev)
if (!ec_dev) {
/*
* We continue even for older devices which don't have the
- * correct device heirarchy, namely, GOOG0003 is a child
+ * correct device hierarchy, namely, GOOG0003 is a child
* of GOOG0004. If GOOG0003 is a child of GOOG0004 and we
* can't get a pointer to the Chrome EC device, defer the
* probe function.
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 460/507] platform/chrome: cros_usbpd_notify: Only use drvdata when parent is GOOG0004
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (458 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 459/507] platform/chrome: Fix typos in comments Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 461/507] mm/userfaultfd: only allocate anon_vma in CoW mappings Greg Kroah-Hartman
` (46 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, James Fairweather,
Sergey Tiraspolsky, Tzung-Bi Shih, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Fairweather <james.a.fairweather@gmail.com>
[ Upstream commit ca75b38b1a3c2eabe81d231dae4ea180cf6287cd ]
cros_usbpd_notify_probe_acpi() takes the EC device pointer from
dev_get_drvdata(dev->parent) and assumes it is a struct cros_ec_device.
That only holds when GOOG0003 is a child of GOOG0004. On older devices
without that hierarchy, such as Google Nami, GOOG0003 and GOOG0004 are
siblings under the ACPI EC (PNP0C09):
PNP0C09:00 (acpi-ec)
|-- GOOG0003:00 (cros-usbpd-notify-acpi)
`-- GOOG0004:00 (cros_ec_lpcs)
Before commit db65a06d10b3 ("ACPI: EC: Convert the driver to a platform
one") the parent platform device had no driver data, so the driver
warned and continued without an EC pointer, as intended for these
devices. Since that commit the ACPI EC driver stores its struct acpi_ec
there, so the driver treats a struct acpi_ec as a struct cros_ec_device
and calls cros_ec_cmd() on it for every USB-C PD host event. Plugging
or unplugging a charger then intermittently oopses, followed by soft
lockups and a hung system:
BUG: unable to handle page fault for address: ffffffff9cf03220
#PF: supervisor write access in kernel mode
Hardware name: Google Nami/Nami, BIOS 09/19/2019
Workqueue: kacpi_notify acpi_os_execute_deferred
RIP: 0010:native_queued_spin_lock_slowpath+0x29d/0x330
Call Trace:
_raw_spin_lock_irqsave+0x59/0x80
__mutex_lock.constprop.0+0x129/0x930
cros_ec_cmd_xfer+0x2a/0xf0 [cros_ec_proto]
cros_ec_cmd_xfer_status+0x1a/0x90 [cros_ec_proto]
cros_ec_cmd+0xb7/0x140 [cros_ec_proto]
cros_usbpd_get_event_and_notify+0x42/0xc0 [cros_usbpd_notify]
acpi_ev_notify_dispatch+0x4e/0x70
acpi_os_execute_deferred+0x1a/0x30
Only read the parent's driver data when the parent's ACPI node is
GOOG0004, and otherwise continue without an EC pointer. While at it,
drop the reference taken by fwnode_get_parent().
Fixes: db65a06d10b3 ("ACPI: EC: Convert the driver to a platform one")
Fixes: e4ee0bb077cd ("platform/chrome: cros_usbpd_notify: defer probe when parent EC driver isn't ready")
Cc: stable@vger.kernel.org
Assisted-by: claude-opus-5-5 checkpatch
Signed-off-by: James Fairweather <james.a.fairweather@gmail.com>
Reported-by: Sergey Tiraspolsky <stiraspo@gmail.com>
Closes: https://lore.kernel.org/all/20261003204623.18124-1-stiraspo@gmail.com
Tested-by: Sergey Tiraspolsky <stiraspo@gmail.com>
Link: https://lore.kernel.org/r/20261003222855.23707-1-james.a.fairweather@gmail.com
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/chrome/cros_usbpd_notify.c | 39 +++++++++++----------
1 file changed, 21 insertions(+), 18 deletions(-)
diff --git a/drivers/platform/chrome/cros_usbpd_notify.c b/drivers/platform/chrome/cros_usbpd_notify.c
index 6f5eea4938cb4..25da31ec19969 100644
--- a/drivers/platform/chrome/cros_usbpd_notify.c
+++ b/drivers/platform/chrome/cros_usbpd_notify.c
@@ -110,26 +110,29 @@ static int cros_usbpd_notify_probe_acpi(struct platform_device *pdev)
if (!pdnotify)
return -ENOMEM;
- /* Get the EC device pointer needed to talk to the EC. */
- ec_dev = dev_get_drvdata(dev->parent);
- if (!ec_dev) {
- /*
- * We continue even for older devices which don't have the
- * correct device hierarchy, namely, GOOG0003 is a child
- * of GOOG0004. If GOOG0003 is a child of GOOG0004 and we
- * can't get a pointer to the Chrome EC device, defer the
- * probe function.
- */
- parent_fwnode = fwnode_get_parent(dev->fwnode);
- if (parent_fwnode) {
- parent_adev = to_acpi_device_node(parent_fwnode);
- if (parent_adev &&
- acpi_dev_hid_match(parent_adev, CREC_DRV_NAME)) {
- return -EPROBE_DEFER;
- }
+ /*
+ * Get the EC device pointer needed to talk to the EC. The parent's
+ * driver data is only a struct cros_ec_device when GOOG0003 is a
+ * child of GOOG0004. On older devices without that hierarchy the
+ * parent may be bound to an unrelated driver (e.g. the ACPI EC
+ * driver for PNP0C09), so don't touch its driver data and continue
+ * without an EC pointer. If GOOG0003 is a child of GOOG0004 and we
+ * can't get a pointer to the Chrome EC device yet, defer the probe.
+ */
+ ec_dev = NULL;
+ parent_fwnode = fwnode_get_parent(dev->fwnode);
+ parent_adev = to_acpi_device_node(parent_fwnode);
+ if (parent_adev && acpi_dev_hid_match(parent_adev, CREC_DRV_NAME)) {
+ ec_dev = dev_get_drvdata(dev->parent);
+ if (!ec_dev) {
+ fwnode_handle_put(parent_fwnode);
+ return -EPROBE_DEFER;
}
- dev_warn(dev, "Couldn't get Chrome EC device pointer.\n");
}
+ fwnode_handle_put(parent_fwnode);
+
+ if (!ec_dev)
+ dev_warn(dev, "Couldn't get Chrome EC device pointer.\n");
pdnotify->dev = dev;
pdnotify->ec = ec_dev;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 461/507] mm/userfaultfd: only allocate anon_vma in CoW mappings
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (459 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 460/507] platform/chrome: cros_usbpd_notify: Only use drvdata when parent is GOOG0004 Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 462/507] mm: add RCU-based VMA lookup helper that waits for writers Greg Kroah-Hartman
` (45 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Hildenbrand (Arm),
Andrew Morton, Kyle Zeng, Lorenzo Stoakes (ARM), Muchun Song,
Mike Rapoport (Microsoft), Lance Yang, Oscar Salvador, Peter Xu,
Miaohe Lin, Lokesh Gidra, Liam R. Howlett, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand (Arm) <david@kernel.org>
[ Upstream commit 514c9247db305922591d806ec65d3c3fe420538d ]
find_vma_and_prepare_anon() can end up allocating an anon_vma in VMAs that
are not CoW mappings, which is wrong.
If we have a MAP_SHARED R/O file mapped, we lack VM_SHARED (but do have
VM_MAYSHARE) and lack VM_MAYWRITE.
While uffd later rejects such mappings (uffd registration requires
VM_MAYWRITE, see comment in validate_dst_vma) find_vma_and_prepare_anon()
still wrongly allocates an anon vma before it validates the vma.
This in turn later confuses copy_page_range()->vma_needs_copy() such
that we end up calling copy_hugetlb_page_range() with ranges that
actually do not contain *any* per-pagetable information that would
require copying, which is the basis for PMD-table sharing in the first
place.
copy_hugetlb_page_range() should not have to worry about shared
PMD tables at all: it doesn't make any sense to copy page tables that are
shared, as they can be fully recreated later. Ending up in the function
with shareable page tables is the real issue.
If a destination PMD table is shared in copy_hugetlb_page_range(), it
might get concurrently unshared as we are not holding relevant
locks, resulting in us using a page table that is no longer mapped and
possibly freed after calling:
dst_pte = huge_pte_alloc(dst, dst_vma, addr, sz);
To fix it, do not allocate an anon_vma in non-CoW mappings and add a
safety guard to copy_hugetlb_page_range(), making sure that we never
end up messing with shared PMD tables in there.
Before commit 867a43a34ff8a ("userfaultfd: use per-vma locks in userfaultfd
operations") we would always validate the VMA before allocating an
anon_vma, and consequently never wrongly allocate an anon_vma.
As uffd_lock_vma() is part of the same lookup machinery and
also contains a misleading VM_SHARED check, change that one as well
directly for consistency.
A follow-up cleanup will stop taking the hugetlb_vma_lock_read(src_vma)
lock in copy_hugetlb_page_range() entirely. Further, the usage of
VM_SHARED in userfaultfd code should be cleaned up later to focus on
CoW vs. non-CoW mappings.
Link: https://lore.kernel.org/20261014-copy_hugetlb_page_range-v1-1-5b68e03fe7fe@kernel.org
Fixes: 867a43a34ff8 ("userfaultfd: use per-vma locks in userfaultfd operations")
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: Kyle Zeng <kylebot@openai.com>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Kyle Zeng <kylebot@openai.com>
Tested-by: Kyle Zeng <kylebot@openai.com>
Acked-by: Muchun Song <muchun.song@linux.dev>
Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Tested-by: Lance Yang <lance.yang@linux.dev>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Peter Xu <peterx@redhat.com>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Lokesh Gidra <lokeshgidra@google.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: <stable@vger.kernel.org>
[ sashal: Replaced vma_has_anon_rmap(vma) with a direct vma->anon_vma check in uffd_lock_vma(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/hugetlb.c | 24 ++++++++++++------------
mm/userfaultfd.c | 5 ++---
2 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 09665fd220752..860c3c6b7673f 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -4939,10 +4939,11 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
raw_write_seqcount_begin(&src->write_protect_seq);
} else {
/*
- * For shared mappings the vma lock must be held before
- * calling hugetlb_walk() in the src vma. Otherwise, the
- * returned ptep could go away if part of a shared pmd and
- * another thread calls huge_pmd_unshare.
+ * Shared mappings only need copying when we could have
+ * information stored in page tables (e.g., userfaultfd PTE
+ * bits or markers), which is incompatible with PMD sharing.
+ * Still take the hugetlb VMA lock for now to satisfy
+ * hugetlb_walk()'s locking requirements.
*/
hugetlb_vma_lock_read(src_vma);
}
@@ -4950,6 +4951,13 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
last_addr_mask = hugetlb_mask_last_page(h);
for (addr = src_vma->vm_start; addr < src_vma->vm_end; addr += sz) {
spinlock_t *src_ptl, *dst_ptl;
+
+ if (WARN_ON_ONCE(want_pmd_share(src_vma, addr) ||
+ want_pmd_share(dst_vma, addr))) {
+ ret = -EINVAL;
+ break;
+ }
+
src_pte = hugetlb_walk(src_vma, addr, sz);
if (!src_pte) {
addr |= last_addr_mask;
@@ -4961,14 +4969,6 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src,
break;
}
-#ifdef CONFIG_HUGETLB_PMD_PAGE_TABLE_SHARING
- /* If the pagetables are shared, there is nothing to do */
- if (ptdesc_pmd_is_shared(virt_to_ptdesc(dst_pte))) {
- addr |= last_addr_mask;
- continue;
- }
-#endif
-
dst_ptl = huge_pte_lock(h, dst, dst_pte);
src_ptl = huge_pte_lockptr(h, src, src_pte);
spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING);
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index cc37b60fc3e81..f8e2b7f2f61c6 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -115,8 +115,7 @@ struct vm_area_struct *find_vma_and_prepare_anon(struct mm_struct *mm,
vma = vma_lookup(mm, addr);
if (!vma)
vma = ERR_PTR(-ENOENT);
- else if (!(vma->vm_flags & VM_SHARED) &&
- unlikely(anon_vma_prepare(vma)))
+ else if (vma_is_cow_mapping(vma) && unlikely(anon_vma_prepare(vma)))
vma = ERR_PTR(-ENOMEM);
return vma;
@@ -144,7 +143,7 @@ static struct vm_area_struct *uffd_lock_vma(struct mm_struct *mm,
* We know we're going to need to use anon_vma, so check
* that early.
*/
- if (!(vma->vm_flags & VM_SHARED) && unlikely(!vma->anon_vma))
+ if (vma_is_cow_mapping(vma) && unlikely(!vma->anon_vma))
vma_end_read(vma);
else
return vma;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 462/507] mm: add RCU-based VMA lookup helper that waits for writers
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (460 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 461/507] mm/userfaultfd: only allocate anon_vma in CoW mappings Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 463/507] mm/vma: avoid spurious write locks when mm->mm_lock_seq overflows Greg Kroah-Hartman
` (44 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dave Hansen, Suren Baghdasaryan,
Andrew Morton, Lorenzo Stoakes (ARM), Vlastimil Babka (SUSE),
Liam R. Howlett, Shakeel Butt, Todd Kjos, Christian Brauner,
Carlos Llamas, Alice Ryhl, David S. Miller, David Ahern,
Arve Hjønnevåg, David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Hansen <dave.hansen@linux.intel.com>
[ Upstream commit d96082aa35043cd1856e2213e683db778482a7d8 ]
There are basically two parallel ways to look up a VMA: the traditional
way, which is protected by mmap_read_lock, and the RCU-based per-VMA lock
way which is based on RCU and refcounts. However, per-VMA locks will fail
if the lock is help by a writer and therefore never waits. In a number of
places we need to wait for the lock and it's done by falling back to
mmap_read_lock, locking the VMA and releasing the mmap_lock once VMA is
locked.
Add vma_start_read_unlocked() - a variant of the RCU-based lookup that
waits for writers. This is basically the same as the existing RCU-based
lookup, but on a failure to lock it temporarily takes mmap_lock for read
and waits for writers to finish before locking the VMA, dropping the
mmap_read_lock and returning the locked VMA. This has some advantages:
1. Callers do not need to have a fallback path for when they collide
with writers.
2. Its fast path does not require taking mmap_lock for read.
Basically, when applied correctly, this approach results in faster *and*
simpler code.
While at it, fix the comments for vma_start_read_locked(),
vma_start_read_locked_nested(), and uffd_lock_vma().
Link: https://lore.kernel.org/20260831203056.838265-4-surenb@google.com
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Suggested-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Todd Kjos <tkjos@android.com>
Cc: Christian Brauner <christian@brauner.io>
Cc: Carlos Llamas <cmllamas@google.com>
Cc: Alice Ryhl <aliceryhl@google.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: David Ahern <dsahern@kernel.org>
Cc: Arve Hjønnevåg <arve@android.com>
Cc: David Hildenbrand (Arm) <david@kernel.org>
Stable-dep-of: 7135a05838e8 ("mm/vma: avoid spurious write locks when mm->mm_lock_seq overflows")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/mmap_lock.h | 19 +++++++++++++++----
mm/mmap_lock.c | 35 +++++++++++++++++++++++++++++++++++
mm/userfaultfd.c | 6 ++++--
3 files changed, 54 insertions(+), 6 deletions(-)
diff --git a/include/linux/mmap_lock.h b/include/linux/mmap_lock.h
index b8a13b8d36a45..084fc66d7f904 100644
--- a/include/linux/mmap_lock.h
+++ b/include/linux/mmap_lock.h
@@ -230,10 +230,14 @@ static inline void vma_refcount_put(struct vm_area_struct *vma)
}
/*
- * Use only while holding mmap read lock which guarantees that locking will not
- * fail (nobody can concurrently write-lock the vma). vma_start_read() should
+ * Use only while holding mmap read lock which guarantees that vma lock is not
+ * contended (nobody can concurrently write-lock the vma). vma_start_read() should
* not be used in such cases because it might fail due to mm_lock_seq overflow.
* This functionality is used to obtain vma read lock and drop the mmap read lock.
+ *
+ * VMA can't be detached while we are holding mmap lock, therefore in practice this
+ * function can fail only when there are so many readers that vm_refcnt overflows.
+ * The failure case is very unlikely and is already annotated as such internally.
*/
static inline bool vma_start_read_locked_nested(struct vm_area_struct *vma, int subclass)
{
@@ -249,16 +253,23 @@ static inline bool vma_start_read_locked_nested(struct vm_area_struct *vma, int
}
/*
- * Use only while holding mmap read lock which guarantees that locking will not
- * fail (nobody can concurrently write-lock the vma). vma_start_read() should
+ * Use only while holding mmap read lock which guarantees that vma lock is not
+ * contended (nobody can concurrently write-lock the vma). vma_start_read() should
* not be used in such cases because it might fail due to mm_lock_seq overflow.
* This functionality is used to obtain vma read lock and drop the mmap read lock.
+ *
+ * VMA can't be detached while we are holding mmap lock, therefore in practice this
+ * function can fail only when there are so many readers that vm_refcnt overflows.
+ * The failure case is very unlikely and is already annotated as such internally.
*/
static inline bool vma_start_read_locked(struct vm_area_struct *vma)
{
return vma_start_read_locked_nested(vma, 0);
}
+struct vm_area_struct *vma_start_read_unlocked(struct mm_struct *mm,
+ unsigned long address);
+
static inline void vma_end_read(struct vm_area_struct *vma)
{
vma_refcount_put(vma);
diff --git a/mm/mmap_lock.c b/mm/mmap_lock.c
index 898c2ef1e9580..f7f1c6ae25910 100644
--- a/mm/mmap_lock.c
+++ b/mm/mmap_lock.c
@@ -341,6 +341,41 @@ struct vm_area_struct *lock_vma_under_rcu(struct mm_struct *mm,
return NULL;
}
+/**
+ * vma_start_read_unlocked() - Find the VMA covering 'address' and read-lock it.
+ * @mm: the mm_struct of the address space to search
+ * @address: address that the vma should contain
+ *
+ * The fast path does not take mmap_lock. Waits for writers to finish if the
+ * VMA is being modified by taking mmap_lock.
+ * Use when mmap_lock is not held, otherwise use vma_start_read_locked().
+ * Nothing prevents VMAs being unmapped/mapped before or after the VMA is
+ * looked up, if a stronger guarantee is required, take an mmap_lock.
+ *
+ * Return: If a VMA exists which spans @address, return that VMA, read-locked.
+ * If no VMA is mapped there or, very unlikely, a reference count overflow
+ * occurred, return NULL.
+ */
+struct vm_area_struct *vma_start_read_unlocked(struct mm_struct *mm,
+ unsigned long address)
+{
+ struct vm_area_struct *vma;
+
+ /* Fast path: return stable VMA covering 'address': */
+ vma = lock_vma_under_rcu(mm, address);
+ if (vma)
+ return vma;
+
+ /* Slow path: preclude VMA writers by temporarily getting mmap read lock. */
+ mmap_read_lock(mm);
+ vma = vma_lookup(mm, address);
+ if (vma && !vma_start_read_locked(vma))
+ vma = NULL;
+ mmap_read_unlock(mm);
+
+ return vma;
+}
+
static struct vm_area_struct *lock_next_vma_under_mmap_lock(struct mm_struct *mm,
struct vma_iterator *vmi,
unsigned long from_addr)
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index f8e2b7f2f61c6..3e13bc9d35fc0 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -129,8 +129,10 @@ struct vm_area_struct *find_vma_and_prepare_anon(struct mm_struct *mm,
*
* Should be called without holding mmap_lock.
*
- * Return: A locked vma containing @address, -ENOENT if no vma is found, or
- * -ENOMEM if anon_vma couldn't be allocated.
+ * Return: A locked vma containing @address, -ENOENT if no vma is found,
+ * -ENOMEM if anon_vma couldn't be allocated, or -EAGAIN if vma refcount
+ * overflow happened due to high number of readers and the caller should
+ * retry later.
*/
static struct vm_area_struct *uffd_lock_vma(struct mm_struct *mm,
unsigned long address)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 463/507] mm/vma: avoid spurious write locks when mm->mm_lock_seq overflows
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (461 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 462/507] mm: add RCU-based VMA lookup helper that waits for writers Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 464/507] mm/shmem: honour F_SEAL_EXEC when an ACL is set Greg Kroah-Hartman
` (43 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM), Andrew Morton,
Daehyeon Ko, Jose A. Perez de Azpillaga, Suren Baghdasaryan,
Liam R. Howlett, Vlastimil Babka, Shakeel Butt, David Hildenbrand,
Mike Rapoport, Michal Hocko, Jonathan Corbet, Randy Dunlap,
Jann Horn, Pedro Falcato, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes (ARM) <ljs@kernel.org>
[ Upstream commit 7135a05838e85845e1bbf6caa6596a7e3b791a40 ]
So far the assumption has been that mm->mm_lock_seq overflow is benign,
resulting only in readers spuriously falling back to the mmap lock, however
it turns out that this was an unsafe assumption.
If a VMA can be spuriously considered write locked that means read lock
exclusion does not take place, and thus a VMA can end up write-locked with
concurrent readers.
Since overflow only occurs every 2^31 write lock/unlock cycles, resolve the
issue by resetting every VMA's vma->vm_lock_seq each time such an overflow
occurs.
This is done in vma_end_write_all(), which is called when the mmap write
lock is released, i.e. in mmap_write_unlock() and mmap_write_downgrade().
Care must be taken, as resetting the sequence count at overflow means
changing the seqcount of VMAs which are already attached and observable.
The mm's seqcount is guaranteed to be odd when a write lock is held, and
thus any write locked VMA will have an odd seqcount assigned.
Therefore resetting to an even value prevents spurious write locks, since
these can only occur with the mmap write lock held, at which point the mmap
seqcount will be odd.
However, vma_start_read() also checks vma->vm_lock_seq == mm->mm_lock_seq,
bailing if so (indicating a write lock).
This would cause any even reset value chosen to prevent VMA read locks from
being taken - avoid this by also checking whether the VMA seqcount is odd
before bailing on the read lock.
So far, vma->vm_lock_seq has defaulted to UINT_MAX, but this has been
unnecessary since commit e5e7fb278e59 ("mm: convert mm_lock_seq to a proper
seqcount"), since this is assigned when the VMA is still detached, and
cannot be observed.
Therefore perform both reset and initialisation of vma->vm_lock_seq by
simply setting vma->vm_lock_seq to zero.
The reset, performed in __mm_reset_vma_seqcounts(), only needs to
WRITE_ONCE() the value.
However the read of vma->vm_lock_seq in vma_start_read() needs to have
acquire semantics to pair with the smp_wmb() in do_raw_write_seqcount_end()
so a reader reading a reset value also observes VMA modifications made
under the write lock.
Since all VMA write locks were just released and the mmap write lock is
still held, there are no concurrent VMA writers.
Concurrent VMA readers are unaffected. New VMA readers observe either zero,
never a write lock, or the prior seqcount, behaving as before the reset.
Since this only occurs every 2^31 write lock/unlock cycles, the time taken
to update all VMAs is considered to be acceptable.
Also update comments, documentation and VMA userland tests to reflect the
change.
User facing effects are - dangerous races that could cause memory
corruption or NULL pointer derefences (especially on page table traversal)
are avoided.
Link: https://lore.kernel.org/20261016-fix-vma-lock-overflow-v2-1-9eb778b79b58@kernel.org
Fixes: 5e31275cc997 ("mm: add per-VMA lock and helper functions to control it")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: Daehyeon Ko <4ncienth@gmail.com>
Closes: https://lore.kernel.org/all/20261015143735.1630957-1-4ncienth@gmail.com/
Reviewed-by: Jose A. Perez de Azpillaga <azpijr@gmail.com>
Tested-by: Jose A. Perez de Azpillaga <azpijr@gmail.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: David Hildenbrand <david@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Jann Horn <jannh@google.com>
Cc: Pedro Falcato <pfalcato@suse.de>
Cc: <stable@vger.kernel.org> # 7.3.x
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/mm/process_addrs.rst | 14 ++++-
include/linux/mm_types.h | 12 ++--
include/linux/mmap_lock.h | 24 ++++++--
mm/mmap_lock.c | 89 ++++++++++++++++++++++++++----
tools/testing/vma/include/dup.h | 2 +-
tools/testing/vma/shared.c | 8 +--
6 files changed, 120 insertions(+), 29 deletions(-)
diff --git a/Documentation/mm/process_addrs.rst b/Documentation/mm/process_addrs.rst
index a7296f251799c..bfd4dfada663c 100644
--- a/Documentation/mm/process_addrs.rst
+++ b/Documentation/mm/process_addrs.rst
@@ -808,9 +808,17 @@ All this is achieved by the use of per-mm and per-VMA sequence counts, which are
used in order to reduce complexity, especially for operations which write-lock
multiple VMAs at once.
-If the mm sequence count, :c:member:`!mm->mm_lock_seq` is equal to the VMA
-sequence count :c:member:`!vma->vm_lock_seq` then the VMA is write-locked. If
-they differ, then it is not.
+The mm sequence count :c:member:`!mm->mm_lock_seq` is incremented on both mmap
+write lock and unlock, so it is odd while the mmap write lock is held. If it is
+equal to the VMA sequence count :c:member:`!vma->vm_lock_seq`, and that value
+is odd, then the VMA is write-locked. If they differ, then it is not.
+
+A VMA's sequence count is not updated on unlock, so after 2^31 write lock/unlock
+cycles the mm sequence count would wrap and match stale VMA values again. To
+prevent this, when the mm sequence count wraps to zero,
+:c:func:`!vma_end_write_all` invokes :c:func:`!__mm_reset_vma_seqcounts` to
+reset every VMA's sequence count to zero, an even value which can never
+indicate a write lock.
Each time the mmap write lock is released in :c:func:`!mmap_write_unlock` or
:c:func:`!mmap_write_downgrade`, :c:func:`!vma_end_write_all` is invoked which
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index f3e5a2fadbe5b..44e6639818378 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -955,15 +955,19 @@ struct vm_area_struct {
* Can only be written (using WRITE_ONCE()) while holding both:
* - mmap_lock (in write mode)
* - vm_refcnt bit at VM_REFCNT_EXCLUDE_READERS_FLAG is set
+ * The one exception is __mm_reset_vma_seqcounts(), which stores zero
+ * (an even value, which can never indicate a write lock) under the
+ * mmap write lock alone once the mm seqcount has wrapped, so a reader
+ * holding only vm_refcnt may observe the value change from odd to zero.
* Can be read reliably while holding one of:
* - mmap_lock (in read or write mode)
- * - vm_refcnt bit at VM_REFCNT_EXCLUDE_READERS_BIT is set or vm_refcnt > 1
+ * - vm_refcnt bit at VM_REFCNT_EXCLUDE_READERS_BIT is set
* Can be read unreliably (using READ_ONCE()) for pessimistic bailout
* while holding nothing (except RCU to keep the VMA struct allocated).
*
- * This sequence counter is explicitly allowed to overflow; sequence
- * counter reuse can only lead to occasional unnecessary use of the
- * slowpath.
+ * Assigned the (odd) mm seqcount on write lock and not updated on
+ * unlock, so a stale value would alias the mm seqcount again 2^31 write
+ * lock/unlock cycles later. The reset described above prevents this.
*/
unsigned int vm_lock_seq;
#endif
diff --git a/include/linux/mmap_lock.h b/include/linux/mmap_lock.h
index 084fc66d7f904..6b51387bca034 100644
--- a/include/linux/mmap_lock.h
+++ b/include/linux/mmap_lock.h
@@ -156,7 +156,7 @@ static inline void vma_lock_init(struct vm_area_struct *vma, bool reset_refcnt)
#endif
if (reset_refcnt)
refcount_set(&vma->vm_refcnt, 0);
- vma->vm_lock_seq = UINT_MAX;
+ vma->vm_lock_seq = 0;
}
/*
@@ -231,8 +231,9 @@ static inline void vma_refcount_put(struct vm_area_struct *vma)
/*
* Use only while holding mmap read lock which guarantees that vma lock is not
- * contended (nobody can concurrently write-lock the vma). vma_start_read() should
- * not be used in such cases because it might fail due to mm_lock_seq overflow.
+ * contended (nobody can concurrently write-lock the vma). vma_start_read() need
+ * not be used in such cases, as the mmap lock already excludes VMA writers so
+ * its sequence number checks are redundant.
* This functionality is used to obtain vma read lock and drop the mmap read lock.
*
* VMA can't be detached while we are holding mmap lock, therefore in practice this
@@ -254,8 +255,9 @@ static inline bool vma_start_read_locked_nested(struct vm_area_struct *vma, int
/*
* Use only while holding mmap read lock which guarantees that vma lock is not
- * contended (nobody can concurrently write-lock the vma). vma_start_read() should
- * not be used in such cases because it might fail due to mm_lock_seq overflow.
+ * contended (nobody can concurrently write-lock the vma). vma_start_read() need
+ * not be used in such cases, as the mmap lock already excludes VMA writers so
+ * its sequence number checks are redundant.
* This functionality is used to obtain vma read lock and drop the mmap read lock.
*
* VMA can't be detached while we are holding mmap lock, therefore in practice this
@@ -577,6 +579,8 @@ static inline int __must_check mmap_write_lock_killable(struct mm_struct *mm)
return ret;
}
+void __mm_reset_vma_seqcounts(struct mm_struct *mm);
+
/*
* Drop all currently-held per-VMA locks.
* This is called from the mmap_lock implementation directly before releasing
@@ -589,6 +593,16 @@ static inline void vma_end_write_all(struct mm_struct *mm)
{
mmap_assert_write_locked(mm);
mm_lock_seqcount_end(mm);
+
+ /*
+ * VMA seqcounts are not updated on unlock, so once the mm seqcount has
+ * wrapped, any VMA still carrying a sequence number from before the
+ * wrap would satisfy __is_vma_write_locked() when that number comes
+ * round again, and readers would not be excluded. Reset every VMA's
+ * seqcount so that no stale value survives the wrap.
+ */
+ if (unlikely(!mm->mm_lock_seq.sequence))
+ __mm_reset_vma_seqcounts(mm);
}
static inline void mmap_write_unlock(struct mm_struct *mm)
diff --git a/mm/mmap_lock.c b/mm/mmap_lock.c
index f7f1c6ae25910..41967538e1045 100644
--- a/mm/mmap_lock.c
+++ b/mm/mmap_lock.c
@@ -197,21 +197,38 @@ void __vma_exclude_readers_for_detach(struct vm_area_struct *vma)
WARN_ON_ONCE(!ves.detached);
}
+/* Do the VMA, mm seqcounts indicate the VMA is write locked? */
+static bool vma_seqcount_is_write_locked(unsigned int vma_seq, unsigned int mm_seq)
+{
+ /* VMA and mm sequence numbers must match for a write lock. */
+ if (vma_seq != mm_seq)
+ return false;
+
+ /*
+ * The VMA seqcount is always odd if locked. For an attached VMA an even
+ * value can only be the zero stored by __mm_reset_vma_seqcounts(),
+ * never a write lock.
+ */
+ return vma_seq & 1;
+}
+
/*
* Try to read-lock a vma. The function is allowed to occasionally yield false
* locked result to avoid performance overhead, in which case we fall back to
* using mmap_lock. The function should never yield false unlocked result.
- * False locked result is possible if mm_lock_seq overflows or if vma gets
- * reused and attached to a different mm before we lock it.
+ * False locked result is possible if vma gets reused and attached to a
+ * different mm before we lock it.
* Returns the vma on success, NULL on failure to lock and EAGAIN if vma got
* detached.
*
* IMPORTANT: RCU lock must be held upon entering the function, but upon error
* IT IS RELEASED. The caller must handle this correctly.
*/
-static inline struct vm_area_struct *vma_start_read(struct mm_struct *mm,
- struct vm_area_struct *vma)
+static struct vm_area_struct *vma_start_read(struct mm_struct *mm,
+ struct vm_area_struct *vma)
{
+ unsigned int vma_seq;
+ unsigned int mm_seq;
struct mm_struct *other_mm;
int oldcnt;
@@ -223,7 +240,9 @@ static inline struct vm_area_struct *vma_start_read(struct mm_struct *mm,
* we don't rely on for anything - the mm_lock_seq read against which we
* need ordering is below.
*/
- if (READ_ONCE(vma->vm_lock_seq) == READ_ONCE(mm->mm_lock_seq.sequence)) {
+ vma_seq = READ_ONCE(vma->vm_lock_seq);
+ mm_seq = READ_ONCE(mm->mm_lock_seq.sequence);
+ if (vma_seqcount_is_write_locked(vma_seq, mm_seq)) {
vma = NULL;
goto err;
}
@@ -249,17 +268,26 @@ static inline struct vm_area_struct *vma_start_read(struct mm_struct *mm,
goto err_unstable;
/*
- * Overflow of vm_lock_seq/mm_lock_seq might produce false locked result.
- * False unlocked result is impossible because we modify and check
+ * False unlocked result is impossible because a write lock sets
* vma->vm_lock_seq under vma->vm_refcnt protection and mm->mm_lock_seq
* modification invalidates all existing locks.
*
- * We must use ACQUIRE semantics for the mm_lock_seq so that if we are
- * racing with vma_end_write_all(), we only start reading from the VMA
- * after it has been unlocked.
- * This pairs with RELEASE semantics in vma_end_write_all().
+ * ACQUIRE semantics are required for both reads.
+ *
+ * __mm_reset_vma_seqcounts() might reset vma->vm_lock_seq to zero
+ * after an overflow. A reader observing that zero must also observe
+ * the VMA modifications made under the write lock which just ended, so
+ * the ACQUIRE pairs with the smp_wmb() in do_raw_write_seqcount_end()
+ * that precedes the reset stores.
+ *
+ * The ACQUIRE semantics for the mm_lock_seq read is required so that,
+ * if we are racing with vma_end_write_all(), we only start reading from
+ * the VMA after it has been unlocked. This pairs with the RELEASE
+ * semantics in vma_end_write_all().
*/
- if (unlikely(vma->vm_lock_seq == raw_read_seqcount(&mm->mm_lock_seq))) {
+ vma_seq = smp_load_acquire(&vma->vm_lock_seq);
+ mm_seq = raw_read_seqcount(&mm->mm_lock_seq);
+ if (unlikely(vma_seqcount_is_write_locked(vma_seq, mm_seq))) {
vma_refcount_put(vma);
vma = NULL;
goto err;
@@ -468,6 +496,43 @@ struct vm_area_struct *lock_next_vma(struct mm_struct *mm,
}
#endif /* CONFIG_PER_VMA_LOCK */
+/*
+ * Called with mmap write lock held after mm->mm_lock_seq just overflowed (and
+ * therefore zero), with all VMA write locks now released.
+ *
+ * The stores below follow the smp_wmb() in do_raw_write_seqcount_end(), so
+ * a reader that observes a reset value also observes this cycle's VMA
+ * modifications (ordered by the ACQUIRE on vma->vm_lock_seq in
+ * vma_start_read()).
+ */
+void __mm_reset_vma_seqcounts(struct mm_struct *mm)
+{
+ struct vm_area_struct *vma;
+ VMA_ITERATOR(vmi, mm, 0);
+
+ mmap_assert_write_locked(mm);
+ VM_WARN_ON_ONCE(mm->mm_lock_seq.sequence);
+
+ /*
+ * Failing to reset means stale vma->vm_lock_seq values could result in
+ * those VMAs becoming spuriously write locked when mm->mm_lock_seq
+ * happens to match their values.
+ *
+ * This is problematic, as it causes the VMA write lock to not exclude
+ * readers, which can result in concurrent readers while a VMA write
+ * lock is held.
+ *
+ * Avoid this by resetting to an even value (indicates no write lock
+ * held).
+ *
+ * Readers will either observe zero (not write locked) or the previous
+ * value, so this is safe.
+ */
+ for_each_vma(vmi, vma)
+ WRITE_ONCE(vma->vm_lock_seq, 0);
+}
+EXPORT_SYMBOL(__mm_reset_vma_seqcounts);
+
#ifdef CONFIG_LOCK_MM_AND_FIND_VMA
#include <linux/extable.h>
diff --git a/tools/testing/vma/include/dup.h b/tools/testing/vma/include/dup.h
index 4c58487b764e9..b5abd7802d7d1 100644
--- a/tools/testing/vma/include/dup.h
+++ b/tools/testing/vma/include/dup.h
@@ -1229,7 +1229,7 @@ static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm)
vma->vm_mm = mm;
vma->vm_ops = &vma_dummy_vm_ops;
INIT_LIST_HEAD(&vma->anon_vma_chain);
- vma->vm_lock_seq = UINT_MAX;
+ vma->vm_lock_seq = 0;
}
/*
diff --git a/tools/testing/vma/shared.c b/tools/testing/vma/shared.c
index 4a39c9d504896..4ba7786be5f14 100644
--- a/tools/testing/vma/shared.c
+++ b/tools/testing/vma/shared.c
@@ -56,7 +56,7 @@ struct vm_area_struct *alloc_and_link_vma(struct mm_struct *mm,
* begun. Linking to the tree will have caused this to be incremented,
* which means we will get a false positive otherwise.
*/
- vma->vm_lock_seq = UINT_MAX;
+ vma->vm_lock_seq = 0;
return vma;
}
@@ -88,13 +88,13 @@ int cleanup_mm(struct mm_struct *mm, struct vma_iterator *vmi)
bool vma_write_started(struct vm_area_struct *vma)
{
- int seq = vma->vm_lock_seq;
+ unsigned int seq = vma->vm_lock_seq;
/* We reset after each check. */
- vma->vm_lock_seq = UINT_MAX;
+ vma->vm_lock_seq = 0;
/* The vma_start_write() stub simply increments this value. */
- return seq > -1;
+ return seq > 0;
}
void __vma_set_dummy_anon_vma(struct vm_area_struct *vma,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 464/507] mm/shmem: honour F_SEAL_EXEC when an ACL is set
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (462 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 463/507] mm/vma: avoid spurious write locks when mm->mm_lock_seq overflows Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 465/507] nvme-tcp: skip TLS control records while waiting for the ICResp Greg Kroah-Hartman
` (42 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Pedro Falcato,
Kiryl Shutsemau (Meta), Zi Yan, Baolin Wang,
Pratyush Yadav (Google), Gregory Price (Meta),
David Hildenbrand (Arm), Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
[ Upstream commit 0237c47ca17005ea41b510c6116f0257dbf84eab ]
The owner of a memfd sealed with F_SEAL_EXEC can still change its
execute bits by setting a POSIX access ACL. With CONFIG_TMPFS_POSIX_ACL,
this lets an unprivileged owner make a non-executable memfd executable,
bypassing vm.memfd_noexec=2.
simple_set_acl() updates i_mode directly, bypassing the seal check in
shmem_setattr(). Add shmem_set_acl() to check the resulting mode. Share
the F_SEAL_EXEC check with shmem_setattr() using memfd_check_seals_mode()
in include/linux/memfd.h.
Fix generated by an LLM and sent by Chris Mason in private.
Fixes: 6fd7353829ca ("mm/memfd: add F_SEAL_EXEC")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
Acked-by: Pedro Falcato <pfalcato@suse.de>
Acked-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Acked-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Reviewed-by: Pratyush Yadav (Google) <pratyush@kernel.org>
Tested-by: Gregory Price (Meta) <gourry@gourry.net>
[ david: use common helper; simplify description ]
Link: https://patch.msgid.link/20261029-fixes_shmem-v4-4-392fc715d8f6@kernel.org
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
[ sashal: Removed const from shmem_set_acl()'s struct mnt_idmap pointer parameter to match existing ACL interfaces. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/memfd.h | 9 +++++++++
mm/shmem.c | 35 ++++++++++++++++++++++++++++++-----
2 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/include/linux/memfd.h b/include/linux/memfd.h
index c159e40e3f34a..272479317cf10 100644
--- a/include/linux/memfd.h
+++ b/include/linux/memfd.h
@@ -2,10 +2,19 @@
#ifndef __LINUX_MEMFD_H
#define __LINUX_MEMFD_H
+#include <linux/fcntl.h>
#include <linux/file.h>
#define MEMFD_ANON_NAME "[memfd]"
+static inline int memfd_check_seals_mode(unsigned int seals, umode_t old_mode,
+ umode_t new_mode)
+{
+ if ((seals & F_SEAL_EXEC) && ((old_mode ^ new_mode) & 0111))
+ return -EPERM;
+ return 0;
+}
+
#ifdef CONFIG_MEMFD_CREATE
extern long memfd_fcntl(struct file *file, unsigned int cmd, unsigned int arg);
struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx);
diff --git a/mm/shmem.c b/mm/shmem.c
index 825a5a961086d..597bbc2e7321a 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -77,6 +77,7 @@ static struct vfsmount *shm_mnt __ro_after_init;
#include <linux/magic.h>
#include <linux/syscalls.h>
#include <linux/fcntl.h>
+#include <linux/memfd.h>
#include <uapi/linux/memfd.h>
#include <linux/rmap.h>
#include <linux/uuid.h>
@@ -1357,10 +1358,11 @@ static int shmem_setattr(struct mnt_idmap *idmap,
if (error)
return error;
- if ((info->seals & F_SEAL_EXEC) && (attr->ia_valid & ATTR_MODE)) {
- if ((inode->i_mode ^ attr->ia_mode) & 0111) {
- return -EPERM;
- }
+ if (attr->ia_valid & ATTR_MODE) {
+ error = memfd_check_seals_mode(info->seals, inode->i_mode,
+ attr->ia_mode);
+ if (error)
+ return error;
}
if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
@@ -5220,12 +5222,35 @@ static const struct file_operations shmem_file_operations = {
#endif
};
+#ifdef CONFIG_TMPFS_POSIX_ACL
+static int shmem_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
+ struct posix_acl *acl, int type)
+{
+ struct inode *inode = d_inode(dentry);
+ umode_t mode = inode->i_mode;
+ int error;
+
+ if (type == ACL_TYPE_ACCESS) {
+ error = posix_acl_equiv_mode(acl, &mode);
+ if (error < 0)
+ return error;
+ error = memfd_check_seals_mode(SHMEM_I(inode)->seals,
+ inode->i_mode, mode);
+ if (error)
+ return error;
+ }
+ return simple_set_acl(idmap, dentry, acl, type);
+}
+#else
+#define shmem_set_acl simple_set_acl
+#endif
+
static const struct inode_operations shmem_inode_operations = {
.getattr = shmem_getattr,
.setattr = shmem_setattr,
#ifdef CONFIG_TMPFS_XATTR
.listxattr = shmem_listxattr,
- .set_acl = simple_set_acl,
+ .set_acl = shmem_set_acl,
.fileattr_get = shmem_fileattr_get,
.fileattr_set = shmem_fileattr_set,
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 465/507] nvme-tcp: skip TLS control records while waiting for the ICResp
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (463 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 464/507] mm/shmem: honour F_SEAL_EXEC when an ACL is set Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 466/507] wifi: rtw88: usb: route bmc frames via the high queue only for DTIM delivery Greg Kroah-Hartman
` (41 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hannes Reinecke, Christoph Hellwig,
Martin Belanger, Keith Busch, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Belanger <martin.belanger@dell.com>
commit 12c20e2903563acfb949342967adb900310a24d4 upstream.
A peer may send a NewSessionTicket as soon as the handshake completes,
ahead of the ICResp. nvme_tcp_init_connection() fails the connection on
any record that is not application data, so such a target cannot be
reached at all. An OpenSSL-based target does this by default.
RFC 9846 section 4.7.1 requires a client that does not support session
resumption to ignore a NewSessionTicket. Discard such a record and read
again, up to a fixed number of records. Report an alert, and fail the
connection for any other record type.
The record type is now checked before the length. A control record
shorter than the ICResp was reported as -ECONNRESET, which hid the real
cause.
Fixes: 2837966ab2a8 ("nvme-tcp: control message handling for recvmsg()")
Assisted-by: LLM
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin Belanger <martin.belanger@dell.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
[ Martin: resolved a context conflict next to nvme_tcp_cpu_queues ]
Signed-off-by: Martin Belanger <martin.belanger@dell.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/tcp.c | 162 ++++++++++++++++++++++++++++++++++------
1 file changed, 140 insertions(+), 22 deletions(-)
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index ce28c9b038178..2c7e9cfa2253e 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -70,6 +70,12 @@ MODULE_PARM_DESC(tls_handshake_timeout,
"nvme TLS handshake timeout in seconds (default 10)");
#endif
+/* read a TLS control record in chunks of this size */
+#define NVME_TCP_TLS_REC_CHUNK 256
+
+/* TLS records read while waiting for the ICResp, the ICResp included */
+#define NVME_TCP_ICRESP_MAX_RECORDS 8
+
static atomic_t nvme_tcp_cpu_queues[NR_CPUS];
enum nvme_tcp_send_state {
@@ -1561,12 +1567,143 @@ static void nvme_tcp_free_queue(struct nvme_ctrl *nctrl, int qid)
mutex_destroy(&queue->pf_cache_lock);
}
+static int nvme_tcp_recv_tls_alert(struct nvme_tcp_queue *queue,
+ struct msghdr *msg, int len)
+{
+ struct sock *sk = queue->sock->sk;
+ u8 level, description;
+
+ if (len < 2) {
+ dev_err(queue->ctrl->ctrl.device,
+ "queue %d: truncated TLS alert\n",
+ nvme_tcp_queue_id(queue));
+ return -ENOTCONN;
+ }
+
+ /* tls_alert_recv() reads through the iterator */
+ iov_iter_revert(&msg->msg_iter, len);
+ tls_alert_recv(sk, msg, &level, &description);
+
+ if (level == TLS_ALERT_LEVEL_FATAL) {
+ dev_err(queue->ctrl->ctrl.device,
+ "queue %d: fatal TLS alert %u\n",
+ nvme_tcp_queue_id(queue), description);
+ return -ENOTCONN;
+ }
+
+ /* a peer shutting down normally is not worth a warning */
+ if (description == TLS_ALERT_DESC_CLOSE_NOTIFY)
+ dev_dbg(queue->ctrl->ctrl.device,
+ "queue %d: TLS close_notify\n",
+ nvme_tcp_queue_id(queue));
+ else
+ dev_warn(queue->ctrl->ctrl.device,
+ "queue %d: TLS alert %u\n",
+ nvme_tcp_queue_id(queue), description);
+
+ return 0;
+}
+
+/*
+ * Discard a TLS record that arrived in place of the ICResp. A peer may send
+ * a NewSessionTicket as soon as the handshake completes.
+ *
+ * Returns 0 when the record was discarded and the ICResp can be read, or a
+ * negative errno if the connection cannot continue.
+ */
+static int nvme_tcp_skip_tls_record(struct nvme_tcp_queue *queue,
+ struct msghdr *msg, u8 ctype, int len)
+{
+ u8 buf[NVME_TCP_TLS_REC_CHUNK];
+ int ret;
+
+ switch (ctype) {
+ case TLS_RECORD_TYPE_HANDSHAKE:
+ break;
+ case TLS_RECORD_TYPE_ALERT:
+ ret = nvme_tcp_recv_tls_alert(queue, msg, len);
+ return ret ? : -ENOTCONN;
+ default:
+ pr_err("queue %d: unhandled TLS record %u\n",
+ nvme_tcp_queue_id(queue), ctype);
+ return -ENOTCONN;
+ }
+
+ /* the ICResp is in a later record, drain this one first */
+ while (!(msg->msg_flags & MSG_EOR)) {
+ struct kvec iov = {
+ .iov_base = buf,
+ .iov_len = sizeof(buf),
+ };
+ char cbuf[CMSG_LEN(sizeof(char))] = {};
+ /* kTLS fails a control record read without a cmsg buffer */
+ struct msghdr drain = {
+ .msg_control = cbuf,
+ .msg_controllen = sizeof(cbuf),
+ };
+
+ ret = kernel_recvmsg(queue->sock, &drain, &iov, 1, sizeof(buf),
+ 0);
+ if (ret <= 0) {
+ pr_warn("queue %d: failed to drain TLS record: %d\n",
+ nvme_tcp_queue_id(queue), ret);
+ return ret ? : -ECONNRESET;
+ }
+ msg->msg_flags = drain.msg_flags;
+ }
+
+ return 0;
+}
+
+/*
+ * Receive the ICResp. Over TLS, skip the records that a peer may send
+ * ahead of it.
+ *
+ * Returns the length received, or a negative errno.
+ */
+static int nvme_tcp_recv_icresp(struct nvme_tcp_queue *queue,
+ struct nvme_tcp_icresp_pdu *icresp)
+{
+ char cbuf[CMSG_LEN(sizeof(char))];
+ struct msghdr msg;
+ struct kvec iov;
+ u8 ctype;
+ int i, ret;
+
+ for (i = 0; i < NVME_TCP_ICRESP_MAX_RECORDS; i++) {
+ memset(&msg, 0, sizeof(msg));
+ memset(cbuf, 0, sizeof(cbuf));
+ iov.iov_base = icresp;
+ iov.iov_len = sizeof(*icresp);
+ if (nvme_tcp_queue_tls(queue)) {
+ msg.msg_control = cbuf;
+ msg.msg_controllen = sizeof(cbuf);
+ }
+ msg.msg_flags = MSG_WAITALL;
+ ret = kernel_recvmsg(queue->sock, &msg, &iov, 1,
+ iov.iov_len, msg.msg_flags);
+ if (ret <= 0 || !nvme_tcp_queue_tls(queue))
+ return ret;
+
+ ctype = tls_get_record_type(queue->sock->sk,
+ (struct cmsghdr *)cbuf);
+ if (ctype == TLS_RECORD_TYPE_DATA)
+ return ret;
+
+ ret = nvme_tcp_skip_tls_record(queue, &msg, ctype, ret);
+ if (ret < 0)
+ return ret;
+ }
+
+ pr_err("queue %d: too many TLS records before the ICResp\n",
+ nvme_tcp_queue_id(queue));
+ return -EPROTO;
+}
+
static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
{
struct nvme_tcp_icreq_pdu *icreq;
struct nvme_tcp_icresp_pdu *icresp;
- char cbuf[CMSG_LEN(sizeof(char))] = {};
- u8 ctype;
struct msghdr msg = {};
struct kvec iov;
bool ctrl_hdgst, ctrl_ddgst;
@@ -1604,16 +1741,7 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
goto free_icresp;
}
- memset(&msg, 0, sizeof(msg));
- iov.iov_base = icresp;
- iov.iov_len = sizeof(*icresp);
- if (nvme_tcp_queue_tls(queue)) {
- msg.msg_control = cbuf;
- msg.msg_controllen = sizeof(cbuf);
- }
- msg.msg_flags = MSG_WAITALL;
- ret = kernel_recvmsg(queue->sock, &msg, &iov, 1,
- iov.iov_len, msg.msg_flags);
+ ret = nvme_tcp_recv_icresp(queue, icresp);
if (ret >= 0 && ret < sizeof(*icresp))
ret = -ECONNRESET;
if (ret < 0) {
@@ -1621,16 +1749,6 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue)
nvme_tcp_queue_id(queue), ret);
goto free_icresp;
}
- ret = -ENOTCONN;
- if (nvme_tcp_queue_tls(queue)) {
- ctype = tls_get_record_type(queue->sock->sk,
- (struct cmsghdr *)cbuf);
- if (ctype != TLS_RECORD_TYPE_DATA) {
- pr_err("queue %d: unhandled TLS record %d\n",
- nvme_tcp_queue_id(queue), ctype);
- goto free_icresp;
- }
- }
ret = -EINVAL;
if (icresp->hdr.type != nvme_tcp_icresp) {
pr_err("queue %d: bad type returned %d\n",
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 466/507] wifi: rtw88: usb: route bmc frames via the high queue only for DTIM delivery
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (464 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 465/507] nvme-tcp: skip TLS control records while waiting for the ICResp Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 467/507] wifi: rtw88: usb: bound what the driver feeds the after-DTIM queue Greg Kroah-Hartman
` (40 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Mehmet Fide, Ping-Ke Shih,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mehmet Fide <mehmet.fide@screeningeagle.com>
[ Upstream commit c710c7c2e0380d7c0eeb33b686262edcaef7cb07 ]
In AP mode every broadcast and multicast data frame is routed to
TX_DESC_QSEL_HIGH, the after-DTIM queue, whether or not anybody is
asleep. The firmware drains that queue at beacon pace, a dozen or so
frames per second measured on RTL8822BU, while one associated client's
mDNS/SSDP chatter alone exceeds that. The excess accumulates inside
the chip until the shared TX page pool is exhausted (measured: 14 of
1803 pages left). From that point every host-sourced frame queues
behind the backlog: authentication responses reach the air seconds
after the client has given up, so no station can associate anymore,
and the beacon reserved-page download fails the BCN_VALID poll
("error beacon valid") because it needs pages from the same pool. The
AP keeps beaconing, so the failure looks like a silent RX stall and
only a reboot recovers.
mac80211 already decides when after-DTIM delivery is needed: it sets
IEEE80211_TX_CTL_SEND_AFTER_DTIM on bmc frames only while at least one
station is actually dozing. Honor that instead of routing
unconditionally: flagged frames keep going through the high queue with
the MORE_DATA and HGQMD handling introduced by commit 076f786a0ae1
("wifi: rtw88: Fix AP mode incorrect DTIM behavior"), everything else
leaves at line rate through the AC queues. This partially reverts the
usb.c hunk of that commit, whose unconditional routing is what lets
the backlog build up.
On a bench AP (USB2, 20 MHz, WPA2, hostapd, a Windows client driven
through disconnect/reconnect cycles): reconnects fail 0/5 on RTL8822BU
and 0/3 on RTL8821CU before this change, and pass 10/10 and 5/5 with
it, with the page pool staying healthy and no beacon errors logged.
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260814053426.2473247-1-mehmet.fide@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/realtek/rtw88/usb.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
index 64e1c3420e0a8..43b9cdb4a79b0 100644
--- a/drivers/net/wireless/realtek/rtw88/usb.c
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
@@ -560,6 +560,7 @@ static int rtw_usb_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size)
static u8 rtw_usb_tx_queue_mapping_to_qsel(struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
__le16 fc = hdr->frame_control;
u8 qsel;
@@ -567,7 +568,8 @@ static u8 rtw_usb_tx_queue_mapping_to_qsel(struct sk_buff *skb)
qsel = TX_DESC_QSEL_MGMT;
else if (is_broadcast_ether_addr(hdr->addr1) ||
is_multicast_ether_addr(hdr->addr1))
- qsel = TX_DESC_QSEL_HIGH;
+ qsel = (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) ?
+ TX_DESC_QSEL_HIGH : skb->priority;
else if (skb_get_queue_mapping(skb) <= IEEE80211_AC_BK)
qsel = skb->priority;
else
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 467/507] wifi: rtw88: usb: bound what the driver feeds the after-DTIM queue
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (465 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 466/507] wifi: rtw88: usb: route bmc frames via the high queue only for DTIM delivery Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 468/507] wifi: rtw88: usb: only let the frames a dozing station needs use " Greg Kroah-Hartman
` (39 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Mehmet Fide, Ping-Ke Shih,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mehmet Fide <mehmet.fide@screeningeagle.com>
[ Upstream commit 04cc8c59a3d79ef7ec2341f1c7aef1d40a0ce7df ]
Frames routed to the high queue are transmitted right after DTIM beacons
only, inside the ATIM window, while they wait in the shared TX page pool.
The driver puts no limit on how many it hands over, so as long as one
station dozes, any sustained broadcast or multicast traffic outruns the
drain and empties the pool: measured on an RTL8822BU AP with a single
client in power save and ~40 frames/s of mDNS chatter, the free page
count at 0x240 goes from 1803 to 16 in about 100 seconds and stays there
for as long as the traffic lasts. From that point every other transmit
queues behind the backlog, authentication responses arrive too late for
anyone to join, and the reserved page download fails ("error beacon
valid"). The AP keeps beaconing and only a reboot recovers.
Feed the high queue through a small budget that refills below the
measured drain rate (about 3 frames per DTIM, ~15/s at dtim_period 2 on
the default 2 TU ATIM window); whatever exceeds the budget leaves on its
access category queue right away. The high queue backlog is now bounded
by the burst size under any load, so the page pool cannot run dry, at
the price that a dozing station may miss part of a broadcast storm.
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260910081716.769081-2-mehmet.fide@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/realtek/rtw88/usb.c | 41 ++++++++++++++++++++++--
drivers/net/wireless/realtek/rtw88/usb.h | 5 +++
2 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
index 43b9cdb4a79b0..d9c52094a6124 100644
--- a/drivers/net/wireless/realtek/rtw88/usb.c
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
@@ -557,7 +557,37 @@ static int rtw_usb_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size)
return rtw_usb_write_data(rtwdev, &pkt_info, buf);
}
-static u8 rtw_usb_tx_queue_mapping_to_qsel(struct sk_buff *skb)
+#define RTW_USB_HIQ_REFILL_INTERVAL (HZ / 10) /* one unit of budget per 100 ms */
+#define RTW_USB_HIQ_BUDGET_MAX 16
+
+static bool rtw_usb_hiq_take_budget(struct rtw_usb *rtwusb)
+{
+ unsigned long flags, elapsed, add;
+ bool ok;
+
+ spin_lock_irqsave(&rtwusb->hiq_lock, flags);
+
+ elapsed = jiffies - rtwusb->hiq_refill;
+ add = elapsed / RTW_USB_HIQ_REFILL_INTERVAL;
+ if (add) {
+ rtwusb->hiq_budget = min_t(unsigned long, rtwusb->hiq_budget + add,
+ RTW_USB_HIQ_BUDGET_MAX);
+
+ /* keep the unfinished part of the interval for the next unit */
+ rtwusb->hiq_refill = jiffies - elapsed % RTW_USB_HIQ_REFILL_INTERVAL;
+ }
+
+ ok = rtwusb->hiq_budget > 0;
+ if (ok)
+ rtwusb->hiq_budget--;
+
+ spin_unlock_irqrestore(&rtwusb->hiq_lock, flags);
+
+ return ok;
+}
+
+static u8 rtw_usb_tx_queue_mapping_to_qsel(struct rtw_usb *rtwusb,
+ struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -568,7 +598,8 @@ static u8 rtw_usb_tx_queue_mapping_to_qsel(struct sk_buff *skb)
qsel = TX_DESC_QSEL_MGMT;
else if (is_broadcast_ether_addr(hdr->addr1) ||
is_multicast_ether_addr(hdr->addr1))
- qsel = (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) ?
+ qsel = (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) &&
+ rtw_usb_hiq_take_budget(rtwusb) ?
TX_DESC_QSEL_HIGH : skb->priority;
else if (skb_get_queue_mapping(skb) <= IEEE80211_AC_BK)
qsel = skb->priority;
@@ -588,7 +619,7 @@ static int rtw_usb_tx_write(struct rtw_dev *rtwdev,
u8 *pkt_desc;
int ep;
- pkt_info->qsel = rtw_usb_tx_queue_mapping_to_qsel(skb);
+ pkt_info->qsel = rtw_usb_tx_queue_mapping_to_qsel(rtwusb, skb);
pkt_desc = skb_push(skb, chip->tx_pkt_desc_sz);
memset(pkt_desc, 0, chip->tx_pkt_desc_sz);
ep = qsel_to_ep(rtwusb, pkt_info->qsel);
@@ -1029,6 +1060,10 @@ static int rtw_usb_init_tx(struct rtw_dev *rtwdev)
struct rtw_usb *rtwusb = rtw_get_usb_priv(rtwdev);
int i;
+ spin_lock_init(&rtwusb->hiq_lock);
+ rtwusb->hiq_budget = RTW_USB_HIQ_BUDGET_MAX;
+ rtwusb->hiq_refill = jiffies;
+
rtwusb->txwq = create_singlethread_workqueue("rtw88_usb: tx wq");
if (!rtwusb->txwq) {
rtw_err(rtwdev, "failed to create TX work queue\n");
diff --git a/drivers/net/wireless/realtek/rtw88/usb.h b/drivers/net/wireless/realtek/rtw88/usb.h
index 9b695b688b242..94ff21dd08463 100644
--- a/drivers/net/wireless/realtek/rtw88/usb.h
+++ b/drivers/net/wireless/realtek/rtw88/usb.h
@@ -75,6 +75,11 @@ struct rtw_usb {
u8 out_ep[RTW_USB_EP_MAX];
int qsel_to_ep[TX_DESC_QSEL_MAX];
+ /* protects hiq_budget and hiq_refill */
+ spinlock_t hiq_lock;
+ u32 hiq_budget;
+ unsigned long hiq_refill;
+
struct workqueue_struct *txwq, *rxwq;
struct sk_buff_head tx_queue[RTW_USB_EP_MAX];
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 468/507] wifi: rtw88: usb: only let the frames a dozing station needs use the after-DTIM queue
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (466 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 467/507] wifi: rtw88: usb: bound what the driver feeds the after-DTIM queue Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 469/507] wifi: rtw88: widen the ATIM window while an AP interface is up Greg Kroah-Hartman
` (38 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Mehmet Fide, Ping-Ke Shih,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mehmet Fide <mehmet.fide@screeningeagle.com>
[ Upstream commit 185971f1b4eb4ea9059d76cf1a18f992eef998c1 ]
With the budget in place the high queue can no longer take the chip
down, but ordinary chatter still competes with the frames a sleeping
station actually needs. mac80211 marks every broadcast and multicast
frame with IEEE80211_TX_CTL_SEND_AFTER_DTIM while a station dozes,
mDNS and SSDP included, so under normal traffic the budget is spent on
frames nobody waits for.
Do what the vendor driver does with its default "allow special" high
queue filter: admit only ARP, EAPOL and DHCP to the after-DTIM path,
the frames a station coming out of power save has to see; everything
else goes out on its access category queue at line rate. The frames
are classified the way rtw89_core_tx_btc_spec_pkt_notify() does it,
from skb->protocol and the network and transport header offsets that
mac80211 keeps from the netdev path; EAPOL is the control port flag.
Frames the AP relays between its own stations arrive as ETH_P_802_3
and are not inspected, they leave on the access category queue.
With the filter in place the page pool stays at 1803 through the same
180 second storm, a DHCP flood still takes the after-DTIM path (and is
then held by the budget), and join/ping cycling without power save is
unchanged (10/10).
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260910081716.769081-3-mehmet.fide@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/realtek/rtw88/usb.c | 27 ++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
index d9c52094a6124..5c766701e632f 100644
--- a/drivers/net/wireless/realtek/rtw88/usb.c
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
@@ -2,9 +2,11 @@
/* Copyright(c) 2018-2019 Realtek Corporation
*/
+#include <linux/ip.h>
#include <linux/module.h>
-#include <linux/usb.h>
#include <linux/mutex.h>
+#include <linux/udp.h>
+#include <linux/usb.h>
#include "main.h"
#include "debug.h"
#include "mac.h"
@@ -557,6 +559,27 @@ static int rtw_usb_write_data_h2c(struct rtw_dev *rtwdev, u8 *buf, u32 size)
return rtw_usb_write_data(rtwdev, &pkt_info, buf);
}
+static bool rtw_usb_bmc_needs_dtim(struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct udphdr *udphdr;
+
+ if (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO)
+ return true;
+
+ if (skb->protocol == htons(ETH_P_ARP))
+ return true;
+
+ if (skb->protocol == htons(ETH_P_IP) &&
+ ip_hdr(skb)->protocol == IPPROTO_UDP) {
+ udphdr = udp_hdr(skb);
+
+ return udphdr->dest == htons(67) || udphdr->dest == htons(68);
+ }
+
+ return false;
+}
+
#define RTW_USB_HIQ_REFILL_INTERVAL (HZ / 10) /* one unit of budget per 100 ms */
#define RTW_USB_HIQ_BUDGET_MAX 16
@@ -599,7 +622,7 @@ static u8 rtw_usb_tx_queue_mapping_to_qsel(struct rtw_usb *rtwusb,
else if (is_broadcast_ether_addr(hdr->addr1) ||
is_multicast_ether_addr(hdr->addr1))
qsel = (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) &&
- rtw_usb_hiq_take_budget(rtwusb) ?
+ rtw_usb_bmc_needs_dtim(skb) && rtw_usb_hiq_take_budget(rtwusb) ?
TX_DESC_QSEL_HIGH : skb->priority;
else if (skb_get_queue_mapping(skb) <= IEEE80211_AC_BK)
qsel = skb->priority;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 469/507] wifi: rtw88: widen the ATIM window while an AP interface is up
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (467 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 468/507] wifi: rtw88: usb: only let the frames a dozing station needs use " Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 470/507] mm/page_alloc: avoid direct reclaim and compaction for costly __GFP_NORETRY allocations Greg Kroah-Hartman
` (37 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ping-Ke Shih, Mehmet Fide,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mehmet Fide <mehmet.fide@screeningeagle.com>
[ Upstream commit cf8b516f67652f550e040951b88a2040b375afcf ]
The frames held for dozing stations go out right after the DTIM beacon
and only for the duration of the ATIM window. The chips come up with a
2 TU window (the two that program it set 0x2 at init), which drains
about three frames per DTIM; the vendor driver sets 0xa or 0xc in AP
mode instead. With the 2 TU window the measured page pool exhaustion
takes ~100 s of ordinary multicast chatter; at 0x4 the same storm
already drains, so 0xa leaves comfortable headroom.
Program 0xa when an AP interface starts and put the default back when
it stops, since most chips never initialize the register themselves.
The bound and the filter of the previous patches still apply: the
window adds drain capacity, the budget protects the pool when that is
not enough, the filter keeps chatter off the beacon-paced path.
Suggested-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Mehmet Fide <mehmet.fide@screeningeagle.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20260910081716.769081-4-mehmet.fide@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/realtek/rtw88/mac80211.c | 2 ++
drivers/net/wireless/realtek/rtw88/reg.h | 2 ++
2 files changed, 4 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw88/mac80211.c b/drivers/net/wireless/realtek/rtw88/mac80211.c
index 0b622d7663b66..2a9b09fa76e7e 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -474,6 +474,7 @@ static int rtw_ops_start_ap(struct ieee80211_hw *hw,
mutex_lock(&rtwdev->mutex);
rtw_write32_set(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD);
+ rtw_write16(rtwdev, REG_ATIMWND, ATIMWND_AP);
rtwdev->ap_active = true;
rtw_store_op_chan(rtwdev, true);
chip->ops->phy_calibration(rtwdev);
@@ -490,6 +491,7 @@ static void rtw_ops_stop_ap(struct ieee80211_hw *hw,
mutex_lock(&rtwdev->mutex);
rtw_write32_clr(rtwdev, REG_TCR, BIT_TCR_UPDATE_HGQMD);
+ rtw_write16(rtwdev, REG_ATIMWND, ATIMWND_DEFAULT);
rtwdev->ap_active = false;
if (!rtw_core_check_sta_active(rtwdev))
rtw_clear_op_chan(rtwdev);
diff --git a/drivers/net/wireless/realtek/rtw88/reg.h b/drivers/net/wireless/realtek/rtw88/reg.h
index 08e9494977e06..0b9ba6f37680b 100644
--- a/drivers/net/wireless/realtek/rtw88/reg.h
+++ b/drivers/net/wireless/realtek/rtw88/reg.h
@@ -483,6 +483,8 @@
#define REG_DRVERLYINT 0x0558
#define REG_BCNDMATIM 0x0559
#define REG_ATIMWND 0x055A
+#define ATIMWND_DEFAULT 0x2
+#define ATIMWND_AP 0xa
#define REG_USTIME_TSF 0x055C
#define REG_BCN_MAX_ERR 0x055D
#define REG_RXTSF_OFFSET_CCK 0x055E
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 470/507] mm/page_alloc: avoid direct reclaim and compaction for costly __GFP_NORETRY allocations
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (468 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 469/507] wifi: rtw88: widen the ATIM window while an AP interface is up Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 471/507] dmaengine: qcom: bam_dma: Defer IRQ trigger type to device tree Greg Kroah-Hartman
` (36 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Salvatore Dipietro, Andrew Morton,
Vlastimil Babka (SUSE), Zi Yan, Johannes Weiner,
Christoph Hellwig, David Hildenbrand, Michal Hocko,
Matthew Wilcox, Dave Chinner, Ritesh Harjani, Dmitry Ilvokhin,
Hazem Mohamed Abuelfotoh, Ali Saidi, Geoff Blake,
Christian Brauner, dipietro.salvatore, Darrick J. Wong,
Brendan Jackman, rvvandan, Suren Baghdasaryan, Garg, Shivank,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Salvatore Dipietro <dipiets@amazon.it>
[ Upstream commit 0e05a469c29400eb6e35448ce7318581688a1806 ]
Commit 5d8edfb900d5 ("iomap: Copy larger chunks from userspace")
introduced high-order folio allocations in the iomap buffered write path.
When memory is fragmented, each failed costly-order allocation enters
__alloc_pages_slowpath() which runs direct reclaim, direct compaction and
drain_all_pages(), causing a 0.38x throughput drop on PostgreSQL pgbench
(simple-update) with 1024 clients on a 96-vCPU arm64 system.
The root issue is that direct reclaim and direct compaction are too
expensive for hot allocation paths that have fallbacks to smaller
allocations. __filemap_get_folio_mpol() already marks higher-order
allocations with __GFP_NORETRY | __GFP_NOWARN, signalling that the caller
can handle failure. However, the page allocator still enters the full
blocking slowpath for costly orders with __GFP_NORETRY, which is
unnecessarily aggressive when the caller will simply retry at a lower
order.
For costly-order allocations with __GFP_NORETRY, clear
__GFP_DIRECT_RECLAIM at the very start of the slowpath, before
can_direct_reclaim, can_compact and the nofail checks are evaluated. This
makes the entire slowpath treat the request as non-blocking: no direct
reclaim, no direct compaction and no drain_all_pages() IPI across every
CPU. Reclaim and compaction move to the background instead: kswapd is
still woken for reclaim, and it wakes kcompactd for defragmentation. The
system keeps its long-term health while the latency-critical direct
allocation path no longer stalls.
Allocations that also request __GFP_THISNODE are exempted. That flag
pairing identifies the local-node-first THP attempt issued by
alloc_pages_mpol() (mempolicy.c), which relies on direct compaction to
form transparent huge pages.
Clearing __GFP_DIRECT_RECLAIM makes these allocations reach the
!can_direct_reclaim bailout, which since commit 4c0ed883e051
("mm/page_alloc: fix defrag_mode for non-reclaimable allocations") drops
ALLOC_NOFRAGMENT and retries instead of failing when defrag_mode is on.
With vm.defrag_mode=1 a __GFP_NORETRY allocation could therefore succeed
by fragmenting another migratetype's pageblock. That is the wrong trade
for a caller that has already communicated it can handle failure and has a
cheap lower-order fallback, so exclude __GFP_NORETRY from the relaxation.
The exclusion is not restricted to costly orders: any __GFP_NORETRY caller
has said it can cope with failure, so failing is preferable to fragmenting
for all of them.
Test environment:
Hardware: AWS EC2 m8g.24xlarge (96 vCPU, arm64)
12x 1TB IO2 32000 IOPS RAID0 XFS
OS: AL2023
Kernel: v7.3-rc1
Database: PostgreSQL 18.4
Workload: pgbench simple-update, 1024 clients, 96 threads, 1200s
Results (average of 3 runs, TPS):
Config Avg TPS % vs baseline
v7.3-rc1 baseline (vm.defrag_mode=0) 58,602 -
v7.3-rc1 + this patch (vm.defrag_mode=0) 157,246 +168.3%
v7.3-rc1 baseline (vm.defrag_mode=1) 109,012 -
v7.3-rc1 + this patch (vm.defrag_mode=1) 157,778 +44.7%
Link: https://lore.kernel.org/20261001082152.2879289-1-dipiets@amazon.it
Link: https://lore.kernel.org/all/20260403193535.9970-1-dipiets@amazon.it/T/#t [v1]
Link: https://lore.kernel.org/linux-mm/20260420161404.642-1-dipiets@amazon.it/T/#u [v2]
Link: https://lore.kernel.org/all/20260710143437.12379-1-dipiets@amazon.it/T/#u [v3]
Link: https://lore.kernel.org/all/20260904115629.3993331-1-dipiets@amazon.it/T/#u [v4]
Link: https://lore.kernel.org/all/20260911142102.2294202-1-dipiets@amazon.it/T/#u [v5]
Fixes: 5d8edfb900d5 ("iomap: Copy larger chunks from userspace")
Signed-off-by: Salvatore Dipietro <dipiets@amazon.it>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Acked-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Johannes Weiner <hannes@cmpxchg.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Cc: David Hildenbrand <david@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Dave Chinner <dgc@kernel.org>
Cc: Ritesh Harjani <ritesh.list@gmail.com>
Cc: Dmitry Ilvokhin <d@ilvokhin.com>
Cc: Hazem Mohamed Abuelfotoh <abuehaze@amazon.com>
Cc: Ali Saidi <alisaidi@amazon.com>
Cc: Geoff Blake <blakgeof@amazon.com>
Cc: Christian Brauner <brauner@kernel.org>
Cc: <dipietro.salvatore@gmail.com>
Cc: Darrick J. Wong <djwong@kernel.org>
Cc: Brendan Jackman <brendan.jackman@linux.dev>
Cc: <rvvandan@amazon.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: "Garg, Shivank" <shivankg@amd.com>
introduced high-order folio allocations in the iomap buffered write path.
When memory is fragmented, each failed costly-order allocation enters
__alloc_pages_slowpath() which runs direct reclaim, direct compaction and
drain_all_pages(), causing a 0.38x throughput drop on PostgreSQL pgbench
(simple-update) with 1024 clients on a 96-vCPU arm64 system.
The root issue is that direct reclaim and direct compaction are too
expensive for hot allocation paths that have fallbacks to smaller
allocations. __filemap_get_folio_mpol() already marks higher-order
allocations with __GFP_NORETRY | __GFP_NOWARN, signalling that the caller
can handle failure. However, the page allocator still enters the full
blocking slowpath for costly orders with __GFP_NORETRY, which is
unnecessarily aggressive when the caller will simply retry at a lower
order.
For costly-order allocations with __GFP_NORETRY, clear
__GFP_DIRECT_RECLAIM at the very start of the slowpath, before
can_direct_reclaim, can_compact and the nofail checks are evaluated. This
makes the entire slowpath treat the request as non-blocking: no direct
reclaim, no direct compaction and no drain_all_pages() IPI across every
CPU. Reclaim and compaction move to the background instead: kswapd is
still woken for reclaim, and it wakes kcompactd for defragmentation. The
system keeps its long-term health while the latency-critical direct
allocation path no longer stalls.
Allocations that also request __GFP_THISNODE are exempted. That flag
pairing identifies the local-node-first THP attempt issued by
alloc_pages_mpol() (mempolicy.c), which relies on direct compaction to
form transparent huge pages.
Clearing __GFP_DIRECT_RECLAIM makes these allocations reach the
!can_direct_reclaim bailout, which since commit 4c0ed883e051
("mm/page_alloc: fix defrag_mode for non-reclaimable allocations") drops
ALLOC_NOFRAGMENT and retries instead of failing when defrag_mode is on.
With vm.defrag_mode=1 a __GFP_NORETRY allocation could therefore succeed
by fragmenting another migratetype's pageblock. That is the wrong trade
for a caller that has already communicated it can handle failure and has a
cheap lower-order fallback, so exclude __GFP_NORETRY from the relaxation.
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/page_alloc.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index ddffc7c8430e8..8714425ffe84e 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -4791,10 +4791,10 @@ static inline struct page *
__alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
struct alloc_context *ac)
{
- bool can_direct_reclaim = gfp_mask & __GFP_DIRECT_RECLAIM;
- bool can_compact = can_direct_reclaim && gfp_compaction_allowed(gfp_mask);
- bool nofail = gfp_mask & __GFP_NOFAIL;
const bool costly_order = order > PAGE_ALLOC_COSTLY_ORDER;
+ bool can_direct_reclaim;
+ bool can_compact;
+ bool nofail;
struct page *page = NULL;
unsigned int alloc_flags;
unsigned long did_some_progress;
@@ -4809,6 +4809,18 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
bool can_retry_reserves = true;
unsigned long alloc_start_time = jiffies;
+ /*
+ * Costly __GFP_NORETRY callers have a cheap fallback, so don't stall
+ * them in reclaim or compaction. __GFP_THISNODE callers are exempt.
+ */
+ if (costly_order && (gfp_mask & __GFP_NORETRY) &&
+ !(gfp_mask & __GFP_THISNODE))
+ gfp_mask &= ~__GFP_DIRECT_RECLAIM;
+
+ can_direct_reclaim = gfp_mask & __GFP_DIRECT_RECLAIM;
+ can_compact = can_direct_reclaim && gfp_compaction_allowed(gfp_mask);
+ nofail = gfp_mask & __GFP_NOFAIL;
+
if (unlikely(nofail)) {
/*
* Also we don't support __GFP_NOFAIL without __GFP_DIRECT_RECLAIM,
@@ -4925,8 +4937,11 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
* Reclaim/compaction cannot run, so defrag_mode's strategy
* of enforcing ALLOC_NOFRAGMENT cannot be fulfilled. Allow
* fallbacks rather than failing the allocation outright.
+ * Not for __GFP_NORETRY: those have a cheap lower order
+ * fallback, so failing beats fragmenting.
*/
if (defrag_mode && (alloc_flags & ALLOC_NOFRAGMENT) &&
+ !(gfp_mask & __GFP_NORETRY) &&
(gfp_mask & __GFP_KSWAPD_RECLAIM)) {
alloc_flags &= ~ALLOC_NOFRAGMENT;
goto retry;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 471/507] dmaengine: qcom: bam_dma: Defer IRQ trigger type to device tree
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (469 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 470/507] mm/page_alloc: avoid direct reclaim and compaction for costly __GFP_NORETRY allocations Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 472/507] dmaengine: qcom: bam_dma: free interrupt before the clock in error path Greg Kroah-Hartman
` (35 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Deepak Kumar Singh, Vishnu Santhosh,
Frank Li, Vinod Koul, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
[ Upstream commit 3cee6f79553202d7d3954555560ac38d719344b8 ]
The driver hardcodes IRQF_TRIGGER_HIGH when registering the BAM
interrupt, which overrides the trigger type specified in the device
tree. On Qualcomm Shikra SoC, the A2 BAM signals an edge interrupt
to the apps processor; registering it as level-high causes the
interrupt to not fire, resulting in missed DMA completions.
Use IRQF_TRIGGER_NONE instead, which causes the kernel to use the
trigger type already configured by platform_get_irq() when it parsed
the device tree interrupts property. This makes the driver
platform-agnostic.
Fixes: e7c0fe2a5c84 ("dmaengine: add Qualcomm BAM dma driver")
Co-developed-by: Deepak Kumar Singh <deepak.singh@oss.qualcomm.com>
Signed-off-by: Deepak Kumar Singh <deepak.singh@oss.qualcomm.com>
Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260717-qcom-bam-dma-irq-trigger-v1-1-6405eac86f00@oss.qualcomm.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Stable-dep-of: 82eed160cfa7 ("dmaengine: qcom: bam_dma: free interrupt before the clock in error path")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma/qcom/bam_dma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index 05a3b1f9e0c23..94cb957d4b187 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -1333,7 +1333,7 @@ static int bam_dma_probe(struct platform_device *pdev)
bam_channel_init(bdev, &bdev->channels[i], i);
ret = devm_request_irq(bdev->dev, bdev->irq, bam_dma_irq,
- IRQF_TRIGGER_HIGH, "bam_dma", bdev);
+ IRQF_TRIGGER_NONE, "bam_dma", bdev);
if (ret)
goto err_bam_channel_exit;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 472/507] dmaengine: qcom: bam_dma: free interrupt before the clock in error path
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (470 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 471/507] dmaengine: qcom: bam_dma: Defer IRQ trigger type to device tree Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 473/507] KVM: arm64: Use kvm_s2_fault_vma_info in pkvm_mem_abort() Greg Kroah-Hartman
` (34 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Manivannan Sadhasivam,
Bartosz Golaszewski, Vinod Koul, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
[ Upstream commit 82eed160cfa7a296ae4eb5acb8dd8f493323eea7 ]
The BAM interrupt is requested with a devres helper and so on error it's
freed after probe() returns. We disable the clock before freeing or
masking it so it may still fire and we may end up reading BAM registers
with clock disabled.
Stop using devres for interrupts as we free it in remove() manually
anyway. Add an appropriate label and free the interrupt before disabling
the clock in error path and in remove().
Cc: stable@vger.kernel.org
Fixes: e7c0fe2a5c84 ("dmaengine: add Qualcomm BAM dma driver")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260427-qcom-qce-cmd-descr-v16-0-945fd1cafbbc%40oss.qualcomm.com?part=2
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Link: https://patch.msgid.link/20261008-bam-dma-free-irq-v28-1-5e5b10de441e@oss.qualcomm.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dma/qcom/bam_dma.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index 94cb957d4b187..f67a93a37d48c 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -1332,8 +1332,8 @@ static int bam_dma_probe(struct platform_device *pdev)
for (i = 0; i < bdev->num_channels; i++)
bam_channel_init(bdev, &bdev->channels[i], i);
- ret = devm_request_irq(bdev->dev, bdev->irq, bam_dma_irq,
- IRQF_TRIGGER_NONE, "bam_dma", bdev);
+ ret = request_irq(bdev->irq, bam_dma_irq, IRQF_TRIGGER_NONE,
+ "bam_dma", bdev);
if (ret)
goto err_bam_channel_exit;
@@ -1366,7 +1366,7 @@ static int bam_dma_probe(struct platform_device *pdev)
ret = dma_async_device_register(&bdev->common);
if (ret) {
dev_err(bdev->dev, "failed to register dma async device\n");
- goto err_bam_channel_exit;
+ goto err_free_irq;
}
ret = of_dma_controller_register(pdev->dev.of_node, bam_dma_xlate,
@@ -1385,6 +1385,8 @@ static int bam_dma_probe(struct platform_device *pdev)
err_unregister_dma:
dma_async_device_unregister(&bdev->common);
+err_free_irq:
+ free_irq(bdev->irq, bdev);
err_bam_channel_exit:
for (i = 0; i < bdev->num_channels; i++)
tasklet_kill(&bdev->channels[i].vc.task);
@@ -1410,7 +1412,7 @@ static void bam_dma_remove(struct platform_device *pdev)
/* mask all interrupts for this execution environment */
writel_relaxed(0, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE));
- devm_free_irq(bdev->dev, bdev->irq, bdev);
+ free_irq(bdev->irq, bdev);
for (i = 0; i < bdev->num_channels; i++) {
bam_dma_terminate_all(&bdev->channels[i].vc.chan);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 473/507] KVM: arm64: Use kvm_s2_fault_vma_info in pkvm_mem_abort()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (471 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 472/507] dmaengine: qcom: bam_dma: free interrupt before the clock in error path Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 474/507] f2fs: zone: fix to avoid bio split on sequential zone Greg Kroah-Hartman
` (33 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Donnefort, Fuad Tabba,
Marc Zyngier, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Donnefort <vdonnefort@google.com>
[ Upstream commit 0cdcc1039200b3c4fbc2ae3f9b5c1be1bc9155e8 ]
To paraphrase Marc in commit 08f97454b7fa ("KVM: arm64: Fix protected
mode handling of pages larger than 4kB"), pkvm_pgtable_stage2_map()
assumes the address passed as a parameter is aligned to the size of the
intended mapping, while HPFAR_EL2 gives the IPA minus the bottom 12
bits, regardless of the system page size configuration.
To fix this alignment, bring support for kvm_s2_fault_vma_info in
pkvm_mem_abort() and use its members where possible. They do contain the
page-alignment we need to fix the fault on system with pages larger than
4K.
Also, add a check at the start of pkvm_pgtable_stage2_map(), it does not
support !PAGE_ALIGNED arguments.
Fixes: ea03466e806f ("KVM: arm64: Handle aborts from protected VMs")
Cc: stable@vger.kernel.org
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
Link: https://patch.msgid.link/20260928095454.3255918-5-vdonnefort@google.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/mmu.c | 27 ++++++++++++++++++---------
arch/arm64/kvm/pkvm.c | 3 +++
2 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 9ebc17d3e0c00..cae133805c76b 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1383,9 +1383,11 @@ static bool fault_supports_stage2_huge_mapping(const struct kvm_s2_fault_desc *s
if (map_size == PAGE_SIZE)
return true;
- /* pKVM only supports PMD_SIZE huge-mappings */
- if (is_protected_kvm_enabled() && map_size != PMD_SIZE)
- return false;
+ /* pKVM only supports PMD_SIZE huge-mappings for non-protected VMs */
+ if (is_protected_kvm_enabled()) {
+ if (vcpu_is_protected(s2fd->vcpu) || map_size != PMD_SIZE)
+ return false;
+ }
size = memslot->npages * PAGE_SIZE;
@@ -1609,6 +1611,9 @@ struct kvm_s2_fault_vma_info {
bool map_non_cacheable;
};
+static int kvm_s2_fault_get_vma_info(const struct kvm_s2_fault_desc *s2fd,
+ struct kvm_s2_fault_vma_info *s2vi);
+
static gfn_t get_canonical_gfn(const struct kvm_s2_fault_desc *s2fd,
const struct kvm_s2_fault_vma_info *s2vi);
@@ -1698,12 +1703,12 @@ static int gmem_abort(const struct kvm_s2_fault_desc *s2fd)
static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
{
unsigned int flags = FOLL_HWPOISON | FOLL_LONGTERM | FOLL_WRITE;
+ struct kvm_s2_fault_vma_info s2vi = {};
struct kvm_vcpu *vcpu = s2fd->vcpu;
struct kvm_pgtable *pgt = vcpu->arch.hw_mmu->pgt;
struct mm_struct *mm = current->mm;
struct kvm *kvm = vcpu->kvm;
void *hyp_memcache;
- struct page *page;
int ret;
hyp_memcache = get_mmu_memcache(vcpu);
@@ -1711,12 +1716,16 @@ static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
if (ret)
return -ENOMEM;
+ ret = kvm_s2_fault_get_vma_info(s2fd, &s2vi);
+ if (ret)
+ return ret;
+
ret = account_locked_vm(mm, 1, true);
if (ret)
return ret;
mmap_read_lock(mm);
- ret = pin_user_pages(s2fd->hva, 1, flags, &page);
+ ret = pin_user_pages(s2fd->hva, 1, flags, &s2vi.page);
mmap_read_unlock(mm);
if (ret == -EHWPOISON) {
@@ -1726,7 +1735,7 @@ static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
} else if (ret != 1) {
ret = -EFAULT;
goto dec_account;
- } else if (!folio_test_swapbacked(page_folio(page))) {
+ } else if (!folio_test_swapbacked(page_folio(s2vi.page))) {
/*
* We really can't deal with page-cache pages returned by GUP
* because (a) we may trigger writeback of a page for which we
@@ -1746,8 +1755,8 @@ static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
}
write_lock(&kvm->mmu_lock);
- ret = pkvm_pgtable_stage2_map(pgt, s2fd->fault_ipa, PAGE_SIZE,
- page_to_phys(page), KVM_PGTABLE_PROT_RWX,
+ ret = pkvm_pgtable_stage2_map(pgt, gfn_to_gpa(s2vi.gfn), PAGE_SIZE,
+ page_to_phys(s2vi.page), KVM_PGTABLE_PROT_RWX,
hyp_memcache, 0);
write_unlock(&kvm->mmu_lock);
if (ret) {
@@ -1758,7 +1767,7 @@ static int pkvm_mem_abort(const struct kvm_s2_fault_desc *s2fd)
return 0;
unpin:
- unpin_user_pages(&page, 1);
+ unpin_user_page(s2vi.page);
dec_account:
account_locked_vm(mm, 1, false);
return ret;
diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
index 8e4c6e4bec123..c298a5b9b12a6 100644
--- a/arch/arm64/kvm/pkvm.c
+++ b/arch/arm64/kvm/pkvm.c
@@ -414,6 +414,9 @@ int pkvm_pgtable_stage2_map(struct kvm_pgtable *pgt, u64 addr, u64 size,
u64 end = addr + size;
int ret;
+ if (WARN_ON_ONCE(!PAGE_ALIGNED(addr | size)))
+ return -EINVAL;
+
lockdep_assert_held_write(&kvm->mmu_lock);
mapping = pkvm_mapping_iter_first(&pgt->pkvm_mappings, addr, end - 1);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 474/507] f2fs: zone: fix to avoid bio split on sequential zone
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (472 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 473/507] KVM: arm64: Use kvm_s2_fault_vma_info in pkvm_mem_abort() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 475/507] f2fs: return -EIO for a lost inode block after cp_error Greg Kroah-Hartman
` (32 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chao Yu, Jaegeuk Kim, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit b9b036bd1e2cfbc189d5811d62d8711e216c40b3 ]
In the block layer, bio_split_to_limits() splits a bio if it exceeds
any underlying queue limits:
1. queue_max_sectors: Splits bios larger than the transfer limit. This
limit is set by the device driver/DMA controller (max_hw_sectors) and
device-mapper targets. When flushing dirty pages (governed by VFS
writeback_chunk_size() and f2fs nr_pages_to_skip()), f2fs merges
contiguous pages into bios up to 512KB (1024 sectors) or more without
checking queue_max_sectors, which will be split if the device or DM
target enforces a smaller limit.
2. queue_max_segments: Splits bios exceeding scatter-gather segment
limits. f2fs allocates bios with up to 256 pages, exceeding the
128-segment limit of DM targets (dm-default-key/dm-crypt) if pages
are discontiguous.
3. chunk_sectors: Splits bios crossing chunk/zone boundaries. In f2fs,
section_size strictly matches zone_size, and block allocation never
spans across section boundaries, so bios never cross chunk_sectors.
Crucially, when bio_split_to_limits() splits a bio, bio_submit_split()
submits the tail half via submit_bio_noacct() before returning the head
half to the caller. On a sequential zoned device, this causes the tail
bio to arrive at the zone write plug before the head:
dm-3: zone 7: prepare_bio wp mismatch: bio sector 30720 offset 2048
!= wp_offset 248, len 248
The write plug rejects the out-of-order tail with BLK_STS_IOERR, causing
f2fs_stop_checkpoint() and remounting the filesystem read-only:
2026-09-30T22:09:23.725678+08:00 localhost kernel: CPU: 9 UID: 0 PID: 243 Comm: kworker/9:1H Not tainted 6.12.81-gb3ef518fb26d #5
2026-09-30T22:09:23.725750+08:00 localhost kernel: Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
2026-09-30T22:09:23.725753+08:00 localhost kernel: Workqueue: dm-3_zwplugs blk_zone_wplug_bio_work
2026-09-30T22:09:23.725756+08:00 localhost kernel: Call Trace:
2026-09-30T22:09:23.725758+08:00 localhost kernel: <TASK>
2026-09-30T22:09:23.725758+08:00 localhost kernel: dump_stack_lvl+0x4d/0x70
2026-09-30T22:09:23.725759+08:00 localhost kernel: f2fs_stop_checkpoint+0x1df/0x5d0
2026-09-30T22:09:23.725759+08:00 localhost kernel: ? blk_zone_wplug_bio_work+0x4eb/0x740
2026-09-30T22:09:23.725760+08:00 localhost kernel: f2fs_cache_write_end_io+0x545/0x6e0
2026-09-30T22:09:23.725761+08:00 localhost kernel: blk_zone_wplug_bio_work+0x4eb/0x740
2026-09-30T22:09:23.725762+08:00 localhost kernel: process_one_work+0x5c6/0xde0
2026-09-30T22:09:23.725764+08:00 localhost kernel: ? assign_work+0x124/0x4e0
2026-09-30T22:09:23.725765+08:00 localhost kernel: worker_thread+0x403/0xb70
2026-09-30T22:09:23.725765+08:00 localhost kernel: ? __kthread_parkme+0x82/0x140
2026-09-30T22:09:23.725766+08:00 localhost kernel: ? __pfx_worker_thread+0x10/0x10
2026-09-30T22:09:23.725766+08:00 localhost kernel: kthread+0x235/0x2e0
2026-09-30T22:09:23.725767+08:00 localhost kernel: ? recalc_sigpending+0x128/0x1d0
2026-09-30T22:09:23.725767+08:00 localhost kernel: ? __pfx_kthread+0x10/0x10
2026-09-30T22:09:23.725769+08:00 localhost kernel: ret_from_fork+0x2f/0x70
2026-09-30T22:09:23.725769+08:00 localhost kernel: ? __pfx_kthread+0x10/0x10
2026-09-30T22:09:23.725770+08:00 localhost kernel: ret_from_fork_asm+0x1a/0x30
2026-09-30T22:09:23.725771+08:00 localhost kernel: </TASK>
2026-09-30T22:09:23.725771+08:00 localhost kernel: F2FS-fs (dm-0): Stopped filesystem due to reason: 3
To prevent write bios destined for sequential zones from being split:
1. In __bio_alloc(), bound npages to bdev_max_segments(bdev) for writes to
sequential zone areas.
2. In page_is_mergeable(), check queue_max_segments() and queue_max_sectors()
for sequential zone areas, so f2fs will not merge beyond the queue limits.
Fixes: 52763a4b7a21 ("f2fs: detect host-managed SMR by feature flag")
Fixes: 664ba972df9b ("f2fs: use BIO_MAX_PAGES for bio allocation")
Cc: stable@vger.kernel.org
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ sashal: Changed F2FS_BLKSIZE(sbi) to F2FS_BLKSIZE to match the existing constant definition. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/data.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index c161d8061e693..cc601b65163be 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -501,6 +501,10 @@ static struct bio *__bio_alloc(struct f2fs_io_info *fio, int npages)
struct bio *bio;
bdev = f2fs_target_device(sbi, fio->new_blkaddr, §or);
+ /* avoid reversed IO if bio is split due to exceeding max_segments */
+ if (npages > 1 && !is_read_io(fio->op) &&
+ f2fs_is_sequential_zone_area(sbi, fio->new_blkaddr))
+ npages = min_t(int, npages, bdev_max_segments(bdev));
bio = bio_alloc_bioset(bdev, npages,
fio->op | fio->op_flags | f2fs_io_flags(fio),
GFP_NOIO, &f2fs_bioset);
@@ -791,7 +795,19 @@ static bool page_is_mergeable(struct f2fs_sb_info *sbi, struct bio *bio,
return false;
if (last_blkaddr + 1 != cur_blkaddr)
return false;
- return bio->bi_bdev == f2fs_target_device(sbi, cur_blkaddr, NULL);
+ if (bio->bi_bdev != f2fs_target_device(sbi, cur_blkaddr, NULL))
+ return false;
+ /* avoid reversed IO if bio is split due to exceeding max_segments/sectors */
+ if (f2fs_is_sequential_zone_area(sbi, cur_blkaddr)) {
+ struct request_queue *q = bdev_get_queue(bio->bi_bdev);
+
+ if (bio->bi_vcnt >= queue_max_segments(q))
+ return false;
+ if (bio_sectors(bio) + (F2FS_BLKSIZE >> SECTOR_SHIFT) >
+ queue_max_sectors(q))
+ return false;
+ }
+ return true;
}
static bool io_type_is_mergeable(struct f2fs_bio_info *io,
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 475/507] f2fs: return -EIO for a lost inode block after cp_error
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (473 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 474/507] f2fs: zone: fix to avoid bio split on sequential zone Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 476/507] f2fs: bound the SIT/NAT bitmaps by the checkpoint pack Greg Kroah-Hartman
` (31 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Daeho Jeong, Chao Yu,
Jaegeuk Kim, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daeho Jeong <daehojeong@google.com>
[ Upstream commit 53b12b63304b34a3850a901c4de3cc6ad08e0aee ]
After cp_error, dirty node caches are dropped without being written.
If such an inode was never written, its NAT entry is still NEW_ADDR,
and reading its inode block returns -ENOENT.
f2fs_get_dnode_of_data() passes that -ENOENT up, and callers take it
as a hole. Since the inode block is missing, the next offset can only
advance one block, so fiemap walks block by block up to maxbytes,
about 2^30 blocks, while holding the inode lock. It took hours in a
power-off recovery test after shutdown and blocked unlink and umount
on the file.
Return -EIO instead of -ENOENT when the inode block itself is missing
after cp_error or shutdown. A missing direct or indirect node is still
reported as -ENOENT.
Cc: stable@kernel.org
Fixes: 28607bf3aa6f ("f2fs: drop dirty node pages when cp is in error status")
Signed-off-by: Daeho Jeong <daehojeong@google.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ sashal: Adapted node-cache access to the existing folio interface. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/node.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index b23fe1383009a..70593f95abfb5 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -835,8 +835,20 @@ int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode)
if (!dn->inode_folio) {
nfolio[0] = f2fs_get_inode_folio(sbi, nids[0]);
- if (IS_ERR(nfolio[0]))
- return PTR_ERR(nfolio[0]);
+ if (IS_ERR(nfolio[0])) {
+ err = PTR_ERR(nfolio[0]);
+ /*
+ * cp_error drops dirty node caches, so the inode block
+ * of an inode that was never written reads as NEW_ADDR
+ * and returns -ENOENT. It is not a hole; the inode is
+ * gone. Callers treat -ENOENT as a hole and keep
+ * looking block by block (e.g. fiemap up to maxbytes).
+ */
+ if (err == -ENOENT && (f2fs_cp_error(sbi) ||
+ is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN)))
+ err = -EIO;
+ return err;
+ }
} else {
nfolio[0] = dn->inode_folio;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 476/507] f2fs: bound the SIT/NAT bitmaps by the checkpoint pack
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (474 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 7.3 475/507] f2fs: return -EIO for a lost inode block after cp_error Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 477/507] perf evsel: Restrict incremental open error unwind Greg Kroah-Hartman
` (30 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Kaixuan Li, Chao Yu,
Jaegeuk Kim, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kaixuan Li <kaixuanli0131@gmail.com>
[ Upstream commit 080833a32fd5dc10b3acf2fa9af9b3213e6cb617 ]
sit_ver_bitmap_bytesize and nat_ver_bitmap_bytesize are used as memcpy
lengths into and out of sbi->ckpt, which is sized from cp_payload alone,
and nothing compares either length against that allocation.
sanity_check_ckpt() has checked these two fields since c77ec61ca0a4, which
added them after a crafted image overran build_sit_info(). That check ties
each length to a segment count; it never compares either against the
allocation, which is the half this adds.
Mounting over-reads in build_sit_info() and build_node_manager(), and the
first checkpoint writes the same lengths back through the same pointers,
so the over-read's contents reach the on-disk checkpoint. An unmount is
enough; the filesystem does not have to be used.
Bound both ends the way __bitmap_ptr() lays them out. The three branches
differ, so a single sum of the two lengths would still admit a small
overflow when cp_payload is non-zero.
Fixes: 39a53e0ce0df ("f2fs: add superblock and major in-memory structure")
Cc: stable@kernel.org
Signed-off-by: Kaixuan Li <kaixuanli0131@gmail.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ sashal: Replaced F2FS_BLKSIZE(sbi) calls with the F2FS_BLKSIZE constant. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/super.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index b9adad85e18c3..b18ea09bcbe2c 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4255,6 +4255,7 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
block_t avail_node_count, valid_node_count;
unsigned int nat_blocks, nat_bits_bytes, nat_bits_blocks;
unsigned int sit_blk_cnt;
+ unsigned long long ckpt_size, sit_end, nat_end;
int i, j;
total = le32_to_cpu(raw_super->segment_count);
@@ -4386,6 +4387,29 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
return 1;
}
+ /*
+ * Nothing above ties the bitmap lengths to sbi->ckpt, which is
+ * (1 + cp_payload) blocks. Bound both ends the way __bitmap_ptr()
+ * lays them out.
+ */
+ ckpt_size = (unsigned long long)(cp_payload + 1) * F2FS_BLKSIZE;
+ if (__is_set_ckpt_flags(ckpt, CP_LARGE_NAT_BITMAP_FLAG)) {
+ nat_end = CP_MIN_CHKSUM_OFFSET + sizeof(__le32) + nat_bitmap_size;
+ sit_end = nat_end + sit_bitmap_size;
+ } else if (cp_payload > 0) {
+ nat_end = CP_MIN_CHKSUM_OFFSET + nat_bitmap_size;
+ sit_end = F2FS_BLKSIZE + sit_bitmap_size;
+ } else {
+ sit_end = CP_MIN_CHKSUM_OFFSET + sit_bitmap_size;
+ nat_end = sit_end + nat_bitmap_size;
+ }
+
+ if (sit_end > ckpt_size || nat_end > ckpt_size) {
+ f2fs_err(sbi, "Bitmaps do not fit the checkpoint pack: sit ends at %llu, nat at %llu, pack is %llu bytes",
+ sit_end, nat_end, ckpt_size);
+ return 1;
+ }
+
if (__is_set_ckpt_flags(ckpt, CP_LARGE_NAT_BITMAP_FLAG) &&
le32_to_cpu(ckpt->checksum_offset) != CP_MIN_CHKSUM_OFFSET) {
f2fs_warn(sbi, "using deprecated layout of large_nat_bitmap, "
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 477/507] perf evsel: Restrict incremental open error unwind
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (475 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 476/507] f2fs: bound the SIT/NAT bitmaps by the checkpoint pack Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 478/507] perf evsel: Close the fds opened so far when disabling missing features Greg Kroah-Hartman
` (29 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ian Rogers, Hui Su, Namhyung Kim,
Arnaldo Carvalho de Melo, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Su <sh_def@163.com>
[ Upstream commit d023b2110d0d7232ba952a486c497ba8817f6f66 ]
evsel__open_cpu(), evsel__tool_pmu_open() and
evsel__hwmon_pmu_open() support opening a subrange of a CPU map, bounded
by [start_cpu_map_idx, end_cpu_map_idx).
Their error paths, however, unwind using "while (--idx >= 0)" all the way
back to CPU index 0 regardless of start_cpu_map_idx. If lower CPU indices
were opened by an earlier invocation, a later incremental open failure
therefore closes those existing file descriptors and overwrites their
slots with -1.
Before this fix, running the new incremental open test demonstrates this
corruption:
$ perf test -v "Tool PMU"
12: Tool PMU:
12.1: Tool PMU : Ok
12.2: Tool PMU leader : Ok
12.3: Incremental open error unwind boundary:
FAILED: CPU 0 FD overwritten: FD(evsel, 0, 0)=-1, expected 4
FAILED!
Stop the unwind at start_cpu_map_idx so that only file descriptors
opened by the current invocation are rolled back.
After this fix:
$ perf test -v "Tool PMU"
12: Tool PMU:
12.1: Tool PMU : Ok
12.2: Tool PMU leader : Ok
12.3: Incremental open error unwind boundary : Ok
Fixes: 4804e0111662d7d8 ("perf stat: Use affinity for opening events")
Fixes: 240505b2d0adcdc8 ("perf tool_pmu: Factor tool events into their own PMU")
Fixes: 53cc0b351ec99278 ("perf hwmon_pmu: Add a tool PMU exposing events from hwmon in sysfs")
Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: Hui Su <sh_def@163.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Stable-dep-of: 16d1234793d4 ("perf evsel: Close the fds opened so far when disabling missing features")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/perf/tests/tool_pmu.c | 79 +++++++++++++++++++++++++++++++++++++
tools/perf/util/evsel.c | 2 +-
tools/perf/util/hwmon_pmu.c | 2 +-
tools/perf/util/tool_pmu.c | 2 +-
4 files changed, 82 insertions(+), 3 deletions(-)
diff --git a/tools/perf/tests/tool_pmu.c b/tools/perf/tests/tool_pmu.c
index c6c5ebf0e935f..667160f9e2cde 100644
--- a/tools/perf/tests/tool_pmu.c
+++ b/tools/perf/tests/tool_pmu.c
@@ -1,8 +1,16 @@
// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <internal/xyarray.h>
+#include "cpumap.h"
#include "debug.h"
#include "evlist.h"
+#include "evsel.h"
#include "parse-events.h"
#include "tests.h"
+#include "thread_map.h"
#include "tool_pmu.h"
static int do_test(enum tool_pmu_event ev, bool with_pmu)
@@ -100,9 +108,80 @@ static int test__tool_pmu_with_pmu(struct test_suite *test __maybe_unused,
return TEST_OK;
}
+static int test__tool_pmu_incremental_open_unwind(struct test_suite *test __maybe_unused,
+ int subtest __maybe_unused)
+{
+ struct evlist *evlist = evlist__new();
+ struct parse_events_error err;
+ struct perf_cpu_map *cpus = NULL;
+ struct perf_thread_map *threads = NULL;
+ struct evsel *evsel;
+ int ret = TEST_FAIL, fd0 = -1;
+
+ if (!evlist)
+ return TEST_FAIL;
+
+ parse_events_error__init(&err);
+ if (parse_events(evlist, "tool/user_time/", &err)) {
+ parse_events_error__exit(&err);
+ evlist__put(evlist);
+ return TEST_FAIL;
+ }
+ parse_events_error__exit(&err);
+
+ evsel = evlist__first(evlist);
+ cpus = perf_cpu_map__new("0,1");
+ threads = thread_map__new_by_tid(getpid());
+ if (!cpus || !threads)
+ goto out;
+
+ /* Step 1: Open CPU index 0 successfully */
+ if (evsel__open_per_cpu_and_thread(evsel, cpus, 0, threads) < 0) {
+ pr_debug("Failed to open CPU index 0\n");
+ goto out;
+ }
+
+ fd0 = (*(int *)xyarray__entry(evsel->core.fd, 0, 0));
+ if (fd0 < 0 || fcntl(fd0, F_GETFD) < 0) {
+ pr_debug("CPU index 0 FD is invalid (%d)\n", fd0);
+ goto out;
+ }
+
+ /* Step 2: Intentionally trigger failure on CPU index 1 */
+ evsel->core.attr.sample_period = 1; /* Not supported for tool PMU -> -EINVAL */
+ if (evsel__open_per_cpu_and_thread(evsel, cpus, 1, threads) >= 0) {
+ pr_debug("Unexpected success opening CPU index 1 with sample_period=1\n");
+ goto out;
+ }
+
+ /*
+ * Step 3: Check that CPU index 0's FD was NOT destroyed by CPU index 1's unwind.
+ */
+ if ((*(int *)xyarray__entry(evsel->core.fd, 0, 0)) != fd0) {
+ pr_debug("FAILED: CPU 0 FD overwritten: FD(evsel, 0, 0)=%d, expected %d\n",
+ (*(int *)xyarray__entry(evsel->core.fd, 0, 0)), fd0);
+ goto out;
+ }
+
+ if (fcntl(fd0, F_GETFD) < 0) {
+ pr_debug("FAILED: CPU 0 FD %d was closed by error unwind! errno=%d (%s)\n",
+ fd0, errno, strerror(errno));
+ goto out;
+ }
+
+ ret = TEST_OK;
+out:
+ evsel__close(evsel);
+ perf_cpu_map__put(cpus);
+ perf_thread_map__put(threads);
+ evlist__put(evlist);
+ return ret;
+}
+
static struct test_case tests__tool_pmu[] = {
TEST_CASE("Parsing without PMU name", tool_pmu_without_pmu),
TEST_CASE("Parsing with PMU name", tool_pmu_with_pmu),
+ TEST_CASE("Incremental open error unwind boundary", tool_pmu_incremental_open_unwind),
{ .name = NULL, }
};
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index d4cb455f4a7d4..eb429087ebfee 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -3127,7 +3127,7 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
FD(evsel, idx, thread) = -1;
}
thread = nthreads;
- } while (--idx >= 0);
+ } while (--idx >= start_cpu_map_idx);
errno = old_errno;
out:
if (err)
diff --git a/tools/perf/util/hwmon_pmu.c b/tools/perf/util/hwmon_pmu.c
index ed544dca70c38..96aeb379e169d 100644
--- a/tools/perf/util/hwmon_pmu.c
+++ b/tools/perf/util/hwmon_pmu.c
@@ -803,7 +803,7 @@ int evsel__hwmon_pmu_open(struct evsel *evsel,
FD(evsel, idx, thread) = -1;
}
thread = nthreads;
- } while (--idx >= 0);
+ } while (--idx >= start_cpu_map_idx);
close(dir);
return err;
}
diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c
index 5c30854b4644a..d2f7591747d94 100644
--- a/tools/perf/util/tool_pmu.c
+++ b/tools/perf/util/tool_pmu.c
@@ -349,7 +349,7 @@ int evsel__tool_pmu_open(struct evsel *evsel,
FD(evsel, idx, thread) = -1;
}
thread = nthreads;
- } while (--idx >= 0);
+ } while (--idx >= start_cpu_map_idx);
errno = old_errno;
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 478/507] perf evsel: Close the fds opened so far when disabling missing features
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (476 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 477/507] perf evsel: Restrict incremental open error unwind Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 479/507] KVM: arm64: vgic: Stop the target vcpu when disabling LPIs Greg Kroah-Hartman
` (28 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Ian Rogers,
Arnaldo Carvalho de Melo, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <acme@redhat.com>
[ Upstream commit 16d1234793d42a5a594db99522845996ab8e0d29 ]
evsel__open_cpu() opens the events one by one and, when an open fails
with EINVAL and evsel__detect_missing_features() has a feature to leave
out, goes back to fallback_missing_features to open them all again from
start_cpu_map_idx, without closing what the abandoned attempt opened:
the fd of every CPU or thread that was opened before the failing one is
overwritten in the FD() array, leaking it.
Close them first, the same way out_close does when returning an error,
leaving the entries at -1 for the retry.
Fixes: af954f76eea5 ("perf tools: Check fallback error and order")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/r/sashiko-outbox-173532@kernel.org
Reviewed-by: Ian Rogers <irogers@google.com>
Tested-by: Ian Rogers <irogers@google.com>
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/perf/util/evsel.c | 30 +++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index eb429087ebfee..5db43520f25e7 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -2974,6 +2974,19 @@ static bool evsel__detect_missing_features(struct evsel *evsel, struct perf_cpu
return false;
}
+static void evsel__close_fds(struct evsel *evsel, int start_cpu_map_idx,
+ int cpu_map_idx, int thread, int nthreads)
+{
+ do {
+ while (--thread >= 0) {
+ if (FD(evsel, cpu_map_idx, thread) >= 0)
+ close(FD(evsel, cpu_map_idx, thread));
+ FD(evsel, cpu_map_idx, thread) = -1;
+ }
+ thread = nthreads;
+ } while (--cpu_map_idx >= start_cpu_map_idx);
+}
+
static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
struct perf_thread_map *threads,
int start_cpu_map_idx, int end_cpu_map_idx)
@@ -3109,8 +3122,14 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
if (err == -EMFILE && rlimit__increase_nofile(&set_rlimit))
goto retry_open;
- if (err == -EINVAL && evsel__detect_missing_features(evsel, cpu))
+ if (err == -EINVAL && evsel__detect_missing_features(evsel, cpu)) {
+ /*
+ * The restart opens the events again, so close what this
+ * attempt opened before its entries are overwritten.
+ */
+ evsel__close_fds(evsel, start_cpu_map_idx, idx, thread, nthreads);
goto fallback_missing_features;
+ }
if (evsel__precise_ip_fallback(evsel))
goto retry_open;
@@ -3120,14 +3139,7 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus,
threads->err_thread = thread;
old_errno = errno;
- do {
- while (--thread >= 0) {
- if (FD(evsel, idx, thread) >= 0)
- close(FD(evsel, idx, thread));
- FD(evsel, idx, thread) = -1;
- }
- thread = nthreads;
- } while (--idx >= start_cpu_map_idx);
+ evsel__close_fds(evsel, start_cpu_map_idx, idx, thread, nthreads);
errno = old_errno;
out:
if (err)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 479/507] KVM: arm64: vgic: Stop the target vcpu when disabling LPIs
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (477 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 478/507] perf evsel: Close the fds opened so far when disabling missing features Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 480/507] f2fs: fix to avoid potential reference count leak in do_garbage_collect() Greg Kroah-Hartman
` (27 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oliver Upton, Fuad Tabba,
Marc Zyngier, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier <maz@kernel.org>
[ Upstream commit a1b4bd2c2c262b8094c86afb99364d16ac08cb66 ]
Disabling LPIs is pretty nasty, as it directly messes with the AP list
of the affected CPU, which could be running... This has the potential to
lead to really bad behaviours, and we should not be doing that.
Take example on the way the Active state is handled and simply pause the
the vcpu so that we are sure it is in a quiescent state, and the state be
safely manipulated.
Nobody has any expectation of performance for this anyway.
Fixes: 96085b949672d ("KVM: arm/arm64: vgic-v3: Retire pending interrupts on disabling LPIs")
Co-developed-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Oliver Upton <oupton@kernel.org>
Cc: stable@vger.kernel.org
Reviewed-by: Fuad Tabba <fuad.tabba@linux.dev>
Tested-by: Fuad Tabba <fuad.tabba@linux.dev>
Link: https://patch.msgid.link/20261015100539.1011760-7-maz@kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>
[ sashal: Replaced per-vCPU pause/resume helpers with kvm_arm_halt_guest() and kvm_arm_resume_guest(), which pause all vCPUs. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/vgic/vgic-mmio-v3.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
index 5ab789accc9d4..9e6200c5adcef 100644
--- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
@@ -303,9 +303,19 @@ static void vgic_mmio_write_v3r_ctlr(struct kvm_vcpu *vcpu,
if (ctlr != GICR_CTLR_ENABLE_LPIS)
return;
+ /*
+ * Yes, disabling LPIs is painful, since it can be done from
+ * a *remote* vcpu! So let's not take any chance, and make
+ * sure that the target vCPU has written their LRs back to the
+ * irq structures, and release any reference they would have.
+ *
+ * If it hurts, don't do it.
+ */
+ kvm_arm_halt_guest(vcpu->kvm);
vgic_flush_pending_lpis(vcpu);
vgic_its_invalidate_all_caches(vcpu->kvm);
atomic_set_release(&vgic_cpu->ctlr, 0);
+ kvm_arm_resume_guest(vcpu->kvm);
} else {
ctlr = atomic_cmpxchg_acquire(&vgic_cpu->ctlr, 0,
GICR_CTLR_ENABLE_LPIS);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 480/507] f2fs: fix to avoid potential reference count leak in do_garbage_collect()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (478 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 479/507] KVM: arm64: vgic: Stop the target vcpu when disabling LPIs Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 481/507] nvme-tcp: Validate the queue state under the queue lock in the address attribute Greg Kroah-Hartman
` (26 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Daeho Jeong, Chao Yu,
Jaegeuk Kim, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit 894ca8b856668a82426dbd0a0042b61541a1a9ec ]
In do_garbage_collect(), we have reserved reference counts on summary cache
of all segments, once gc_thread encounter freezing, we need to release all
reference counts.
Cc: stable@kernel.org
Cc: Daeho Jeong <daehojeong@google.com>
Fixes: 02d91398a602 ("f2fs: fix to freeze GC and discard threads quickly")
Signed-off-by: Chao Yu <chao@kernel.org>
Reviewed-by: Daeho Jeong <daehojeong@google.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ sashal: Used folio_put_refs(sum_folio, 2) instead of two f2fs_put_cache() calls. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/gc.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 738a5543f086a..6220d55709e9c 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1857,6 +1857,9 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
if (block_end_segno > end_segno)
block_end_segno = end_segno;
+ if (unlikely(freezing(current)))
+ goto next_block;
+
if (is_cursec(sbi, GET_SEC_FROM_SEG(sbi, segno))) {
f2fs_err(sbi, "%s: segment %u is used by log",
__func__, segno);
@@ -1924,18 +1927,12 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
sbi->next_victim_seg[gc_type] =
(cur_segno + 1 < sec_end_segno) ?
cur_segno + 1 : NULL_SEGNO;
-
- if (unlikely(freezing(current))) {
- folio_put_refs(sum_folio, 2);
- goto stop;
- }
}
next_block:
folio_put_refs(sum_folio, 2);
segno = block_end_segno;
}
-stop:
if (submitted)
f2fs_submit_merged_write(sbi, data_type);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 481/507] nvme-tcp: Validate the queue state under the queue lock in the address attribute
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (479 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 480/507] f2fs: fix to avoid potential reference count leak in do_garbage_collect() Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 482/507] ASoC: hdac_hda: Allocate the private data at codec driver bind Greg Kroah-Hartman
` (25 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guixin Liu, Nilay Shroff,
Keith Busch, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guixin Liu <kanie@linux.alibaba.com>
[ Upstream commit 2eeeaa9c1ff0c429096acc2947c296db6a56f96d ]
Reading the "address" sysfs attribute calls kernel_getsockname() on the
admin queue socket, which can race with the queue teardown during
connection error recovery: a reader can observe NVME_TCP_Q_LIVE set,
then block on the queue lock while nvme_tcp_free_queue() releases the
socket and clears queue->sock without holding the lock. Once the
reader acquires the lock it dereferences the NULL socket pointer.
Commit 76d54bf20cdc ("nvme-tcp: don't access released socket during
error recovery") had the queue liveness check inside the lock.
Commit 782373ba2766 ("nvme: tcp: avoid race between queue_lock lock
and destroy") moved it back out because the lock itself is destroyed
in nvme_tcp_free_queue(), so a reader arriving late trips
mutex_destroy().
Check the queue liveness inside the queue lock, and clear queue->sock
under the same lock. The teardown clears NVME_TCP_Q_LIVE under the
lock well before the socket is released, so a reader either sees the
bit cleared or a socket that cannot be released while it holds the
lock. To also close the lock lifetime race, the queue locks are now
owned by the controller: they are initialized with the queue array and
only destroyed when the controller is freed, which cannot happen while
a sysfs attribute read is still in progress. The queue count is
computed by the NVME_TCP_OPT_NR_QUEUES() macro from the original
connect options for both initialization and destruction, as reconnects
may shrink ctrl->queue_count.
Fixes: 782373ba2766 ("nvme: tcp: avoid race between queue_lock lock and destroy")
Cc: stable@vger.kernel.org
Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
Reviewed-by: Nilay Shroff <nilay@linux.ibm.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
[ sashal: Added a standalone queue_lock initialization loop because the upstream page-fragment cache initialization loop is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/tcp.c | 51 +++++++++++++++++++++++++++++------------
1 file changed, 36 insertions(+), 15 deletions(-)
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index 2c7e9cfa2253e..50297ce8bdde6 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -117,6 +117,9 @@ enum nvme_tcp_queue_flags {
NVME_TCP_Q_IO_CPU_SET = 3,
};
+#define NVME_TCP_OPT_NR_QUEUES(opts) ((opts)->nr_io_queues + \
+ (opts)->nr_write_queues + (opts)->nr_poll_queues + 1)
+
enum nvme_tcp_recv_state {
NVME_TCP_RECV_PDU = 0,
NVME_TCP_RECV_DATA,
@@ -1556,14 +1559,21 @@ static void nvme_tcp_free_queue(struct nvme_ctrl *nctrl, int qid)
* nvme_reset_ctrl_work(), queue teardown is immediately followed by
* re-allocation. fput() defers socket cleanup to delayed_fput_work
* in workqueue context, which can race with new queue setup.
+ *
+ * Clear queue->sock under the queue lock so that a sysfs reader in
+ * nvme_tcp_get_address() either observes the NVME_TCP_Q_LIVE bit
+ * cleared or a still valid socket. The queue lock itself is owned
+ * by the controller and only destroyed when the controller is
+ * freed, so readers blocked on it cannot race its teardown.
*/
+ mutex_lock(&queue->queue_lock);
__fput_sync(queue->sock->file);
queue->sock = NULL;
+ mutex_unlock(&queue->queue_lock);
memalloc_noio_restore(noio_flag);
kfree(queue->pdu);
mutex_destroy(&queue->send_mutex);
- mutex_destroy(&queue->queue_lock);
mutex_destroy(&queue->pf_cache_lock);
}
@@ -1995,7 +2005,6 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, int qid,
int ret, rcv_pdu_size;
struct file *sock_file;
- mutex_init(&queue->queue_lock);
queue->ctrl = ctrl;
init_llist_head(&queue->req_list);
INIT_LIST_HEAD(&queue->send_list);
@@ -2133,7 +2142,6 @@ static int nvme_tcp_alloc_queue(struct nvme_ctrl *nctrl, int qid,
queue->sock = NULL;
err_destroy_mutex:
mutex_destroy(&queue->send_mutex);
- mutex_destroy(&queue->queue_lock);
mutex_destroy(&queue->pf_cache_lock);
return ret;
}
@@ -2783,6 +2791,9 @@ static void nvme_tcp_stop_ctrl(struct nvme_ctrl *ctrl)
static void nvme_tcp_free_ctrl(struct nvme_ctrl *nctrl)
{
struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl);
+ /* the same count used to size and initialize the queue array */
+ unsigned int nr_queues = NVME_TCP_OPT_NR_QUEUES(nctrl->opts);
+ unsigned int i;
if (list_empty_careful(&ctrl->list))
goto free_ctrl;
@@ -2793,6 +2804,8 @@ static void nvme_tcp_free_ctrl(struct nvme_ctrl *nctrl)
nvmf_free_options(nctrl->opts);
free_ctrl:
+ for (i = 0; i < nr_queues; i++)
+ mutex_destroy(&ctrl->queues[i].queue_lock);
kfree(ctrl->queues);
kfree(ctrl);
}
@@ -3045,17 +3058,18 @@ static int nvme_tcp_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
len = nvmf_get_address(ctrl, buf, size);
- if (!test_bit(NVME_TCP_Q_LIVE, &queue->flags))
- return len;
-
mutex_lock(&queue->queue_lock);
- ret = kernel_getsockname(queue->sock, (struct sockaddr *)&src_addr);
- if (ret > 0) {
- if (len > 0)
- len--; /* strip trailing newline */
- len += scnprintf(buf + len, size - len, "%ssrc_addr=%pISc\n",
- (len) ? "," : "", &src_addr);
+ if (test_bit(NVME_TCP_Q_LIVE, &queue->flags)) {
+ ret = kernel_getsockname(queue->sock,
+ (struct sockaddr *)&src_addr);
+ if (ret > 0) {
+ if (len > 0)
+ len--; /* strip trailing newline */
+ len += scnprintf(buf + len, size - len,
+ "%ssrc_addr=%pISc\n",
+ (len) ? "," : "", &src_addr);
+ }
}
mutex_unlock(&queue->queue_lock);
@@ -3121,7 +3135,7 @@ static struct nvme_tcp_ctrl *nvme_tcp_alloc_ctrl(struct device *dev,
struct nvmf_ctrl_options *opts)
{
struct nvme_tcp_ctrl *ctrl;
- int ret;
+ int ret, i;
ctrl = kzalloc_obj(*ctrl);
if (!ctrl)
@@ -3132,8 +3146,7 @@ static struct nvme_tcp_ctrl *nvme_tcp_alloc_ctrl(struct device *dev,
*/
context_unsafe(INIT_LIST_HEAD(&ctrl->list));
ctrl->ctrl.opts = opts;
- ctrl->ctrl.queue_count = opts->nr_io_queues + opts->nr_write_queues +
- opts->nr_poll_queues + 1;
+ ctrl->ctrl.queue_count = NVME_TCP_OPT_NR_QUEUES(opts);
ctrl->ctrl.sqsize = opts->queue_size - 1;
ctrl->ctrl.kato = opts->kato;
@@ -3191,6 +3204,14 @@ static struct nvme_tcp_ctrl *nvme_tcp_alloc_ctrl(struct device *dev,
goto out_free_ctrl;
}
+ /*
+ * The queue locks are owned by the controller, not the queues:
+ * they outlive the per-queue connect/disconnect cycles so that
+ * sysfs readers can never race their destruction.
+ */
+ for (i = 0; i < ctrl->ctrl.queue_count; i++)
+ mutex_init(&ctrl->queues[i].queue_lock);
+
ret = nvme_init_ctrl(&ctrl->ctrl, dev, &nvme_tcp_ctrl_ops, 0);
if (ret)
goto out_kfree_queues;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 482/507] ASoC: hdac_hda: Allocate the private data at codec driver bind
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (480 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 481/507] nvme-tcp: Validate the queue state under the queue lock in the address attribute Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 483/507] ASoC: hdac_hda: Restore the codec device type on unbind Greg Kroah-Hartman
` (24 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Peter Ujfalusi, Mark Brown,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
[ Upstream commit 7d357eae973a1e1933f81f55aa1b3b4e3064570f ]
The SOF HDA code allocates struct hdac_hda_priv and stores it as drvdata
of the codec device before the codec driver is bound. The driver core
clears drvdata on unbind, so after unbinding the codec driver via sysfs
a subsequent bind dereferences a NULL pointer in hdac_hda_dev_probe().
All information in the private data can be derived from the codec
device itself, so allocate and set it up in hdac_hda_dev_probe() as a
device managed resource, which is released on unbind.
Remove the allocation from SOF, keeping the check for iDisp codecs
without display audio component.
Fixes: 3fd63658caed ("ASoC: Intel: Drop hdac_ext usage for codec device creation")
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://patch.msgid.link/20261027083840.28813-2-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 08a44bde821d ("ASoC: hdac_hda: Restore the codec device type on unbind")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/hdac_hda.c | 13 ++++++++++++-
sound/soc/sof/intel/hda-codec.c | 23 ++++-------------------
2 files changed, 16 insertions(+), 20 deletions(-)
diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c
index 40d602f79314a..0604315a1f0f3 100644
--- a/sound/soc/codecs/hdac_hda.c
+++ b/sound/soc/codecs/hdac_hda.c
@@ -635,10 +635,21 @@ static const struct snd_soc_component_driver hdac_hda_hdmi_codec = {
static int hdac_hda_dev_probe(struct hdac_device *hdev)
{
- struct hdac_hda_priv *hda_pvt = dev_get_drvdata(&hdev->dev);
+ struct hdac_hda_priv *hda_pvt;
struct hdac_ext_link *hlink;
int ret;
+ hda_pvt = devm_kzalloc(&hdev->dev, sizeof(*hda_pvt), GFP_KERNEL);
+ if (!hda_pvt)
+ return -ENOMEM;
+
+ hda_pvt->codec = dev_to_hda_codec(&hdev->dev);
+ hda_pvt->dev_index = hdev->addr;
+ /* Intel iDisp (HDMI/DP) codec */
+ if (((hdev->vendor_id >> 16) & 0xFFFF) == 0x8086)
+ hda_pvt->need_display_power = true;
+ dev_set_drvdata(&hdev->dev, hda_pvt);
+
/* hold the ref while we probe */
hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev));
if (!hlink) {
diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c
index fd371850b0d69..32fcc1cd3f923 100644
--- a/sound/soc/sof/intel/hda-codec.c
+++ b/sound/soc/sof/intel/hda-codec.c
@@ -15,8 +15,6 @@
#include "hda.h"
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
-#include "../../codecs/hdac_hda.h"
-
#define CODEC_PROBE_RETRIES 3
#define IDISP_VID_INTEL 0x80860000
@@ -148,7 +146,6 @@ static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, i
/* probe individual codec */
static int hda_codec_probe(struct snd_sof_dev *sdev, int address)
{
- struct hdac_hda_priv *hda_priv;
struct hda_bus *hbus = sof_to_hbus(sdev);
struct hda_codec *codec;
u32 hda_cmd = (address << 28) | (AC_NODE_ROOT << 20) |
@@ -168,27 +165,15 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address)
dev_dbg(sdev->dev, "HDA codec #%d probed OK: response: %x\n",
address, resp);
- hda_priv = devm_kzalloc(sdev->dev, sizeof(*hda_priv), GFP_KERNEL);
- if (!hda_priv)
- return -ENOMEM;
-
codec = hda_codec_device_init(&hbus->core, address, HDA_DEV_LEGACY);
ret = PTR_ERR_OR_ZERO(codec);
if (ret < 0)
return ret;
- hda_priv->codec = codec;
- hda_priv->dev_index = address;
- dev_set_drvdata(&codec->core.dev, hda_priv);
-
- if ((resp & 0xFFFF0000) == IDISP_VID_INTEL) {
- if (!hbus->core.audio_component) {
- dev_dbg(sdev->dev,
- "iDisp hw present but no driver\n");
- ret = -ENOENT;
- goto out;
- }
- hda_priv->need_display_power = true;
+ if ((resp & 0xFFFF0000) == IDISP_VID_INTEL && !hbus->core.audio_component) {
+ dev_dbg(sdev->dev, "iDisp hw present but no driver\n");
+ ret = -ENOENT;
+ goto out;
}
if (is_generic_config(hbus))
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 483/507] ASoC: hdac_hda: Restore the codec device type on unbind
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (481 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 482/507] ASoC: hdac_hda: Allocate the private data at codec driver bind Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 484/507] erofs: fix metadata reads at the end of file-backed images Greg Kroah-Hartman
` (23 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Peter Ujfalusi, Mark Brown,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
[ Upstream commit 08a44bde821d4fe22c0b6e63da04b3c59ac243a8 ]
hdac_hda_codec_probe() changes the type of the codec device to
HDA_DEV_ASOC to prevent snd_hda_codec_unregister() from unregistering
the device when the card is freed.
The type is never restored, and hda_bus_match() requires the device and
driver types to be equal. After unbinding the codec driver via sysfs the
HDA_DEV_LEGACY codec drivers no longer match the device and bind fails
with -ENODEV.
Restore HDA_DEV_LEGACY with a device managed action registered before
the component, so it runs after the component and the card are gone.
Fixes: b60ee2e281b6 ("ASoC: hdac_hda: overwrite hdev type to HDA_DEV_ASOC")
Cc: stable@vger.kernel.org
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://patch.msgid.link/20261027083840.28813-3-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/hdac_hda.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c
index 0604315a1f0f3..9e45b20940f2f 100644
--- a/sound/soc/codecs/hdac_hda.c
+++ b/sound/soc/codecs/hdac_hda.c
@@ -633,6 +633,13 @@ static const struct snd_soc_component_driver hdac_hda_hdmi_codec = {
.endianness = 1,
};
+static void hdac_hda_restore_dev_type(void *data)
+{
+ struct hdac_device *hdev = data;
+
+ hdev->type = HDA_DEV_LEGACY;
+}
+
static int hdac_hda_dev_probe(struct hdac_device *hdev)
{
struct hdac_hda_priv *hda_pvt;
@@ -650,6 +657,11 @@ static int hdac_hda_dev_probe(struct hdac_device *hdev)
hda_pvt->need_display_power = true;
dev_set_drvdata(&hdev->dev, hda_pvt);
+ /* Allow the legacy codec driver to match again after unbind */
+ ret = devm_add_action(&hdev->dev, hdac_hda_restore_dev_type, hdev);
+ if (ret)
+ return ret;
+
/* hold the ref while we probe */
hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev));
if (!hlink) {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 484/507] erofs: fix metadata reads at the end of file-backed images
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (482 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 483/507] ASoC: hdac_hda: Restore the codec device type on unbind Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 485/507] PCI: cadence: Remove device links to PHY Greg Kroah-Hartman
` (22 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hengyu Liang, Gao Xiang, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hengyu Liang <hengyul@cs.unc.edu>
[ Upstream commit 52dceb88082b4c7983d1c8c7de1c181f018055ac ]
Commit e587a984d332 ("erofs: use dedicated meta inodes for file-backed
mounts") made erofs_read_meta_folio() read the metadata of a
file-backed mount one whole folio at a time.
However, an image only has to be a multiple of its block size. With a
block size below the page size, it can end in the middle of a page. The
read of that last page is then short, and erofs_fileio_ki_complete()
fails it with -EIO. As of now, inodes in the last page of such an image
cannot be read, and an image smaller than a page cannot be mounted.
The issue can be reproduced with util-linux 2.41, whose mount uses the
image file directly:
mkdir src
for i in $(seq 50); do echo $i > src/$i; done
mkfs.erofs -b512 test.erofs src
mount -t erofs test.erofs /mnt
ls -l /mnt
Before that commit, ls -l lists all 50 files. After it, ls -l reports
"Input/output error" for 24 of them.
This patch reads the folio only up to the end of the backing file and
zeroes the rest, as the page cache of the backing file did before. A
folio that lies wholly past the end is zeroed without a read.
Fixes: e587a984d332 ("erofs: use dedicated meta inodes for file-backed mounts")
Cc: stable@vger.kernel.org
Signed-off-by: Hengyu Liang <hengyul@cs.unc.edu>
Reviewed-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: Gao Xiang (Docker) <xiang@kernel.org>
[ sashal: adjusted context to retain the older metadata I/O allocation and completion mechanism ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/erofs/fileio.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/fs/erofs/fileio.c b/fs/erofs/fileio.c
index ebb81a7ffd4cb..ac846cfbc5633 100644
--- a/fs/erofs/fileio.c
+++ b/fs/erofs/fileio.c
@@ -201,17 +201,29 @@ int erofs_read_meta_folio(struct file *file, struct folio *folio)
.dev = { .m_pa = folio_pos(folio), },
};
struct inode *inode = folio_inode(folio);
+ size_t len = folio_size(folio);
+ loff_t pos, isize;
int err;
err = erofs_map_dev(inode->i_sb, &io.dev);
if (err)
return err;
+ pos = io.dev.m_dif->fsoff + io.dev.m_pa;
+ isize = i_size_read(file_inode(io.dev.m_dif->file));
+ if (pos + folio_size(folio) > isize) {
+ len = isize > pos ? isize - pos : 0;
+ folio_zero_segment(folio, len, folio_size(folio));
+ if (!len) {
+ folio_end_read(folio, true);
+ return 0;
+ }
+ }
+
io.rq = erofs_fileio_rq_alloc(&io.dev);
- io.rq->bio.bi_iter.bi_sector =
- (io.dev.m_dif->fsoff + io.dev.m_pa) >> 9;
+ io.rq->bio.bi_iter.bi_sector = pos >> 9;
erofs_onlinefolio_init(folio);
- bio_add_folio_nofail(&io.rq->bio, folio, folio_size(folio), 0);
+ bio_add_folio_nofail(&io.rq->bio, folio, len, 0);
erofs_fileio_rq_submit(io.rq);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 485/507] PCI: cadence: Remove device links to PHY
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (483 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 484/507] erofs: fix metadata reads at the end of file-backed images Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 486/507] PCI: cadence: Store the core controller in platform drvdata Greg Kroah-Hartman
` (21 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vladimir Oltean, Bjorn Helgaas,
Aksh Garg, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: vladimir.oltean@nxp.com <vladimir.oltean@nxp.com>
[ Upstream commit b59e98ae3841f84d0fb21dbf80e69e6c241a29d9 ]
This is a partial revert of the device link pieces from commit
dfb80534692d ("PCI: cadence: Add generic PHY support to host and EP
drivers").
The trouble with this is that a PHY consumer driver dereferences fields
from struct phy, which will become no longer possible.
Since commit 987351e1ea77 ("phy: core: Add consumer device link support")
from 2019, the PHY core also adds a device link to order PHY provider and
consumer suspend/resume operations. The reverted functionality is from
2018 and is redundant with the PHY core now.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Aksh Garg <a-garg7@ti.com>
Link: https://patch.msgid.link/20260912161440.1032188-2-vladimir.oltean@nxp.com
Stable-dep-of: cfe96ce583c5 ("PCI: cadence: Store the core controller in platform drvdata")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../pci/controller/cadence/pcie-cadence-plat.c | 4 ----
drivers/pci/controller/cadence/pcie-cadence.c | 16 +---------------
drivers/pci/controller/cadence/pcie-cadence.h | 2 --
3 files changed, 1 insertion(+), 21 deletions(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-plat.c b/drivers/pci/controller/cadence/pcie-cadence-plat.c
index a1ea24fc3b63f..5900d68c6e83a 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-plat.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-plat.c
@@ -41,7 +41,6 @@ static int cdns_plat_pcie_probe(struct platform_device *pdev)
struct pci_host_bridge *bridge;
struct cdns_pcie_ep *ep;
struct cdns_pcie_rc *rc;
- int phy_count;
bool is_rc;
int ret;
@@ -122,9 +121,6 @@ static int cdns_plat_pcie_probe(struct platform_device *pdev)
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
cdns_pcie_disable_phy(cdns_plat_pcie->pcie);
- phy_count = cdns_plat_pcie->pcie->phy_count;
- while (phy_count--)
- device_link_del(cdns_plat_pcie->pcie->link[phy_count]);
return 0;
}
diff --git a/drivers/pci/controller/cadence/pcie-cadence.c b/drivers/pci/controller/cadence/pcie-cadence.c
index a1eada56edba7..0ac9802499414 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.c
+++ b/drivers/pci/controller/cadence/pcie-cadence.c
@@ -222,7 +222,6 @@ int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie)
struct device_node *np = dev->of_node;
int phy_count;
struct phy **phy;
- struct device_link **link;
int i;
int ret;
const char *name;
@@ -238,10 +237,6 @@ int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie)
if (!phy)
return -ENOMEM;
- link = devm_kcalloc(dev, phy_count, sizeof(*link), GFP_KERNEL);
- if (!link)
- return -ENOMEM;
-
for (i = 0; i < phy_count; i++) {
of_property_read_string_index(np, "phy-names", i, &name);
phy[i] = devm_phy_get(dev, name);
@@ -249,17 +244,10 @@ int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie)
ret = PTR_ERR(phy[i]);
goto err_phy;
}
- link[i] = device_link_add(dev, &phy[i]->dev, DL_FLAG_STATELESS);
- if (!link[i]) {
- devm_phy_put(dev, phy[i]);
- ret = -EINVAL;
- goto err_phy;
- }
}
pcie->phy_count = phy_count;
pcie->phy = phy;
- pcie->link = link;
ret = cdns_pcie_enable_phy(pcie);
if (ret)
@@ -268,10 +256,8 @@ int cdns_pcie_init_phy(struct device *dev, struct cdns_pcie *pcie)
return 0;
err_phy:
- while (--i >= 0) {
- device_link_del(link[i]);
+ while (--i >= 0)
devm_phy_put(dev, phy[i]);
- }
return ret;
}
diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
index b4d51adefea53..4a96e1869e535 100644
--- a/drivers/pci/controller/cadence/pcie-cadence.h
+++ b/drivers/pci/controller/cadence/pcie-cadence.h
@@ -260,7 +260,6 @@ struct cdns_plat_pcie_of_data {
* @is_hpa: indicates if the architecture is HPA
* @phy_count: number of supported PHY devices
* @phy: list of pointers to specific PHY control blocks
- * @link: list of pointers to corresponding device link representations
* @ops: Platform-specific ops to control various inputs from Cadence PCIe
* wrapper
* @cdns_pcie_reg_offsets: Register bank offsets for different SoC
@@ -276,7 +275,6 @@ struct cdns_pcie {
bool is_hpa;
int phy_count;
struct phy **phy;
- struct device_link **link;
const struct cdns_pcie_ops *ops;
const struct cdns_plat_pcie_of_data *cdns_pcie_reg_offsets;
int max_link_speed;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 486/507] PCI: cadence: Store the core controller in platform drvdata
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (484 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 485/507] PCI: cadence: Remove device links to PHY Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 487/507] PCI: cadence: Preserve all error codes in cdns_plat_pcie_probe() Greg Kroah-Hartman
` (20 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Linmao Li, Manivannan Sadhasivam,
Bjorn Helgaas, Aksh Garg, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linmao Li <lilinmao@kylinos.cn>
[ Upstream commit cfe96ce583c51bf6e034d4038c652a1e8227867c ]
cdns_plat_pcie_probe() stores a struct cdns_plat_pcie pointer with
platform_set_drvdata(). cdns_plat_pcie_shutdown() and the callbacks in
cdns_pcie_pm_ops retrieve the same pointer with dev_get_drvdata() but use
it as a struct cdns_pcie pointer. This makes them read phy_count and phy
beyond the wrapper.
struct cdns_plat_pcie only contains a pointer to struct cdns_pcie. Drop
the redundant wrapper and store the struct cdns_pcie pointer directly.
Fixes: bd22885aa188 ("PCI: cadence: Refactor driver to use as a core library")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Aksh Garg <a-garg7@ti.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260915082826.4135665-1-lilinmao@kylinos.cn
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../controller/cadence/pcie-cadence-plat.c | 27 ++++++-------------
1 file changed, 8 insertions(+), 19 deletions(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-plat.c b/drivers/pci/controller/cadence/pcie-cadence-plat.c
index 5900d68c6e83a..abda260543c8b 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-plat.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-plat.c
@@ -14,14 +14,6 @@
#define CDNS_PLAT_CPU_TO_BUS_ADDR 0x0FFFFFFF
-/**
- * struct cdns_plat_pcie - private data for this PCIe platform driver
- * @pcie: Cadence PCIe controller
- */
-struct cdns_plat_pcie {
- struct cdns_pcie *pcie;
-};
-
static const struct of_device_id cdns_plat_pcie_of_match[];
static u64 cdns_plat_cpu_addr_fixup(struct cdns_pcie *pcie, u64 cpu_addr)
@@ -36,9 +28,9 @@ static const struct cdns_pcie_ops cdns_plat_ops = {
static int cdns_plat_pcie_probe(struct platform_device *pdev)
{
const struct cdns_plat_pcie_of_data *data;
- struct cdns_plat_pcie *cdns_plat_pcie;
struct device *dev = &pdev->dev;
struct pci_host_bridge *bridge;
+ struct cdns_pcie *pcie;
struct cdns_pcie_ep *ep;
struct cdns_pcie_rc *rc;
bool is_rc;
@@ -51,11 +43,6 @@ static int cdns_plat_pcie_probe(struct platform_device *pdev)
is_rc = data->is_rc;
pr_debug(" Started %s with is_rc: %d\n", __func__, is_rc);
- cdns_plat_pcie = devm_kzalloc(dev, sizeof(*cdns_plat_pcie), GFP_KERNEL);
- if (!cdns_plat_pcie)
- return -ENOMEM;
-
- platform_set_drvdata(pdev, cdns_plat_pcie);
if (is_rc) {
if (!IS_ENABLED(CONFIG_PCIE_CADENCE_PLAT_HOST))
return -ENODEV;
@@ -67,9 +54,9 @@ static int cdns_plat_pcie_probe(struct platform_device *pdev)
rc = pci_host_bridge_priv(bridge);
rc->pcie.dev = dev;
rc->pcie.ops = &cdns_plat_ops;
- cdns_plat_pcie->pcie = &rc->pcie;
+ pcie = &rc->pcie;
- ret = cdns_pcie_init_phy(dev, cdns_plat_pcie->pcie);
+ ret = cdns_pcie_init_phy(dev, pcie);
if (ret) {
dev_err(dev, "failed to init phy\n");
return ret;
@@ -94,9 +81,9 @@ static int cdns_plat_pcie_probe(struct platform_device *pdev)
ep->pcie.dev = dev;
ep->pcie.ops = &cdns_plat_ops;
- cdns_plat_pcie->pcie = &ep->pcie;
+ pcie = &ep->pcie;
- ret = cdns_pcie_init_phy(dev, cdns_plat_pcie->pcie);
+ ret = cdns_pcie_init_phy(dev, pcie);
if (ret) {
dev_err(dev, "failed to init phy\n");
return ret;
@@ -114,13 +101,15 @@ static int cdns_plat_pcie_probe(struct platform_device *pdev)
goto err_init;
}
+ platform_set_drvdata(pdev, pcie);
+
return 0;
err_init:
err_get_sync:
pm_runtime_put_sync(dev);
pm_runtime_disable(dev);
- cdns_pcie_disable_phy(cdns_plat_pcie->pcie);
+ cdns_pcie_disable_phy(pcie);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 487/507] PCI: cadence: Preserve all error codes in cdns_plat_pcie_probe()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (485 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 486/507] PCI: cadence: Store the core controller in platform drvdata Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 488/507] f2fs: fix to invalidate curseg if change_curseg() fails Greg Kroah-Hartman
` (19 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vladimir Oltean,
Manivannan Sadhasivam, Bjorn Helgaas, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean <vladimir.oltean@nxp.com>
[ Upstream commit fe108800a865b268eec103e4940c248c85a86e9f ]
The blamed commit functionally changed the error path of
cdns_pcie_host_probe(), now cdns_plat_pcie_probe().
When the old code path executed "goto err_get_sync", the PCIe controller
probe function propagated the pm_runtime_get_sync() error code. The new
code doesn't, and returns 0.
Similarly for the "goto err_init" previously triggered by
cdns_pcie_host_init() errors, and now triggered by
cdns_pcie_host_setup() and cdns_pcie_ep_setup() errors. These are not
propagated and will result in probing success, which is incorrect.
Fixes: bd22885aa188 ("PCI: cadence: Refactor driver to use as a core library")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20260810124315.433448-2-vladimir.oltean@nxp.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pci/controller/cadence/pcie-cadence-plat.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-plat.c b/drivers/pci/controller/cadence/pcie-cadence-plat.c
index abda260543c8b..4a24302cc5b2c 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-plat.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-plat.c
@@ -111,7 +111,7 @@ static int cdns_plat_pcie_probe(struct platform_device *pdev)
pm_runtime_disable(dev);
cdns_pcie_disable_phy(pcie);
- return 0;
+ return ret;
}
static void cdns_plat_pcie_shutdown(struct platform_device *pdev)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 488/507] f2fs: fix to invalidate curseg if change_curseg() fails
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (486 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 487/507] PCI: cadence: Preserve all error codes in cdns_plat_pcie_probe() Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 489/507] ACPI: utils: Add exclusive AML evaluation helpers Greg Kroah-Hartman
` (18 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Chao Yu, Jaegeuk Kim,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit e74476ad8162c1facc74b74ce2d1372492df872e ]
Our consistency stress test (fsstress + fio + atomic write workers +
"f2fs_io shutdown 1") triggers below kernel BUG:
F2FS-fs (vdd): Stopped filesystem due to reason: 0
------------[ cut here ]------------
kernel BUG at fs/f2fs/segment.c:3989!
Oops: invalid opcode: 0000 [#1] SMP KASAN PTI
Workqueue: writeback wb_workfn (flush-253:48)
RIP: 0010:f2fs_allocate_data_block+0x257a/0x38e0
Call Trace:
<TASK>
do_write_block+0x155/0xc10
f2fs_outplace_write_data+0x192/0x340
f2fs_do_write_data_page+0xc57/0x1880
f2fs_write_single_data_page+0xda9/0x15a0
f2fs_write_cache_pages+0x973/0x1f20
__f2fs_write_data_pages+0x6c4/0x1890
do_writepages+0x21e/0x560
__writeback_single_inode+0x119/0x11b0
writeback_sb_inodes+0x67d/0x17a0
wb_writeback+0x207/0x820
wb_workfn+0x128/0xc30
process_one_work+0x925/0x1600
worker_thread+0x60a/0xff0
kthread+0x35f/0x460
ret_from_fork+0x474/0x7e0
ret_from_fork_asm+0x1a/0x30
</TASK>
The BUG is f2fs_bug_on(sbi, curseg->next_blkoff >= BLKS_PER_SEG(sbi))
in f2fs_allocate_data_block(), next_blkoff was 512.
The root cause is a race in between atomic write commit and shutdown
as below:
Thread A (commit atomic write) Thread B (shutdown) Thread C (writeback)
- f2fs_ioc_commit_atomic_write
- f2fs_commit_atomic_write
- __f2fs_commit_atomic_write
- __replace_atomic_write_block
- f2fs_replace_block
- __f2fs_replace_block
- f2fs_ioc_shutdown
- f2fs_do_shutdown
: F2FS_GOING_DOWN_METASYNC
- f2fs_sync_fs
- f2fs_write_single_data_page
: pass f2fs_cp_error() check
- f2fs_stop_checkpoint
: set CP_ERROR_FLAG
- change_curseg
- reset_curseg
: curseg->segno = new_segno
: curseg->alloc_type = SSR
: curseg->next_blkoff = __next_free_blkoff()
which is BLKS_PER_SEG if there is no free
slot in new_segno
- f2fs_get_sum_cache
: return -EIO due to f2fs_cp_error()
: return error w/o restoring curseg
: goto out_unlock, skip restoring
old segno, blkoff and alloc_type
- f2fs_do_write_data_page
- f2fs_outplace_write_data
- do_write_block
- f2fs_allocate_data_block
: curseg->segno is valid
: f2fs_bug_on(next_blkoff >=
BLKS_PER_SEG)
Since commit 86f33603f8c5 ("f2fs: handle errors of
f2fs_get_meta_page_nofail"), change_curseg() can fail after the curseg
has already been switched to the new segment, then the curseg is left
in an inconsistent state: it points to a segment which may have no
free slot, its summary block is zeroed, and the caller can not restore
it. Subsequent block allocation on the curseg will trigger the BUG.
Moreover, the writeback thread dies with curseg_lock, curseg_mutex and
sentry_lock held, so the commit, shutdown and other I/O threads hang
in D state.
Since change_curseg() only fails once CP_ERROR_FLAG is set, no
checkpoint will be committed afterward, let's invalidate the curseg via
reset_curseg_fields() on failure, as new_curseg() does for -ENOSPC,
then f2fs_allocate_data_block() will fail with -ENOSPC on the curseg
instead of triggering BUG, and do_write_block() can handle the error
since CP_ERROR_FLAG has been set.
Cc: stable@kernel.org
Fixes: 86f33603f8c5 ("f2fs: handle errors of f2fs_get_meta_page_nofail")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ sashal: Adjusted context to retain the existing folio summary API instead of the upstream cached-block API. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/segment.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 09d044c6a166d..75f78ed7eb909 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3234,6 +3234,7 @@ static int change_curseg(struct f2fs_sb_info *sbi, int type)
if (IS_ERR(sum_folio)) {
/* GC won't be able to use stale summary pages by cp_error */
memset(curseg->sum_blk, 0, sbi->sum_entry_size);
+ reset_curseg_fields(curseg);
return PTR_ERR(sum_folio);
}
sum_node = SUM_BLK_PAGE_ADDR(sbi, sum_folio, new_segno);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 489/507] ACPI: utils: Add exclusive AML evaluation helpers
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (487 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 488/507] f2fs: fix to invalidate curseg if change_curseg() fails Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 490/507] ACPI: battery: Evaluate battery methods exclusively Greg Kroah-Hartman
` (17 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rafael J. Wysocki,
Ali Ahmet Memiş, Rong Zhang, Rafael J. Wysocki, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ali Ahmet Memiş <aliamemis@disroot.org>
[ Upstream commit 80892972ff23bf0b9049230ef0931b34163aaed3 ]
ACPICA drops the interpreter lock while AML waits, for example around EC
accesses, so two methods can run interleaved.
Some firmware relies on methods not interleaving, for instance by
switching an EC page selector without taking the AML mutex that the
other users of that page hold.
Add acpi_evaluate_object_exclusive(), acpi_evaluate_integer_exclusive()
and acpi_execute_simple_method_exclusive() which serialize the
evaluation under a global mutex, for callers that are known to be
affected.
Suggested-by: Rafael J. Wysocki <rafael@kernel.org>
Link: https://lore.kernel.org/all/CAJZ5v0gS4agVUkCO6M=VW4Wi2y1-s+k23bpzmX9aAZ0Rsv4z9Q@mail.gmail.com/
Signed-off-by: Ali Ahmet Memiş <aliamemis@disroot.org>
Reviewed-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20261018122220.678822-2-aliamemis@disroot.org
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Stable-dep-of: 645f370c932d ("ACPI: battery: Evaluate battery methods exclusively")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/acpi/utils.c | 41 +++++++++++++++++++++++++++++++++++++++++
include/acpi/acpi_bus.h | 7 +++++++
2 files changed, 48 insertions(+)
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index d499b72574ab2..ea8cb876c12d2 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/types.h>
@@ -243,6 +244,28 @@ acpi_extract_package(union acpi_object *package,
EXPORT_SYMBOL(acpi_extract_package);
+static DEFINE_MUTEX(acpi_exclusive_eval_lock);
+
+/**
+ * acpi_evaluate_object_exclusive - Evaluate an object without interleaving
+ * @handle: ACPI handle of the object or its scope.
+ * @pathname: Path of the object relative to @handle.
+ * @arguments: Arguments to pass, or NULL.
+ * @buffer: Buffer for the return value, or NULL.
+ *
+ * Same as acpi_evaluate_object(), but serialized with other exclusive
+ * evaluations. Use it only for methods known to break when interleaved.
+ */
+acpi_status acpi_evaluate_object_exclusive(acpi_handle handle, acpi_string pathname,
+ struct acpi_object_list *arguments,
+ struct acpi_buffer *buffer)
+{
+ guard(mutex)(&acpi_exclusive_eval_lock);
+
+ return acpi_evaluate_object(handle, pathname, arguments, buffer);
+}
+EXPORT_SYMBOL_GPL(acpi_evaluate_object_exclusive);
+
acpi_status
acpi_evaluate_integer(acpi_handle handle,
acpi_string pathname,
@@ -277,6 +300,16 @@ acpi_evaluate_integer(acpi_handle handle,
EXPORT_SYMBOL(acpi_evaluate_integer);
+acpi_status acpi_evaluate_integer_exclusive(acpi_handle handle, acpi_string pathname,
+ struct acpi_object_list *arguments,
+ unsigned long long *data)
+{
+ guard(mutex)(&acpi_exclusive_eval_lock);
+
+ return acpi_evaluate_integer(handle, pathname, arguments, data);
+}
+EXPORT_SYMBOL_GPL(acpi_evaluate_integer_exclusive);
+
int acpi_get_local_u64_address(acpi_handle handle, u64 *addr)
{
acpi_status status;
@@ -685,6 +718,14 @@ acpi_status acpi_execute_simple_method(acpi_handle handle, char *method,
}
EXPORT_SYMBOL(acpi_execute_simple_method);
+acpi_status acpi_execute_simple_method_exclusive(acpi_handle handle, char *method, u64 arg)
+{
+ guard(mutex)(&acpi_exclusive_eval_lock);
+
+ return acpi_execute_simple_method(handle, method, arg);
+}
+EXPORT_SYMBOL_GPL(acpi_execute_simple_method_exclusive);
+
/**
* acpi_evaluate_ej0: Evaluate _EJ0 method for hotplug operations
* @handle: ACPI device handle
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index a10a591c18b23..8b1d329455f7b 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -32,6 +32,12 @@ acpi_status
acpi_evaluate_integer(acpi_handle handle,
acpi_string pathname,
struct acpi_object_list *arguments, unsigned long long *data);
+acpi_status acpi_evaluate_object_exclusive(acpi_handle handle, acpi_string pathname,
+ struct acpi_object_list *arguments,
+ struct acpi_buffer *buffer);
+acpi_status acpi_evaluate_integer_exclusive(acpi_handle handle, acpi_string pathname,
+ struct acpi_object_list *arguments,
+ unsigned long long *data);
bool acpi_evaluate_reference(acpi_handle handle, acpi_string pathname,
struct acpi_object_list *arguments,
struct acpi_handle_list *list);
@@ -48,6 +54,7 @@ acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code,
bool acpi_has_method(acpi_handle handle, char *name);
acpi_status acpi_execute_simple_method(acpi_handle handle, char *method,
u64 arg);
+acpi_status acpi_execute_simple_method_exclusive(acpi_handle handle, char *method, u64 arg);
acpi_status acpi_evaluate_ej0(acpi_handle handle);
acpi_status acpi_evaluate_lck(acpi_handle handle, int lock);
acpi_status acpi_evaluate_reg(acpi_handle handle, u8 space_id, u32 function);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 490/507] ACPI: battery: Evaluate battery methods exclusively
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (488 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 489/507] ACPI: utils: Add exclusive AML evaluation helpers Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 491/507] PCI: dwc: Set DMA_BYPASS bit in outbound IATU CTRL2 register Greg Kroah-Hartman
` (16 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Charis Stratakis,
Ali Ahmet Memiş, Hans de Goede, Rong Zhang,
Rafael J. Wysocki, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ali Ahmet Memiş <aliamemis@disroot.org>
[ Upstream commit 645f370c932db2cd3893f7fee61aa8b9debc8ac0 ]
On ThinkPad P1 Gen2 and P53, INT3403 _TMP switches the EC page selector
without taking the AML mutex the battery methods use, so _BIX and _BST
running at the same time can read the wrong page. Since commit d33e89d12295
("thermal: core: Suspend thermal zones later and resume them earlier")
this happens on most resumes.
Evaluate the battery methods with acpi_evaluate_object_exclusive().
Fixes: d33e89d12295 ("thermal: core: Suspend thermal zones later and resume them earlier")
Reported-by: Charis Stratakis <c.stratakis@proton.me>
Closes: https://lore.kernel.org/all/37N_jFulf7n-Z55NfKfE71C_wVPxYvZ0xD_iRUg2fXu7TypDiF5PStQ6siSfVBih6fThg5WoPes8U5ZQpfVm_teMFcUGXFxz2DdMbfSWuws=@proton.me/
Cc: All applicable <stable@vger.kernel.org> # 80892972ff23 ACPI: utils: Add exclusive AML evaluation helpers
Signed-off-by: Ali Ahmet Memiş <aliamemis@disroot.org>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Reviewed-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20261018122220.678822-3-aliamemis@disroot.org
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/acpi/battery.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 670853ec3a4d7..7169ac7e83f31 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -583,9 +583,8 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
acpi_status status = AE_ERROR;
- status = acpi_evaluate_object(battery->device->handle,
- use_bix ? "_BIX":"_BIF",
- NULL, &buffer);
+ status = acpi_evaluate_object_exclusive(battery->device->handle,
+ use_bix ? "_BIX" : "_BIF", NULL, &buffer);
if (ACPI_FAILURE(status)) {
acpi_handle_info(battery->device->handle,
@@ -624,8 +623,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
msecs_to_jiffies(cache_time)))
return 0;
- status = acpi_evaluate_object(battery->device->handle, "_BST",
- NULL, &buffer);
+ status = acpi_evaluate_object_exclusive(battery->device->handle, "_BST", NULL, &buffer);
if (ACPI_FAILURE(status)) {
acpi_handle_info(battery->device->handle,
"_BST evaluation failed: %s",
@@ -675,8 +673,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)
!test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags))
return -ENODEV;
- status = acpi_execute_simple_method(battery->device->handle, "_BTP",
- battery->alarm);
+ status = acpi_execute_simple_method_exclusive(battery->device->handle, "_BTP",
+ battery->alarm);
if (ACPI_FAILURE(status))
return -ENODEV;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 491/507] PCI: dwc: Set DMA_BYPASS bit in outbound IATU CTRL2 register
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (489 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 490/507] ACPI: battery: Evaluate battery methods exclusively Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 492/507] clk: nuvoton: ma35d1: Keep the clock count in the driver Greg Kroah-Hartman
` (15 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sumit Kumar, Manivannan Sadhasivam,
Bjorn Helgaas, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sumit Kumar <sumit.kumar@oss.qualcomm.com>
[ Upstream commit efadda401c5c8e2390ba66508eba154dbd0db5a9 ]
An outbound iATU region matches any local (AXI/application-side)
address that falls within its Base/Limit window and rewrites it to
the PCIe-side address programmed in that region's Target Address
Registers before the transaction goes out on the link. This matching
does not distinguish CPU-initiated transactions from ones issued by
the internal DMA engine (eDMA/HDMA).
Example: outbound region 0 is programmed with Base/Limit covering
local addresses 0x8000_0000-0x8000_0FFF and Target 0x1_0000_0000, for
CPU-initiated accesses. The DMA engine is later given a descriptor
whose destination is the host address 0x8000_0080, which happens to
fall inside region 0's Base/Limit range. The iATU matches the DMA
transaction against region 0 too and rewrites it to 0x1_0000_0080
instead of passing 0x8000_0080 through unchanged. The transaction
then lands on the wrong host address, causing data corruption or an
IOMMU fault when the rewritten address has no valid mapping.
Set the DMA_BYPASS bit (bit 27) in PCIE_ATU_REGION_CTRL2 when
programming outbound iATU regions so only CPU/AXI-initiated
transactions are matched against the region; DMA engine transactions
bypass the translation and go out on the PCIe link with their
original address.
Signed-off-by: Sumit Kumar <sumit.kumar@oss.qualcomm.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260908-dma_bypass-v2-1-c3c81d408c0c@oss.qualcomm.com
[ sashal: Adapted ATU_* register macros to the existing PCIE_ATU_* naming convention. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pci/controller/dwc/pcie-designware.c | 2 ++
drivers/pci/controller/dwc/pcie-designware.h | 1 +
2 files changed, 3 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 593388f29bdd4..9297d0e607e3a 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -577,6 +577,8 @@ int dw_pcie_prog_outbound_atu(struct dw_pcie *pci,
/* The data-less messages only for now */
val |= PCIE_ATU_INHIBIT_PAYLOAD | atu->code;
}
+ if (dw_pcie_ver_is_ge(pci, 460A))
+ val |= PCIE_ATU_DMA_BYPASS;
dw_pcie_writel_atu_ob(pci, atu->index, PCIE_ATU_REGION_CTRL2, val);
/*
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index 0735ae9409240..668a5ba1c6f59 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -201,6 +201,7 @@
#define PCIE_ATU_ENABLE BIT(31)
#define PCIE_ATU_BAR_MODE_ENABLE BIT(30)
#define PCIE_ATU_CFG_SHIFT_MODE_ENABLE BIT(28)
+#define PCIE_ATU_DMA_BYPASS BIT(27)
#define PCIE_ATU_INHIBIT_PAYLOAD BIT(22)
#define PCIE_ATU_FUNC_NUM_MATCH_EN BIT(19)
#define PCIE_ATU_LOWER_BASE 0x008
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 492/507] clk: nuvoton: ma35d1: Keep the clock count in the driver
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (490 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 491/507] PCI: dwc: Set DMA_BYPASS bit in outbound IATU CTRL2 register Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 493/507] dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define Greg Kroah-Hartman
` (14 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Miquel Raynal, Jerome Brunet,
Brian Masney, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Raynal <miquel.raynal@bootlin.com>
[ Upstream commit 26ec588063d9b6c70773b8729372e2bf6d3ea95a ]
The number of clocks is not a binding since this is a value that can
change. As such, in order to support the missing watchdog clocks and
allow the deprecation and removal of CLK_MAX_IDX from the bindings, we
need to switch to a local definition first.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://patch.msgid.link/20260930-perso-ma35d1-upstream-clk-v6-1-48937ee6c9bb@bootlin.com
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Brian Masney <bmasney@redhat.com>
Stable-dep-of: 1dc3871ce7ec ("clk: nuvoton: ma35d1: Add missing WDT/WWDT parent clocks")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/clk/nuvoton/clk-ma35d1.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/nuvoton/clk-ma35d1.c b/drivers/clk/nuvoton/clk-ma35d1.c
index 9f65d0623517a..6aa42a3e1be3b 100644
--- a/drivers/clk/nuvoton/clk-ma35d1.c
+++ b/drivers/clk/nuvoton/clk-ma35d1.c
@@ -17,6 +17,7 @@
static DEFINE_SPINLOCK(ma35d1_lock);
#define PLL_MAX_NUM 5
+#define MA35D1_CLK_COUNT 236
/* Clock Control Registers Offset */
#define REG_CLK_PWRCTL 0x00
@@ -467,12 +468,12 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
int ret;
ma35d1_hw_data = devm_kzalloc(dev,
- struct_size(ma35d1_hw_data, hws, CLK_MAX_IDX),
+ struct_size(ma35d1_hw_data, hws, MA35D1_CLK_COUNT),
GFP_KERNEL);
if (!ma35d1_hw_data)
return -ENOMEM;
- ma35d1_hw_data->num = CLK_MAX_IDX;
+ ma35d1_hw_data->num = MA35D1_CLK_COUNT;
hws = ma35d1_hw_data->hws;
clk_base = devm_platform_ioremap_resource(pdev, 0);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 493/507] dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (491 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 492/507] clk: nuvoton: ma35d1: Keep the clock count in the driver Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 494/507] dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks Greg Kroah-Hartman
` (13 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Conor Dooley, Miquel Raynal,
Jerome Brunet, Brian Masney, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Raynal <miquel.raynal@bootlin.com>
[ Upstream commit 653738db38c7c7f0fb959a7870f9461cf4987825 ]
Drop CLK_MAX_IDX define of MA35D1 include. This is not a binding and
should not be placed here. Value is defined in the user driver.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://patch.msgid.link/20260930-perso-ma35d1-upstream-clk-v6-3-48937ee6c9bb@bootlin.com
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Brian Masney <bmasney@redhat.com>
Stable-dep-of: 1dc3871ce7ec ("clk: nuvoton: ma35d1: Add missing WDT/WWDT parent clocks")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/dt-bindings/clock/nuvoton,ma35d1-clk.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/include/dt-bindings/clock/nuvoton,ma35d1-clk.h b/include/dt-bindings/clock/nuvoton,ma35d1-clk.h
index ba2d70f776a6d..2d6a44a7e55c4 100644
--- a/include/dt-bindings/clock/nuvoton,ma35d1-clk.h
+++ b/include/dt-bindings/clock/nuvoton,ma35d1-clk.h
@@ -248,6 +248,5 @@
#define ADC_GATE 233
#define EADC_DIV 234
#define EADC_GATE 235
-#define CLK_MAX_IDX 236
#endif /* __DT_BINDINGS_CLOCK_NUVOTON_MA35D1_CLK_H */
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 494/507] dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (492 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 493/507] dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 495/507] clk: nuvoton: " Greg Kroah-Hartman
` (12 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Conor Dooley, Miquel Raynal,
Jerome Brunet, Brian Masney, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Raynal <miquel.raynal@bootlin.com>
[ Upstream commit 8c7453cb0b01bee47ec2f902a9ac1872d3b77f3d ]
The WDT and WWDT muxes have PCLK3/4096 and PCLK4/4096 among their
possible parents, but these fixed factor clocks are currently not
defined, even though they are needed to properly describe the clock
tree. Add them to the bindings.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://patch.msgid.link/20260930-perso-ma35d1-upstream-clk-v6-4-48937ee6c9bb@bootlin.com
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Brian Masney <bmasney@redhat.com>
Stable-dep-of: 1dc3871ce7ec ("clk: nuvoton: ma35d1: Add missing WDT/WWDT parent clocks")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/dt-bindings/clock/nuvoton,ma35d1-clk.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/dt-bindings/clock/nuvoton,ma35d1-clk.h b/include/dt-bindings/clock/nuvoton,ma35d1-clk.h
index 2d6a44a7e55c4..764d837d6162a 100644
--- a/include/dt-bindings/clock/nuvoton,ma35d1-clk.h
+++ b/include/dt-bindings/clock/nuvoton,ma35d1-clk.h
@@ -248,5 +248,7 @@
#define ADC_GATE 233
#define EADC_DIV 234
#define EADC_GATE 235
+#define PCLK3_DIV4096 236
+#define PCLK4_DIV4096 237
#endif /* __DT_BINDINGS_CLOCK_NUVOTON_MA35D1_CLK_H */
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 495/507] clk: nuvoton: ma35d1: Add missing WDT/WWDT parent clocks
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (493 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 494/507] dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 496/507] f2fs: release a removed xattr node in roll-forward recovery Greg Kroah-Hartman
` (11 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jacky Huang, Jerome Brunet,
Miquel Raynal, Brian Masney, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miquel Raynal <miquel.raynal@bootlin.com>
[ Upstream commit 1dc3871ce7ec819030c22297f8960c61cc42a990 ]
The WDT and WWDT muxes list PCLK3/4096 and PCLK4/4096 among their
possible parents, but the driver never registers the corresponding
clocks, so these parents could never be used.
Add pclk3_div4096 and pclk4_div4096 as fixed factor children of pclk3
and pclk4 and expose them through the clock provider.
Reported-by: Jacky Huang <ychuang570808@gmail.com>
Closes: https://lore.kernel.org/linux-clk/b8a8a65b-e302-4747-bc90-4920fc48795a@gmail.com/
Suggested-by: Jacky Huang <ychuang570808@gmail.com>
Fixes: 691521a367cf ("clk: nuvoton: Add clock driver for ma35d1 clock controller")
Cc: stable@vger.kernel.org
Reviewed-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://patch.msgid.link/20260930-perso-ma35d1-upstream-clk-v6-5-48937ee6c9bb@bootlin.com
[jbrunet@baylibre.com: removed stale link trailer]
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/clk/nuvoton/clk-ma35d1.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/nuvoton/clk-ma35d1.c b/drivers/clk/nuvoton/clk-ma35d1.c
index 6aa42a3e1be3b..c914079cee2d4 100644
--- a/drivers/clk/nuvoton/clk-ma35d1.c
+++ b/drivers/clk/nuvoton/clk-ma35d1.c
@@ -17,7 +17,7 @@
static DEFINE_SPINLOCK(ma35d1_lock);
#define PLL_MAX_NUM 5
-#define MA35D1_CLK_COUNT 236
+#define MA35D1_CLK_COUNT 238
/* Clock Control Registers Offset */
#define REG_CLK_PWRCTL 0x00
@@ -544,6 +544,8 @@ static int ma35d1_clocks_probe(struct platform_device *pdev)
hws[HCLK3] = ma35d1_clk_fixed_factor(dev, "hclk3", "sysclk1_mux", 1, 2);
hws[PCLK3] = ma35d1_clk_fixed_factor(dev, "pclk3", "sysclk1_mux", 1, 2);
hws[PCLK4] = ma35d1_clk_fixed_factor(dev, "pclk4", "sysclk1_mux", 1, 2);
+ hws[PCLK3_DIV4096] = ma35d1_clk_fixed_factor(dev, "pclk3_div4096", "pclk3", 1, 4096);
+ hws[PCLK4_DIV4096] = ma35d1_clk_fixed_factor(dev, "pclk4_div4096", "pclk4", 1, 4096);
hws[USBPHY0] = ma35d1_clk_fixed("usbphy0", 480000000);
hws[USBPHY1] = ma35d1_clk_fixed("usbphy1", 480000000);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 496/507] f2fs: release a removed xattr node in roll-forward recovery
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (494 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 495/507] clk: nuvoton: " Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 497/507] media: ipu6: Rename pointer to firmware context Greg Kroah-Hartman
` (10 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daeho Jeong, Chao Yu, Jaegeuk Kim,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daeho Jeong <daehojeong@google.com>
[ Upstream commit f5924de8867c09206ba631b9faed63862ec00a10 ]
When xattrs shrink enough to fit in the inline xattr area,
write_all_xattrs() truncates the xattr node and clears i_xattr_nid. If
the file is then fsynced without a checkpoint, only the inode block is
written, with i_xattr_nid of 0.
Roll-forward recovery starts from the checkpointed inode, whose
i_xattr_nid still points to the old xattr node.
f2fs_recover_inline_xattr() copies only the inline xattr area, and
f2fs_update_inode() writes the old i_xattr_nid back. So the inode keeps
the stale xattr node:
- The node block is never released, and fsck reports "nonzero bytes in
xattr space after end of list".
- If the inline xattr list ends exactly at the end of the inline area,
its terminator is read from the stale node, and the removed xattrs
come back after recovery.
When the fsynced inode has no xattr node but the checkpointed one has,
release the old xattr node as truncate_node() does: check its block
address, invalidate the block and drop its node cache, which may still
be dirty.
Fixes: 28cdce0459cc ("f2fs: recover inline xattr data in roll-forward process")
Cc: stable@vger.kernel.org
Signed-off-by: Daeho Jeong <daehojeong@google.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ sashal: Replaced newer node-cache helpers with f2fs_folio_put() and truncate_inode_pages_range(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/node.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 70593f95abfb5..e166c5a5d1703 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -2883,6 +2883,45 @@ int f2fs_recover_inline_xattr(struct inode *inode, struct folio *folio)
f2fs_folio_wait_writeback(ifolio, NODE, true, true);
memcpy(dst_addr, src_addr, inline_size);
update_inode:
+ /*
+ * The xattr node of the checkpoint was removed before fsync, e.g. the
+ * xattrs became small enough to fit inline. Release it as well, or
+ * the inode keeps pointing to the stale xattrs.
+ */
+ if (!ri->i_xattr_nid && F2FS_I(inode)->i_xattr_nid) {
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct node_info ni;
+ int err;
+
+ err = f2fs_get_node_info(sbi, F2FS_I(inode)->i_xattr_nid,
+ &ni, false);
+ if (err) {
+ f2fs_folio_put(ifolio, true);
+ return err;
+ }
+
+ if (ni.blk_addr != NEW_ADDR &&
+ !f2fs_is_valid_blkaddr(sbi, ni.blk_addr,
+ DATA_GENERIC_ENHANCE)) {
+ f2fs_err_ratelimited(sbi,
+ "nat entry is corrupted, run fsck to fix it, ino:%u, nid:%u, blkaddr:%u",
+ ni.ino, ni.nid, ni.blk_addr);
+ set_sbi_flag(sbi, SBI_NEED_FSCK);
+ f2fs_handle_error(sbi, ERROR_INCONSISTENT_NAT);
+ f2fs_folio_put(ifolio, true);
+ return -EFSCORRUPTED;
+ }
+
+ f2fs_invalidate_blocks(sbi, ni.blk_addr, 1);
+ dec_valid_node_count(sbi, inode, false);
+ set_node_addr(sbi, &ni, NULL_ADDR, false);
+ /* drop the cached xattr node, which may be dirty */
+ truncate_inode_pages_range(NODE_MAPPING(sbi),
+ F2FS_BLK_TO_BYTES((loff_t)ni.nid),
+ F2FS_BLK_END_BYTES((loff_t)ni.nid));
+ f2fs_i_xnid_write(inode, 0);
+ }
+
f2fs_update_inode(inode, ifolio);
f2fs_folio_put(ifolio, true);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 497/507] media: ipu6: Rename pointer to firmware context
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (495 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 496/507] f2fs: release a removed xattr node in roll-forward recovery Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 498/507] media: ipu6: Fix firmware config leak on stream start Greg Kroah-Hartman
` (9 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Antti Laakso, Sakari Ailus,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antti Laakso <antti.laakso@linux.intel.com>
[ Upstream commit ac1a76fdf7e1815445c76d90ef688eff85cbb012 ]
The name fwcom is used to refer firmware communication context
and firmware communication configuration. Try to avoid confusion
and rename context variable.
Signed-off-by: Antti Laakso <antti.laakso@linux.intel.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Stable-dep-of: d3d9bc694fe0 ("media: ipu6: Fix firmware config leak on stream start")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/pci/intel/ipu6/ipu6-fw-isys.c | 56 ++++++++++---------
.../media/pci/intel/ipu6/ipu6-isys-video.c | 4 +-
drivers/media/pci/intel/ipu6/ipu6-isys.c | 6 +-
drivers/media/pci/intel/ipu6/ipu6-isys.h | 5 +-
4 files changed, 36 insertions(+), 35 deletions(-)
diff --git a/drivers/media/pci/intel/ipu6/ipu6-fw-isys.c b/drivers/media/pci/intel/ipu6/ipu6-fw-isys.c
index 62ed92ff1d303..a65e9f1aa1042 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-fw-isys.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-fw-isys.c
@@ -32,7 +32,7 @@ static int handle_proxy_response(struct ipu6_isys *isys, unsigned int req_id)
struct ipu6_fw_isys_proxy_resp_info_abi *resp;
int ret;
- resp = ipu6_recv_get_token(isys->fwcom, IPU6_BASE_PROXY_RECV_QUEUES);
+ resp = ipu6_recv_get_token(isys->fwctx, IPU6_BASE_PROXY_RECV_QUEUES);
if (!resp)
return 1;
@@ -42,7 +42,7 @@ static int handle_proxy_response(struct ipu6_isys *isys, unsigned int req_id)
ret = req_id == resp->request_id ? 0 : -EIO;
- ipu6_recv_put_token(isys->fwcom, IPU6_BASE_PROXY_RECV_QUEUES);
+ ipu6_recv_put_token(isys->fwctx, IPU6_BASE_PROXY_RECV_QUEUES);
return ret;
}
@@ -52,7 +52,7 @@ int ipu6_fw_isys_send_proxy_token(struct ipu6_isys *isys,
unsigned int index,
unsigned int offset, u32 value)
{
- struct ipu6_fw_com_context *ctx = isys->fwcom;
+ struct ipu6_fw_com_context *ctx = isys->fwctx;
struct device *dev = &isys->adev->auxdev.dev;
struct ipu6_fw_proxy_send_queue_token *token;
unsigned int timeout = 1000;
@@ -96,7 +96,7 @@ int ipu6_fw_isys_complex_cmd(struct ipu6_isys *isys,
dma_addr_t dma_mapped_buf,
size_t size, u16 send_type)
{
- struct ipu6_fw_com_context *ctx = isys->fwcom;
+ struct ipu6_fw_com_context *ctx = isys->fwctx;
struct device *dev = &isys->adev->auxdev.dev;
struct ipu6_fw_send_queue_token *token;
@@ -138,7 +138,7 @@ int ipu6_fw_isys_close(struct ipu6_isys *isys)
struct device *dev = &isys->adev->auxdev.dev;
int retry = IPU6_ISYS_CLOSE_RETRY;
unsigned long flags;
- void *fwcom;
+ void *fwctx;
int ret;
/*
@@ -148,9 +148,9 @@ int ipu6_fw_isys_close(struct ipu6_isys *isys)
* spinlock to wait the interrupt handler to be finished
*/
spin_lock_irqsave(&isys->power_lock, flags);
- ret = ipu6_fw_com_close(isys->fwcom);
- fwcom = isys->fwcom;
- isys->fwcom = NULL;
+ ret = ipu6_fw_com_close(isys->fwctx);
+ fwctx = isys->fwctx;
+ isys->fwctx = NULL;
spin_unlock_irqrestore(&isys->power_lock, flags);
if (ret)
dev_err(dev, "Device close failure: %d\n", ret);
@@ -158,14 +158,14 @@ int ipu6_fw_isys_close(struct ipu6_isys *isys)
/* release probably fails if the close failed. Let's try still */
do {
usleep_range(400, 500);
- ret = ipu6_fw_com_release(fwcom, 0);
+ ret = ipu6_fw_com_release(fwctx, 0);
retry--;
} while (ret && retry);
if (ret) {
dev_err(dev, "Device release time out %d\n", ret);
spin_lock_irqsave(&isys->power_lock, flags);
- isys->fwcom = fwcom;
+ isys->fwctx = fwctx;
spin_unlock_irqrestore(&isys->power_lock, flags);
}
@@ -176,11 +176,11 @@ void ipu6_fw_isys_cleanup(struct ipu6_isys *isys)
{
int ret;
- ret = ipu6_fw_com_release(isys->fwcom, 1);
+ ret = ipu6_fw_com_release(isys->fwctx, 1);
if (ret < 0)
dev_warn(&isys->adev->auxdev.dev,
"Device busy, fw_com release failed.");
- isys->fwcom = NULL;
+ isys->fwctx = NULL;
}
static void start_sp(struct ipu6_bus_device *adev)
@@ -212,7 +212,7 @@ static int query_sp(struct ipu6_bus_device *adev)
}
static int ipu6_isys_fwcom_cfg_init(struct ipu6_isys *isys,
- struct ipu6_fw_com_cfg *fwcom,
+ struct ipu6_fw_com_cfg *fwcom_cfg,
unsigned int num_streams)
{
unsigned int max_send_queues, max_sram_blocks, max_devq_size;
@@ -258,14 +258,16 @@ static int ipu6_isys_fwcom_cfg_init(struct ipu6_isys *isys,
if (!output_queue_cfg)
return -ENOMEM;
- fwcom->input = input_queue_cfg;
- fwcom->output = output_queue_cfg;
+ fwcom_cfg->input = input_queue_cfg;
+ fwcom_cfg->output = output_queue_cfg;
- fwcom->num_input_queues = isys_fw_cfg->num_send_queues[type_proxy] +
+ fwcom_cfg->num_input_queues =
+ isys_fw_cfg->num_send_queues[type_proxy] +
isys_fw_cfg->num_send_queues[type_dev] +
isys_fw_cfg->num_send_queues[type_msg];
- fwcom->num_output_queues = isys_fw_cfg->num_recv_queues[type_proxy] +
+ fwcom_cfg->num_output_queues =
+ isys_fw_cfg->num_recv_queues[type_proxy] +
isys_fw_cfg->num_recv_queues[type_dev] +
isys_fw_cfg->num_recv_queues[type_msg];
@@ -280,7 +282,7 @@ static int ipu6_isys_fwcom_cfg_init(struct ipu6_isys *isys,
isys_fw_cfg->buffer_partition.num_gda_pages[i] = 0;
}
- /* FW assumes proxy interface at fwcom queue 0 */
+ /* FW assumes proxy interface at fwcom_cfg queue 0 */
for (i = 0; i < isys_fw_cfg->num_send_queues[type_proxy]; i++) {
input_queue_cfg[i].token_size =
sizeof(struct ipu6_fw_proxy_send_queue_token);
@@ -314,9 +316,9 @@ static int ipu6_isys_fwcom_cfg_init(struct ipu6_isys *isys,
IPU6_ISYS_SIZE_RECV_QUEUE;
}
- fwcom->dmem_addr = isys->pdata->ipdata->hw_variant.dmem_offset;
- fwcom->specific_addr = isys_fw_cfg;
- fwcom->specific_size = sizeof(*isys_fw_cfg);
+ fwcom_cfg->dmem_addr = isys->pdata->ipdata->hw_variant.dmem_offset;
+ fwcom_cfg->specific_addr = isys_fw_cfg;
+ fwcom_cfg->specific_size = sizeof(*isys_fw_cfg);
return 0;
}
@@ -325,23 +327,23 @@ int ipu6_fw_isys_init(struct ipu6_isys *isys, unsigned int num_streams)
{
struct device *dev = &isys->adev->auxdev.dev;
int retry = IPU6_ISYS_OPEN_RETRY;
- struct ipu6_fw_com_cfg fwcom = {
+ struct ipu6_fw_com_cfg fwcom_cfg = {
.cell_start = start_sp,
.cell_ready = query_sp,
.buttress_boot_offset = SYSCOM_BUTTRESS_FW_PARAMS_ISYS_OFFSET,
};
int ret;
- ipu6_isys_fwcom_cfg_init(isys, &fwcom, num_streams);
+ ipu6_isys_fwcom_cfg_init(isys, &fwcom_cfg, num_streams);
- isys->fwcom = ipu6_fw_com_prepare(&fwcom, isys->adev,
+ isys->fwctx = ipu6_fw_com_prepare(&fwcom_cfg, isys->adev,
isys->pdata->base);
- if (!isys->fwcom) {
+ if (!isys->fwctx) {
dev_err(dev, "isys fw com prepare failed\n");
return -EIO;
}
- ret = ipu6_fw_com_open(isys->fwcom);
+ ret = ipu6_fw_com_open(isys->fwctx);
if (ret) {
dev_err(dev, "isys fw com open failed %d\n", ret);
return ret;
@@ -349,7 +351,7 @@ int ipu6_fw_isys_init(struct ipu6_isys *isys, unsigned int num_streams)
do {
usleep_range(400, 500);
- if (ipu6_fw_com_ready(isys->fwcom))
+ if (ipu6_fw_com_ready(isys->fwctx))
break;
retry--;
} while (retry > 0);
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
index 3ac48d2076da9..89eb265737d79 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
@@ -1114,7 +1114,7 @@ int ipu6_isys_fw_open(struct ipu6_isys *isys)
*/
ipu6_cleanup_fw_msg_bufs(isys);
- if (isys->fwcom) {
+ if (isys->fwctx) {
/*
* Something went wrong in previous shutdown. As we are now
* restarting isys we can safely delete old context.
@@ -1147,7 +1147,7 @@ void ipu6_isys_fw_close(struct ipu6_isys *isys)
isys->ref_count--;
if (!isys->ref_count) {
ipu6_fw_isys_close(isys);
- if (isys->fwcom) {
+ if (isys->fwctx) {
isys->need_reset = true;
dev_warn(&isys->adev->auxdev.dev,
"failed to close fw isys\n");
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys.c b/drivers/media/pci/intel/ipu6/ipu6-isys.c
index 24db2763de544..e13fbbae8c98b 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys.c
@@ -1212,10 +1212,10 @@ static int isys_isr_one(struct ipu6_bus_device *adev)
u32 index;
u64 ts;
- if (!isys->fwcom)
+ if (!isys->fwctx)
return 1;
- resp = ipu6_fw_isys_get_resp(isys->fwcom, IPU6_BASE_MSG_RECV_QUEUES);
+ resp = ipu6_fw_isys_get_resp(isys->fwctx, IPU6_BASE_MSG_RECV_QUEUES);
if (!resp)
return 1;
@@ -1324,7 +1324,7 @@ static int isys_isr_one(struct ipu6_bus_device *adev)
ipu6_isys_put_stream(stream);
leave:
- ipu6_fw_isys_put_resp(isys->fwcom, IPU6_BASE_MSG_RECV_QUEUES);
+ ipu6_fw_isys_put_resp(isys->fwctx, IPU6_BASE_MSG_RECV_QUEUES);
return 0;
}
diff --git a/drivers/media/pci/intel/ipu6/ipu6-isys.h b/drivers/media/pci/intel/ipu6/ipu6-isys.h
index 7fb8cb820912b..0b139ab244312 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys.h
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys.h
@@ -114,8 +114,7 @@ struct sensor_async_sd {
* @csi2_rx_ctrl_cached: cached shared value between all CSI2 receivers
* @streams_lock: serialise access to streams
* @streams: streams per firmware stream ID
- * @fwcom: fw communication layer private pointer
- * or optional external library private pointer
+ * @fwctx: fw communication layer context pointer
* @phy_termcal_val: the termination calibration value, only used for DWC PHY
* @need_reset: Isys requires d0i0->i3 transition
* @ref_count: total number of callers fw open
@@ -136,7 +135,7 @@ struct ipu6_isys {
spinlock_t streams_lock;
struct ipu6_isys_stream streams[IPU6_ISYS_MAX_STREAMS];
int streams_ref_count[IPU6_ISYS_MAX_STREAMS];
- void *fwcom;
+ void *fwctx;
u32 phy_termcal_val;
bool need_reset;
bool icache_prefetch;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 498/507] media: ipu6: Fix firmware config leak on stream start
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (496 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 497/507] media: ipu6: Rename pointer to firmware context Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 499/507] iommufd/iova_bitmap: Ensure that iova_bitmap_set() handles the full IOVA Greg Kroah-Hartman
` (8 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Carlier, Sakari Ailus,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Carlier <devnexen@gmail.com>
[ Upstream commit d3d9bc694fe087c672c3ad5871984dc45cd9f425 ]
ipu6_isys_fwcom_cfg_init() runs on every first stream start and allocates
the firmware config and queue configs with devm, so each STREAMON/STREAMOFF
cycle leaks them. They are only needed until ipu6_fw_com_prepare() has
copied them, so free them right after. Also check the return value, an
allocation failure would otherwise make ipu6_fw_com_prepare() dereference
a NULL queue config.
Fixes: f625e8d7ffc1 ("media: intel/ipu6: input system ABI between firmware and driver")
Cc: stable@vger.kernel.org
Signed-off-by: David Carlier <devnexen@gmail.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/pci/intel/ipu6/ipu6-fw-isys.c | 34 +++++++++++++++------
1 file changed, 24 insertions(+), 10 deletions(-)
diff --git a/drivers/media/pci/intel/ipu6/ipu6-fw-isys.c b/drivers/media/pci/intel/ipu6/ipu6-fw-isys.c
index a65e9f1aa1042..9f5bd9c4ddf91 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-fw-isys.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-fw-isys.c
@@ -218,7 +218,6 @@ static int ipu6_isys_fwcom_cfg_init(struct ipu6_isys *isys,
unsigned int max_send_queues, max_sram_blocks, max_devq_size;
struct ipu6_fw_syscom_queue_config *input_queue_cfg;
struct ipu6_fw_syscom_queue_config *output_queue_cfg;
- struct device *dev = &isys->adev->auxdev.dev;
int type_proxy = IPU6_FW_ISYS_QUEUE_TYPE_PROXY;
int type_dev = IPU6_FW_ISYS_QUEUE_TYPE_DEV;
int type_msg = IPU6_FW_ISYS_QUEUE_TYPE_MSG;
@@ -228,7 +227,6 @@ static int ipu6_isys_fwcom_cfg_init(struct ipu6_isys *isys,
struct ipu6_fw_isys_fw_config *isys_fw_cfg;
u32 num_in_message_queues;
unsigned int max_streams;
- unsigned int size;
unsigned int i;
max_streams = isys->pdata->ipdata->max_streams;
@@ -236,7 +234,7 @@ static int ipu6_isys_fwcom_cfg_init(struct ipu6_isys *isys,
max_sram_blocks = isys->pdata->ipdata->max_sram_blocks;
max_devq_size = isys->pdata->ipdata->max_devq_size;
num_in_message_queues = clamp(num_streams, 1U, max_streams);
- isys_fw_cfg = devm_kzalloc(dev, sizeof(*isys_fw_cfg), GFP_KERNEL);
+ isys_fw_cfg = kzalloc_obj(*isys_fw_cfg);
if (!isys_fw_cfg)
return -ENOMEM;
@@ -248,15 +246,14 @@ static int ipu6_isys_fwcom_cfg_init(struct ipu6_isys *isys,
isys_fw_cfg->num_recv_queues[type_dev] = 0;
isys_fw_cfg->num_recv_queues[type_msg] = 1;
- size = sizeof(*input_queue_cfg) * max_send_queues;
- input_queue_cfg = devm_kzalloc(dev, size, GFP_KERNEL);
+ input_queue_cfg = kzalloc_objs(*input_queue_cfg, max_send_queues);
if (!input_queue_cfg)
- return -ENOMEM;
+ goto err_free_fw_cfg;
- size = sizeof(*output_queue_cfg) * IPU6_N_MAX_RECV_QUEUES;
- output_queue_cfg = devm_kzalloc(dev, size, GFP_KERNEL);
+ output_queue_cfg = kzalloc_objs(*output_queue_cfg,
+ IPU6_N_MAX_RECV_QUEUES);
if (!output_queue_cfg)
- return -ENOMEM;
+ goto err_free_input_queue_cfg;
fwcom_cfg->input = input_queue_cfg;
fwcom_cfg->output = output_queue_cfg;
@@ -321,6 +318,20 @@ static int ipu6_isys_fwcom_cfg_init(struct ipu6_isys *isys,
fwcom_cfg->specific_size = sizeof(*isys_fw_cfg);
return 0;
+
+err_free_input_queue_cfg:
+ kfree(input_queue_cfg);
+err_free_fw_cfg:
+ kfree(isys_fw_cfg);
+
+ return -ENOMEM;
+}
+
+static void ipu6_isys_fwcom_cfg_free(struct ipu6_fw_com_cfg *fwcom_cfg)
+{
+ kfree(fwcom_cfg->specific_addr);
+ kfree(fwcom_cfg->output);
+ kfree(fwcom_cfg->input);
}
int ipu6_fw_isys_init(struct ipu6_isys *isys, unsigned int num_streams)
@@ -334,10 +345,13 @@ int ipu6_fw_isys_init(struct ipu6_isys *isys, unsigned int num_streams)
};
int ret;
- ipu6_isys_fwcom_cfg_init(isys, &fwcom_cfg, num_streams);
+ ret = ipu6_isys_fwcom_cfg_init(isys, &fwcom_cfg, num_streams);
+ if (ret)
+ return ret;
isys->fwctx = ipu6_fw_com_prepare(&fwcom_cfg, isys->adev,
isys->pdata->base);
+ ipu6_isys_fwcom_cfg_free(&fwcom_cfg);
if (!isys->fwctx) {
dev_err(dev, "isys fw com prepare failed\n");
return -EIO;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 499/507] iommufd/iova_bitmap: Ensure that iova_bitmap_set() handles the full IOVA
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (497 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 498/507] media: ipu6: Fix firmware config leak on stream start Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 500/507] thermal: intel: int340x: Evaluate _TMP exclusively Greg Kroah-Hartman
` (7 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andrea Parri, Jason Gunthorpe,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrea Parri <parri.andrea@gmail.com>
[ Upstream commit e21952d72b4740f08a272d694cca223b6b0099ca ]
Generally userspace is going to step the dirty bitmap through the IOVA
space. However if the bitmap ends in the middle of a large PTE this is
problematic. The first step will clear the dirty bit and report dirty to
the end of its bitmap while the second step will see the clear'd dirty and
report clean for the start of the bitmap. If it happens this ends up
losing dirties.
Further this function is missing bounds checking so if this does happen
ther is a good chance it will write memory beyond what the userspace was
expecting.
Return an error code if this illegal condition happens.
Fixes: 58ccf0190d19 ("vfio: Add an IOVA bitmap support")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
Link: https://patch.msgid.link/20260925161142.189813-2-parri.andrea@gmail.com
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
[ sashal: Added missing prerequisite error storage and propagation from the bitmap through the iterator to the ioctl. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iommu/iommufd/io_pagetable.c | 2 +-
drivers/iommu/iommufd/iova_bitmap.c | 19 ++++++++++++++++++-
include/uapi/linux/iommufd.h | 6 ++++++
3 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/iommufd/io_pagetable.c b/drivers/iommu/iommufd/io_pagetable.c
index 283ab372e8da8..5ac736cf5bb5a 100644
--- a/drivers/iommu/iommufd/io_pagetable.c
+++ b/drivers/iommu/iommufd/io_pagetable.c
@@ -589,7 +589,7 @@ iommu_read_and_clear_dirty(struct iommu_domain *domain,
arg.iopt = iopt;
arg.domain = domain;
arg.dirty = &dirty;
- iova_bitmap_for_each(iter, &arg, __iommu_read_and_clear_dirty);
+ ret = iova_bitmap_for_each(iter, &arg, __iommu_read_and_clear_dirty);
if (!(flags & IOMMU_DIRTY_NO_CLEAR))
iommu_iotlb_sync(domain, &gather);
diff --git a/drivers/iommu/iommufd/iova_bitmap.c b/drivers/iommu/iommufd/iova_bitmap.c
index dac3e657d498d..908c70f5362e0 100644
--- a/drivers/iommu/iommufd/iova_bitmap.c
+++ b/drivers/iommu/iommufd/iova_bitmap.c
@@ -116,6 +116,9 @@ struct iova_bitmap {
/* length of the IOVA range for the whole bitmap */
size_t length;
+
+ /* first error from recording an IOVA range */
+ int err;
};
/*
@@ -384,7 +387,9 @@ static int iova_bitmap_advance_to(struct iova_bitmap *bitmap,
int iova_bitmap_for_each(struct iova_bitmap *bitmap, void *opaque,
iova_bitmap_fn_t fn)
{
- return fn(bitmap, bitmap->iova, bitmap->length, opaque);
+ int ret = fn(bitmap, bitmap->iova, bitmap->length, opaque);
+
+ return ret ? ret : bitmap->err;
}
EXPORT_SYMBOL_NS_GPL(iova_bitmap_for_each, "IOMMUFD");
@@ -404,6 +409,18 @@ void iova_bitmap_set(struct iova_bitmap *bitmap,
struct iova_bitmap_map *mapped = &bitmap->mapped;
unsigned long cur_bit, last_bit, last_page_idx;
+ /*
+ * If the range cannot be recorded then the system call returns failure.
+ * This is to prevent loosing dirties if userspace is expecting to step
+ * the bitmap through the IOVA space.
+ */
+ if (!length || length > bitmap->length || iova < bitmap->iova ||
+ iova - bitmap->iova > bitmap->length - length) {
+ if (!bitmap->err)
+ bitmap->err = -EPROTO;
+ return;
+ }
+
update_indexes:
if (unlikely(!iova_bitmap_mapped_range(mapped, iova, length))) {
/*
diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
index 5d47d1421c1fc..63a86354e822f 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -871,6 +871,12 @@ enum iommufd_hwpt_get_dirty_bitmap_flags {
* Walk the IOMMU pagetables for a given IOVA range to return a bitmap
* with the dirty IOVAs. In doing so it will also by default clear any
* dirty bit metadata set in the IOPTE.
+ *
+ * The IOVA range given must fully enclose any IOPTE. If the range starts or
+ * ends inside a dirty IOPTE then the ioctl will fail. This avoids partially
+ * reporting a dirty range.
+ *
+ * On failure the dirty state becomes unknown and the userspace must restart.
*/
struct iommu_hwpt_get_dirty_bitmap {
__u32 size;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 500/507] thermal: intel: int340x: Evaluate _TMP exclusively
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (498 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 499/507] iommufd/iova_bitmap: Ensure that iova_bitmap_set() handles the full IOVA Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 501/507] intel_idle: Use 2-argument strscpy() Greg Kroah-Hartman
` (6 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Charis Stratakis,
Ali Ahmet Memiş, Hans de Goede, Rong Zhang,
Rafael J. Wysocki, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ali Ahmet Memiş <aliamemis@disroot.org>
[ Upstream commit c4aae727beb23a736c15b8d53e219da29d791065 ]
On ThinkPad P1 Gen2 and P53, INT3403 _TMP switches the EC page selector
without taking the mutex the battery methods use, so it must not run
interleaved with them.
Evaluate _TMP with acpi_evaluate_integer_exclusive(), also where int3403
and processor_thermal probe for it.
Fixes: d33e89d12295 ("thermal: core: Suspend thermal zones later and resume them earlier")
Reported-by: Charis Stratakis <c.stratakis@proton.me>
Closes: https://lore.kernel.org/all/37N_jFulf7n-Z55NfKfE71C_wVPxYvZ0xD_iRUg2fXu7TypDiF5PStQ6siSfVBih6fThg5WoPes8U5ZQpfVm_teMFcUGXFxz2DdMbfSWuws=@proton.me/
Cc: All applicable <stable@vger.kernel.org> # 80892972ff23 ACPI: utils: Add exclusive AML evaluation helpers
Signed-off-by: Ali Ahmet Memiş <aliamemis@disroot.org>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Reviewed-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20261018122220.678822-4-aliamemis@disroot.org
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/thermal/intel/int340x_thermal/int3403_thermal.c | 3 +--
.../thermal/intel/int340x_thermal/int340x_thermal_zone.c | 6 +++++-
.../intel/int340x_thermal/processor_thermal_device.c | 2 +-
3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/thermal/intel/int340x_thermal/int3403_thermal.c b/drivers/thermal/intel/int340x_thermal/int3403_thermal.c
index 264c9bc8e6454..2262de1e14d95 100644
--- a/drivers/thermal/intel/int340x_thermal/int3403_thermal.c
+++ b/drivers/thermal/intel/int340x_thermal/int3403_thermal.c
@@ -217,8 +217,7 @@ static int int3403_add(struct platform_device *pdev)
}
- status = acpi_evaluate_integer(priv->adev->handle, "_TMP",
- NULL, &tmp);
+ status = acpi_evaluate_integer_exclusive(priv->adev->handle, "_TMP", NULL, &tmp);
if (ACPI_FAILURE(status)) {
status = acpi_evaluate_integer(priv->adev->handle, "PTYP",
NULL, &priv->type);
diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c
index 965700ee69626..9451fea1f65c7 100644
--- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c
+++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c
@@ -18,7 +18,11 @@ static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone,
unsigned long long tmp;
acpi_status status;
- status = acpi_evaluate_integer(d->adev->handle, "_TMP", NULL, &tmp);
+ /*
+ * On some ThinkPads _TMP switches the EC page selector without
+ * taking the mutex the battery methods use.
+ */
+ status = acpi_evaluate_integer_exclusive(d->adev->handle, "_TMP", NULL, &tmp);
if (ACPI_FAILURE(status))
return -EIO;
diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
index b0284c2e2e74d..9bdb65f54b6ae 100644
--- a/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
+++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
@@ -287,7 +287,7 @@ int proc_thermal_add(struct device *dev, struct proc_thermal_device *proc_priv)
if (ret)
return ret;
- status = acpi_evaluate_integer(adev->handle, "_TMP", NULL, &tmp);
+ status = acpi_evaluate_integer_exclusive(adev->handle, "_TMP", NULL, &tmp);
if (ACPI_FAILURE(status)) {
/* there is no _TMP method, add local method */
if (intel_tcc_get_tjmax(-1) > 0)
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 501/507] intel_idle: Use 2-argument strscpy()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (499 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 500/507] thermal: intel: int340x: Evaluate _TMP exclusively Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 502/507] intel_idle: Adjust state names and descriptions for _LPI states Greg Kroah-Hartman
` (5 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andy Shevchenko, Rafael J. Wysocki,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <andy.shevchenko@gmail.com>
[ Upstream commit 2094ae12eed8e83dd91a631ac0a582fee5934c36 ]
Use 2-argument strscpy(), which is not only shorter but also provides
an additional check that destination buffer is an array.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/20260813082624.2650581-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Stable-dep-of: 403524796685 ("intel_idle: Adjust state names and descriptions for _LPI states")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/idle/intel_idle.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 651408df9c24a..c5b65f7d7271c 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -1906,7 +1906,7 @@ static void __init intel_idle_init_cstates_acpi_lpi(struct cpuidle_driver *drv)
state = &drv->states[drv->state_count++];
scnprintf(state->name, CPUIDLE_NAME_LEN, "C%d_LPI", index + 1);
- strscpy(state->desc, lpi_state->desc, CPUIDLE_DESC_LEN);
+ strscpy(state->desc, lpi_state->desc);
state->exit_latency = lpi_state->wake_latency;
state->target_residency = lpi_state->min_residency;
state->flags = MWAIT2flg(lpi_state->address);
@@ -1956,7 +1956,7 @@ static void __init intel_idle_init_cstates_acpi_cst(struct cpuidle_driver *drv)
state = &drv->states[drv->state_count++];
snprintf(state->name, CPUIDLE_NAME_LEN, "C%d_ACPI", cstate);
- strscpy(state->desc, cx->desc, CPUIDLE_DESC_LEN);
+ strscpy(state->desc, cx->desc);
state->exit_latency = cx->latency;
/*
* For C1-type C-states use the same number for both the exit
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 502/507] intel_idle: Adjust state names and descriptions for _LPI states
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (500 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 501/507] intel_idle: Use 2-argument strscpy() Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 503/507] f2fs: expose resizable_tail feature via sysfs Greg Kroah-Hartman
` (4 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Len Brown, Rafael J. Wysocki,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
[ Upstream commit 4035247966859152a6523bc041f81cb9905695a5 ]
The value of the _LPI "State Name" field is used as the description of
the given idle state (that is, the value of its "desc" attribute in
sysfs) which is not consistent with idle state descriptions used when
the idle state information comes from an ACPI _CST object.
To rectify that, use the _LPI "State Name" field value as the value of
the "name" sysfs attribute of a given idle state and use the MWAIT hint
value from the _LPI register address value to derive the value of its
"desc" sysfs attribute in analogy with the _CST case.
Fixes: abc5c103c66d ("intel_idle: Add ACPI _LPI support")
Tested-by: Len Brown <len.brown@intel.com>
Cc: 7.3+ <stable@vger.kernel.org> # 7.3+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
[ rjw: Adjusted scnprintf() format string, tweaked changelog ]
Link: https://patch.msgid.link/6061409.DvuYhMxLoT@rafael.j.wysocki
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/admin-guide/pm/intel_idle.rst | 12 +++++++-----
drivers/idle/intel_idle.c | 9 +++++++--
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/Documentation/admin-guide/pm/intel_idle.rst b/Documentation/admin-guide/pm/intel_idle.rst
index 996e5bd83c425..d1a6251790b80 100644
--- a/Documentation/admin-guide/pm/intel_idle.rst
+++ b/Documentation/admin-guide/pm/intel_idle.rst
@@ -145,11 +145,13 @@ for the other idle state types (C2 and C3) the target residency value is 3 times
the exit latency (again, that is because it reflects the target residency to
exit latency ratio in the majority of cases for the processor models recognized
by ``intel_idle``). The name of the idle state (to be returned by the ``name``
-idle state attribute in ``sysfs``) is either "Cx_LPI" (if it comes from ``_LPI``
-processing) or "Cx_ACPI", where x is the index of that idle state in the final
-list (note that the minimum value of x is 1, because 0 is reserved for the
-"polling" state), and its target residency is based on the exit latency value.
-All of the idle states in the final list are enabled by default in this case.
+idle state attribute in ``sysfs``) either is equal to the state name value that
+comes from ``_LPI`` processing (with the possible fallback to "Cx_LPI" if the
+state name is not provided) or it is "Cx_ACPI", where x is the index of that
+idle state in the final list (note that the minimum value of x is 1, because 0
+is reserved for the "polling" state), and its target residency is based on the
+exit latency value. All of the idle states in the final list are enabled by
+default in this case.
.. _intel-idle-initialization:
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index c5b65f7d7271c..ec951c148d4a2 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -1905,8 +1905,13 @@ static void __init intel_idle_init_cstates_acpi_lpi(struct cpuidle_driver *drv)
state = &drv->states[drv->state_count++];
- scnprintf(state->name, CPUIDLE_NAME_LEN, "C%d_LPI", index + 1);
- strscpy(state->desc, lpi_state->desc);
+ if (strlen(lpi_state->desc) > 0)
+ strscpy(state->name, lpi_state->desc);
+ else
+ scnprintf(state->name, CPUIDLE_NAME_LEN, "C%d_LPI", index + 1);
+
+ scnprintf(state->desc, CPUIDLE_DESC_LEN, "ACPI LPI MWAIT 0x%02llx",
+ lpi_state->address);
state->exit_latency = lpi_state->wake_latency;
state->target_residency = lpi_state->min_residency;
state->flags = MWAIT2flg(lpi_state->address);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 503/507] f2fs: expose resizable_tail feature via sysfs
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (501 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 502/507] intel_idle: Adjust state names and descriptions for _LPI states Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 504/507] mm/mglru: use explicit tier range in read_ctrl_pos() Greg Kroah-Hartman
` (3 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daeho Jeong, Chao Yu, Jaegeuk Kim,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daeho Jeong <daehojeong@google.com>
[ Upstream commit 714f97f477fe2834ac9e9e66979ae52824b9f914 ]
Userspace has no way to know whether the kernel supports the
resizable_tail_secno mount option before mounting. Passing it to a
kernel without the support fails the mount with -EINVAL, and checking
/sys/fs/f2fs/<disk>/pinned_area_max_secno requires an f2fs instance
to be mounted already.
Export /sys/fs/f2fs/features/resizable_tail so that userspace can check
the support before formatting or mounting a filesystem that relies on
resizable_tail_secno, e.g. a filesystem whose tail is going to be shrunk
online later.
Cc: stable@vger.kernel.org
Fixes: c966d29e01bb ("f2fs: support resizable tail section and unify pinned allocation")
Signed-off-by: Daeho Jeong <daehojeong@google.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ sashal: Placed resizable_tail entries after fserror because metadata_cache is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/ABI/testing/sysfs-fs-f2fs | 2 +-
fs/f2fs/sysfs.c | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index 0cebc89799dd1..4f3915948176f 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -271,7 +271,7 @@ Description: Shows all enabled kernel features.
inode_crtime, lost_found, verity, sb_checksum,
casefold, readonly, compression, test_dummy_encryption_v2,
atomic_write, pin_file, encrypted_casefold, linear_lookup,
- fserror.
+ fserror, resizable_tail.
What: /sys/fs/f2fs/<disk>/inject_rate
Date: May 2016
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 811e350a14302..5ee12547171cc 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -1404,6 +1404,7 @@ F2FS_FEATURE_RO_ATTR(linear_lookup);
#endif
F2FS_FEATURE_RO_ATTR(packed_ssa);
F2FS_FEATURE_RO_ATTR(fserror);
+F2FS_FEATURE_RO_ATTR(resizable_tail);
#define ATTR_LIST(name) (&f2fs_attr_##name.attr)
static struct attribute *f2fs_attrs[] = {
@@ -1574,6 +1575,7 @@ static struct attribute *f2fs_feat_attrs[] = {
#endif
BASE_ATTR_LIST(packed_ssa),
BASE_ATTR_LIST(fserror),
+ BASE_ATTR_LIST(resizable_tail),
NULL,
};
ATTRIBUTE_GROUPS(f2fs_feat);
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 504/507] mm/mglru: use explicit tier range in read_ctrl_pos()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (502 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 503/507] f2fs: expose resizable_tail feature via sysfs Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 505/507] mm/vmscan: avoid false-positive -Wuninitialized warning, again Greg Kroah-Hartman
` (2 subsequent siblings)
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kairui Song, Andrew Morton,
Baolin Wang, Baoquan He, Barry Song, Ridong Chen, Axel Rasmussen,
Chris Li, David Hildenbrand (Arm), Johannes Weiner, Kairui Song,
Liam R. Howlett, Lian Wang, Lorenzo Stoakes, Michal Hocko,
Muchun Song, Qi Zheng, Roman Gushchin, Shakeel Butt,
Vlastimil Babka, Wei Xu, Yuanchu Xie, Yu Zhao, Zi Yan,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kairui Song <kasong@tencent.com>
[ Upstream commit c1d0e799321c817a22eab2abf2485250cffad7b4 ]
read_ctrl_pos() encodes the tier range in a single "tier" parameter via
"tier % MAX_NR_TIERS" as the start and "min(tier, MAX_NR_TIERS-1)" as the
end. This is hard to follow, maintain, or extend. Tier values 0..3
select a single tier, while tier == MAX_NR_TIERS selects the full range.
Replace it with explicit (tier_min, tier_max) parameters using a closed
[tier_min, tier_max] interval, and add LRU_TIER_MIN and LRU_TIER_MAX for
the tier bounds. The call sites now become self-documenting:
- get_tier_idx: (LRU_TIER_MIN, LRU_TIER_MIN) for the first tier,
(tier, tier) for each subsequent tier
- get_type_to_scan: (LRU_TIER_MIN, LRU_TIER_MAX) for the full range
No functional change.
Link: https://lore.kernel.org/20260906-mglru-flags-cleanup-v6-5-9aacbd77d4ca@tencent.com
Signed-off-by: Kairui Song <kasong@tencent.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Reviewed-by: Baoquan He <baoquan.he@linux.dev>
Reviewed-by: Barry Song <baohua@kernel.org>
Reviewed-by: Ridong Chen <ridong.chen@linux.dev>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Chris Li <chrisl@kernel.org>
Cc: David Hildenbrand (Arm) <david@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Kairui Song <ryncsn@gmail.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lian Wang <lianux.mm@gmail.com>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Qi Zheng <qi.zheng@linux.dev>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Wei Xu <weixugc@google.com>
Cc: Yuanchu Xie <yuanchu@google.com>
Cc: Yu Zhao <yuzhao@google.com>
Cc: Zi Yan <ziy@nvidia.com>
Stable-dep-of: ca6e32f3f424 ("mm/vmscan: avoid false-positive -Wuninitialized warning, again")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/mmzone.h | 2 ++
mm/vmscan.c | 18 ++++++++++--------
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 94f9c3ff54160..da8dd04fb462a 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -492,6 +492,8 @@ enum lruvec_flags {
* folio->flags, masked by LRU_REFS_MASK.
*/
#define MAX_NR_TIERS 4U
+#define LRU_TIER_MIN 0U
+#define LRU_TIER_MAX (MAX_NR_TIERS - 1)
#ifndef __GENERATING_BOUNDS_H
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 963cdd67039d1..8ec8fdede5dd8 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3194,8 +3194,8 @@ struct ctrl_pos {
int gain;
};
-static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier, int gain,
- struct ctrl_pos *pos)
+static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier_min,
+ int tier_max, int gain, struct ctrl_pos *pos)
{
int i;
struct lru_gen_folio *lrugen = &lruvec->lrugen;
@@ -3204,7 +3204,7 @@ static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier, int gain,
pos->gain = gain;
pos->refaulted = pos->total = 0;
- for (i = tier % MAX_NR_TIERS; i <= min(tier, MAX_NR_TIERS - 1); i++) {
+ for (i = tier_min; i <= tier_max; i++) {
pos->refaulted += lrugen->avg_refaulted[type][i] +
atomic_long_read(&lrugen->refaulted[hist][type][i]);
pos->total += lrugen->avg_total[type][i] +
@@ -4808,9 +4808,9 @@ static int get_tier_idx(struct lruvec *lruvec, int type)
* This value is chosen because any other tier would have at least twice
* as many refaults as the first tier.
*/
- read_ctrl_pos(lruvec, type, 0, 2, &sp);
- for (tier = 1; tier < MAX_NR_TIERS; tier++) {
- read_ctrl_pos(lruvec, type, tier, 3, &pv);
+ read_ctrl_pos(lruvec, type, LRU_TIER_MIN, LRU_TIER_MIN, 2, &sp);
+ for (tier = LRU_TIER_MIN + 1; tier <= LRU_TIER_MAX; tier++) {
+ read_ctrl_pos(lruvec, type, tier, tier, 3, &pv);
if (!positive_ctrl_err(&sp, &pv))
break;
}
@@ -4831,8 +4831,10 @@ static int get_type_to_scan(struct lruvec *lruvec, int swappiness)
* Compare the sum of all tiers of anon with that of file to determine
* which type to scan.
*/
- read_ctrl_pos(lruvec, LRU_GEN_ANON, MAX_NR_TIERS, swappiness, &sp);
- read_ctrl_pos(lruvec, LRU_GEN_FILE, MAX_NR_TIERS, MAX_SWAPPINESS - swappiness, &pv);
+ read_ctrl_pos(lruvec, LRU_GEN_ANON, LRU_TIER_MIN, LRU_TIER_MAX,
+ swappiness, &sp);
+ read_ctrl_pos(lruvec, LRU_GEN_FILE, LRU_TIER_MIN, LRU_TIER_MAX,
+ MAX_SWAPPINESS - swappiness, &pv);
return positive_ctrl_err(&sp, &pv);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 505/507] mm/vmscan: avoid false-positive -Wuninitialized warning, again
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (503 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 504/507] mm/mglru: use explicit tier range in read_ctrl_pos() Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 506/507] f2fs: fix to use bio_in_atomic() in f2fs_write_end_io() Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 507/507] ASoC: amd: yc: Add DMI quirk for HP OmniBook 3 Laptop 16-by0xxx Greg Kroah-Hartman
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Arnd Bergmann, Andrew Morton,
Axel Rasmussen, Baolin Wang, Baoquan He, Barry Song,
David Hildenbrand, Johannes Weiner, Kairui Song, Lorenzo Stoakes,
Michal Hocko, Shakeel Butt, Wei Xu, Yuanchu Xie, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <arnd@arndb.de>
[ Upstream commit ca6e32f3f4240d0335775a11afc21e0451dd8d8f ]
I previously worked around a false-postive gcc-16 warning in the
get_tier_idx() function, by adding a fake initializer. This happens with
the -fsanitize=bounds sanitizer when the compiler creates a specialized
variant of isolate_folios():
In function 'get_tier_idx',
inlined from 'isolate_folios.constprop' at mm/vmscan.c:4982:9:
mm/vmscan.c:4934:9: error: 'sp.refaulted' is used uninitialized [-Werror=uninitialized]
4934 | read_ctrl_pos(lruvec, type, LRU_TIER_MIN, LRU_TIER_MIN, 2, &sp);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mm/vmscan.c: In function 'isolate_folios.constprop':
mm/vmscan.c:4946:25: note: 'sp.refaulted' was declared here
4946 | struct ctrl_pos sp, pv = {};
| ^~
Adding another "= {}" would solve the problem as well, but to prevent
this from happening again after the next code refactoring, try instead to
prevent this by forbidding interprocedural optimizations on this function.
Link: https://lore.kernel.org/all/20260213123902.3466040-1-arnd@kernel.org/
Link: https://lore.kernel.org/20260916083456.4136132-1-arnd@kernel.org
Fixes: 3de705a43a46 ("mm/vmscan: avoid false-positive -Wuninitialized warning")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Barry Song <baohua@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Kairui Song <kasong@tencent.com>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Wei Xu <weixugc@google.com>
Cc: Yuanchu Xie <yuanchu@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/vmscan.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 8ec8fdede5dd8..88fd31d135853 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3194,8 +3194,11 @@ struct ctrl_pos {
int gain;
};
-static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier_min,
- int tier_max, int gain, struct ctrl_pos *pos)
+/*
+ * __noipa works around gcc-16 warning for uninitialized use of pos->refaulted
+ */
+static void __noipa read_ctrl_pos(struct lruvec *lruvec, int type, int tier_min,
+ int tier_max, int gain, struct ctrl_pos *pos)
{
int i;
struct lru_gen_folio *lrugen = &lruvec->lrugen;
@@ -4801,7 +4804,7 @@ static int scan_folios(unsigned long nr_to_scan, struct lruvec *lruvec,
static int get_tier_idx(struct lruvec *lruvec, int type)
{
int tier;
- struct ctrl_pos sp, pv = {};
+ struct ctrl_pos sp, pv;
/*
* To leave a margin for fluctuations, use a larger gain factor (2:3).
@@ -4820,7 +4823,7 @@ static int get_tier_idx(struct lruvec *lruvec, int type)
static int get_type_to_scan(struct lruvec *lruvec, int swappiness)
{
- struct ctrl_pos sp, pv = {};
+ struct ctrl_pos sp, pv;
if (swappiness <= MIN_SWAPPINESS + 1)
return LRU_GEN_FILE;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 506/507] f2fs: fix to use bio_in_atomic() in f2fs_write_end_io()
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (504 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 505/507] mm/vmscan: avoid false-positive -Wuninitialized warning, again Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 507/507] ASoC: amd: yc: Add DMI quirk for HP OmniBook 3 Laptop 16-by0xxx Greg Kroah-Hartman
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Chao Yu, Jaegeuk Kim,
Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit e4582e5f3b439228d4e900edcf8225aa89be32b4 ]
f2fs_write_end_io() uses in_atomic() to decide whether a write bio which
exceeds max_atc_write_bio_size or max_atc_write_bio_entry_cnt should be
completed in sbi->wq rather than in the current context.
However, in_atomic() is not meant to be used outside core kernel code
(checkpatch.pl warns about it), as it only looks at preempt_count(): it
misses irqs-disabled and RCU read-side critical sections, and on kernels
without CONFIG_PREEMPT_COUNT it cannot see spinlock-held sections at all.
In those contexts, a large write bio will still be completed inline,
which defeats the purpose of the above knobs.
The block layer provides bio_in_atomic() for exactly this purpose, it
checks rcu_preempt_depth() and preemptible(), and conservatively returns
true if CONFIG_PREEMPT_COUNT is disabled, let's use it instead. The
difference is as below:
Context | in_atomic() | bio_in_atomic()
-------------------------------------+----------------+----------------
Hard IRQ / softirq | true | true
IRQs disabled, preempt count 0 | false (missed) | true
RCU read lock (CONFIG_PREEMPTION) | false (missed) | true
Kernel w/o CONFIG_PREEMPT_COUNT | IRQ ctx only | always true
Note that on kernels without CONFIG_PREEMPT_COUNT, write bios exceeding
the thresholds will always be offloaded to sbi->wq, since there is no way
to tell whether the current context is atomic. The thresholds default to
UINT_MAX, so the default behavior is not changed.
Cc: stable@kernel.org
Fixes: 3de6b8094115 ("f2fs: Run f2fs_write_end_io() asynchronously")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ sashal: Retained the bio-size check without the entry-count condition because the required fields are absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/data.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index cc601b65163be..e0abc159b796c 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -400,7 +400,8 @@ static void f2fs_write_end_io(struct bio *bio)
sbi = bio->bi_private;
- if (in_atomic() && bio->bi_iter.bi_size > sbi->max_atc_write_bio_size) {
+ if (bio_in_atomic() &&
+ bio->bi_iter.bi_size > sbi->max_atc_write_bio_size) {
struct work_struct *w;
w = &container_of(bio, struct f2fs_bio, bio)->work;
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
* [PATCH 7.3 507/507] ASoC: amd: yc: Add DMI quirk for HP OmniBook 3 Laptop 16-by0xxx
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
` (505 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 7.3 506/507] f2fs: fix to use bio_in_atomic() in f2fs_write_end_io() Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
506 siblings, 0 replies; 508+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gianluca Balboni, Vijendar Mukunda,
Mark Brown, Sasha Levin
7.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gianluca Balboni <gianluca.balboni06@gmail.com>
[ Upstream commit 1e73257dff33ff851af60d5bb00d73893a8b6dc8 ]
The HP OmniBook 3 Laptop 16-by0xxx (board ID 8EE3) has an internal DMIC
connected to the AMD ACP6x audio coprocessor. The BIOS does not set the
AcpDmicConnected _DSD property or the _WOV method, and the board is missing
from yc_acp_quirk_table[], so acp6x_probe() returns -ENODEV and no DMIC
capture device is registered.
Add a DMI quirk entry for this model to enable ACP DMIC support.
Cc: stable@vger.kernel.org
Signed-off-by: Gianluca Balboni <gianluca.balboni06@gmail.com>
Reviewed-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Link: https://patch.msgid.link/20261031102136.24600-1-gianluca.balboni06@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
[ sashal: Adjusted DMI table insertion context to place the unchanged entry after 8BD6 because the upstream 8DC2 entry is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/amd/yc/acp6x-mach.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c
index 1be8504571ad3..96b0bfeddc061 100644
--- a/sound/soc/amd/yc/acp6x-mach.c
+++ b/sound/soc/amd/yc/acp6x-mach.c
@@ -745,6 +745,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "8BD6"),
}
},
+ {
+ .driver_data = &acp6x_card,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+ DMI_MATCH(DMI_BOARD_NAME, "8EE3"),
+ }
+ },
{
.driver_data = &acp6x_card,
.matches = {
--
2.53.0
^ permalink raw reply related [flat|nested] 508+ messages in thread
end of thread, other threads:[~2026-11-13 16:06 UTC | newest]
Thread overview: 508+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-13 15:45 [PATCH 7.3 000/507] 7.3.5-rc1 review Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 001/507] cxl/features: Ensure that count is set before access to ent[] __counted_by() Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 002/507] Bluetooth: L2CAP: Reject signalling responses in invalid states Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 003/507] Bluetooth: L2CAP: Only accept connection responses to outstanding requests Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 004/507] Bluetooth: L2CAP: Ignore connection responses with wrong ident Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 005/507] smb/server: prevent file publication after tree disconnect Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 006/507] xfs: break out xattr entry checks into separate functions Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 007/507] xfs: check for buffer overruns when examining local/remote xattr entries Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 008/507] xfs: refactor directory data block walking loops in scrub Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 009/507] xfs: improve dirent bounds checking in scrub and repair Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 010/507] NFSD: Replace nfsd_write()s "stable" argument with "iocb_flags" Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 011/507] NFSD: Move version-specific ACCESS maps into per-version code Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 012/507] NFSD: map fh_verify() status codes for NFS_ACLv2 replies Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 013/507] NFSD: report listener creation failures through extack Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 014/507] SUNRPC: report local rpcbind calls that get no answer Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 015/507] NFSD: stop registering with rpcbind after a failure in listener_set Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 016/507] NFSD: Send a meaningful CB_RECALL_ANY keep count Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 017/507] NFSD: Move the cld upcall message out of the callers stack frame Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 018/507] NFSD: Complete a cld upcall when the daemon closes the pipe Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 019/507] NFSD: Complete a cld upcall when copying its reply fails Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 020/507] ksmbd: look up stream size by exact xattr name Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 021/507] wifi: brcmfmac: cfg80211: Report port_authorized for 4-way HS offload Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 022/507] io_uring/cancel: drop sqd->lock while SQPOLL waits Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 023/507] io_uring/sqpoll: dont attach to a thread that is canceling Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 024/507] io_uring/sqpoll: dont set IO_SQ_THREAD_SHOULD_STOP on thread exit Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 025/507] io_uring/sqpoll: do the return-to-userspace work in the SQPOLL thread Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 026/507] io_uring/cancel: count all requests that a CANCEL_ALL cancels Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 027/507] io_uring/poll: cancel all matching requests in one pass Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 028/507] io_uring/poll: dont poll a writer for a read side hangup Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 029/507] io_uring/poll: dont poll a writer for urgent data Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 030/507] io_uring/rsrc: hold uring_lock across index-alloc put_user Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 031/507] mm/damon/core: remove unreachable damos charge_{target,addr}_from Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 032/507] block: restore the iterator when rejecting a misaligned bio Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 033/507] wifi: rtw88: TX report with long timeout for non-PCIE devices Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 034/507] ACPI: CPPC: Validate FFH register fields before hardware access Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 035/507] ACPI: CPPC: Accept requests to retain immutable autonomous selection Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 036/507] xfs: reinitialize dquot block if non-first dquot cant load Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 037/507] xfs: forcibly reset quota timers when upgrading to bigtime during repair Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 038/507] nfsd: shorten extack string returned with dodgy listener Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 039/507] cpufreq: CPPC: Select the frequency-invariance callback per CPU Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 040/507] media: uvcvideo: Add autosuspend quirk for AVerMedia Live Gamer HD 2 Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 041/507] media: uvcvideo: Force UVC version for Avermedia GC515 Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 042/507] mm/damon/sysfs-schemes: read sysfs_filter->sz_range only once Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 043/507] 9p: fix privport option setting wrong RDMA field Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 044/507] net/9p/usbg: fix prefix matching in device lookup Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 045/507] xfrm: retry inexact policy lookup after node reinsertion Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 046/507] net/9p/usbg: clear stale request context after abort Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 047/507] 9p/trans_virtio: reject mount tags longer than NAME_MAX at probe Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 048/507] 9p/xen: fix refcount leak in p9_xen_response() on wrong tag Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 049/507] 9p: fix caches_show() out-of-bounds write Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 050/507] net/9p/usbg: Fix use-after-free in disable_usb9pfs() Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 051/507] net/9p/usbg: also disable endpoints on p9_usbg_close Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 052/507] net/9p/usbg: set client to Disconnected on usb9pfs_disable Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 053/507] net/9p/usbg: always reset completion when disconnecting Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 054/507] net/9p/usbg: call disable_usb9pfs() from usb9pfs_disable() Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 7.3 055/507] net/9p/usbg: fix out_req buffer leak in disable_usb9pfs Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 056/507] net/9p/usbg: remove bogus context initialization in alloc_requests Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 057/507] net/9p/usbg: clear stale client pointer on close Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 058/507] xfrm: interface: validate the IP header on xmit Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 059/507] xfrm: espintcp: reorder operations within espintcp_init_sk Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 060/507] drm/panic: Fix kmsg screen hang on a long log line Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 061/507] drm/drm_crtc: ensure dma_fence_ops remain valid during device unbind Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 062/507] drm/drm_crtc: fix race with dma_fence_signal() in ::get_driver_name() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 063/507] dma-buf: Fix IOVA offset when linking phys vecs to sgt Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 064/507] wifi: mac80211: reload TDLS header pointer after skb_linearize() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 065/507] wifi: brcmfmac: map msgbuf RX packet IDs bidirectional Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 066/507] wifi: rsi: Skip TX aggregation setup for non-QoS frames Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 067/507] wifi: cfg80211: fix out-of-bounds read in valid_rule() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 068/507] drm/vc4: Publish the output fence outside of job_lock Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 069/507] drm/vc4: Drop the BO reservations " Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 070/507] lib/crypto: mips: Disable Octeon SHA code on little-endian kernels Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 071/507] wifi: mac80211: reinstate IEEE80211_TX_CTL_AMPDU flag in ieee80211_tx_prep_agg() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 072/507] xfrm4: use a full socket for local errors Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 073/507] scsi: aic7xxx: Use default settings on the SGI O2 onboard controllers Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 074/507] scsi: aic79xx: Fix NULL pointer dereference in device reset Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 075/507] scsi: target: Fix demo-mode dynamic ACL dev-entry UAF vs LUN teardown Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 076/507] 9p/xen: validate the response size from the backend Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 077/507] 9p: dont decrement a server-owned zero nlink Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 078/507] batman-adv: Close OGM aggregation before transmission Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 079/507] lib/crypto: mldsa: Check pk_len before doing pointer arithmetic Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 080/507] lib/crypto: mldsa: Explicitly check that alg is a valid value Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 081/507] lib/crypto: mldsa: Add __must_check to mldsa_verify() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 082/507] batman-adv: mcast: validate tracker padding before forwarding Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 083/507] batman-adv: tpmeter: fix u32 truncation of reported bytes Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 084/507] batman-adv: dat: initialize orig_node of unfilled candidate slots Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 085/507] batman-adv: fix skb leak when hard_iface is being released Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 086/507] batman-adv: stop originator purge worker before freeing TT Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 087/507] batman-adv: tt: ignore ROAM flag of received ADD changes Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 088/507] batman-adv: tt: dont drop local events queued during TVLV update Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 089/507] net: jme: keep RX MAC clock enabled for WoL Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 090/507] ipv6: raw: fix use-after-free in rawv6_send_hdrinc() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 091/507] drm/vc4: hdmi: power down the BCM2712 PHY when the output is disabled Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 092/507] drm/vc4: hdmi: always cancel the scrambling work synchronously Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 093/507] drm/vc4: hdmi: enable scrambling before the TMDS clock starts Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 094/507] sctp: account for chunk padding in sctp_init_cause() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 095/507] btrfs: fix chattr failing on nodatasum files that have the compress flag Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 096/507] btrfs: sysfs: restore NOFS context on early return in btrfs_sysfs_add_block_group_type() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 097/507] btrfs: prevent deleting the wrong subvolume by ID Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 098/507] ptp: fix use-after-free in extts_fifo_show() reading tsevqs unlocked Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 099/507] scsi: bsg: Report synchronous data copyback failures Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 100/507] scsi: bsg: Report io_uring " Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 101/507] scsi: target: Verify the iSCSI ISID is null-terminated Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 102/507] scsi: target: tcmu: Fix divide-by-zero in data_pages_per_blk store Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 103/507] drm/loongson: Fix framebuffer selection in async cursor updates Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 104/507] drm/loongson: Fix double free on BO initialization failure Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 105/507] drm/loongson: Handle buffer mapping failures when clearing a BO Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 106/507] ALSA: us122l: Add missing NULL check in usb_stream_hwdep_mmap() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 107/507] ALSA: us122l: Fix NULL dereference at hwdep open and release Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 108/507] ALSA: usx2y: Initialize idle URBs before submitting streams Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 109/507] ALSA: hwdep: Serialize DSP load requests Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 110/507] bpf: Fix skb_pull() BUG in __bpf_redirect_neigh() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 111/507] ksmbd: require DELETE access for delete-on-close opens Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 112/507] ksmbd: enforce the read-only share flag when creating a stream Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 113/507] ksmbd: revert fsids on durable reconnect and replay failure Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 114/507] ksmbd: fix NULL pointer dereference in session_user_name() and session_account_type() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 7.3 115/507] rust: cpufreq: fix `undocumented_unsafe_blocks` in `PolicyCpu::from_cpu()` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 116/507] ASoC: SOF: Intel: hda-sdw-bpt: Stop active DMA before closing BPT streams Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 117/507] x86/bugs: Select the BHI mitigation based on the attack vector properly Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 118/507] x86/csum: Relax the len and proto constraints in 32-bit csum_ipv6_magic() Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 119/507] drm/i915/psr: Clear selective fetch area when duplicating plane state Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 120/507] drm/i915/display: Add enabled pipe planes into state for selective fetch Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 121/507] drm/i915/psr: Disable linked plane sel fetch as well Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 122/507] drm/i915/psr: Fix SFF and CFF CTL register bit definitions Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 123/507] drm/i915/psr: Dont clip plane state destination rectangle Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 124/507] drm/i915/display: Add quirk to force backlight type on some TUXEDO devices Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 125/507] drm/i915/gem: Reset err for each fence entry Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 126/507] drm/i915/display: Single scaler per pipe on WCL Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 127/507] drm/i915/display: Disable pipe joiner " Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 128/507] drm/i915/display: Allow port sync on PTL Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 129/507] net: atl1c: drop oversized RX frames instead of panicking Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 130/507] ksmbd: do not read past the DACL in the access denied debug message Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 131/507] ksmbd: grant a POSIX ACL group entry only to the groups members Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 132/507] ksmbd: let the owner read and change the DACL when no ACE names it Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 133/507] mm/mempolicy: charge shared policy nodes Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 134/507] tmpfs: keep the quota soft limits of an unused id Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 135/507] tmpfs: preserve explicitly disabled quota limits Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 136/507] mm/shmem: stop retrying folios that cannot be split Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 137/507] mm/shmem: preserve data in clean folios when splitting fails Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 138/507] mm/shmem: discard whole new large folios on fallocate rollback Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 139/507] mm/shmem: rescan after nonuniform folio splitting Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 140/507] mm/shmem: fix truncate hang in large swap entry Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 141/507] mm/shmem: preserve allocation errors when swapping in large entries Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 142/507] mm/shmem: fix truncate loop after boundary swapin failure Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 143/507] mm/shmem: fix accounting of swapin-error markers Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 144/507] mm/shmem: fix truncation of files containing only " Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 145/507] mm/mglru: dont use stack pointers when walking PUD and PMD tables Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 146/507] fork: take mmap_lock before copying mm_struct Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 147/507] mm/shmem: make shmem_file() check the files inode Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 148/507] mm/memfd: make f_pos accesses atomic Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 149/507] mm/truncate: look again if a folio left the mapping Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 150/507] mm/filemap: read mapping->a_ops->free_folio under i_lock Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 151/507] mm/filemap: dont lose a folio lock wakeup to a signal Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 152/507] mm/filemap: finish fault cleanup before dropping the fault lock Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 153/507] mm/rmap: handle device-exclusive entries in folio_referenced_one() Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 154/507] mm/huge_memory: fix list corruption when deferred_split_scan() races with deferred_split_folio() Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 155/507] mm/huge_memory: properly handle refcounted PUD mappings on fork Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 156/507] ext2: preserve completed DIO bytes when buffered fallback fails Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 157/507] xfs: set healthmon mount cookie before publishing it Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 158/507] xfs: dont skip free extents in later batches of a whole-AG FITRIM Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 159/507] xfs: dont skip free extents of the longest length in " Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 160/507] drm/v3d: Initialize timedout_batches when running a CSD job Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 161/507] drm/v3d: Widen cache_clean_lock over the whole L2TCACTL sequence Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 162/507] cipso: fix optlen corruption in cipso_v4_delopt() Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 163/507] ntfs: dont allow compression on volumes with clusters larger than 4K Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 164/507] vhost-vdpa: fix pinned page leak in vhost_vdpa_pa_map() error path Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 165/507] vringh: bound top-level re-entry into indirect tables Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 166/507] vringh: reject empty / undersized indirect descriptor tables Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 167/507] veth: keep carrier off when resizing channels with a down peer Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 168/507] hwmon: (sht15) Stop deferred work before releasing its resources Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 169/507] hwmon: (corsair-cpro) Cache fan target only after a successful command Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 170/507] hwmon: (aquacomputer_d5next) reject short status reports Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 171/507] hwmon: (asus_rog_ryujin) Fix pump control source on the Ryujin III Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 172/507] hwmon: (gpd-fan) Reset both fans to automatic on duo boards Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 173/507] hwmon: chipcap2: fix command error diagnostics Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 174/507] hwmon: chipcap2: fix off-by-one in command mode retry loop Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 7.3 175/507] hwmon: chipcap2: fix be16 handling Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 176/507] hwmon: chipcap2: defer probe when IRQs are unavailable Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 177/507] hwmon: chipcap2: fix IRQ teardown ordering Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 178/507] hwmon: chipcap2: disable device after hwmon teardown Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 179/507] hwmon: chipcap2: enable IRQ processing when regulator is already enabled Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 180/507] hwmon: chipcap2: balance regulator state Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 181/507] hwmon: chipcap2: do not discard pending alarms on disable Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 182/507] hwmon: chipcap2: serialize access to the alarm indicators Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 183/507] hwmon: chipcap2: synchronize ready IRQ state Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 184/507] hwmon: (aquacomputer_d5next) Check maxcollection when probing AQUAERO devices Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 185/507] hwmon: (asus_wmi_sensors) Avoid global struct mutation Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 186/507] hwmon: (hp-wmi-sensors) " Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 187/507] hwmon: (hp-wmi-sensors) Fix unbounded loops in scale_numeric_sensor() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 188/507] hwmon: (lm87) Fix drvdata type confusion in vrm_show() and vrm_store() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 189/507] hwmon: (nct6683) Fix incorrect struct cast in show_pwm() and store_pwm() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 190/507] hwmon: (peci/dimmtemp) Fix devres leak and UAF on concurrent unbind Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 191/507] hwmon: (pmbus/q54sj108a2) Add missing NULL pointer check Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 192/507] hwmon: (pmbus) Check return value from pmbus_thermal_add_sensor() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 193/507] hwmon: (pmbus) Release devres allocated memory after devm_thermal_of_zone_register error Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 194/507] hwmon: (pmbus) Fix return value check from thermal zone registration Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 195/507] hwmon: (lm75) Fix setting polarity mask for chips with 16-bit config register Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 196/507] hwmon: (tmp108) Fix initial conversion delay and wait until ready Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 197/507] hwmon: (gpio-fan) Update the speed cache before dropping the PM reference Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 198/507] hwmon: (coretemp) Check for NULL platform device in hotplug callbacks Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 199/507] hwmon: (coretemp) Set nr_cores only after core_data allocation succeeds Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 200/507] hwmon: (sht4x) Convert update_interval to jiffies in pending data check Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 201/507] hwmon: (aquacomputer_d5next) Avoid truncating scaled sensor readings Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 202/507] net: qrtr: announce local services again once our HELLO is sent Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 203/507] nvme-rdma: fix NULL queue->ctrl dereference on reconnect Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 204/507] nvme: unregister when pr_register() is given a zero new key Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 205/507] nvme: Do not drop the cdev reference twice when cdev_device_add() fails Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 206/507] KVM: x86/mmu: Conditionally resched when retrying gPTE walk on A/D update failure Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 207/507] KVM: x86: Conditionally resched when restarting REP string emulation Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 208/507] KVM: nVMX: Process each host MSR entry at most once when unwinding failed VM-Entry Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 209/507] KVM: x86/mmu: Cap number of parent PTEs per SP at 1000 (the arbitrary rmap limit) Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 210/507] KVM: x86: Unconditionally reset MMU context when emulating INIT Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 211/507] ASoC: tas2770: Fix error detection in tas2770_set_dai_tdm_idle Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 212/507] inet: frags: limit the truesize of a reassembly queue Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 213/507] ipv6: reject wrapped temporary address preferred lifetimes Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 214/507] x86/vmware: Fix i386 high-bandwidth hypercall arguments Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 215/507] Bluetooth: hci_sync: re-enable legacy advertising on resume Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 216/507] Bluetooth: hci_sync: pause advertising for the scan address update Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 217/507] Bluetooth: qca: Fix the WCN3950 NVM baud rate offset Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 218/507] ASoC: qcom: q6apm: Guard callbacks until probe data is ready Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 219/507] x86/resctrl: Correct ABMC counter ID field width Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 220/507] x86,fs/resctrl: Keep mbm_assign_mode in default mode at boot Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 221/507] mm/khugepaged: flush deferred unmaps before dropping a failed folio Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 222/507] mm: fix address wraparound when scanning large folio PTEs Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 223/507] mm: memory: fix truncation removing mapped folios Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 224/507] mm/page-writeback: avoid 32-bit overflow in dirty threshold shares Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 225/507] mm/page_alloc: let the highest memory node recover from hopeless state Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 226/507] mm/hugetlb: fix mremap move length truncation Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 227/507] mm/hugetlb: fix mremap deadlock when PMD sharing is possible Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 228/507] mm/page_alloc: mark pages freed by __free_pages_core() as not tagged Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 229/507] mm/vma: write lock source VMA before duplicating it in __split_vma() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 230/507] mm/ksm: keep soft-dirty when merging a page Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 231/507] fs/proc/task_mmu: return -ENOTTY for unknown pagemap ioctls Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 232/507] mm/damon/sysfs-schemes: hold damon_sysfs_lock in target_metric_store() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 233/507] mm/damon/core: move static variable last_nr_regions to damon_ctx Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 234/507] mm/damon/core: move static variable rotation " Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 7.3 235/507] mm: make swapoff interruptible when unusing mms/shmem Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 236/507] mm/migrate: untag addresses when querying page nodes Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 237/507] mm/ksm: fix userfaultfd protection during merge and unmerge Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 238/507] mm/migrate: snapshot the source nid before the misplaced migration Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 239/507] mm/vma: update VMA iterator state on error in new VMA merge Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 240/507] mm/hugetlb_vmemmap: map the shared tail page writable Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 241/507] mm: page_alloc: do not give all non-blocking requests reserve access Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 242/507] mm: page_alloc: remove ALLOC_NON_BLOCK from ALLOC_RESERVES Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 243/507] mm/cma: accept memory of multi-range CMA areas Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 244/507] mm/cma: accept memory of CMA areas reserved at a fixed address Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 245/507] mm: memcontrol: fix NULL pointer deref and UAF from high_work_func() on dying memcg Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 246/507] lib/base64: silence clang-24 -Wconstant-conversion with diag pragmas Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 247/507] openrisc: export __mulsi3 for modules Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 248/507] ocfs2: find the xattr entry again after defragmenting a bucket Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 249/507] ocfs2: find the xattr entry again after converting a block to " Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 250/507] ocfs2: do not read the entry array of an empty xattr bucket Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 251/507] ocfs2: do not index before the entry array when dividing an empty bucket Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 252/507] ocfs2: do not read the entry array of an empty xattr block Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 253/507] fat: hold truncate_lock in fat_write_failed() Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 254/507] ocfs2: validate move extents against a stable EOF Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 255/507] ocfs2: keep locking_state within the cluster connection lifetime Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 256/507] panic: zero the dynamically allocated taint buffer Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 257/507] ocfs2/dlm: serialize migration MLE cleanup on failure Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 258/507] ocfs2: stop recovery before shutting down local allocators Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 259/507] ocfs2/cluster: unlink socket containers before releasing resources Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 260/507] ocfs2: wait for filecheck kobject release after a failed add Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 261/507] ocfs2: cache the mount context for dentry lock callbacks Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 262/507] x86/init: Initialize wall clock in get_rtc_noop() Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 263/507] xfs: fix temporary cursor leak in btree shift corruption paths Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 264/507] net/sched: sch_qfq: prevent aggregate self-replacement Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 265/507] vhost-scsi: zero misaligned I/O bounce pages Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 266/507] vhost: fix used ring index wrap in vhost_add_used_n_in_order Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 267/507] iommu/virtio: Reset device before deleting virtqueues on probe failure Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 268/507] vdpa/snet: Dont discard the DPU error in snet_send_ctrl_msg() Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 269/507] drm/bridge: nwl-dsi: Cleanup endpoint mux control selection Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 270/507] drm/bridge: nwl-dsi: Limit LCDIF specific sync override Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 271/507] hwrng: virtio - prevent use-after-free after a failed restore Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 272/507] vduse: fix VA/PA confusion in the coherent page fault path Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 273/507] inotify: do not coalesce rename events Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 274/507] blk-mq: end the request if getting a keyslot fails Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 275/507] virtio_blk: use synchronous quiesce in virtblk_freeze_priv() Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 276/507] block: Return the soft block size for compat BLKBSZGET Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 277/507] xfs: fix wrong compat fields in xfs_ioctl32_bstat_copyin() Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 278/507] block: only serialize elevator switches of the same queue Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 279/507] blk-mq: fix out-of-bounds read in blk_mq_free_rqs Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 280/507] blk-iocost: account flush sequence latency only once Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 281/507] xfs: mark the inode preallocated for pNFS write layouts past EOF Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 282/507] xfs: add a flag to convert unwritten extents without allocating blocks Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 283/507] xfs: refuse a pNFS LAYOUTCOMMIT of a range without blocks Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 284/507] xfs: clamp a pNFS LAYOUTCOMMIT extent before computing its end Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 285/507] xfs: cap the block count of xfs_iomap_write_direct() at one extent Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 286/507] xfs: clamp the pNFS layout range to the maximum file size Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 287/507] net: restore refcount ordering for lockless socket access Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 288/507] xfs: fix recovery of partial attr removals Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 289/507] nvmet: reject keep-alive timeouts that would overflow Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 290/507] can: dev: can_dropped_invalid_skb: drop CAN XL frames on non-CAN XL devices Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 291/507] can: isotp: check the frame type, not just the length Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 292/507] can: skb: make echo skb freeing safe in any IRQ context Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 293/507] can: dev: can_put_echo_skb(): free skb on invalid echo index Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 294/507] can: replace ARPHRD_CAN type checks with can_get_ml_priv() Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 7.3 295/507] can: isotp: check the return values of can_rx_register() in isotp_bind() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 296/507] can: protect the receive lists with a per-device lock Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 297/507] can: raw, isotp: copy socket options outside of lock_sock() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 298/507] can: proc: reset pkg_stats atomics individually Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 299/507] can: proc: skip stats calculation after reset in can_stat_update() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 300/507] can: dev: can_fill_info(): dont wake up controller if interface is down Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 301/507] can: peak_usb: pcan_usb_fd_decode_buf(): accept short uCAN end-of-list records Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 302/507] mm/huge_memory: fix truncate racing with PMD zapping Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 303/507] mm/huge_memory: fix zapping migration entries for device-private THPs Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 304/507] mm/khugepaged: always recheck the pmd in try_collapse_pte_mapped_thp() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 305/507] mm/khugepaged: fix PMD table lock leak " Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 306/507] mm/khugepaged: preserve dirty bits when collapsing PTE-mapped THPs Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 307/507] mm/gup: recheck the PUD under PTL in follow_pud_mask() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 308/507] mm/gup: fix clearing folios in memfd_pin_folios() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 309/507] mm/gup: fix out-of-bounds write for nr_pages == 0 in GUP-fast Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 310/507] mm/gup: check for overflow when converting nr_pages to bytes " Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 311/507] mm/userfaultfd: write-lock the VMA before waking waiters when unregistering Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 312/507] mm/userfaultfd: wake all waiters on unregister Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 313/507] mm/mmu_gather: fix flushing ranges with 4 GiB or larger Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 314/507] mm/mmu_notifier: finish non-blocking interval invalidation on error Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 315/507] mm/mmu_notifier: set ->mm only after mmgrab() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 316/507] mm/mremap: use pudp_huge_get_and_clear() when moving huge PUDs Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 317/507] mm/mremap: recheck PUDs under the page table lock Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 318/507] mm/mremap: fix moving PUD leaves Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 319/507] mm/madvise: fix data loss from MADV_FREE on a KSM page Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 320/507] mm/memory: reject remote COW faults on PFN mappings Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 321/507] mm: fix unmap_mapping_range() beyond 4 GiB on 32-bit Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 322/507] mm: fix unkillable fault loop on MAP_DROPPABLE memory Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 323/507] mm: fix deadlock of mremap() against UFFDIO_MOVE Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 324/507] mm/ksm: reset the unstable trees of all nodes Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 325/507] mm/ksm: fix use of a freed anon_vma at swap-in Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 326/507] mm/ksm: check large swap-cache folios before mapping them Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 327/507] mm/vma: call ->may_split() before a partial merge Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 328/507] mm/huge_memory: split huge PUDs when adjusting VMA boundaries Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 329/507] mm/vma: dont leak the charge for stack growth Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 330/507] mm/cma: dont release CMA pages still in use Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 331/507] mm/memory-tiers: unregister empty tiers outside memory_tier_lock Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 332/507] mm/huge_memory: set the mmu_gather page size in zap_huge_pud() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 333/507] khugepaged: fix readahead lock inversion in collapse_file() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 334/507] mm/gup: check folio->mapping under folio lock in memfd_pin_folios() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 335/507] x86/entry: Fix ptrace regression Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 336/507] ipv6: fix device binding after failed datagram connect Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 337/507] ovl: fail the mount if the casefold flag has changed Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 338/507] ovl: do not let chattr change the casefold flag Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 339/507] ovl: fix whiteout creation in casefolded directories Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 340/507] net/sched: clamp skb->queue_mapping before indexing the tx queue Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 341/507] ovl: inherit FMODE_NONOTIFY when opening directory realfiles Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 342/507] net: reject a negative TCP header offset in qdisc_pkt_len_segs_init() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 343/507] vhost/vsock: size receive SKBs from declared payload Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 344/507] mptcp: do not use Fast Open on MP_JOIN subflows Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 345/507] ublk: add missing DEL_DEV_ASYNC to unprivileged permission check Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 346/507] nvme-keyring: Add a missing key_put() call to nvme_tls_key_lookup() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 347/507] drm/amdgpu: Check cs flags Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 348/507] drm/amdgpu: skip RAS error count reset in debug mode Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 349/507] drm/amdgpu: sign extend the addresses GEM_OP(GET_MAPPING_INFO) returns Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 350/507] drm/amdgpu: parse CS IBs at the BO offset their VA mapping starts at Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 351/507] drm/amdgpu: keep the CS user fence BO in GTT Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 352/507] drm/amdkfd: use the queues process info for the WPTR BO eviction fence Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 353/507] drm/amdgpu/userq: wait for GPU reset before mapping or unmapping queues Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 354/507] drm/amdgpu: check amdgpu_vm_ready() in dma-buf move notify Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 7.3 355/507] drm/amdgpu/userq: validate the moved individual BOs on restore Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 356/507] drm/amd/display: add missing CRC engine 1 registers Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 357/507] drm/amdgpu: finish GPU recovery callbacks before restarting schedulers Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 358/507] drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts for navi10_ih Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 359/507] drm/amdgpu: stop the schedulers before preparing the GPU reset Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 360/507] drm/amdgpu: Ensure that harvest information gets set Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 361/507] drm/amdgpu: publish IH enabled before PSP programs IH_RB_CNTL Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 362/507] drm/amd/display: Avoid closing unowned DDC pins Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 363/507] drm/amd/display: Reset DET of HUBPs without a plane before outstanding updates Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 364/507] drm/amdgpu/gfx12: disallow GFXOFF while updating the SPM VMID Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 365/507] drm/amd/display: Fix NULL deref in dcn401_update_clocks_update_dtb_dto Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 366/507] drm/amd/display: Drop clock requirements on DCN32 when no displays are active Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 367/507] drm/amd/display: Keep the nominal vtotal while VRR is inactive Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 368/507] drm/amd/display: Dont select zero V_TOTAL_MIN/MAX on seamless boot Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 369/507] drm/amd/display: set allow_freesync before validating a new stream Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 370/507] drm/amd/display: Signal PQ EOTF in FreeSync infopacket for DP HDR Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 371/507] drm/amd/pm: populate unique ID for smu 13.0.7 Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 372/507] drm/amdgpu: Fix duplicate dependency fence releases Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 373/507] drm/amdgpu: Report MES ring wait timeouts Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 374/507] drm/amdgpu: Clamp the ATIF backlight curve to its 99 points Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 375/507] drm/amdgpu: drop the dma-buf reference when a KFD import fails Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 376/507] drm/amdgpu: unlock the VM and BO when attaching a KFD BO fails Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 377/507] drm/amdgpu: rewrite all PTEs of the BOs after a VM reset Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 378/507] drm/amdgpu: dont walk the CS chunks when allocating them failed Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 379/507] drm/amdgpu: Only enable HDMI audio if display supports it Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 380/507] drm/amdgpu: dont drop the gang dependency fence twice Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 381/507] nvmet: dont return memory contents beyond valid data when reading ANA log page Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 382/507] arm64: suspend: Save and restore TPIDR2_EL0 across CPU suspend Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 383/507] arm64: mm: validate /dev/mem mmap ranges without overflow Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 384/507] nvme-pci: add NVME_QUIRK_DMAPOOL_ALIGN_512 for KIOXIA XG10d Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 385/507] ovl: look up the index by the decoded origin Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 386/507] selftests/fscontext_ns: expect EINVAL for overlay descendant userns create Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 387/507] l2tp: only return sessions of the given tunnel in l2tp_session_get() Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 388/507] drm/nouveau/nvkm: clear use.enabled when subdev init fails Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 389/507] drm/dp: keep MOT set between messages when no_zero_sized is set Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 390/507] drm/nouveau/devinit/gf100-: try to avoid double-running vbios scripts Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 391/507] ALSA: ump: Fix dropped data bytes at UMP System message conversion Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 392/507] ALSA: hda/realtek: Enable bass speakers on Alienware m17 R3 Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 393/507] ALSA: cs46xx: Handle SCB creation failures before dereferencing Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 394/507] ALSA: bcd2000: Fix use-after-free of MIDI URBs on file close Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 395/507] ALSA: usx2y: Refuse a retried DSP load after a failure Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 396/507] ALSA: usb-audio: qcom: Check the return value of qmi_handle_init() Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 397/507] ALSA: hda/realtek: Enable mute and mic-mute LEDs on HP ENVY 17-cr0xxx Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 398/507] ALSA: hda/tas2781: Only accept CRC-less V1 data if all entries are valid Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 399/507] ALSA: line6: Reject capture buffers smaller than two packets Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 400/507] ALSA: caiaq: free the EP4 URB when input setup fails Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 401/507] ALSA: usx2y: Require a buffer of two URBs Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 402/507] ALSA: usx2y: Guard the playback copy Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 403/507] ext2: preserve IOMAP_F_DIRTY for extending direct writes Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 404/507] net/smc: dont spin in smc_rx_recvmsg() while a pipe holds spliced data Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 405/507] net: count last skb of each sk_backlog pass in __release_sock() Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 406/507] net: ethernet: ti: am65-cpsw-nuss: Enable timestamping of unicast PTP packets Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 407/507] drm/etnaviv: Fix NULL dereference on unbind without PPU flop reset Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 408/507] drm/etnaviv: Flush the tile status cache through both the PE and BLT Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 409/507] drm/sched: Fix out of bounds entity priority check Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 410/507] drm/sched: Adjust run-queue when changing priority at runtime Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 411/507] mptcp: pm: kernel: use RCU to free endpoint listeners Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 412/507] udf: dont let the extent type hide an exhausted free-space table extent Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 413/507] udf: check the unallocated space table when it is loaded Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 414/507] udf: fix preallocation discarding before an empty allocation extent Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 7.3 415/507] udf: dont use eloc after the end of the unallocated space table Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 416/507] MIPS: mm: Fix the cache error vector jump for XKPHYS kernels Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 417/507] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 418/507] MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 419/507] srcu: Add list_splice_init_srcu() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 420/507] nvme: wait for SRCU readers before splicing the namespace list Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 421/507] nvmet: bound the traddr and trsvcid configfs writes Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 422/507] perf/core: Dont send SIGTRAP after exec removed the event Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 423/507] sched/fair: Clear throttle state when leaving the fair class Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 424/507] x86/nmi: Ignore negative NMI handler durations Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 425/507] iommu/amd: Skip non-IVMD entries when parsing IVRS memory definitions Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 426/507] iommu/amd: remove obsolete domain pointer warning on release Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 427/507] arm64: kexec_file: Fix elf_headers memory leak in retry loop Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 428/507] x86/boot: Fix off-by-one error in sme_clear_pgd() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 429/507] arm64: sdei: Run the event handler on the kernel vectors Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 430/507] arm64: sdei: Preserve the interrupted contexts exception registers Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 431/507] ata: libata-pmp: disable the SEMB port on Marvell 88SM9705 Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 432/507] x86/mm: Fix global ASID handed out to two processes Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 433/507] iommu/amd: Force device table to maximum size Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 434/507] ceph: clamp the inline data length in ceph_fill_inline_data() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 435/507] vxlan: Stop rejecting dynamic FDB entries with a nexthop ID Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 436/507] batman-adv: tt: only transmit local ROAM flag together with DEL Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 437/507] batman-adv: tt: clear ROAM flag when re-adding a pending local client Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 438/507] batman-adv: tt: send ROAM_ADV on each roamed back client Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 439/507] batman-adv: tt: only update flags for TT events Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 440/507] ata: libata-scsi: reject data-in commands with a data-out buffer Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 441/507] iommu/arm-smmu-v3: Handle ARM erratum for CONT under invalidation with SVA Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 442/507] ASoC: cs35l56: Wait for firmware timer expiry before system suspend Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 443/507] mtd: spi-nor: macronix: Restore fallback parameters for MX25L12805D Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 444/507] media: microchip-isc: store the unshifted PFE_CFG0 BPS value Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 445/507] media: microchip-isc: fix WB offset and gain register field masking Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 446/507] KVM: arm64: Pass kvm_s2_fault_desc to fault_supports_stage2_huge_mapping() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 447/507] KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 448/507] media: microchip-isc: fix ISC_PFG_CFG0_BPS macro name typo Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 449/507] media: microchip-isc: fix SBGGR10 Bayer pattern Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 450/507] ALSA: usb-audio: keep MIDI input running for Roland TD-11 Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 451/507] ALSA: usb-audio: Protect Roland control activation Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 452/507] f2fs: fix to avoid folio->mapping dereference in is_{meta, node}_folio() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 453/507] f2fs: fix to check continuousness in f2fs_sync_meta_pages() correctly Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 454/507] ALSA: hda/realtek: Fix speakers on ASUS ExpertBook PM3606CHA Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 455/507] ALSA: hda/realtek: Fix internal mic on Minisforum V3 and V3 SE Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 456/507] sctp: hold shkey across socket migration Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 457/507] sctp: re-point retained control chunks on association migration Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 458/507] fs/ntfs3: validate the EA value length in ntfs_read_ea() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 459/507] platform/chrome: Fix typos in comments Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 460/507] platform/chrome: cros_usbpd_notify: Only use drvdata when parent is GOOG0004 Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 461/507] mm/userfaultfd: only allocate anon_vma in CoW mappings Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 462/507] mm: add RCU-based VMA lookup helper that waits for writers Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 463/507] mm/vma: avoid spurious write locks when mm->mm_lock_seq overflows Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 464/507] mm/shmem: honour F_SEAL_EXEC when an ACL is set Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 465/507] nvme-tcp: skip TLS control records while waiting for the ICResp Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 466/507] wifi: rtw88: usb: route bmc frames via the high queue only for DTIM delivery Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 467/507] wifi: rtw88: usb: bound what the driver feeds the after-DTIM queue Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 468/507] wifi: rtw88: usb: only let the frames a dozing station needs use " Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 469/507] wifi: rtw88: widen the ATIM window while an AP interface is up Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 470/507] mm/page_alloc: avoid direct reclaim and compaction for costly __GFP_NORETRY allocations Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 471/507] dmaengine: qcom: bam_dma: Defer IRQ trigger type to device tree Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 472/507] dmaengine: qcom: bam_dma: free interrupt before the clock in error path Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 473/507] KVM: arm64: Use kvm_s2_fault_vma_info in pkvm_mem_abort() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 474/507] f2fs: zone: fix to avoid bio split on sequential zone Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 7.3 475/507] f2fs: return -EIO for a lost inode block after cp_error Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 476/507] f2fs: bound the SIT/NAT bitmaps by the checkpoint pack Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 477/507] perf evsel: Restrict incremental open error unwind Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 478/507] perf evsel: Close the fds opened so far when disabling missing features Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 479/507] KVM: arm64: vgic: Stop the target vcpu when disabling LPIs Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 480/507] f2fs: fix to avoid potential reference count leak in do_garbage_collect() Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 481/507] nvme-tcp: Validate the queue state under the queue lock in the address attribute Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 482/507] ASoC: hdac_hda: Allocate the private data at codec driver bind Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 483/507] ASoC: hdac_hda: Restore the codec device type on unbind Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 484/507] erofs: fix metadata reads at the end of file-backed images Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 485/507] PCI: cadence: Remove device links to PHY Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 486/507] PCI: cadence: Store the core controller in platform drvdata Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 487/507] PCI: cadence: Preserve all error codes in cdns_plat_pcie_probe() Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 488/507] f2fs: fix to invalidate curseg if change_curseg() fails Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 489/507] ACPI: utils: Add exclusive AML evaluation helpers Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 490/507] ACPI: battery: Evaluate battery methods exclusively Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 491/507] PCI: dwc: Set DMA_BYPASS bit in outbound IATU CTRL2 register Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 492/507] clk: nuvoton: ma35d1: Keep the clock count in the driver Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 493/507] dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 494/507] dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 495/507] clk: nuvoton: " Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 496/507] f2fs: release a removed xattr node in roll-forward recovery Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 497/507] media: ipu6: Rename pointer to firmware context Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 498/507] media: ipu6: Fix firmware config leak on stream start Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 499/507] iommufd/iova_bitmap: Ensure that iova_bitmap_set() handles the full IOVA Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 500/507] thermal: intel: int340x: Evaluate _TMP exclusively Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 501/507] intel_idle: Use 2-argument strscpy() Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 502/507] intel_idle: Adjust state names and descriptions for _LPI states Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 503/507] f2fs: expose resizable_tail feature via sysfs Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 504/507] mm/mglru: use explicit tier range in read_ctrl_pos() Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 505/507] mm/vmscan: avoid false-positive -Wuninitialized warning, again Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 506/507] f2fs: fix to use bio_in_atomic() in f2fs_write_end_io() Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 7.3 507/507] ASoC: amd: yc: Add DMI quirk for HP OmniBook 3 Laptop 16-by0xxx Greg Kroah-Hartman
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.